diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-20 18:39:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-20 18:39:50 -0400 |
commit | d025d7858f7415f558e89d870ad1a205954b64cd (patch) | |
tree | c405da2a5ce0e8b5e6db92fa4cc9df51c3a34e77 | |
parent | b3f4256fe0682143883ce6903e4646a03943f792 (diff) | |
parent | 24315c5e6f508edd84e996d67daef3d1bcc72f8b (diff) |
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: Only set client->iso_context if allocation was successful.
ieee1394: fix to ether1394_tx in ether1394.c
firewire: fix hang after card ejection
-rw-r--r-- | drivers/firewire/fw-cdev.c | 19 | ||||
-rw-r--r-- | drivers/firewire/fw-ohci.c | 2 | ||||
-rw-r--r-- | drivers/ieee1394/eth1394.c | 21 |
3 files changed, 27 insertions, 15 deletions
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index 5d402d63799f..dbb76427d529 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, | |||
640 | static int ioctl_create_iso_context(struct client *client, void *buffer) | 640 | static int ioctl_create_iso_context(struct client *client, void *buffer) |
641 | { | 641 | { |
642 | struct fw_cdev_create_iso_context *request = buffer; | 642 | struct fw_cdev_create_iso_context *request = buffer; |
643 | struct fw_iso_context *context; | ||
643 | 644 | ||
644 | if (request->channel > 63) | 645 | if (request->channel > 63) |
645 | return -EINVAL; | 646 | return -EINVAL; |
@@ -661,15 +662,17 @@ static int ioctl_create_iso_context(struct client *client, void *buffer) | |||
661 | return -EINVAL; | 662 | return -EINVAL; |
662 | } | 663 | } |
663 | 664 | ||
665 | context = fw_iso_context_create(client->device->card, | ||
666 | request->type, | ||
667 | request->channel, | ||
668 | request->speed, | ||
669 | request->header_size, | ||
670 | iso_callback, client); | ||
671 | if (IS_ERR(context)) | ||
672 | return PTR_ERR(context); | ||
673 | |||
664 | client->iso_closure = request->closure; | 674 | client->iso_closure = request->closure; |
665 | client->iso_context = fw_iso_context_create(client->device->card, | 675 | client->iso_context = context; |
666 | request->type, | ||
667 | request->channel, | ||
668 | request->speed, | ||
669 | request->header_size, | ||
670 | iso_callback, client); | ||
671 | if (IS_ERR(client->iso_context)) | ||
672 | return PTR_ERR(client->iso_context); | ||
673 | 676 | ||
674 | /* We only support one context at this time. */ | 677 | /* We only support one context at this time. */ |
675 | request->handle = 0; | 678 | request->handle = 0; |
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index 0d08bf9b78c2..b72a5c1f9e69 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) | |||
1001 | 1001 | ||
1002 | event = reg_read(ohci, OHCI1394_IntEventClear); | 1002 | event = reg_read(ohci, OHCI1394_IntEventClear); |
1003 | 1003 | ||
1004 | if (!event) | 1004 | if (!event || !~event) |
1005 | return IRQ_NONE; | 1005 | return IRQ_NONE; |
1006 | 1006 | ||
1007 | reg_write(ohci, OHCI1394_IntEventClear, event); | 1007 | reg_write(ohci, OHCI1394_IntEventClear, event); |
diff --git a/drivers/ieee1394/eth1394.c b/drivers/ieee1394/eth1394.c index 5f026b5d7857..7c13fb3c167b 100644 --- a/drivers/ieee1394/eth1394.c +++ b/drivers/ieee1394/eth1394.c | |||
@@ -1565,7 +1565,7 @@ static void ether1394_complete_cb(void *__ptask) | |||
1565 | /* Transmit a packet (called by kernel) */ | 1565 | /* Transmit a packet (called by kernel) */ |
1566 | static int ether1394_tx(struct sk_buff *skb, struct net_device *dev) | 1566 | static int ether1394_tx(struct sk_buff *skb, struct net_device *dev) |
1567 | { | 1567 | { |
1568 | struct eth1394hdr *eth; | 1568 | struct eth1394hdr hdr_buf; |
1569 | struct eth1394_priv *priv = netdev_priv(dev); | 1569 | struct eth1394_priv *priv = netdev_priv(dev); |
1570 | __be16 proto; | 1570 | __be16 proto; |
1571 | unsigned long flags; | 1571 | unsigned long flags; |
@@ -1595,16 +1595,17 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev) | |||
1595 | if (!skb) | 1595 | if (!skb) |
1596 | goto fail; | 1596 | goto fail; |
1597 | 1597 | ||
1598 | /* Get rid of the fake eth1394 header, but save a pointer */ | 1598 | /* Get rid of the fake eth1394 header, but first make a copy. |
1599 | eth = (struct eth1394hdr *)skb->data; | 1599 | * We might need to rebuild the header on tx failure. */ |
1600 | memcpy(&hdr_buf, skb->data, sizeof(hdr_buf)); | ||
1600 | skb_pull(skb, ETH1394_HLEN); | 1601 | skb_pull(skb, ETH1394_HLEN); |
1601 | 1602 | ||
1602 | proto = eth->h_proto; | 1603 | proto = hdr_buf.h_proto; |
1603 | dg_size = skb->len; | 1604 | dg_size = skb->len; |
1604 | 1605 | ||
1605 | /* Set the transmission type for the packet. ARP packets and IP | 1606 | /* Set the transmission type for the packet. ARP packets and IP |
1606 | * broadcast packets are sent via GASP. */ | 1607 | * broadcast packets are sent via GASP. */ |
1607 | if (memcmp(eth->h_dest, dev->broadcast, ETH1394_ALEN) == 0 || | 1608 | if (memcmp(hdr_buf.h_dest, dev->broadcast, ETH1394_ALEN) == 0 || |
1608 | proto == htons(ETH_P_ARP) || | 1609 | proto == htons(ETH_P_ARP) || |
1609 | (proto == htons(ETH_P_IP) && | 1610 | (proto == htons(ETH_P_IP) && |
1610 | IN_MULTICAST(ntohl(ip_hdr(skb)->daddr)))) { | 1611 | IN_MULTICAST(ntohl(ip_hdr(skb)->daddr)))) { |
@@ -1616,7 +1617,7 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev) | |||
1616 | if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF]) | 1617 | if (max_payload < dg_size + hdr_type_len[ETH1394_HDR_LF_UF]) |
1617 | priv->bc_dgl++; | 1618 | priv->bc_dgl++; |
1618 | } else { | 1619 | } else { |
1619 | __be64 guid = get_unaligned((u64 *)eth->h_dest); | 1620 | __be64 guid = get_unaligned((u64 *)hdr_buf.h_dest); |
1620 | 1621 | ||
1621 | node = eth1394_find_node_guid(&priv->ip_node_list, | 1622 | node = eth1394_find_node_guid(&priv->ip_node_list, |
1622 | be64_to_cpu(guid)); | 1623 | be64_to_cpu(guid)); |
@@ -1673,6 +1674,14 @@ static int ether1394_tx(struct sk_buff *skb, struct net_device *dev) | |||
1673 | if (dest_node == (LOCAL_BUS | ALL_NODES)) | 1674 | if (dest_node == (LOCAL_BUS | ALL_NODES)) |
1674 | goto fail; | 1675 | goto fail; |
1675 | 1676 | ||
1677 | /* At this point we want to restore the packet. When we return | ||
1678 | * here with NETDEV_TX_BUSY we will get another entrance in this | ||
1679 | * routine with the same skb and we need it to look the same. | ||
1680 | * So we pull 4 more bytes, then build the header again. */ | ||
1681 | skb_pull(skb, 4); | ||
1682 | ether1394_header(skb, dev, ntohs(hdr_buf.h_proto), | ||
1683 | hdr_buf.h_dest, NULL, 0); | ||
1684 | |||
1676 | /* Most failures of ether1394_send_packet are recoverable. */ | 1685 | /* Most failures of ether1394_send_packet are recoverable. */ |
1677 | netif_stop_queue(dev); | 1686 | netif_stop_queue(dev); |
1678 | priv->wake_node = dest_node; | 1687 | priv->wake_node = dest_node; |