From a515958d6f77fdff1a40f8b08a9a95ac223c5d48 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 9 Jun 2007 19:31:14 +0200 Subject: firewire: fix hang after card ejection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Stefan Richter Signed-off-by: Kristian Høgsberg --- drivers/firewire/fw-ohci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 0d08bf9b78c..b72a5c1f9e6 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c @@ -1001,7 +1001,7 @@ static irqreturn_t irq_handler(int irq, void *data) event = reg_read(ohci, OHCI1394_IntEventClear); - if (!event) + if (!event || !~event) return IRQ_NONE; reg_write(ohci, OHCI1394_IntEventClear, event); -- cgit v1.2.3-70-g09d2 From 18b461796b737f94286f73710debc8649467161b Mon Sep 17 00:00:00 2001 From: "Carlos E. Ugarte" Date: Mon, 4 Jun 2007 11:49:19 -0400 Subject: ieee1394: fix to ether1394_tx in ether1394.c This patch fixes a problem that occurs when packets cannot be sent across the ieee1394 bus and we return NETDEV_TX_BUSY in the net driver "hard start xmit" routine ether1394_tx. When we return NETDEV_TX_BUSY the stack will call ether1394_tx again with the same skb. So we need to restore the header to look like it did before we munged it for xmit over ieee1394. [Stefan Richter: changed whitespace, deleted a local variable] Signed-off-by: Stefan Richter --- drivers/ieee1394/eth1394.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index 5f026b5d785..7c13fb3c167 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c @@ -1565,7 +1565,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; @@ -1595,16 +1595,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)))) { @@ -1616,7 +1617,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)); @@ -1673,6 +1674,14 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev) 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; -- cgit v1.2.3-70-g09d2 From 24315c5e6f508edd84e996d67daef3d1bcc72f8b Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Wed, 20 Jun 2007 17:48:07 -0400 Subject: firewire: Only set client->iso_context if allocation was successful. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes an OOPS on cdev release for an fd where iso context creation failed. Signed-off-by: Kristian Høgsberg Signed-off-by: Stefan Richter --- drivers/firewire/fw-cdev.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index 5d402d63799..dbb76427d52 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c @@ -640,6 +640,7 @@ iso_callback(struct fw_iso_context *context, u32 cycle, static int ioctl_create_iso_context(struct client *client, void *buffer) { struct fw_cdev_create_iso_context *request = buffer; + struct fw_iso_context *context; if (request->channel > 63) return -EINVAL; @@ -661,15 +662,17 @@ static int ioctl_create_iso_context(struct client *client, void *buffer) return -EINVAL; } + context = fw_iso_context_create(client->device->card, + request->type, + request->channel, + request->speed, + request->header_size, + iso_callback, client); + if (IS_ERR(context)) + return PTR_ERR(context); + client->iso_closure = request->closure; - client->iso_context = fw_iso_context_create(client->device->card, - request->type, - request->channel, - request->speed, - request->header_size, - iso_callback, client); - if (IS_ERR(client->iso_context)) - return PTR_ERR(client->iso_context); + client->iso_context = context; /* We only support one context at this time. */ request->handle = 0; -- cgit v1.2.3-70-g09d2