From 20e2008e1f24a6831bf4311f8e2f8692f16a92de Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 5 May 2007 17:18:12 +0200 Subject: ieee1394: sbp2: include workqueue.h Signed-off-by: Stefan Richter --- drivers/ieee1394/sbp2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 4cb6fa2bcfb..875eadd5e8f 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -70,6 +70,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From 69c29fa7d142d65b13e366ae51e50944484b65ab Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 5 May 2007 17:19:09 +0200 Subject: ieee1394: eth1394: remove bogus netif_wake_queue When we are within hard_start_xmit, the queue is already awake. Signed-off-by: Stefan Richter --- drivers/ieee1394/eth1394.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index 2296d43a241..8e4c959e586 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c @@ -1636,7 +1636,6 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev) if (ether1394_send_packet(ptask, tx_len)) goto fail; - netif_wake_queue(dev); return NETDEV_TX_OK; fail: if (ptask) @@ -1650,9 +1649,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, -- cgit v1.2.3 From 7a97bc03e089d1a75dc533f0fe69ec8dac672916 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 5 May 2007 17:25:51 +0200 Subject: ieee1394: eth1394: handle tlabel exhaustion When eth1394 was unable to acquire a transaction label, it just dropped outgoing packets without attempt to resend them later. The transmit queue is now halted if no tlabel is available to ->hard_start_xmit(). A workqueue job is then scheduled to catch the moment when ieee1394 recycled the next lot of tlabels. Fixes http://bugzilla.kernel.org/show_bug.cgi?id=8402 Signed-off-by: Stefan Richter --- drivers/ieee1394/eth1394.c | 80 ++++++++++++++++++++++++++++++++++++---------- drivers/ieee1394/eth1394.h | 4 +++ 2 files changed, 67 insertions(+), 17 deletions(-) diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index 8e4c959e586..d6b19c2780a 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -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; } @@ -530,6 +534,37 @@ static void ether1394_init_dev(struct net_device *dev) dev->tx_queue_len = 1000; } +/* + * 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 @@ -574,6 +609,8 @@ static void ether1394_add_host(struct hpsb_host *host) 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 +1427,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 +1483,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 +1494,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 +1503,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 +1546,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); } @@ -1633,8 +1670,17 @@ 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; + + /* 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; + } return NETDEV_TX_OK; fail: diff --git a/drivers/ieee1394/eth1394.h b/drivers/ieee1394/eth1394.h index a3439ee7cb4..4f3e2dd46f0 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 */ }; -- cgit v1.2.3 From ef50a6c59dc66f22eba67704e291d709f21e0456 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 21 May 2007 01:05:41 +0200 Subject: ieee1394: eth1394: bring back a parent device This adds a real parent device to eth1394's ethX device like in Linux 2.6.20 and older. However, due to unfinished conversion of the ieee1394 away from class_device, we now refer to the FireWire controller's PCI device as the parent, not to the ieee1394 driver's fw-host device. Having a real parent device instead of a virtual one allows udev scripts to distinguish eth1394 interfaces from networking bridges, bondings and the likes. Fixes a regression since 2.6.21: https://bugs.gentoo.org/show_bug.cgi?id=177199 Signed-off-by: Stefan Richter --- drivers/ieee1394/eth1394.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index d6b19c2780a..5f026b5d785 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c @@ -599,10 +599,9 @@ 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 + + /* This used to be &host->device in Linux 2.6.20 and before. */ + SET_NETDEV_DEV(dev, host->device.parent); priv = netdev_priv(dev); INIT_LIST_HEAD(&priv->ip_node_list); -- cgit v1.2.3 From 976da96a5d4fe84bd292b950e566325dc3e5904e Mon Sep 17 00:00:00 2001 From: Petr Vandrovec Date: Sun, 13 May 2007 22:14:44 -0700 Subject: ieee1394: raw1394: Fix async send While playing with libiec61883 I've noticed that async_send is broken because it was doing copy_from_user(...., packet->data_size) before packet->data_size was set to any useful value. It got broken when packet->allocated_data_size got introduced, as hpsb_alloc_packet does not set packet->data_size anymore. (Regression in 2.6.22-rc1) Signed-off-by: Petr Vandrovec Signed-off-by: Stefan Richter --- drivers/ieee1394/raw1394.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c index d382500f421..f1d05eeb9f5 100644 --- a/drivers/ieee1394/raw1394.c +++ b/drivers/ieee1394/raw1394.c @@ -936,6 +936,7 @@ 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)) { @@ -945,7 +946,8 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) return sizeof(struct raw1394_request); } - 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; @@ -960,7 +962,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) 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); @@ -974,7 +976,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, -- cgit v1.2.3 From ec839e43fbe1b1ab74264ac510f6cd9c8e8334a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 22 May 2007 18:55:48 -0400 Subject: firewire: Add missing byteswapping for receive DMA programs. Signed-off-by: Kristian Hoegsberg Signed-off-by: Stefan Richter --- drivers/firewire/fw-ohci.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index c17342d3e6f..2e4cfa57126 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -268,7 +268,7 @@ static int ar_context_add_page(struct ar_context *ctx) dma_sync_single_for_device(dev, ab_bus, PAGE_SIZE, DMA_BIDIRECTIONAL); - ctx->last_buffer->descriptor.branch_address = ab_bus | 1; + ctx->last_buffer->descriptor.branch_address = cpu_to_le32(ab_bus | 1); ctx->last_buffer->next = ab; ctx->last_buffer = ab; @@ -417,7 +417,8 @@ ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, u32 regs) ctx->current_buffer = ab.next; ctx->pointer = ctx->current_buffer->data; - reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ab.descriptor.branch_address); + reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), + le32_to_cpu(ab.descriptor.branch_address)); reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN); flush_writes(ctx->ohci); -- cgit v1.2.3 From 9a60731d0036a6c6c265acd4248c17fd24fc8e13 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Fri, 25 May 2007 13:54:49 +0200 Subject: firewire: prefix modules with firewire- instead of fw- Of course everybody immediately associates "fw-" with FireWire, not firmware or firewall or whatever. But "firewire-" has a nice ring to it too. Signed-off-by: Stefan Richter Acked-by: Kristian Hoegsberg --- drivers/firewire/Kconfig | 14 +++++++------- drivers/firewire/Makefile | 12 +++++++----- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig index 5932c72f9e4..396dade731f 100644 --- a/drivers/firewire/Kconfig +++ b/drivers/firewire/Kconfig @@ -18,7 +18,7 @@ config FIREWIRE your IEEE 1394 adapter. To compile this driver as a module, say M here: the module will be - called fw-core. + called firewire-core. This is the "JUJU" FireWire stack, an alternative implementation designed for robustness and simplicity. You can build either this @@ -34,11 +34,11 @@ config FIREWIRE_OHCI is the only chipset in use, so say Y here. To compile this driver as a module, say M here: The module will be - called fw-ohci. + called firewire-ohci. If you also build ohci1394 of the classic IEEE 1394 driver stack, - blacklist either ohci1394 or fw-ohci to let hotplug load the desired - driver. + blacklist either ohci1394 or firewire-ohci to let hotplug load the + desired driver. config FIREWIRE_SBP2 tristate "Support for storage devices (SBP-2 protocol driver)" @@ -50,12 +50,12 @@ config FIREWIRE_SBP2 like scanners. To compile this driver as a module, say M here: The module will be - called fw-sbp2. + called firewire-sbp2. You should also enable support for disks, CD-ROMs, etc. in the SCSI configuration section. If you also build sbp2 of the classic IEEE 1394 driver stack, - blacklist either sbp2 or fw-sbp2 to let hotplug load the desired - driver. + blacklist either sbp2 or firewire-sbp2 to let hotplug load the + desired driver. diff --git a/drivers/firewire/Makefile b/drivers/firewire/Makefile index fc7d59d4bce..a7c31e9039c 100644 --- a/drivers/firewire/Makefile +++ b/drivers/firewire/Makefile @@ -2,9 +2,11 @@ # Makefile for the Linux IEEE 1394 implementation # -fw-core-y += fw-card.o fw-topology.o fw-transaction.o fw-iso.o \ - fw-device.o fw-cdev.o +firewire-core-y += fw-card.o fw-topology.o fw-transaction.o fw-iso.o \ + fw-device.o fw-cdev.o +firewire-ohci-y += fw-ohci.o +firewire-sbp2-y += fw-sbp2.o -obj-$(CONFIG_FIREWIRE) += fw-core.o -obj-$(CONFIG_FIREWIRE_OHCI) += fw-ohci.o -obj-$(CONFIG_FIREWIRE_SBP2) += fw-sbp2.o +obj-$(CONFIG_FIREWIRE) += firewire-core.o +obj-$(CONFIG_FIREWIRE_OHCI) += firewire-ohci.o +obj-$(CONFIG_FIREWIRE_SBP2) += firewire-sbp2.o -- cgit v1.2.3 From 350958f984268dcf0f087aac78c5b9fe2846aeff Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 27 May 2007 07:09:18 -0400 Subject: firewire: fix return code Fix this warning on x86-64 drivers/firewire/fw-cdev.c:798: warning: initialization from incompatible pointer type by making the return code of ioctl_send_request() the same as all the other ioctl_xxx() return codes. Signed-off-by: Jeff Garzik Signed-off-by: Stefan Richter --- drivers/firewire/fw-cdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index 0fa5bd54c6a..3ab3585d360 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c @@ -365,7 +365,7 @@ complete_transaction(struct fw_card *card, int rcode, response->response.data, response->response.length); } -static ssize_t ioctl_send_request(struct client *client, void *buffer) +static int ioctl_send_request(struct client *client, void *buffer) { struct fw_device *device = client->device; struct fw_cdev_send_request *request = buffer; -- cgit v1.2.3