Commit 486b4ce1 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
  firewire: fix return code
  firewire: prefix modules with firewire- instead of fw-
  firewire: Add missing byteswapping for receive DMA programs.
  ieee1394: raw1394: Fix async send
  ieee1394: eth1394: bring back a parent device
  ieee1394: eth1394: handle tlabel exhaustion
  ieee1394: eth1394: remove bogus netif_wake_queue
  ieee1394: sbp2: include workqueue.h
parents 358a9afc 350958f9
...@@ -18,7 +18,7 @@ config FIREWIRE ...@@ -18,7 +18,7 @@ config FIREWIRE
your IEEE 1394 adapter. your IEEE 1394 adapter.
To compile this driver as a module, say M here: the module will be 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 This is the "JUJU" FireWire stack, an alternative implementation
designed for robustness and simplicity. You can build either this designed for robustness and simplicity. You can build either this
...@@ -34,11 +34,11 @@ config FIREWIRE_OHCI ...@@ -34,11 +34,11 @@ config FIREWIRE_OHCI
is the only chipset in use, so say Y here. is the only chipset in use, so say Y here.
To compile this driver as a module, say M here: The module will be 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, If you also build ohci1394 of the classic IEEE 1394 driver stack,
blacklist either ohci1394 or fw-ohci to let hotplug load the desired blacklist either ohci1394 or firewire-ohci to let hotplug load the
driver. desired driver.
config FIREWIRE_SBP2 config FIREWIRE_SBP2
tristate "Support for storage devices (SBP-2 protocol driver)" tristate "Support for storage devices (SBP-2 protocol driver)"
...@@ -50,12 +50,12 @@ config FIREWIRE_SBP2 ...@@ -50,12 +50,12 @@ config FIREWIRE_SBP2
like scanners. like scanners.
To compile this driver as a module, say M here: The module will be 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 You should also enable support for disks, CD-ROMs, etc. in the SCSI
configuration section. configuration section.
If you also build sbp2 of the classic IEEE 1394 driver stack, If you also build sbp2 of the classic IEEE 1394 driver stack,
blacklist either sbp2 or fw-sbp2 to let hotplug load the desired blacklist either sbp2 or firewire-sbp2 to let hotplug load the
driver. desired driver.
...@@ -2,9 +2,11 @@ ...@@ -2,9 +2,11 @@
# Makefile for the Linux IEEE 1394 implementation # Makefile for the Linux IEEE 1394 implementation
# #
fw-core-y += fw-card.o fw-topology.o fw-transaction.o fw-iso.o \ firewire-core-y += fw-card.o fw-topology.o fw-transaction.o fw-iso.o \
fw-device.o fw-cdev.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) += firewire-core.o
obj-$(CONFIG_FIREWIRE_OHCI) += fw-ohci.o obj-$(CONFIG_FIREWIRE_OHCI) += firewire-ohci.o
obj-$(CONFIG_FIREWIRE_SBP2) += fw-sbp2.o obj-$(CONFIG_FIREWIRE_SBP2) += firewire-sbp2.o
...@@ -365,7 +365,7 @@ complete_transaction(struct fw_card *card, int rcode, ...@@ -365,7 +365,7 @@ complete_transaction(struct fw_card *card, int rcode,
response->response.data, response->response.length); 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_device *device = client->device;
struct fw_cdev_send_request *request = buffer; struct fw_cdev_send_request *request = buffer;
......
...@@ -268,7 +268,7 @@ static int ar_context_add_page(struct ar_context *ctx) ...@@ -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); 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->next = ab;
ctx->last_buffer = ab; ctx->last_buffer = ab;
...@@ -417,7 +417,8 @@ ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, u32 regs) ...@@ -417,7 +417,8 @@ ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, u32 regs)
ctx->current_buffer = ab.next; ctx->current_buffer = ab.next;
ctx->pointer = ctx->current_buffer->data; 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); reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN);
flush_writes(ctx->ohci); flush_writes(ctx->ohci);
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/workqueue.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/inetdevice.h> #include <linux/inetdevice.h>
...@@ -235,6 +236,9 @@ static int ether1394_open(struct net_device *dev) ...@@ -235,6 +236,9 @@ static int ether1394_open(struct net_device *dev)
/* This is called after an "ifdown" */ /* This is called after an "ifdown" */
static int ether1394_stop(struct net_device *dev) static int ether1394_stop(struct net_device *dev)
{ {
/* flush priv->wake */
flush_scheduled_work();
netif_stop_queue(dev); netif_stop_queue(dev);
return 0; return 0;
} }
...@@ -530,6 +534,37 @@ static void ether1394_init_dev(struct net_device *dev) ...@@ -530,6 +534,37 @@ static void ether1394_init_dev(struct net_device *dev)
dev->tx_queue_len = 1000; 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 * 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 * when the module is installed. This is where we add all of our ethernet
...@@ -564,16 +599,17 @@ static void ether1394_add_host(struct hpsb_host *host) ...@@ -564,16 +599,17 @@ static void ether1394_add_host(struct hpsb_host *host)
} }
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
#if 0
/* FIXME - Is this the correct parent device anyway? */ /* This used to be &host->device in Linux 2.6.20 and before. */
SET_NETDEV_DEV(dev, &host->device); SET_NETDEV_DEV(dev, host->device.parent);
#endif
priv = netdev_priv(dev); priv = netdev_priv(dev);
INIT_LIST_HEAD(&priv->ip_node_list); INIT_LIST_HEAD(&priv->ip_node_list);
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
priv->host = host; priv->host = host;
priv->local_fifo = fifo_addr; priv->local_fifo = fifo_addr;
INIT_WORK(&priv->wake, ether1394_wake_queue);
priv->wake_dev = dev;
hi = hpsb_create_hostinfo(&eth1394_highlevel, host, sizeof(*hi)); hi = hpsb_create_hostinfo(&eth1394_highlevel, host, sizeof(*hi));
if (hi == NULL) { if (hi == NULL) {
...@@ -1390,22 +1426,17 @@ static int ether1394_prep_write_packet(struct hpsb_packet *p, ...@@ -1390,22 +1426,17 @@ static int ether1394_prep_write_packet(struct hpsb_packet *p,
u64 addr, void *data, int tx_len) u64 addr, void *data, int tx_len)
{ {
p->node_id = node; p->node_id = node;
p->data = NULL;
p->tcode = TCODE_WRITEB; if (hpsb_get_tlabel(p))
p->header[1] = host->node_id << 16 | addr >> 32; return -EAGAIN;
p->header[2] = addr & 0xffffffff;
p->tcode = TCODE_WRITEB;
p->header_size = 16; p->header_size = 16;
p->expect_response = 1; p->expect_response = 1;
if (hpsb_get_tlabel(p)) {
ETH1394_PRINT_G(KERN_ERR, "Out of tlabels\n");
return -1;
}
p->header[0] = p->header[0] =
p->node_id << 16 | p->tlabel << 10 | 1 << 8 | TCODE_WRITEB << 4; 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->header[3] = tx_len << 16;
p->data_size = (tx_len + 3) & ~3; p->data_size = (tx_len + 3) & ~3;
p->data = data; p->data = data;
...@@ -1451,7 +1482,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len) ...@@ -1451,7 +1482,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
packet = ether1394_alloc_common_packet(priv->host); packet = ether1394_alloc_common_packet(priv->host);
if (!packet) if (!packet)
return -1; return -ENOMEM;
if (ptask->tx_type == ETH1394_GASP) { if (ptask->tx_type == ETH1394_GASP) {
int length = tx_len + 2 * sizeof(quadlet_t); int length = tx_len + 2 * sizeof(quadlet_t);
...@@ -1462,7 +1493,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len) ...@@ -1462,7 +1493,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
ptask->addr, ptask->skb->data, ptask->addr, ptask->skb->data,
tx_len)) { tx_len)) {
hpsb_free_packet(packet); hpsb_free_packet(packet);
return -1; return -EAGAIN;
} }
ptask->packet = packet; ptask->packet = packet;
...@@ -1471,7 +1502,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len) ...@@ -1471,7 +1502,7 @@ static int ether1394_send_packet(struct packet_task *ptask, unsigned int tx_len)
if (hpsb_send_packet(packet) < 0) { if (hpsb_send_packet(packet) < 0) {
ether1394_free_packet(packet); ether1394_free_packet(packet);
return -1; return -EIO;
} }
return 0; return 0;
...@@ -1514,13 +1545,18 @@ static void ether1394_complete_cb(void *__ptask) ...@@ -1514,13 +1545,18 @@ static void ether1394_complete_cb(void *__ptask)
ptask->outstanding_pkts--; ptask->outstanding_pkts--;
if (ptask->outstanding_pkts > 0 && !fail) { if (ptask->outstanding_pkts > 0 && !fail) {
int tx_len; int tx_len, err;
/* Add the encapsulation header to the fragment */ /* Add the encapsulation header to the fragment */
tx_len = ether1394_encapsulate(ptask->skb, ptask->max_payload, tx_len = ether1394_encapsulate(ptask->skb, ptask->max_payload,
&ptask->hdr); &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); ether1394_dg_complete(ptask, 1);
}
} else { } else {
ether1394_dg_complete(ptask, fail); ether1394_dg_complete(ptask, fail);
} }
...@@ -1633,10 +1669,18 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev) ...@@ -1633,10 +1669,18 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev)
/* Add the encapsulation header to the fragment */ /* Add the encapsulation header to the fragment */
tx_len = ether1394_encapsulate(skb, max_payload, &ptask->hdr); tx_len = ether1394_encapsulate(skb, max_payload, &ptask->hdr);
dev->trans_start = jiffies; dev->trans_start = jiffies;
if (ether1394_send_packet(ptask, tx_len)) if (ether1394_send_packet(ptask, tx_len)) {
goto fail; 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;
}
netif_wake_queue(dev);
return NETDEV_TX_OK; return NETDEV_TX_OK;
fail: fail:
if (ptask) if (ptask)
...@@ -1650,9 +1694,6 @@ fail: ...@@ -1650,9 +1694,6 @@ fail:
priv->stats.tx_errors++; priv->stats.tx_errors++;
spin_unlock_irqrestore(&priv->lock, flags); 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 * FIXME: According to a patch from 2003-02-26, "returning non-zero
* causes serious problems" here, allegedly. Before that patch, * causes serious problems" here, allegedly. Before that patch,
......
...@@ -66,6 +66,10 @@ struct eth1394_priv { ...@@ -66,6 +66,10 @@ struct eth1394_priv {
int bc_dgl; /* Outgoing broadcast datagram label */ int bc_dgl; /* Outgoing broadcast datagram label */
struct list_head ip_node_list; /* List of IP capable nodes */ struct list_head ip_node_list; /* List of IP capable nodes */
struct unit_directory *ud_list[ALL_NODES]; /* Cached unit dir list */ 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 */
}; };
......
...@@ -936,6 +936,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) ...@@ -936,6 +936,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
struct hpsb_packet *packet; struct hpsb_packet *packet;
int header_length = req->req.misc & 0xffff; int header_length = req->req.misc & 0xffff;
int expect_response = req->req.misc >> 16; int expect_response = req->req.misc >> 16;
size_t data_size;
if (header_length > req->req.length || header_length < 12 || if (header_length > req->req.length || header_length < 12 ||
header_length > FIELD_SIZEOF(struct hpsb_packet, header)) { 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) ...@@ -945,7 +946,8 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
return sizeof(struct raw1394_request); 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; req->packet = packet;
if (!packet) if (!packet)
return -ENOMEM; return -ENOMEM;
...@@ -960,7 +962,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) ...@@ -960,7 +962,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
if (copy_from_user if (copy_from_user
(packet->data, int2ptr(req->req.sendb) + header_length, (packet->data, int2ptr(req->req.sendb) + header_length,
packet->data_size)) { data_size)) {
req->req.error = RAW1394_ERROR_MEMFAULT; req->req.error = RAW1394_ERROR_MEMFAULT;
req->req.length = 0; req->req.length = 0;
queue_complete_req(req); queue_complete_req(req);
...@@ -974,7 +976,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req) ...@@ -974,7 +976,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
packet->host = fi->host; packet->host = fi->host;
packet->expect_response = expect_response; packet->expect_response = expect_response;
packet->header_size = header_length; packet->header_size = header_length;
packet->data_size = req->req.length - header_length; packet->data_size = data_size;
req->req.length = 0; req->req.length = 0;
hpsb_set_packet_complete_task(packet, hpsb_set_packet_complete_task(packet,
......
...@@ -70,6 +70,7 @@ ...@@ -70,6 +70,7 @@
#include <linux/stringify.h> #include <linux/stringify.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/workqueue.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/errno.h> #include <asm/errno.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment