diff options
Diffstat (limited to 'drivers/ieee1394')
-rw-r--r-- | drivers/ieee1394/dv1394.c | 8 | ||||
-rw-r--r-- | drivers/ieee1394/eth1394.c | 108 | ||||
-rw-r--r-- | drivers/ieee1394/eth1394.h | 4 | ||||
-rw-r--r-- | drivers/ieee1394/highlevel.c | 45 | ||||
-rw-r--r-- | drivers/ieee1394/highlevel.h | 16 | ||||
-rw-r--r-- | drivers/ieee1394/hosts.c | 11 | ||||
-rw-r--r-- | drivers/ieee1394/hosts.h | 10 | ||||
-rw-r--r-- | drivers/ieee1394/ieee1394_core.c | 11 | ||||
-rw-r--r-- | drivers/ieee1394/ieee1394_core.h | 15 | ||||
-rw-r--r-- | drivers/ieee1394/ieee1394_transactions.c | 30 | ||||
-rw-r--r-- | drivers/ieee1394/ieee1394_transactions.h | 2 | ||||
-rw-r--r-- | drivers/ieee1394/nodemgr.c | 195 | ||||
-rw-r--r-- | drivers/ieee1394/nodemgr.h | 5 | ||||
-rw-r--r-- | drivers/ieee1394/ohci1394.c | 272 | ||||
-rw-r--r-- | drivers/ieee1394/ohci1394.h | 14 | ||||
-rw-r--r-- | drivers/ieee1394/pcilynx.c | 16 | ||||
-rw-r--r-- | drivers/ieee1394/raw1394-private.h | 5 | ||||
-rw-r--r-- | drivers/ieee1394/raw1394.c | 372 | ||||
-rw-r--r-- | drivers/ieee1394/raw1394.h | 4 | ||||
-rw-r--r-- | drivers/ieee1394/sbp2.c | 122 | ||||
-rw-r--r-- | drivers/ieee1394/sbp2.h | 2 | ||||
-rw-r--r-- | drivers/ieee1394/video1394.c | 10 |
22 files changed, 453 insertions, 824 deletions
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c index 208141377612..65722117ab6e 100644 --- a/drivers/ieee1394/dv1394.c +++ b/drivers/ieee1394/dv1394.c @@ -2280,7 +2280,7 @@ static void dv1394_remove_host(struct hpsb_host *host) } while (video); if (found_ohci_card) - class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, + device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (host->id << 2))); } @@ -2295,9 +2295,9 @@ static void dv1394_add_host(struct hpsb_host *host) ohci = (struct ti_ohci *)host->hostdata; - class_device_create(hpsb_protocol_class, NULL, MKDEV( - IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), - NULL, "dv1394-%d", id); + device_create(hpsb_protocol_class, NULL, MKDEV( + IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), + "dv1394-%d", id); dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE); dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT); diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index 2296d43a2414..93362eed94ed 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c @@ -47,6 +47,7 @@ #include <linux/types.h> #include <linux/delay.h> #include <linux/init.h> +#include <linux/workqueue.h> #include <linux/netdevice.h> #include <linux/inetdevice.h> @@ -235,6 +236,9 @@ static int ether1394_open(struct net_device *dev) /* This is called after an "ifdown" */ static int ether1394_stop(struct net_device *dev) { + /* flush priv->wake */ + flush_scheduled_work(); + netif_stop_queue(dev); return 0; } @@ -531,6 +535,37 @@ static void ether1394_init_dev(struct net_device *dev) } /* + * Wake the queue up after commonly encountered transmit failure conditions are + * hopefully over. Currently only tlabel exhaustion is accounted for. + */ +static void ether1394_wake_queue(struct work_struct *work) +{ + struct eth1394_priv *priv; + struct hpsb_packet *packet; + + priv = container_of(work, struct eth1394_priv, wake); + packet = hpsb_alloc_packet(0); + + /* This is really bad, but unjam the queue anyway. */ + if (!packet) + goto out; + + packet->host = priv->host; + packet->node_id = priv->wake_node; + /* + * A transaction label is all we really want. If we get one, it almost + * always means we can get a lot more because the ieee1394 core recycled + * a whole batch of tlabels, at last. + */ + if (hpsb_get_tlabel(packet) == 0) + hpsb_free_tlabel(packet); + + hpsb_free_packet(packet); +out: + netif_wake_queue(priv->wake_dev); +} + +/* * This function is called every time a card is found. It is generally called * when the module is installed. This is where we add all of our ethernet * devices. One for each host. @@ -564,16 +599,15 @@ static void ether1394_add_host(struct hpsb_host *host) } SET_MODULE_OWNER(dev); -#if 0 - /* FIXME - Is this the correct parent device anyway? */ SET_NETDEV_DEV(dev, &host->device); -#endif priv = netdev_priv(dev); INIT_LIST_HEAD(&priv->ip_node_list); spin_lock_init(&priv->lock); priv->host = host; priv->local_fifo = fifo_addr; + INIT_WORK(&priv->wake, ether1394_wake_queue); + priv->wake_dev = dev; hi = hpsb_create_hostinfo(ð1394_highlevel, host, sizeof(*hi)); if (hi == NULL) { @@ -1390,22 +1424,17 @@ static int ether1394_prep_write_packet(struct hpsb_packet *p, u64 addr, void *data, int tx_len) { p->node_id = node; - p->data = NULL; - p->tcode = TCODE_WRITEB; - p->header[1] = host->node_id << 16 | addr >> 32; - p->header[2] = addr & 0xffffffff; + if (hpsb_get_tlabel(p)) + return -EAGAIN; + p->tcode = TCODE_WRITEB; p->header_size = 16; p->expect_response = 1; - - if (hpsb_get_tlabel(p)) { - ETH1394_PRINT_G(KERN_ERR, "Out of tlabels\n"); - return -1; - } p->header[0] = p->node_id << 16 | p->tlabel << 10 | 1 << 8 | TCODE_WRITEB << 4; - + p->header[1] = host->node_id << 16 | addr >> 32; + p->header[2] = addr & 0xffffffff; p->header[3] = tx_len << 16; p->data_size = (tx_len + 3) & ~3; p->data = data; @@ -1451,7 +1480,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len) packet = ether1394_alloc_common_packet(priv->host); if (!packet) - return -1; + return -ENOMEM; if (ptask->tx_type == ETH1394_GASP) { int length = tx_len + 2 * sizeof(quadlet_t); @@ -1462,7 +1491,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len) ptask->addr, ptask->skb->data, tx_len)) { hpsb_free_packet(packet); - return -1; + return -EAGAIN; } ptask->packet = packet; @@ -1471,7 +1500,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len) if (hpsb_send_packet(packet) < 0) { ether1394_free_packet(packet); - return -1; + return -EIO; } return 0; @@ -1514,13 +1543,18 @@ static void ether1394_complete_cb(void *__ptask) ptask->outstanding_pkts--; if (ptask->outstanding_pkts > 0 && !fail) { - int tx_len; + int tx_len, err; /* Add the encapsulation header to the fragment */ tx_len = ether1394_encapsulate(ptask->skb, ptask->max_payload, &ptask->hdr); - if (ether1394_send_packet(ptask, tx_len)) + err = ether1394_send_packet(ptask, tx_len); + if (err) { + if (err == -EAGAIN) + ETH1394_PRINT_G(KERN_ERR, "Out of tlabels\n"); + ether1394_dg_complete(ptask, 1); + } } else { ether1394_dg_complete(ptask, fail); } @@ -1529,7 +1563,7 @@ static void ether1394_complete_cb(void *__ptask) /* Transmit a packet (called by kernel) */ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev) { - struct eth1394hdr *eth; + struct eth1394hdr hdr_buf; struct eth1394_priv *priv = netdev_priv(dev); __be16 proto; unsigned long flags; @@ -1559,16 +1593,17 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev) if (!skb) goto fail; - /* Get rid of the fake eth1394 header, but save a pointer */ - eth = (struct eth1394hdr *)skb->data; + /* Get rid of the fake eth1394 header, but first make a copy. + * We might need to rebuild the header on tx failure. */ + memcpy(&hdr_buf, skb->data, sizeof(hdr_buf)); skb_pull(skb, ETH1394_HLEN); - proto = eth->h_proto; + proto = hdr_buf.h_proto; dg_size = skb->len; /* Set the transmission type for the packet. ARP packets and IP * broadcast packets are sent via GASP. */ - if (memcmp(eth->h_dest, dev->broadcast, ETH1394_ALEN) == 0 || + if (memcmp(hdr_buf.h_dest, dev->broadcast, ETH1394_ALEN) == 0 || proto == htons(ETH_P_ARP) || (proto == htons(ETH_P_IP) && IN_MULTICAST(ntohl(ip_hdr(skb)->daddr)))) { @@ -1580,7 +1615,7 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev) if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF]) priv->bc_dgl++; } else { - __be64 guid = get_unaligned((u64 *)eth->h_dest); + __be64 guid = get_unaligned((u64 *)hdr_buf.h_dest); node = eth1394_find_node_guid(&priv->ip_node_list, be64_to_cpu(guid)); @@ -1633,10 +1668,26 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev) /* Add the encapsulation header to the fragment */ tx_len = ether1394_encapsulate(skb, max_payload, &ptask->hdr); dev->trans_start = jiffies; - if (ether1394_send_packet(ptask, tx_len)) - goto fail; + if (ether1394_send_packet(ptask, tx_len)) { + if (dest_node == (LOCAL_BUS | ALL_NODES)) + goto fail; + + /* At this point we want to restore the packet. When we return + * here with NETDEV_TX_BUSY we will get another entrance in this + * routine with the same skb and we need it to look the same. + * So we pull 4 more bytes, then build the header again. */ + skb_pull(skb, 4); + ether1394_header(skb, dev, ntohs(hdr_buf.h_proto), + hdr_buf.h_dest, NULL, 0); + + /* Most failures of ether1394_send_packet are recoverable. */ + netif_stop_queue(dev); + priv->wake_node = dest_node; + schedule_work(&priv->wake); + kmem_cache_free(packet_task_cache, ptask); + return NETDEV_TX_BUSY; + } - netif_wake_queue(dev); return NETDEV_TX_OK; fail: if (ptask) @@ -1650,9 +1701,6 @@ fail: priv->stats.tx_errors++; spin_unlock_irqrestore(&priv->lock, flags); - if (netif_queue_stopped(dev)) - netif_wake_queue(dev); - /* * FIXME: According to a patch from 2003-02-26, "returning non-zero * causes serious problems" here, allegedly. Before that patch, diff --git a/drivers/ieee1394/eth1394.h b/drivers/ieee1394/eth1394.h index a3439ee7cb4e..4f3e2dd46f00 100644 --- a/drivers/ieee1394/eth1394.h +++ b/drivers/ieee1394/eth1394.h @@ -66,6 +66,10 @@ struct eth1394_priv { int bc_dgl; /* Outgoing broadcast datagram label */ struct list_head ip_node_list; /* List of IP capable nodes */ struct unit_directory *ud_list[ALL_NODES]; /* Cached unit dir list */ + + struct work_struct wake; /* Wake up after xmit failure */ + struct net_device *wake_dev; /* Stupid backlink for .wake */ + nodeid_t wake_node; /* Destination of failed xmit */ }; diff --git a/drivers/ieee1394/highlevel.c b/drivers/ieee1394/highlevel.c index 83a493312751..b6425469b6ee 100644 --- a/drivers/ieee1394/highlevel.c +++ b/drivers/ieee1394/highlevel.c @@ -483,37 +483,6 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host, return retval; } -/** - * hpsb_listen_channel - enable receving a certain isochronous channel - * - * Reception is handled through the @hl's iso_receive op. - */ -int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, - unsigned int channel) -{ - if (channel > 63) { - HPSB_ERR("%s called with invalid channel", __FUNCTION__); - return -EINVAL; - } - if (host->iso_listen_count[channel]++ == 0) - return host->driver->devctl(host, ISO_LISTEN_CHANNEL, channel); - return 0; -} - -/** - * hpsb_unlisten_channel - disable receving a certain isochronous channel - */ -void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, - unsigned int channel) -{ - if (channel > 63) { - HPSB_ERR("%s called with invalid channel", __FUNCTION__); - return; - } - if (--host->iso_listen_count[channel] == 0) - host->driver->devctl(host, ISO_UNLISTEN_CHANNEL, channel); -} - static void init_hpsb_highlevel(struct hpsb_host *host) { INIT_LIST_HEAD(&dummy_zero_addr.host_list); @@ -570,20 +539,6 @@ void highlevel_host_reset(struct hpsb_host *host) read_unlock_irqrestore(&hl_irqs_lock, flags); } -void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length) -{ - unsigned long flags; - struct hpsb_highlevel *hl; - int channel = (((quadlet_t *)data)[0] >> 8) & 0x3f; - - read_lock_irqsave(&hl_irqs_lock, flags); - list_for_each_entry(hl, &hl_irqs, irq_list) { - if (hl->iso_receive) - hl->iso_receive(host, channel, data, length); - } - read_unlock_irqrestore(&hl_irqs_lock, flags); -} - void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction, void *data, size_t length) { diff --git a/drivers/ieee1394/highlevel.h b/drivers/ieee1394/highlevel.h index 63474f7ee69d..eb9fe321e09a 100644 --- a/drivers/ieee1394/highlevel.h +++ b/drivers/ieee1394/highlevel.h @@ -26,9 +26,7 @@ struct hpsb_address_serve { struct hpsb_highlevel { const char *name; - /* Any of the following pointers can legally be NULL, except for - * iso_receive which can only be NULL when you don't request - * channels. */ + /* Any of the following pointers can legally be NULL. */ /* New host initialized. Will also be called during * hpsb_register_highlevel for all hosts already installed. */ @@ -43,13 +41,6 @@ struct hpsb_highlevel { * You can not expect to be able to do stock hpsb_reads. */ void (*host_reset)(struct hpsb_host *host); - /* An isochronous packet was received. Channel contains the channel - * number for your convenience, it is also contained in the included - * packet header (first quadlet, CRCs are missing). You may get called - * for channel/host combinations you did not request. */ - void (*iso_receive)(struct hpsb_host *host, int channel, - quadlet_t *data, size_t length); - /* A write request was received on either the FCP_COMMAND (direction = * 0) or the FCP_RESPONSE (direction = 1) register. The cts arg * contains the cts field (first byte of data). */ @@ -109,7 +100,6 @@ int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store, int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store, u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags); -void highlevel_iso_receive(struct hpsb_host *host, void *data, size_t length); void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction, void *data, size_t length); @@ -125,10 +115,6 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host, struct hpsb_address_ops *ops, u64 start, u64 end); int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, struct hpsb_host *host, u64 start); -int hpsb_listen_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, - unsigned int channel); -void hpsb_unlisten_channel(struct hpsb_highlevel *hl, struct hpsb_host *host, - unsigned int channel); void *hpsb_get_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host); void *hpsb_create_hostinfo(struct hpsb_highlevel *hl, struct hpsb_host *host, diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c index bd0755c789c5..8dd09d850419 100644 --- a/drivers/ieee1394/hosts.c +++ b/drivers/ieee1394/hosts.c @@ -154,15 +154,16 @@ struct hpsb_host *hpsb_alloc_host(struct hpsb_host_driver *drv, size_t extra, memcpy(&h->device, &nodemgr_dev_template_host, sizeof(h->device)); h->device.parent = dev; + set_dev_node(&h->device, dev_to_node(dev)); snprintf(h->device.bus_id, BUS_ID_SIZE, "fw-host%d", h->id); - h->class_dev.dev = &h->device; - h->class_dev.class = &hpsb_host_class; - snprintf(h->class_dev.class_id, BUS_ID_SIZE, "fw-host%d", h->id); + h->host_dev.parent = &h->device; + h->host_dev.class = &hpsb_host_class; + snprintf(h->host_dev.bus_id, BUS_ID_SIZE, "fw-host%d", h->id); if (device_register(&h->device)) goto fail; - if (class_device_register(&h->class_dev)) { + if (device_register(&h->host_dev)) { device_unregister(&h->device); goto fail; } @@ -202,7 +203,7 @@ void hpsb_remove_host(struct hpsb_host *host) host->driver = &dummy_driver; highlevel_remove_host(host); - class_device_unregister(&host->class_dev); + device_unregister(&host->host_dev); device_unregister(&host->device); } diff --git a/drivers/ieee1394/hosts.h b/drivers/ieee1394/hosts.h index feb55d032294..e4e8aeb4d778 100644 --- a/drivers/ieee1394/hosts.h +++ b/drivers/ieee1394/hosts.h @@ -28,8 +28,6 @@ struct hpsb_host { struct timer_list timeout; unsigned long timeout_interval; - unsigned char iso_listen_count[64]; - int node_count; /* number of identified nodes on this bus */ int selfid_count; /* total number of SelfIDs received */ int nodes_active; /* number of nodes with active link layer */ @@ -57,7 +55,7 @@ struct hpsb_host { struct hpsb_host_driver *driver; struct pci_dev *pdev; struct device device; - struct class_device class_dev; + struct device host_dev; struct delayed_work delayed_reset; unsigned config_roms:31; @@ -99,12 +97,6 @@ enum devctl_cmd { /* Cancel all outstanding async requests without resetting the bus. * Return void. */ CANCEL_REQUESTS, - - /* Start or stop receiving isochronous channel in arg. Return void. - * This acts as an optimization hint, hosts are not required not to - * listen on unrequested channels. */ - ISO_LISTEN_CHANNEL, - ISO_UNLISTEN_CHANNEL }; enum isoctl_cmd { diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index 8f71b6a06aa0..ee45259573c8 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c @@ -30,6 +30,7 @@ #include <linux/moduleparam.h> #include <linux/bitops.h> #include <linux/kdev_t.h> +#include <linux/freezer.h> #include <linux/suspend.h> #include <linux/kthread.h> #include <linux/preempt.h> @@ -1028,11 +1029,6 @@ void hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size, handle_incoming_packet(host, tcode, data, size, write_acked); break; - - case TCODE_ISO_DATA: - highlevel_iso_receive(host, data, size); - break; - case TCODE_CYCLE_START: /* simply ignore this packet if it is passed on */ break; @@ -1133,8 +1129,6 @@ static int hpsbpkt_thread(void *__hi) struct list_head tmp; int may_schedule; - current->flags |= PF_NOFREEZE; - while (!kthread_should_stop()) { INIT_LIST_HEAD(&tmp); @@ -1316,7 +1310,6 @@ EXPORT_SYMBOL(hpsb_make_streampacket); EXPORT_SYMBOL(hpsb_make_lockpacket); EXPORT_SYMBOL(hpsb_make_lock64packet); EXPORT_SYMBOL(hpsb_make_phypacket); -EXPORT_SYMBOL(hpsb_make_isopacket); EXPORT_SYMBOL(hpsb_read); EXPORT_SYMBOL(hpsb_write); EXPORT_SYMBOL(hpsb_packet_success); @@ -1327,8 +1320,6 @@ EXPORT_SYMBOL(hpsb_unregister_highlevel); EXPORT_SYMBOL(hpsb_register_addrspace); EXPORT_SYMBOL(hpsb_unregister_addrspace); EXPORT_SYMBOL(hpsb_allocate_and_register_addrspace); -EXPORT_SYMBOL(hpsb_listen_channel); -EXPORT_SYMBOL(hpsb_unlisten_channel); EXPORT_SYMBOL(hpsb_get_hostinfo); EXPORT_SYMBOL(hpsb_create_hostinfo); EXPORT_SYMBOL(hpsb_destroy_hostinfo); diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h index ad526523d0ef..21d50f73a210 100644 --- a/drivers/ieee1394/ieee1394_core.h +++ b/drivers/ieee1394/ieee1394_core.h @@ -24,9 +24,8 @@ struct hpsb_packet { nodeid_t node_id; - /* Async and Iso types should be clear, raw means send-as-is, do not - * CRC! Byte swapping shall still be done in this case. */ - enum { hpsb_async, hpsb_iso, hpsb_raw } __attribute__((packed)) type; + /* hpsb_raw = send as-is, do not CRC (but still byte-swap it) */ + enum { hpsb_async, hpsb_raw } __attribute__((packed)) type; /* Okay, this is core internal and a no care for hosts. * queued = queued for sending @@ -37,7 +36,7 @@ struct hpsb_packet { hpsb_unused, hpsb_queued, hpsb_pending, hpsb_complete } __attribute__((packed)) state; - /* These are core internal. */ + /* These are core-internal. */ signed char tlabel; signed char ack_code; unsigned char tcode; @@ -62,11 +61,15 @@ struct hpsb_packet { /* Store jiffies for implementing bus timeouts. */ unsigned long sendtime; - /* Sizes are in bytes. *data can be DMA-mapped. */ + /* Core-internal. */ size_t allocated_data_size; /* as allocated */ + + /* Sizes are in bytes. To be set by caller of hpsb_alloc_packet. */ size_t data_size; /* as filled in */ size_t header_size; /* as filled in, not counting the CRC */ - quadlet_t *data; + + /* Buffers */ + quadlet_t *data; /* can be DMA-mapped */ quadlet_t header[5]; quadlet_t embedded_data[0]; /* keep as last member */ }; diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c index 40078ce930c8..c39c70a8aa9f 100644 --- a/drivers/ieee1394/ieee1394_transactions.c +++ b/drivers/ieee1394/ieee1394_transactions.c @@ -89,18 +89,6 @@ static void fill_async_lock(struct hpsb_packet *packet, u64 addr, int extcode, packet->expect_response = 1; } -static void fill_iso_packet(struct hpsb_packet *packet, int length, int channel, - int tag, int sync) -{ - packet->header[0] = (length << 16) | (tag << 14) | (channel << 8) - | (TCODE_ISO_DATA << 4) | sync; - - packet->header_size = 4; - packet->data_size = length; - packet->type = hpsb_iso; - packet->tcode = TCODE_ISO_DATA; -} - static void fill_phy_packet(struct hpsb_packet *packet, quadlet_t data) { packet->header[0] = data; @@ -491,24 +479,6 @@ struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data) return p; } -struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, - int length, int channel, - int tag, int sync) -{ - struct hpsb_packet *p; - - p = hpsb_alloc_packet(length); - if (!p) - return NULL; - - p->host = host; - fill_iso_packet(p, length, channel, tag, sync); - - p->generation = get_hpsb_generation(host); - - return p; -} - /* * FIXME - these functions should probably read from / write to user space to * avoid in kernel buffers for user space callers diff --git a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h index 86b8ee692ea7..d2d5bc3546d7 100644 --- a/drivers/ieee1394/ieee1394_transactions.h +++ b/drivers/ieee1394/ieee1394_transactions.h @@ -19,8 +19,6 @@ struct hpsb_packet *hpsb_make_lock64packet(struct hpsb_host *host, nodeid_t node, u64 addr, int extcode, octlet_t *data, octlet_t arg); struct hpsb_packet *hpsb_make_phypacket(struct hpsb_host *host, quadlet_t data); -struct hpsb_packet *hpsb_make_isopacket(struct hpsb_host *host, int length, - int channel, int tag, int sync); struct hpsb_packet *hpsb_make_writepacket(struct hpsb_host *host, nodeid_t node, u64 addr, quadlet_t *buffer, size_t length); diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index 835937e38529..2ffd53461db6 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c @@ -19,6 +19,7 @@ #include <linux/mutex.h> #include <linux/freezer.h> #include <asm/atomic.h> +#include <asm/semaphore.h> #include "csr.h" #include "highlevel.h" @@ -145,8 +146,6 @@ static struct csr1212_bus_ops nodemgr_csr_ops = { * but now we are much simpler because of the LDM. */ -static DEFINE_MUTEX(nodemgr_serialize); - struct host_info { struct hpsb_host *host; struct list_head list; @@ -154,7 +153,7 @@ struct host_info { }; static int nodemgr_bus_match(struct device * dev, struct device_driver * drv); -static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, +static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); static void nodemgr_resume_ne(struct node_entry *ne); static void nodemgr_remove_ne(struct node_entry *ne); @@ -165,37 +164,38 @@ struct bus_type ieee1394_bus_type = { .match = nodemgr_bus_match, }; -static void host_cls_release(struct class_device *class_dev) +static void host_cls_release(struct device *dev) { - put_device(&container_of((class_dev), struct hpsb_host, class_dev)->device); + put_device(&container_of((dev), struct hpsb_host, host_dev)->device); } struct class hpsb_host_class = { .name = "ieee1394_host", - .release = host_cls_release, + .dev_release = host_cls_release, }; -static void ne_cls_release(struct class_device *class_dev) +static void ne_cls_release(struct device *dev) { - put_device(&container_of((class_dev), struct node_entry, class_dev)->device); + put_device(&container_of((dev), struct node_entry, node_dev)->device); } static struct class nodemgr_ne_class = { .name = "ieee1394_node", - .release = ne_cls_release, + .dev_release = ne_cls_release, }; -static void ud_cls_release(struct class_device *class_dev) +static void ud_cls_release(struct device *dev) { - put_device(&container_of((class_dev), struct unit_directory, class_dev)->device); + put_device(&container_of((dev), struct unit_directory, unit_dev)->device); } /* The name here is only so that unit directory hotplug works with old - * style hotplug, which only ever did unit directories anyway. */ + * style hotplug, which only ever did unit directories anyway. + */ static struct class nodemgr_ud_class = { .name = "ieee1394", - .release = ud_cls_release, - .uevent = nodemgr_uevent, + .dev_release = ud_cls_release, + .dev_uevent = nodemgr_uevent, }; static struct hpsb_highlevel nodemgr_highlevel; @@ -283,7 +283,7 @@ static ssize_t fw_show_##class##_##td_kv (struct device *dev, struct device_attr memcpy(buf, \ CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(class->td_kv), \ len); \ - while ((buf + len - 1) == '\0') \ + while (buf[len - 1] == '\0') \ len--; \ buf[len++] = '\n'; \ buf[len] = '\0'; \ @@ -730,11 +730,11 @@ static DEFINE_MUTEX(nodemgr_serialize_remove_uds); static void nodemgr_remove_uds(struct node_entry *ne) { - struct class_device *cdev; + struct device *dev; struct unit_directory *tmp, *ud; - /* Iteration over nodemgr_ud_class.children has to be protected by - * nodemgr_ud_class.sem, but class_device_unregister() will eventually + /* Iteration over nodemgr_ud_class.devices has to be protected by + * nodemgr_ud_class.sem, but device_unregister() will eventually * take nodemgr_ud_class.sem too. Therefore pick out one ud at a time, * release the semaphore, and then unregister the ud. Since this code * may be called from other contexts besides the knodemgrds, protect the @@ -744,9 +744,9 @@ static void nodemgr_remove_uds(struct node_entry *ne) for (;;) { ud = NULL; down(&nodemgr_ud_class.sem); - list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { - tmp = container_of(cdev, struct unit_directory, - class_dev); + list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { + tmp = container_of(dev, struct unit_directory, + unit_dev); if (tmp->ne == ne) { ud = tmp; break; @@ -755,7 +755,7 @@ static void nodemgr_remove_uds(struct node_entry *ne) up(&nodemgr_ud_class.sem); if (ud == NULL) break; - class_device_unregister(&ud->class_dev); + device_unregister(&ud->unit_dev); device_unregister(&ud->device); } mutex_unlock(&nodemgr_serialize_remove_uds); @@ -772,10 +772,9 @@ static void nodemgr_remove_ne(struct node_entry *ne) HPSB_DEBUG("Node removed: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); - nodemgr_remove_uds(ne); - class_device_unregister(&ne->class_dev); + device_unregister(&ne->node_dev); device_unregister(dev); put_device(dev); @@ -783,7 +782,9 @@ static void nodemgr_remove_ne(struct node_entry *ne) static int __nodemgr_remove_host_dev(struct device *dev, void *data) { - nodemgr_remove_ne(container_of(dev, struct node_entry, device)); + if (dev->bus == &ieee1394_bus_type) + nodemgr_remove_ne(container_of(dev, struct node_entry, + device)); return 0; } @@ -850,14 +851,14 @@ static struct node_entry *nodemgr_create_node(octlet_t guid, struct csr1212_csr snprintf(ne->device.bus_id, BUS_ID_SIZE, "%016Lx", (unsigned long long)(ne->guid)); - ne->class_dev.dev = &ne->device; - ne->class_dev.class = &nodemgr_ne_class; - snprintf(ne->class_dev.class_id, BUS_ID_SIZE, "%016Lx", - (unsigned long long)(ne->guid)); + ne->node_dev.parent = &ne->device; + ne->node_dev.class = &nodemgr_ne_class; + snprintf(ne->node_dev.bus_id, BUS_ID_SIZE, "%016Lx", + (unsigned long long)(ne->guid)); if (device_register(&ne->device)) goto fail_devreg; - if (class_device_register(&ne->class_dev)) + if (device_register(&ne->node_dev)) goto fail_classdevreg; get_device(&ne->device); @@ -885,12 +886,12 @@ fail_alloc: static struct node_entry *find_entry_by_guid(u64 guid) { - struct class_device *cdev; + struct device *dev; struct node_entry *ne, *ret_ne = NULL; down(&nodemgr_ne_class.sem); - list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { - ne = container_of(cdev, struct node_entry, class_dev); + list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { + ne = container_of(dev, struct node_entry, node_dev); if (ne->guid == guid) { ret_ne = ne; @@ -906,12 +907,12 @@ static struct node_entry *find_entry_by_guid(u64 guid) static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host, nodeid_t nodeid) { - struct class_device *cdev; + struct device *dev; struct node_entry *ne, *ret_ne = NULL; down(&nodemgr_ne_class.sem); - list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { - ne = container_of(cdev, struct node_entry, class_dev); + list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { + ne = container_of(dev, struct node_entry, node_dev); if (ne->host == host && ne->nodeid == nodeid) { ret_ne = ne; @@ -935,14 +936,14 @@ static void nodemgr_register_device(struct node_entry *ne, snprintf(ud->device.bus_id, BUS_ID_SIZE, "%s-%u", ne->device.bus_id, ud->id); - ud->class_dev.dev = &ud->device; - ud->class_dev.class = &nodemgr_ud_class; - snprintf(ud->class_dev.class_id, BUS_ID_SIZE, "%s-%u", + ud->unit_dev.parent = &ud->device; + ud->unit_dev.class = &nodemgr_ud_class; + snprintf(ud->unit_dev.bus_id, BUS_ID_SIZE, "%s-%u", ne->device.bus_id, ud->id); if (device_register(&ud->device)) goto fail_devreg; - if (class_device_register(&ud->class_dev)) + if (device_register(&ud->unit_dev)) goto fail_classdevreg; get_device(&ud->device); @@ -976,7 +977,8 @@ static struct unit_directory *nodemgr_process_unit_directory ud->ne = ne; ud->ignore_driver = ignore_drivers; - ud->address = ud_kv->offset + CSR1212_CONFIG_ROM_SPACE_BASE; + ud->address = ud_kv->offset + CSR1212_REGISTER_SPACE_BASE; + ud->directory_id = ud->address & 0xffffff; ud->ud_kv = ud_kv; ud->id = (*id)++; @@ -1085,6 +1087,10 @@ static struct unit_directory *nodemgr_process_unit_directory break; + case CSR1212_KV_ID_DIRECTORY_ID: + ud->directory_id = kv->value.immediate; + break; + default: break; } @@ -1154,7 +1160,7 @@ static void nodemgr_process_root_directory(struct host_info *hi, struct node_ent #ifdef CONFIG_HOTPLUG -static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, +static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) { struct unit_directory *ud; @@ -1164,10 +1170,10 @@ static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, /* ieee1394:venNmoNspNverN */ char buf[8 + 1 + 3 + 8 + 2 + 8 + 2 + 8 + 3 + 8 + 1]; - if (!cdev) + if (!dev) return -ENODEV; - ud = container_of(cdev, struct unit_directory, class_dev); + ud = container_of(dev, struct unit_directory, unit_dev); if (ud->ne->in_limbo || ud->ignore_driver) return -ENODEV; @@ -1202,7 +1208,7 @@ do { \ #else -static int nodemgr_uevent(struct class_device *cdev, char **envp, int num_envp, +static int nodemgr_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) { return -ENODEV; @@ -1373,8 +1379,10 @@ static void nodemgr_node_scan(struct host_info *hi, int generation) static void nodemgr_suspend_ne(struct node_entry *ne) { - struct class_device *cdev; + struct device *dev; struct unit_directory *ud; + struct device_driver *drv; + int error; HPSB_DEBUG("Node suspended: ID:BUS[" NODE_BUS_FMT "] GUID[%016Lx]", NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid); @@ -1383,15 +1391,24 @@ static void nodemgr_suspend_ne(struct node_entry *ne) WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo)); down(&nodemgr_ud_class.sem); - list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { - ud = container_of(cdev, struct unit_directory, class_dev); + list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { + ud = container_of(dev, struct unit_directory, unit_dev); if (ud->ne != ne) continue; - if (ud->device.driver && - (!ud->device.driver->suspend || - ud->device.driver->suspend(&ud->device, PMSG_SUSPEND))) + drv = get_driver(ud->device.driver); + if (!drv) + continue; + + error = 1; /* release if suspend is not implemented */ + if (drv->suspend) { + down(&ud->device.sem); + error = drv->suspend(&ud->device, PMSG_SUSPEND); + up(&ud->device.sem); + } + if (error) device_release_driver(&ud->device); + put_driver(drv); } up(&nodemgr_ud_class.sem); } @@ -1399,20 +1416,29 @@ static void nodemgr_suspend_ne(struct node_entry *ne) static void nodemgr_resume_ne(struct node_entry *ne) { - struct class_device *cdev; + struct device *dev; struct unit_directory *ud; + struct device_driver *drv; ne->in_limbo = 0; device_remove_file(&ne->device, &dev_attr_ne_in_limbo); down(&nodemgr_ud_class.sem); - list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { - ud = container_of(cdev, struct unit_directory, class_dev); + list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { + ud = container_of(dev, struct unit_directory, unit_dev); if (ud->ne != ne) continue; - if (ud->device.driver && ud->device.driver->resume) - ud->device.driver->resume(&ud->device); + drv = get_driver(ud->device.driver); + if (!drv) + continue; + + if (drv->resume) { + down(&ud->device.sem); + drv->resume(&ud->device); + up(&ud->device.sem); + } + put_driver(drv); } up(&nodemgr_ud_class.sem); @@ -1423,23 +1449,32 @@ static void nodemgr_resume_ne(struct node_entry *ne) static void nodemgr_update_pdrv(struct node_entry *ne) { + struct device *dev; struct unit_directory *ud; + struct device_driver *drv; struct hpsb_protocol_driver *pdrv; - struct class_device *cdev; + int error; down(&nodemgr_ud_class.sem); - list_for_each_entry(cdev, &nodemgr_ud_class.children, node) { - ud = container_of(cdev, struct unit_directory, class_dev); + list_for_each_entry(dev, &nodemgr_ud_class.devices, node) { + ud = container_of(dev, struct unit_directory, unit_dev); if (ud->ne != ne) continue; - if (ud->device.driver) { - pdrv = container_of(ud->device.driver, - struct hpsb_protocol_driver, - driver); - if (pdrv->update && pdrv->update(ud)) - device_release_driver(&ud->device); + drv = get_driver(ud->device.driver); + if (!drv) + continue; + + error = 0; + pdrv = container_of(drv, struct hpsb_protocol_driver, driver); + if (pdrv->update) { + down(&ud->device.sem); + error = pdrv->update(ud); + up(&ud->device.sem); } + if (error) + device_release_driver(&ud->device); + put_driver(drv); } up(&nodemgr_ud_class.sem); } @@ -1504,7 +1539,7 @@ static void nodemgr_probe_ne(struct host_info *hi, struct node_entry *ne, int ge static void nodemgr_node_probe(struct host_info *hi, int generation) { struct hpsb_host *host = hi->host; - struct class_device *cdev; + struct device *dev; struct node_entry *ne; /* Do some processing of the nodes we've probed. This pulls them @@ -1517,13 +1552,13 @@ static void nodemgr_node_probe(struct host_info *hi, int generation) * improvement...) */ down(&nodemgr_ne_class.sem); - list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { - ne = container_of(cdev, struct node_entry, class_dev); + list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { + ne = container_of(dev, struct node_entry, node_dev); if (!ne->needs_probe) nodemgr_probe_ne(hi, ne, generation); } - list_for_each_entry(cdev, &nodemgr_ne_class.children, node) { - ne = container_of(cdev, struct node_entry, class_dev); + list_for_each_entry(dev, &nodemgr_ne_class.devices, node) { + ne = container_of(dev, struct node_entry, node_dev); if (ne->needs_probe) nodemgr_probe_ne(hi, ne, generation); } @@ -1664,6 +1699,7 @@ static int nodemgr_host_thread(void *__hi) unsigned int g, generation = 0; int i, reset_cycles = 0; + set_freezable(); /* Setup our device-model entries */ nodemgr_create_host_dev_files(host); @@ -1681,18 +1717,12 @@ static int nodemgr_host_thread(void *__hi) if (kthread_should_stop()) goto exit; - if (mutex_lock_interruptible(&nodemgr_serialize)) { - if (try_to_freeze()) - continue; - goto exit; - } - /* Pause for 1/4 second in 1/16 second intervals, * to make sure things settle down. */ g = get_hpsb_generation(host); for (i = 0; i < 4 ; i++) { if (msleep_interruptible(63) || kthread_should_stop()) - goto unlock_exit; + goto exit; /* Now get the generation in which the node ID's we collect * are valid. During the bus scan we will use this generation @@ -1710,7 +1740,6 @@ static int nodemgr_host_thread(void *__hi) if (!nodemgr_check_irm_capability(host, reset_cycles) || !nodemgr_do_irm_duties(host, reset_cycles)) { reset_cycles++; - mutex_unlock(&nodemgr_serialize); continue; } reset_cycles = 0; @@ -1727,11 +1756,7 @@ static int nodemgr_host_thread(void *__hi) /* Update some of our sysfs symlinks */ nodemgr_update_host_dev_links(host); - - mutex_unlock(&nodemgr_serialize); } -unlock_exit: - mutex_unlock(&nodemgr_serialize); exit: HPSB_VERBOSE("NodeMgr: Exiting thread"); return 0; @@ -1751,13 +1776,13 @@ exit: */ int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *)) { - struct class_device *cdev; + struct device *dev; struct hpsb_host *host; int error = 0; down(&hpsb_host_class.sem); - list_for_each_entry(cdev, &hpsb_host_class.children, node) { - host = container_of(cdev, struct hpsb_host, class_dev); + list_for_each_entry(dev, &hpsb_host_class.devices, node) { + host = container_of(dev, struct hpsb_host, host_dev); if ((error = cb(host, data))) break; diff --git a/drivers/ieee1394/nodemgr.h b/drivers/ieee1394/nodemgr.h index e7ac683c72c7..919e92e2a955 100644 --- a/drivers/ieee1394/nodemgr.h +++ b/drivers/ieee1394/nodemgr.h @@ -75,6 +75,7 @@ struct unit_directory { struct csr1212_keyval *model_name_kv; quadlet_t specifier_id; quadlet_t version; + quadlet_t directory_id; unsigned int id; @@ -83,7 +84,7 @@ struct unit_directory { int length; /* Number of quadlets */ struct device device; - struct class_device class_dev; + struct device unit_dev; struct csr1212_keyval *ud_kv; u32 lun; /* logical unit number immediate value */ @@ -106,7 +107,7 @@ struct node_entry { u32 capabilities; struct device device; - struct class_device class_dev; + struct device node_dev; /* Means this node is not attached anymore */ int in_limbo; diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index 5dadfd296f79..5667c8102efc 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c @@ -138,19 +138,6 @@ printk(KERN_INFO "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host-> #define DBGMSG(fmt, args...) do {} while (0) #endif -#ifdef CONFIG_IEEE1394_OHCI_DMA_DEBUG -#define OHCI_DMA_ALLOC(fmt, args...) \ - HPSB_ERR("%s(%s)alloc(%d): "fmt, OHCI1394_DRIVER_NAME, __FUNCTION__, \ - ++global_outstanding_dmas, ## args) -#define OHCI_DMA_FREE(fmt, args...) \ - HPSB_ERR("%s(%s)free(%d): "fmt, OHCI1394_DRIVER_NAME, __FUNCTION__, \ - --global_outstanding_dmas, ## args) -static int global_outstanding_dmas = 0; -#else -#define OHCI_DMA_ALLOC(fmt, args...) do {} while (0) -#define OHCI_DMA_FREE(fmt, args...) do {} while (0) -#endif - /* print general (card independent) information */ #define PRINT_G(level, fmt, args...) \ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args) @@ -170,7 +157,6 @@ static void dma_trm_reset(struct dma_trm_ctx *d); static int alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, enum context_type type, int ctx, int num_desc, int buf_size, int split_buf_size, int context_base); -static void stop_dma_rcv_ctx(struct dma_rcv_ctx *d); static void free_dma_rcv_ctx(struct dma_rcv_ctx *d); static int alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, @@ -533,9 +519,6 @@ static void ohci_initialize(struct ti_ohci *ohci) initialize_dma_trm_ctx(&ohci->at_req_context); initialize_dma_trm_ctx(&ohci->at_resp_context); - /* Initialize IR Legacy DMA channel mask */ - ohci->ir_legacy_channels = 0; - /* Accept AR requests from all nodes */ reg_write(ohci, OHCI1394_AsReqFilterHiSet, 0x80000000); @@ -733,7 +716,6 @@ static void insert_packet(struct ti_ohci *ohci, pci_map_single(ohci->dev, packet->data, packet->data_size, PCI_DMA_TODEVICE)); - OHCI_DMA_ALLOC("single, block transmit packet"); d->prg_cpu[idx]->end.branchAddress = 0; d->prg_cpu[idx]->end.status = 0; @@ -783,7 +765,6 @@ static void insert_packet(struct ti_ohci *ohci, d->prg_cpu[idx]->end.address = cpu_to_le32( pci_map_single(ohci->dev, packet->data, packet->data_size, PCI_DMA_TODEVICE)); - OHCI_DMA_ALLOC("single, iso transmit packet"); d->prg_cpu[idx]->end.branchAddress = 0; d->prg_cpu[idx]->end.status = 0; @@ -884,36 +865,9 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet) return -EOVERFLOW; } - /* Decide whether we have an iso, a request, or a response packet */ if (packet->type == hpsb_raw) d = &ohci->at_req_context; - else if ((packet->tcode == TCODE_ISO_DATA) && (packet->type == hpsb_iso)) { - /* The legacy IT DMA context is initialized on first - * use. However, the alloc cannot be run from - * interrupt context, so we bail out if that is the - * case. I don't see anyone sending ISO packets from - * interrupt context anyway... */ - - if (ohci->it_legacy_context.ohci == NULL) { - if (in_interrupt()) { - PRINT(KERN_ERR, - "legacy IT context cannot be initialized during interrupt"); - return -EINVAL; - } - - if (alloc_dma_trm_ctx(ohci, &ohci->it_legacy_context, - DMA_CTX_ISO, 0, IT_NUM_DESC, - OHCI1394_IsoXmitContextBase) < 0) { - PRINT(KERN_ERR, - "error initializing legacy IT context"); - return -ENOMEM; - } - - initialize_dma_trm_ctx(&ohci->it_legacy_context); - } - - d = &ohci->it_legacy_context; - } else if ((packet->tcode & 0x02) && (packet->tcode != TCODE_ISO_DATA)) + else if ((packet->tcode & 0x02) && (packet->tcode != TCODE_ISO_DATA)) d = &ohci->at_resp_context; else d = &ohci->at_req_context; @@ -932,9 +886,7 @@ static int ohci_transmit(struct hpsb_host *host, struct hpsb_packet *packet) static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) { struct ti_ohci *ohci = host->hostdata; - int retval = 0; - unsigned long flags; - int phy_reg; + int retval = 0, phy_reg; switch (cmd) { case RESET_BUS: @@ -1027,117 +979,6 @@ static int ohci_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) dma_trm_reset(&ohci->at_resp_context); break; - case ISO_LISTEN_CHANNEL: - { - u64 mask; - struct dma_rcv_ctx *d = &ohci->ir_legacy_context; - int ir_legacy_active; - - if (arg<0 || arg>63) { - PRINT(KERN_ERR, - "%s: IS0 listen channel %d is out of range", - __FUNCTION__, arg); - return -EFAULT; - } - - mask = (u64)0x1<<arg; - - spin_lock_irqsave(&ohci->IR_channel_lock, flags); - - if (ohci->ISO_channel_usage & mask) { - PRINT(KERN_ERR, - "%s: IS0 listen channel %d is already used", - __FUNCTION__, arg); - spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); - return -EFAULT; - } - - ir_legacy_active = ohci->ir_legacy_channels; - - ohci->ISO_channel_usage |= mask; - ohci->ir_legacy_channels |= mask; - - spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); - - if (!ir_legacy_active) { - if (ohci1394_register_iso_tasklet(ohci, - &ohci->ir_legacy_tasklet) < 0) { - PRINT(KERN_ERR, "No IR DMA context available"); - return -EBUSY; - } - - /* the IR context can be assigned to any DMA context - * by ohci1394_register_iso_tasklet */ - d->ctx = ohci->ir_legacy_tasklet.context; - d->ctrlSet = OHCI1394_IsoRcvContextControlSet + - 32*d->ctx; - d->ctrlClear = OHCI1394_IsoRcvContextControlClear + - 32*d->ctx; - d->cmdPtr = OHCI1394_IsoRcvCommandPtr + 32*d->ctx; - d->ctxtMatch = OHCI1394_IsoRcvContextMatch + 32*d->ctx; - - initialize_dma_rcv_ctx(&ohci->ir_legacy_context, 1); - - if (printk_ratelimit()) - DBGMSG("IR legacy activated"); - } - - spin_lock_irqsave(&ohci->IR_channel_lock, flags); - - if (arg>31) - reg_write(ohci, OHCI1394_IRMultiChanMaskHiSet, - 1<<(arg-32)); - else - reg_write(ohci, OHCI1394_IRMultiChanMaskLoSet, - 1<<arg); - - spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); - DBGMSG("Listening enabled on channel %d", arg); - break; - } - case ISO_UNLISTEN_CHANNEL: - { - u64 mask; - - if (arg<0 || arg>63) { - PRINT(KERN_ERR, - "%s: IS0 unlisten channel %d is out of range", - __FUNCTION__, arg); - return -EFAULT; - } - - mask = (u64)0x1<<arg; - - spin_lock_irqsave(&ohci->IR_channel_lock, flags); - - if (!(ohci->ISO_channel_usage & mask)) { - PRINT(KERN_ERR, - "%s: IS0 unlisten channel %d is not used", - __FUNCTION__, arg); - spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); - return -EFAULT; - } - - ohci->ISO_channel_usage &= ~mask; - ohci->ir_legacy_channels &= ~mask; - - if (arg>31) - reg_write(ohci, OHCI1394_IRMultiChanMaskHiClear, - 1<<(arg-32)); - else - reg_write(ohci, OHCI1394_IRMultiChanMaskLoClear, - 1<<arg); - - spin_unlock_irqrestore(&ohci->IR_channel_lock, flags); - DBGMSG("Listening disabled on channel %d", arg); - - if (ohci->ir_legacy_channels == 0) { - stop_dma_rcv_ctx(&ohci->ir_legacy_context); - DBGMSG("ISO legacy receive context stopped"); - } - - break; - } default: PRINT_G(KERN_ERR, "ohci_devctl cmd %d not implemented yet", cmd); @@ -2869,12 +2710,10 @@ static void dma_trm_tasklet (unsigned long data) list_del_init(&packet->driver_list); hpsb_packet_sent(ohci->host, packet, ack); - if (datasize) { + if (datasize) pci_unmap_single(ohci->dev, cpu_to_le32(d->prg_cpu[d->sent_ind]->end.address), datasize, PCI_DMA_TODEVICE); - OHCI_DMA_FREE("single Xmit data packet"); - } d->sent_ind = (d->sent_ind+1)%d->num_desc; d->free_prgs++; @@ -2885,22 +2724,6 @@ static void dma_trm_tasklet (unsigned long data) spin_unlock_irqrestore(&d->lock, flags); } -static void stop_dma_rcv_ctx(struct dma_rcv_ctx *d) -{ - if (d->ctrlClear) { - ohci1394_stop_context(d->ohci, d->ctrlClear, NULL); - - if (d->type == DMA_CTX_ISO) { - /* disable interrupts */ - reg_write(d->ohci, OHCI1394_IsoRecvIntMaskClear, 1 << d->ctx); - ohci1394_unregister_iso_tasklet(d->ohci, &d->ohci->ir_legacy_tasklet); - } else { - tasklet_kill(&d->task); - } - } -} - - static void free_dma_rcv_ctx(struct dma_rcv_ctx *d) { int i; @@ -2913,23 +2736,19 @@ static void free_dma_rcv_ctx(struct dma_rcv_ctx *d) if (d->buf_cpu) { for (i=0; i<d->num_desc; i++) - if (d->buf_cpu[i] && d->buf_bus[i]) { + if (d->buf_cpu[i] && d->buf_bus[i]) pci_free_consistent( ohci->dev, d->buf_size, d->buf_cpu[i], d->buf_bus[i]); - OHCI_DMA_FREE("consistent dma_rcv buf[%d]", i); - } kfree(d->buf_cpu); kfree(d->buf_bus); } if (d->prg_cpu) { for (i=0; i<d->num_desc; i++) - if (d->prg_cpu[i] && d->prg_bus[i]) { - pci_pool_free(d->prg_pool, d->prg_cpu[i], d->prg_bus[i]); - OHCI_DMA_FREE("consistent dma_rcv prg[%d]", i); - } + if (d->prg_cpu[i] && d->prg_bus[i]) + pci_pool_free(d->prg_pool, d->prg_cpu[i], + d->prg_bus[i]); pci_pool_destroy(d->prg_pool); - OHCI_DMA_FREE("dma_rcv prg pool"); kfree(d->prg_cpu); kfree(d->prg_bus); } @@ -2998,13 +2817,10 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, } num_allocs++; - OHCI_DMA_ALLOC("dma_rcv prg pool"); - for (i=0; i<d->num_desc; i++) { d->buf_cpu[i] = pci_alloc_consistent(ohci->dev, d->buf_size, d->buf_bus+i); - OHCI_DMA_ALLOC("consistent dma_rcv buf[%d]", i); if (d->buf_cpu[i] != NULL) { memset(d->buf_cpu[i], 0, d->buf_size); @@ -3016,7 +2832,6 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, } d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i); - OHCI_DMA_ALLOC("pool dma_rcv prg[%d]", i); if (d->prg_cpu[i] != NULL) { memset(d->prg_cpu[i], 0, sizeof(struct dma_cmd)); @@ -3030,18 +2845,11 @@ alloc_dma_rcv_ctx(struct ti_ohci *ohci, struct dma_rcv_ctx *d, spin_lock_init(&d->lock); - if (type == DMA_CTX_ISO) { - ohci1394_init_iso_tasklet(&ohci->ir_legacy_tasklet, - OHCI_ISO_MULTICHANNEL_RECEIVE, - dma_rcv_tasklet, (unsigned long) d); - } else { - d->ctrlSet = context_base + OHCI1394_ContextControlSet; - d->ctrlClear = context_base + OHCI1394_ContextControlClear; - d->cmdPtr = context_base + OHCI1394_ContextCommandPtr; - - tasklet_init (&d->task, dma_rcv_tasklet, (unsigned long) d); - } + d->ctrlSet = context_base + OHCI1394_ContextControlSet; + d->ctrlClear = context_base + OHCI1394_ContextControlClear; + d->cmdPtr = context_base + OHCI1394_ContextCommandPtr; + tasklet_init(&d->task, dma_rcv_tasklet, (unsigned long) d); return 0; } @@ -3057,12 +2865,10 @@ static void free_dma_trm_ctx(struct dma_trm_ctx *d) if (d->prg_cpu) { for (i=0; i<d->num_desc; i++) - if (d->prg_cpu[i] && d->prg_bus[i]) { - pci_pool_free(d->prg_pool, d->prg_cpu[i], d->prg_bus[i]); - OHCI_DMA_FREE("pool dma_trm prg[%d]", i); - } + if (d->prg_cpu[i] && d->prg_bus[i]) + pci_pool_free(d->prg_pool, d->prg_cpu[i], + d->prg_bus[i]); pci_pool_destroy(d->prg_pool); - OHCI_DMA_FREE("dma_trm prg pool"); kfree(d->prg_cpu); kfree(d->prg_bus); } @@ -3108,11 +2914,8 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, } num_allocs++; - OHCI_DMA_ALLOC("dma_rcv prg pool"); - for (i = 0; i < d->num_desc; i++) { d->prg_cpu[i] = pci_pool_alloc(d->prg_pool, GFP_KERNEL, d->prg_bus+i); - OHCI_DMA_ALLOC("pool dma_trm prg[%d]", i); if (d->prg_cpu[i] != NULL) { memset(d->prg_cpu[i], 0, sizeof(struct at_dma_prg)); @@ -3127,28 +2930,10 @@ alloc_dma_trm_ctx(struct ti_ohci *ohci, struct dma_trm_ctx *d, spin_lock_init(&d->lock); /* initialize tasklet */ - if (type == DMA_CTX_ISO) { - ohci1394_init_iso_tasklet(&ohci->it_legacy_tasklet, OHCI_ISO_TRANSMIT, - dma_trm_tasklet, (unsigned long) d); - if (ohci1394_register_iso_tasklet(ohci, - &ohci->it_legacy_tasklet) < 0) { - PRINT(KERN_ERR, "No IT DMA context available"); - free_dma_trm_ctx(d); - return -EBUSY; - } - - /* IT can be assigned to any context by register_iso_tasklet */ - d->ctx = ohci->it_legacy_tasklet.context; - d->ctrlSet = OHCI1394_IsoXmitContextControlSet + 16 * d->ctx; - d->ctrlClear = OHCI1394_IsoXmitContextControlClear + 16 * d->ctx; - d->cmdPtr = OHCI1394_IsoXmitCommandPtr + 16 * d->ctx; - } else { - d->ctrlSet = context_base + OHCI1394_ContextControlSet; - d->ctrlClear = context_base + OHCI1394_ContextControlClear; - d->cmdPtr = context_base + OHCI1394_ContextCommandPtr; - tasklet_init (&d->task, dma_trm_tasklet, (unsigned long)d); - } - + d->ctrlSet = context_base + OHCI1394_ContextControlSet; + d->ctrlClear = context_base + OHCI1394_ContextControlClear; + d->cmdPtr = context_base + OHCI1394_ContextCommandPtr; + tasklet_init(&d->task, dma_trm_tasklet, (unsigned long)d); return 0; } @@ -3294,7 +3079,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, ohci->csr_config_rom_cpu = pci_alloc_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN, &ohci->csr_config_rom_bus); - OHCI_DMA_ALLOC("consistent csr_config_rom"); if (ohci->csr_config_rom_cpu == NULL) FAIL(-ENOMEM, "Failed to allocate buffer config rom"); ohci->init_state = OHCI_INIT_HAVE_CONFIG_ROM_BUFFER; @@ -3303,8 +3087,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, ohci->selfid_buf_cpu = pci_alloc_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, &ohci->selfid_buf_bus); - OHCI_DMA_ALLOC("consistent selfid_buf"); - if (ohci->selfid_buf_cpu == NULL) FAIL(-ENOMEM, "Failed to allocate DMA buffer for self-id packets"); ohci->init_state = OHCI_INIT_HAVE_SELFID_BUFFER; @@ -3377,20 +3159,6 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, ohci->ISO_channel_usage = 0; spin_lock_init(&ohci->IR_channel_lock); - /* Allocate the IR DMA context right here so we don't have - * to do it in interrupt path - note that this doesn't - * waste much memory and avoids the jugglery required to - * allocate it in IRQ path. */ - if (alloc_dma_rcv_ctx(ohci, &ohci->ir_legacy_context, - DMA_CTX_ISO, 0, IR_NUM_DESC, - IR_BUF_SIZE, IR_SPLIT_BUF_SIZE, - OHCI1394_IsoRcvContextBase) < 0) { - FAIL(-ENOMEM, "Cannot allocate IR Legacy DMA context"); - } - - /* We hopefully don't have to pre-allocate IT DMA like we did - * for IR DMA above. Allocate it on-demand and mark inactive. */ - ohci->it_legacy_context.ohci = NULL; spin_lock_init(&ohci->event_lock); /* @@ -3483,20 +3251,16 @@ static void ohci1394_pci_remove(struct pci_dev *pdev) free_dma_rcv_ctx(&ohci->ar_resp_context); free_dma_trm_ctx(&ohci->at_req_context); free_dma_trm_ctx(&ohci->at_resp_context); - free_dma_rcv_ctx(&ohci->ir_legacy_context); - free_dma_trm_ctx(&ohci->it_legacy_context); case OHCI_INIT_HAVE_SELFID_BUFFER: pci_free_consistent(ohci->dev, OHCI1394_SI_DMA_BUF_SIZE, ohci->selfid_buf_cpu, ohci->selfid_buf_bus); - OHCI_DMA_FREE("consistent selfid_buf"); case OHCI_INIT_HAVE_CONFIG_ROM_BUFFER: pci_free_consistent(ohci->dev, OHCI_CONFIG_ROM_LEN, ohci->csr_config_rom_cpu, ohci->csr_config_rom_bus); - OHCI_DMA_FREE("consistent csr_config_rom"); case OHCI_INIT_HAVE_IOMAPPING: iounmap(ohci->registers); diff --git a/drivers/ieee1394/ohci1394.h b/drivers/ieee1394/ohci1394.h index f1ad539e7c1b..4320bf010495 100644 --- a/drivers/ieee1394/ohci1394.h +++ b/drivers/ieee1394/ohci1394.h @@ -190,23 +190,10 @@ struct ti_ohci { unsigned long ir_multichannel_used; /* ditto */ spinlock_t IR_channel_lock; - /* iso receive (legacy API) */ - u64 ir_legacy_channels; /* note: this differs from ISO_channel_usage; - it only accounts for channels listened to - by the legacy API, so that we can know when - it is safe to free the legacy API context */ - - struct dma_rcv_ctx ir_legacy_context; - struct ohci1394_iso_tasklet ir_legacy_tasklet; - /* iso transmit */ int nb_iso_xmit_ctx; unsigned long it_ctx_usage; /* use test_and_set_bit() for atomicity */ - /* iso transmit (legacy API) */ - struct dma_trm_ctx it_legacy_context; - struct ohci1394_iso_tasklet it_legacy_tasklet; - u64 ISO_channel_usage; /* IEEE-1394 part follows */ @@ -221,7 +208,6 @@ struct ti_ohci { /* Tasklets for iso receive and transmit, used by video1394 * and dv1394 */ - struct list_head iso_tasklet_list; spinlock_t iso_tasklet_list_lock; diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c index 0742befe9227..d1a5bcdb5e0b 100644 --- a/drivers/ieee1394/pcilynx.c +++ b/drivers/ieee1394/pcilynx.c @@ -477,7 +477,11 @@ static void send_next(struct ti_lynx *lynx, int what) struct lynx_send_data *d; struct hpsb_packet *packet; +#if 0 /* has been removed from ieee1394 core */ d = (what == hpsb_iso ? &lynx->iso_send : &lynx->async); +#else + d = &lynx->async; +#endif if (!list_empty(&d->pcl_queue)) { PRINT(KERN_ERR, lynx->id, "trying to queue a new packet in nonempty fifo"); BUG(); @@ -511,9 +515,11 @@ static void send_next(struct ti_lynx *lynx, int what) case hpsb_async: pcl.buffer[0].control |= PCL_CMD_XMT; break; +#if 0 /* has been removed from ieee1394 core */ case hpsb_iso: pcl.buffer[0].control |= PCL_CMD_XMT | PCL_ISOMODE; break; +#endif case hpsb_raw: pcl.buffer[0].control |= PCL_CMD_UNFXMT; break; @@ -542,9 +548,11 @@ static int lynx_transmit(struct hpsb_host *host, struct hpsb_packet *packet) case hpsb_raw: d = &lynx->async; break; +#if 0 /* has been removed from ieee1394 core */ case hpsb_iso: d = &lynx->iso_send; break; +#endif default: PRINT(KERN_ERR, lynx->id, "invalid packet type %d", packet->type); @@ -797,7 +805,7 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) } break; - +#if 0 /* has been removed from ieee1394 core */ case ISO_LISTEN_CHANNEL: spin_lock_irqsave(&lynx->iso_rcv.lock, flags); @@ -819,7 +827,7 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) spin_unlock_irqrestore(&lynx->iso_rcv.lock, flags); break; - +#endif default: PRINT(KERN_ERR, lynx->id, "unknown devctl command %d", cmd); retval = -1; @@ -1009,11 +1017,11 @@ static irqreturn_t lynx_irq_handler(int irq, void *dev_id) pci_unmap_single(lynx->dev, lynx->iso_send.data_dma, packet->data_size, PCI_DMA_TODEVICE); } - +#if 0 /* has been removed from ieee1394 core */ if (!list_empty(&lynx->iso_send.queue)) { send_next(lynx, hpsb_iso); } - +#endif spin_unlock(&lynx->iso_send.queue_lock); if (pcl.pcl_status & DMA_CHAN_STAT_PKTCMPL) { diff --git a/drivers/ieee1394/raw1394-private.h b/drivers/ieee1394/raw1394-private.h index 50daabf6e5fa..a06aaad5b448 100644 --- a/drivers/ieee1394/raw1394-private.h +++ b/drivers/ieee1394/raw1394-private.h @@ -36,11 +36,6 @@ struct file_info { u8 __user *fcp_buffer; - /* old ISO API */ - u64 listen_channels; - quadlet_t __user *iso_buffer; - size_t iso_buffer_length; - u8 notification; /* (busreset-notification) RAW1394_NOTIFY_OFF/ON */ /* new rawiso API */ diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index d382500f4210..336e5ff4cfcf 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -98,21 +98,6 @@ static struct hpsb_address_ops arm_ops = { static void queue_complete_cb(struct pending_request *req); -#include <asm/current.h> -static void print_old_iso_deprecation(void) -{ - static pid_t p; - - if (p == current->pid) - return; - p = current->pid; - printk(KERN_WARNING "raw1394: WARNING - Program \"%s\" uses unsupported" - " isochronous request types which will be removed in a next" - " kernel release\n", current->comm); - printk(KERN_WARNING "raw1394: Update your software to use libraw1394's" - " newer interface\n"); -} - static struct pending_request *__alloc_pending_request(gfp_t flags) { struct pending_request *req; @@ -297,67 +282,6 @@ static void host_reset(struct hpsb_host *host) spin_unlock_irqrestore(&host_info_lock, flags); } -static void iso_receive(struct hpsb_host *host, int channel, quadlet_t * data, - size_t length) -{ - unsigned long flags; - struct host_info *hi; - struct file_info *fi; - struct pending_request *req, *req_next; - struct iso_block_store *ibs = NULL; - LIST_HEAD(reqs); - - if ((atomic_read(&iso_buffer_size) + length) > iso_buffer_max) { - HPSB_INFO("dropped iso packet"); - return; - } - - spin_lock_irqsave(&host_info_lock, flags); - hi = find_host_info(host); - - if (hi != NULL) { - list_for_each_entry(fi, &hi->file_info_list, list) { - if (!(fi->listen_channels & (1ULL << channel))) - continue; - - req = __alloc_pending_request(GFP_ATOMIC); - if (!req) - break; - - if (!ibs) { - ibs = kmalloc(sizeof(*ibs) + length, - GFP_ATOMIC); - if (!ibs) { - kfree(req); - break; - } - - atomic_add(length, &iso_buffer_size); - atomic_set(&ibs->refcount, 0); - ibs->data_size = length; - memcpy(ibs->data, data, length); - } - - atomic_inc(&ibs->refcount); - - req->file_info = fi; - req->ibs = ibs; - req->data = ibs->data; - req->req.type = RAW1394_REQ_ISO_RECEIVE; - req->req.generation = get_hpsb_generation(host); - req->req.misc = 0; - req->req.recvb = ptr2int(fi->iso_buffer); - req->req.length = min(length, fi->iso_buffer_length); - - list_add_tail(&req->list, &reqs); - } - } - spin_unlock_irqrestore(&host_info_lock, flags); - - list_for_each_entry_safe(req, req_next, &reqs, list) - queue_complete_req(req); -} - static void fcp_request(struct hpsb_host *host, int nodeid, int direction, int cts, u8 * data, size_t length) { @@ -434,7 +358,11 @@ struct compat_raw1394_req { __u64 sendb; __u64 recvb; -} __attribute__((packed)); +} +#if defined(CONFIG_X86_64) || defined(CONFIG_IA64) +__attribute__((packed)) +#endif +; static const char __user *raw1394_compat_write(const char __user *buf) { @@ -459,7 +387,7 @@ static const char __user *raw1394_compat_write(const char __user *buf) static int raw1394_compat_read(const char __user *buf, struct raw1394_request *r) { - struct compat_raw1394_req __user *cr = (typeof(cr)) r; + struct compat_raw1394_req __user *cr = (typeof(cr)) buf; if (!access_ok(VERIFY_WRITE, cr, sizeof(struct compat_raw1394_req)) || P(type) || P(error) || @@ -587,7 +515,7 @@ static int state_opened(struct file_info *fi, struct pending_request *req) req->req.length = 0; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } static int state_initialized(struct file_info *fi, struct pending_request *req) @@ -601,7 +529,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req) req->req.generation = atomic_read(&internal_generation); req->req.length = 0; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } switch (req->req.type) { @@ -673,44 +601,7 @@ out_set_card: } queue_complete_req(req); - return sizeof(struct raw1394_request); -} - -static void handle_iso_listen(struct file_info *fi, struct pending_request *req) -{ - int channel = req->req.misc; - - if ((channel > 63) || (channel < -64)) { - req->req.error = RAW1394_ERROR_INVALID_ARG; - } else if (channel >= 0) { - /* allocate channel req.misc */ - if (fi->listen_channels & (1ULL << channel)) { - req->req.error = RAW1394_ERROR_ALREADY; - } else { - if (hpsb_listen_channel - (&raw1394_highlevel, fi->host, channel)) { - req->req.error = RAW1394_ERROR_ALREADY; - } else { - fi->listen_channels |= 1ULL << channel; - fi->iso_buffer = int2ptr(req->req.recvb); - fi->iso_buffer_length = req->req.length; - } - } - } else { - /* deallocate channel (one's complement neg) req.misc */ - channel = ~channel; - - if (fi->listen_channels & (1ULL << channel)) { - hpsb_unlisten_channel(&raw1394_highlevel, fi->host, - channel); - fi->listen_channels &= ~(1ULL << channel); - } else { - req->req.error = RAW1394_ERROR_INVALID_ARG; - } - } - - req->req.length = 0; - queue_complete_req(req); + return 0; } static void handle_fcp_listen(struct file_info *fi, struct pending_request *req) @@ -865,7 +756,7 @@ static int handle_async_request(struct file_info *fi, if (req->req.error) { req->req.length = 0; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } hpsb_set_packet_complete_task(packet, @@ -883,51 +774,7 @@ static int handle_async_request(struct file_info *fi, hpsb_free_tlabel(packet); queue_complete_req(req); } - return sizeof(struct raw1394_request); -} - -static int handle_iso_send(struct file_info *fi, struct pending_request *req, - int channel) -{ - unsigned long flags; - struct hpsb_packet *packet; - - packet = hpsb_make_isopacket(fi->host, req->req.length, channel & 0x3f, - (req->req.misc >> 16) & 0x3, - req->req.misc & 0xf); - if (!packet) - return -ENOMEM; - - packet->speed_code = req->req.address & 0x3; - - req->packet = packet; - - if (copy_from_user(packet->data, int2ptr(req->req.sendb), - req->req.length)) { - req->req.error = RAW1394_ERROR_MEMFAULT; - req->req.length = 0; - queue_complete_req(req); - return sizeof(struct raw1394_request); - } - - req->req.length = 0; - hpsb_set_packet_complete_task(packet, - (void (*)(void *))queue_complete_req, - req); - - spin_lock_irqsave(&fi->reqlists_lock, flags); - list_add_tail(&req->list, &fi->req_pending); - spin_unlock_irqrestore(&fi->reqlists_lock, flags); - - /* Update the generation of the packet just before sending. */ - packet->generation = req->req.generation; - - if (hpsb_send_packet(packet) < 0) { - req->req.error = RAW1394_ERROR_SEND_ERROR; - queue_complete_req(req); - } - - return sizeof(struct raw1394_request); + return 0; } static int handle_async_send(struct file_info *fi, struct pending_request *req) @@ -936,16 +783,18 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) struct hpsb_packet *packet; int header_length = req->req.misc & 0xffff; int expect_response = req->req.misc >> 16; + size_t data_size; if (header_length > req->req.length || header_length < 12 || header_length > FIELD_SIZEOF(struct hpsb_packet, header)) { req->req.error = RAW1394_ERROR_INVALID_ARG; req->req.length = 0; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } - packet = hpsb_alloc_packet(req->req.length - header_length); + data_size = req->req.length - header_length; + packet = hpsb_alloc_packet(data_size); req->packet = packet; if (!packet) return -ENOMEM; @@ -955,16 +804,16 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) req->req.error = RAW1394_ERROR_MEMFAULT; req->req.length = 0; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } if (copy_from_user (packet->data, int2ptr(req->req.sendb) + header_length, - packet->data_size)) { + data_size)) { req->req.error = RAW1394_ERROR_MEMFAULT; req->req.length = 0; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } packet->type = hpsb_async; @@ -974,7 +823,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) packet->host = fi->host; packet->expect_response = expect_response; packet->header_size = header_length; - packet->data_size = req->req.length - header_length; + packet->data_size = data_size; req->req.length = 0; hpsb_set_packet_complete_task(packet, @@ -992,7 +841,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) queue_complete_req(req); } - return sizeof(struct raw1394_request); + return 0; } static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer, @@ -1867,7 +1716,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) spin_lock_irqsave(&host_info_lock, flags); list_add_tail(&addr->addr_list, &fi->addr_list); spin_unlock_irqrestore(&host_info_lock, flags); - return sizeof(struct raw1394_request); + return 0; } retval = hpsb_register_addrspace(&raw1394_highlevel, fi->host, &arm_ops, @@ -1885,7 +1734,7 @@ static int arm_register(struct file_info *fi, struct pending_request *req) return (-EALREADY); } free_pending_request(req); /* immediate success or fail */ - return sizeof(struct raw1394_request); + return 0; } static int arm_unregister(struct file_info *fi, struct pending_request *req) @@ -1953,7 +1802,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) vfree(addr->addr_space_buffer); kfree(addr); free_pending_request(req); /* immediate success or fail */ - return sizeof(struct raw1394_request); + return 0; } retval = hpsb_unregister_addrspace(&raw1394_highlevel, fi->host, @@ -1969,7 +1818,7 @@ static int arm_unregister(struct file_info *fi, struct pending_request *req) vfree(addr->addr_space_buffer); kfree(addr); free_pending_request(req); /* immediate success or fail */ - return sizeof(struct raw1394_request); + return 0; } /* Copy data from ARM buffer(s) to user buffer. */ @@ -2011,7 +1860,7 @@ static int arm_get_buf(struct file_info *fi, struct pending_request *req) * queue no response, and therefore nobody * will free it. */ free_pending_request(req); - return sizeof(struct raw1394_request); + return 0; } else { DBGMSG("arm_get_buf request exceeded mapping"); spin_unlock_irqrestore(&host_info_lock, flags); @@ -2063,7 +1912,7 @@ static int arm_set_buf(struct file_info *fi, struct pending_request *req) * queue no response, and therefore nobody * will free it. */ free_pending_request(req); - return sizeof(struct raw1394_request); + return 0; } else { DBGMSG("arm_set_buf request exceeded mapping"); spin_unlock_irqrestore(&host_info_lock, flags); @@ -2084,7 +1933,7 @@ static int reset_notification(struct file_info *fi, struct pending_request *req) (req->req.misc == RAW1394_NOTIFY_ON)) { fi->notification = (u8) req->req.misc; free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ - return sizeof(struct raw1394_request); + return 0; } /* error EINVAL (22) invalid argument */ return (-EINVAL); @@ -2117,12 +1966,12 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req) req->req.length = 0; queue_complete_req(req); } - return sizeof(struct raw1394_request); + return 0; } static int get_config_rom(struct file_info *fi, struct pending_request *req) { - int ret = sizeof(struct raw1394_request); + int ret = 0; quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); int status; @@ -2152,7 +2001,7 @@ static int get_config_rom(struct file_info *fi, struct pending_request *req) static int update_config_rom(struct file_info *fi, struct pending_request *req) { - int ret = sizeof(struct raw1394_request); + int ret = 0; quadlet_t *data = kmalloc(req->req.length, GFP_KERNEL); if (!data) return -ENOMEM; @@ -2219,7 +2068,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) hpsb_update_config_rom_image(fi->host); free_pending_request(req); - return sizeof(struct raw1394_request); + return 0; } } @@ -2284,7 +2133,7 @@ static int modify_config_rom(struct file_info *fi, struct pending_request *req) /* we have to free the request, because we queue no response, * and therefore nobody will free it */ free_pending_request(req); - return sizeof(struct raw1394_request); + return 0; } else { for (dentry = fi->csr1212_dirs[dr]->value.directory.dentries_head; @@ -2309,11 +2158,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) case RAW1394_REQ_ECHO: queue_complete_req(req); - return sizeof(struct raw1394_request); - - case RAW1394_REQ_ISO_SEND: - print_old_iso_deprecation(); - return handle_iso_send(fi, req, node); + return 0; case RAW1394_REQ_ARM_REGISTER: return arm_register(fi, req); @@ -2330,27 +2175,30 @@ static int state_connected(struct file_info *fi, struct pending_request *req) case RAW1394_REQ_RESET_NOTIFY: return reset_notification(fi, req); + case RAW1394_REQ_ISO_SEND: case RAW1394_REQ_ISO_LISTEN: - print_old_iso_deprecation(); - handle_iso_listen(fi, req); - return sizeof(struct raw1394_request); + printk(KERN_DEBUG "raw1394: old iso ABI has been removed\n"); + req->req.error = RAW1394_ERROR_COMPAT; + req->req.misc = RAW1394_KERNELAPI_VERSION; + queue_complete_req(req); + return 0; case RAW1394_REQ_FCP_LISTEN: handle_fcp_listen(fi, req); - return sizeof(struct raw1394_request); + return 0; case RAW1394_REQ_RESET_BUS: if (req->req.misc == RAW1394_LONG_RESET) { DBGMSG("busreset called (type: LONG)"); hpsb_reset_bus(fi->host, LONG_RESET); free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ - return sizeof(struct raw1394_request); + return 0; } if (req->req.misc == RAW1394_SHORT_RESET) { DBGMSG("busreset called (type: SHORT)"); hpsb_reset_bus(fi->host, SHORT_RESET); free_pending_request(req); /* we have to free the request, because we queue no response, and therefore nobody will free it */ - return sizeof(struct raw1394_request); + return 0; } /* error EINVAL (22) invalid argument */ return (-EINVAL); @@ -2369,7 +2217,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) req->req.generation = get_hpsb_generation(fi->host); req->req.length = 0; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } switch (req->req.type) { @@ -2382,7 +2230,7 @@ static int state_connected(struct file_info *fi, struct pending_request *req) if (req->req.length == 0) { req->req.error = RAW1394_ERROR_INVALID_ARG; queue_complete_req(req); - return sizeof(struct raw1394_request); + return 0; } return handle_async_request(fi, req, node); @@ -2393,7 +2241,7 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, { struct file_info *fi = (struct file_info *)file->private_data; struct pending_request *req; - ssize_t retval = 0; + ssize_t retval = -EBADFD; #ifdef CONFIG_COMPAT if (count == sizeof(struct compat_raw1394_req) && @@ -2435,6 +2283,9 @@ static ssize_t raw1394_write(struct file *file, const char __user * buffer, if (retval < 0) { free_pending_request(req); + } else { + BUG_ON(retval); + retval = count; } return retval; @@ -2800,6 +2651,103 @@ static int raw1394_ioctl(struct inode *inode, struct file *file, return -EINVAL; } +#ifdef CONFIG_COMPAT +struct raw1394_iso_packets32 { + __u32 n_packets; + compat_uptr_t infos; +} __attribute__((packed)); + +struct raw1394_cycle_timer32 { + __u32 cycle_timer; + __u64 local_time; +} +#if defined(CONFIG_X86_64) || defined(CONFIG_IA64) +__attribute__((packed)) +#endif +; + +#define RAW1394_IOC_ISO_RECV_PACKETS32 \ + _IOW ('#', 0x25, struct raw1394_iso_packets32) +#define RAW1394_IOC_ISO_XMIT_PACKETS32 \ + _IOW ('#', 0x27, struct raw1394_iso_packets32) +#define RAW1394_IOC_GET_CYCLE_TIMER32 \ + _IOR ('#', 0x30, struct raw1394_cycle_timer32) + +static long raw1394_iso_xmit_recv_packets32(struct file *file, unsigned int cmd, + struct raw1394_iso_packets32 __user *arg) +{ + compat_uptr_t infos32; + void *infos; + long err = -EFAULT; + struct raw1394_iso_packets __user *dst = compat_alloc_user_space(sizeof(struct raw1394_iso_packets)); + + if (!copy_in_user(&dst->n_packets, &arg->n_packets, sizeof arg->n_packets) && + !copy_from_user(&infos32, &arg->infos, sizeof infos32)) { + infos = compat_ptr(infos32); + if (!copy_to_user(&dst->infos, &infos, sizeof infos)) + err = raw1394_ioctl(NULL, file, cmd, (unsigned long)dst); + } + return err; +} + +static long raw1394_read_cycle_timer32(struct file_info *fi, void __user * uaddr) +{ + struct raw1394_cycle_timer32 ct; + int err; + + err = hpsb_read_cycle_timer(fi->host, &ct.cycle_timer, &ct.local_time); + if (!err) + if (copy_to_user(uaddr, &ct, sizeof(ct))) + err = -EFAULT; + return err; +} + +static long raw1394_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct file_info *fi = file->private_data; + void __user *argp = (void __user *)arg; + long err; + + lock_kernel(); + switch (cmd) { + /* These requests have same format as long as 'int' has same size. */ + case RAW1394_IOC_ISO_RECV_INIT: + case RAW1394_IOC_ISO_RECV_START: + case RAW1394_IOC_ISO_RECV_LISTEN_CHANNEL: + case RAW1394_IOC_ISO_RECV_UNLISTEN_CHANNEL: + case RAW1394_IOC_ISO_RECV_SET_CHANNEL_MASK: + case RAW1394_IOC_ISO_RECV_RELEASE_PACKETS: + case RAW1394_IOC_ISO_RECV_FLUSH: + case RAW1394_IOC_ISO_XMIT_RECV_STOP: + case RAW1394_IOC_ISO_XMIT_INIT: + case RAW1394_IOC_ISO_XMIT_START: + case RAW1394_IOC_ISO_XMIT_SYNC: + case RAW1394_IOC_ISO_GET_STATUS: + case RAW1394_IOC_ISO_SHUTDOWN: + case RAW1394_IOC_ISO_QUEUE_ACTIVITY: + err = raw1394_ioctl(NULL, file, cmd, arg); + break; + /* These request have different format. */ + case RAW1394_IOC_ISO_RECV_PACKETS32: + err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_RECV_PACKETS, argp); + break; + case RAW1394_IOC_ISO_XMIT_PACKETS32: + err = raw1394_iso_xmit_recv_packets32(file, RAW1394_IOC_ISO_XMIT_PACKETS, argp); + break; + case RAW1394_IOC_GET_CYCLE_TIMER32: + err = raw1394_read_cycle_timer32(fi, argp); + break; + default: + err = -EINVAL; + break; + } + unlock_kernel(); + + return err; +} +#endif + static unsigned int raw1394_poll(struct file *file, poll_table * pt) { struct file_info *fi = file->private_data; @@ -2859,14 +2807,7 @@ static int raw1394_release(struct inode *inode, struct file *file) if (fi->iso_state != RAW1394_ISO_INACTIVE) raw1394_iso_shutdown(fi); - for (i = 0; i < 64; i++) { - if (fi->listen_channels & (1ULL << i)) { - hpsb_unlisten_channel(&raw1394_highlevel, fi->host, i); - } - } - spin_lock_irqsave(&host_info_lock, flags); - fi->listen_channels = 0; fail = 0; /* set address-entries invalid */ @@ -3028,7 +2969,6 @@ static struct hpsb_highlevel raw1394_highlevel = { .add_host = add_host, .remove_host = remove_host, .host_reset = host_reset, - .iso_receive = iso_receive, .fcp_request = fcp_request, }; @@ -3039,7 +2979,9 @@ static const struct file_operations raw1394_fops = { .write = raw1394_write, .mmap = raw1394_mmap, .ioctl = raw1394_ioctl, - // .compat_ioctl = ... someone needs to do this +#ifdef CONFIG_COMPAT + .compat_ioctl = raw1394_compat_ioctl, +#endif .poll = raw1394_poll, .open = raw1394_open, .release = raw1394_release, @@ -3052,9 +2994,9 @@ static int __init init_raw1394(void) hpsb_register_highlevel(&raw1394_highlevel); if (IS_ERR - (class_device_create - (hpsb_protocol_class, NULL, - MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), NULL, + (device_create( + hpsb_protocol_class, NULL, + MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16), RAW1394_DEVICE_NAME))) { ret = -EFAULT; goto out_unreg; @@ -3081,9 +3023,9 @@ static int __init init_raw1394(void) goto out; out_dev: - class_device_destroy(hpsb_protocol_class, - MKDEV(IEEE1394_MAJOR, - IEEE1394_MINOR_BLOCK_RAW1394 * 16)); + device_destroy(hpsb_protocol_class, + MKDEV(IEEE1394_MAJOR, + IEEE1394_MINOR_BLOCK_RAW1394 * 16)); out_unreg: hpsb_unregister_highlevel(&raw1394_highlevel); out: @@ -3092,9 +3034,9 @@ static int __init init_raw1394(void) static void __exit cleanup_raw1394(void) { - class_device_destroy(hpsb_protocol_class, - MKDEV(IEEE1394_MAJOR, - IEEE1394_MINOR_BLOCK_RAW1394 * 16)); + device_destroy(hpsb_protocol_class, + MKDEV(IEEE1394_MAJOR, + IEEE1394_MINOR_BLOCK_RAW1394 * 16)); cdev_del(&raw1394_cdev); hpsb_unregister_highlevel(&raw1394_highlevel); hpsb_unregister_protocol(&raw1394_driver); diff --git a/drivers/ieee1394/raw1394.h b/drivers/ieee1394/raw1394.h index 7bd22ee1afbb..963ac20373d2 100644 --- a/drivers/ieee1394/raw1394.h +++ b/drivers/ieee1394/raw1394.h @@ -17,11 +17,11 @@ #define RAW1394_REQ_ASYNC_WRITE 101 #define RAW1394_REQ_LOCK 102 #define RAW1394_REQ_LOCK64 103 -#define RAW1394_REQ_ISO_SEND 104 +#define RAW1394_REQ_ISO_SEND 104 /* removed ABI, now a no-op */ #define RAW1394_REQ_ASYNC_SEND 105 #define RAW1394_REQ_ASYNC_STREAM 106 -#define RAW1394_REQ_ISO_LISTEN 200 +#define RAW1394_REQ_ISO_LISTEN 200 /* removed ABI, now a no-op */ #define RAW1394_REQ_FCP_LISTEN 201 #define RAW1394_REQ_RESET_BUS 202 #define RAW1394_REQ_GET_ROM 203 diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 4cb6fa2bcfb7..e882cb951b47 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -70,6 +70,7 @@ #include <linux/stringify.h> #include <linux/types.h> #include <linux/wait.h> +#include <linux/workqueue.h> #include <asm/byteorder.h> #include <asm/errno.h> @@ -117,14 +118,13 @@ MODULE_PARM_DESC(max_speed, "Force max speed " "(3 = 800Mb/s, 2 = 400Mb/s, 1 = 200Mb/s, 0 = 100Mb/s)"); /* - * Set serialize_io to 1 if you'd like only one scsi command sent - * down to us at a time (debugging). This might be necessary for very - * badly behaved sbp2 devices. + * Set serialize_io to 0 or N to use dynamically appended lists of command ORBs. + * This is and always has been buggy in multiple subtle ways. See above TODOs. */ static int sbp2_serialize_io = 1; -module_param_named(serialize_io, sbp2_serialize_io, int, 0444); -MODULE_PARM_DESC(serialize_io, "Serialize I/O coming from scsi drivers " - "(default = 1, faster = 0)"); +module_param_named(serialize_io, sbp2_serialize_io, bool, 0444); +MODULE_PARM_DESC(serialize_io, "Serialize requests coming from SCSI drivers " + "(default = Y, faster but buggy = N)"); /* * Bump up max_sectors if you'd like to support very large sized @@ -153,9 +153,9 @@ MODULE_PARM_DESC(max_sectors, "Change max sectors per I/O supported " * are possible on OXFW911 and newer Oxsemi bridges. */ static int sbp2_exclusive_login = 1; -module_param_named(exclusive_login, sbp2_exclusive_login, int, 0644); +module_param_named(exclusive_login, sbp2_exclusive_login, bool, 0644); MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device " - "(default = 1)"); + "(default = Y, use N for concurrent initiators)"); /* * If any of the following workarounds is required for your device to work, @@ -193,6 +193,27 @@ MODULE_PARM_DESC(workarounds, "Work around device bugs (default = 0" ", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE) ", or a combination)"); +/* + * This influences the format of the sysfs attribute + * /sys/bus/scsi/devices/.../ieee1394_id. + * + * The default format is like in older kernels: %016Lx:%d:%d + * It contains the target's EUI-64, a number given to the logical unit by + * the ieee1394 driver's nodemgr (starting at 0), and the LUN. + * + * The long format is: %016Lx:%06x:%04x + * It contains the target's EUI-64, the unit directory's directory_ID as per + * IEEE 1212 clause 7.7.19, and the LUN. This format comes closest to the + * format of SBP(-3) target port and logical unit identifier as per SAM (SCSI + * Architecture Model) rev.2 to 4 annex A. Therefore and because it is + * independent of the implementation of the ieee1394 nodemgr, the longer format + * is recommended for future use. + */ +static int sbp2_long_sysfs_ieee1394_id; +module_param_named(long_ieee1394_id, sbp2_long_sysfs_ieee1394_id, bool, 0644); +MODULE_PARM_DESC(long_ieee1394_id, "8+3+2 bytes format of ieee1394_id in sysfs " + "(default = backwards-compatible = N, SAM-conforming = Y)"); + #define SBP2_INFO(fmt, args...) HPSB_INFO("sbp2: "fmt, ## args) #define SBP2_ERR(fmt, args...) HPSB_ERR("sbp2: "fmt, ## args) @@ -1488,69 +1509,6 @@ static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, } } -static void sbp2_prep_command_orb_no_sg(struct sbp2_command_orb *orb, - struct sbp2_fwhost_info *hi, - struct sbp2_command_info *cmd, - struct scatterlist *sgpnt, - u32 orb_direction, - unsigned int scsi_request_bufflen, - void *scsi_request_buffer, - enum dma_data_direction dma_dir) -{ - cmd->dma_dir = dma_dir; - cmd->dma_size = scsi_request_bufflen; - cmd->dma_type = CMD_DMA_SINGLE; - cmd->cmd_dma = dma_map_single(hi->host->device.parent, - scsi_request_buffer, - cmd->dma_size, cmd->dma_dir); - orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id); - orb->misc |= ORB_SET_DIRECTION(orb_direction); - - /* handle case where we get a command w/o s/g enabled - * (but check for transfers larger than 64K) */ - if (scsi_request_bufflen <= SBP2_MAX_SG_ELEMENT_LENGTH) { - - orb->data_descriptor_lo = cmd->cmd_dma; - orb->misc |= ORB_SET_DATA_SIZE(scsi_request_bufflen); - - } else { - /* The buffer is too large. Turn this into page tables. */ - - struct sbp2_unrestricted_page_table *sg_element = - &cmd->scatter_gather_element[0]; - u32 sg_count, sg_len; - dma_addr_t sg_addr; - - orb->data_descriptor_lo = cmd->sge_dma; - orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1); - - /* fill out our SBP-2 page tables; split up the large buffer */ - sg_count = 0; - sg_len = scsi_request_bufflen; - sg_addr = cmd->cmd_dma; - while (sg_len) { - sg_element[sg_count].segment_base_lo = sg_addr; - if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) { - sg_element[sg_count].length_segment_base_hi = - PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH); - sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH; - sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH; - } else { - sg_element[sg_count].length_segment_base_hi = - PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len); - sg_len = 0; - } - sg_count++; - } - - orb->misc |= ORB_SET_DATA_SIZE(sg_count); - - sbp2util_cpu_to_be32_buffer(sg_element, - (sizeof(struct sbp2_unrestricted_page_table)) * - sg_count); - } -} - static void sbp2_create_command_orb(struct sbp2_lu *lu, struct sbp2_command_info *cmd, unchar *scsi_cmd, @@ -1594,13 +1552,9 @@ static void sbp2_create_command_orb(struct sbp2_lu *lu, orb->data_descriptor_hi = 0x0; orb->data_descriptor_lo = 0x0; orb->misc |= ORB_SET_DIRECTION(1); - } else if (scsi_use_sg) + } else sbp2_prep_command_orb_sg(orb, hi, cmd, scsi_use_sg, sgpnt, orb_direction, dma_dir); - else - sbp2_prep_command_orb_no_sg(orb, hi, cmd, sgpnt, orb_direction, - scsi_request_bufflen, - scsi_request_buffer, dma_dir); sbp2util_cpu_to_be32_buffer(orb, sizeof(*orb)); @@ -1689,15 +1643,15 @@ static int sbp2_send_command(struct sbp2_lu *lu, struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) { unchar *scsi_cmd = (unchar *)SCpnt->cmnd; - unsigned int request_bufflen = SCpnt->request_bufflen; + unsigned int request_bufflen = scsi_bufflen(SCpnt); struct sbp2_command_info *cmd; cmd = sbp2util_allocate_command_orb(lu, SCpnt, done); if (!cmd) return -EIO; - sbp2_create_command_orb(lu, cmd, scsi_cmd, SCpnt->use_sg, - request_bufflen, SCpnt->request_buffer, + sbp2_create_command_orb(lu, cmd, scsi_cmd, scsi_sg_count(SCpnt), + request_bufflen, scsi_sglist(SCpnt), SCpnt->sc_data_direction); sbp2_link_orb_command(lu, cmd); @@ -2099,8 +2053,14 @@ static ssize_t sbp2_sysfs_ieee1394_id_show(struct device *dev, if (!(lu = (struct sbp2_lu *)sdev->host->hostdata[0])) return 0; - return sprintf(buf, "%016Lx:%d:%d\n", (unsigned long long)lu->ne->guid, - lu->ud->id, ORB_SET_LUN(lu->lun)); + if (sbp2_long_sysfs_ieee1394_id) + return sprintf(buf, "%016Lx:%06x:%04x\n", + (unsigned long long)lu->ne->guid, + lu->ud->directory_id, ORB_SET_LUN(lu->lun)); + else + return sprintf(buf, "%016Lx:%d:%d\n", + (unsigned long long)lu->ne->guid, + lu->ud->id, ORB_SET_LUN(lu->lun)); } MODULE_AUTHOR("Ben Collins <bcollins@debian.org>"); diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index 44402b9d82a8..333a4bb76743 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h @@ -67,7 +67,7 @@ struct sbp2_command_orb { #define ORB_SET_LUN(v) ((v) & 0xffff) #define ORB_SET_FUNCTION(v) (((v) & 0xf) << 16) #define ORB_SET_RECONNECT(v) (((v) & 0xf) << 20) -#define ORB_SET_EXCLUSIVE(v) (((v) & 0x1) << 28) +#define ORB_SET_EXCLUSIVE(v) ((v) ? 1 << 28 : 0) #define ORB_SET_LOGIN_RESP_LENGTH(v) ((v) & 0xffff) #define ORB_SET_PASSWD_LENGTH(v) (((v) & 0xffff) << 16) diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index 87ebd0846c34..bd28adfd7afc 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c @@ -1340,9 +1340,9 @@ static void video1394_add_host (struct hpsb_host *host) hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id); minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id; - class_device_create(hpsb_protocol_class, NULL, MKDEV( - IEEE1394_MAJOR, minor), - NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id); + device_create(hpsb_protocol_class, NULL, + MKDEV(IEEE1394_MAJOR, minor), + "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id); } @@ -1351,8 +1351,8 @@ static void video1394_remove_host (struct hpsb_host *host) struct ti_ohci *ohci = hpsb_get_hostinfo(&video1394_highlevel, host); if (ohci) - class_device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, - IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id)); + device_destroy(hpsb_protocol_class, MKDEV(IEEE1394_MAJOR, + IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id)); return; } |