diff options
| author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-02-24 14:31:04 -0500 |
|---|---|---|
| committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2010-02-24 14:33:45 -0500 |
| commit | 109d28152b6e9d5de64cd23e3bc08885ccb3d1ef (patch) | |
| tree | b7b8863faa05254781acfb85cc41da3eef467c6b /drivers/firewire/net.c | |
| parent | 168cf9af699e87d5a6f44b684583714ecabb8e71 (diff) | |
| parent | 60b341b778cc2929df16c0a504c91621b3c6a4ad (diff) | |
Merge tag 'v2.6.33' for its firewire changes since last branch point
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/net.c')
| -rw-r--r-- | drivers/firewire/net.c | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index cbaf420c36c5..2d3dc7ded0a9 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c | |||
| @@ -893,20 +893,31 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context, | |||
| 893 | 893 | ||
| 894 | static struct kmem_cache *fwnet_packet_task_cache; | 894 | static struct kmem_cache *fwnet_packet_task_cache; |
| 895 | 895 | ||
| 896 | static void fwnet_free_ptask(struct fwnet_packet_task *ptask) | ||
| 897 | { | ||
| 898 | dev_kfree_skb_any(ptask->skb); | ||
| 899 | kmem_cache_free(fwnet_packet_task_cache, ptask); | ||
| 900 | } | ||
| 901 | |||
| 896 | static int fwnet_send_packet(struct fwnet_packet_task *ptask); | 902 | static int fwnet_send_packet(struct fwnet_packet_task *ptask); |
| 897 | 903 | ||
| 898 | static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | 904 | static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) |
| 899 | { | 905 | { |
| 900 | struct fwnet_device *dev; | 906 | struct fwnet_device *dev = ptask->dev; |
| 901 | unsigned long flags; | 907 | unsigned long flags; |
| 902 | 908 | bool free; | |
| 903 | dev = ptask->dev; | ||
| 904 | 909 | ||
| 905 | spin_lock_irqsave(&dev->lock, flags); | 910 | spin_lock_irqsave(&dev->lock, flags); |
| 906 | list_del(&ptask->pt_link); | ||
| 907 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 908 | 911 | ||
| 909 | ptask->outstanding_pkts--; /* FIXME access inside lock */ | 912 | ptask->outstanding_pkts--; |
| 913 | |||
| 914 | /* Check whether we or the networking TX soft-IRQ is last user. */ | ||
| 915 | free = (ptask->outstanding_pkts == 0 && !list_empty(&ptask->pt_link)); | ||
| 916 | |||
| 917 | if (ptask->outstanding_pkts == 0) | ||
| 918 | list_del(&ptask->pt_link); | ||
| 919 | |||
| 920 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 910 | 921 | ||
| 911 | if (ptask->outstanding_pkts > 0) { | 922 | if (ptask->outstanding_pkts > 0) { |
| 912 | u16 dg_size; | 923 | u16 dg_size; |
| @@ -951,10 +962,10 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | |||
| 951 | ptask->max_payload = skb->len + RFC2374_FRAG_HDR_SIZE; | 962 | ptask->max_payload = skb->len + RFC2374_FRAG_HDR_SIZE; |
| 952 | } | 963 | } |
| 953 | fwnet_send_packet(ptask); | 964 | fwnet_send_packet(ptask); |
| 954 | } else { | ||
| 955 | dev_kfree_skb_any(ptask->skb); | ||
| 956 | kmem_cache_free(fwnet_packet_task_cache, ptask); | ||
| 957 | } | 965 | } |
| 966 | |||
| 967 | if (free) | ||
| 968 | fwnet_free_ptask(ptask); | ||
| 958 | } | 969 | } |
| 959 | 970 | ||
| 960 | static void fwnet_write_complete(struct fw_card *card, int rcode, | 971 | static void fwnet_write_complete(struct fw_card *card, int rcode, |
| @@ -977,6 +988,7 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) | |||
| 977 | unsigned tx_len; | 988 | unsigned tx_len; |
| 978 | struct rfc2734_header *bufhdr; | 989 | struct rfc2734_header *bufhdr; |
| 979 | unsigned long flags; | 990 | unsigned long flags; |
| 991 | bool free; | ||
| 980 | 992 | ||
| 981 | dev = ptask->dev; | 993 | dev = ptask->dev; |
| 982 | tx_len = ptask->max_payload; | 994 | tx_len = ptask->max_payload; |
| @@ -1022,12 +1034,16 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) | |||
| 1022 | generation, SCODE_100, 0ULL, ptask->skb->data, | 1034 | generation, SCODE_100, 0ULL, ptask->skb->data, |
| 1023 | tx_len + 8, fwnet_write_complete, ptask); | 1035 | tx_len + 8, fwnet_write_complete, ptask); |
| 1024 | 1036 | ||
| 1025 | /* FIXME race? */ | ||
| 1026 | spin_lock_irqsave(&dev->lock, flags); | 1037 | spin_lock_irqsave(&dev->lock, flags); |
| 1027 | list_add_tail(&ptask->pt_link, &dev->broadcasted_list); | 1038 | |
| 1039 | /* If the AT tasklet already ran, we may be last user. */ | ||
| 1040 | free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link)); | ||
| 1041 | if (!free) | ||
| 1042 | list_add_tail(&ptask->pt_link, &dev->broadcasted_list); | ||
| 1043 | |||
| 1028 | spin_unlock_irqrestore(&dev->lock, flags); | 1044 | spin_unlock_irqrestore(&dev->lock, flags); |
| 1029 | 1045 | ||
| 1030 | return 0; | 1046 | goto out; |
| 1031 | } | 1047 | } |
| 1032 | 1048 | ||
| 1033 | fw_send_request(dev->card, &ptask->transaction, | 1049 | fw_send_request(dev->card, &ptask->transaction, |
| @@ -1035,12 +1051,19 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) | |||
| 1035 | ptask->generation, ptask->speed, ptask->fifo_addr, | 1051 | ptask->generation, ptask->speed, ptask->fifo_addr, |
| 1036 | ptask->skb->data, tx_len, fwnet_write_complete, ptask); | 1052 | ptask->skb->data, tx_len, fwnet_write_complete, ptask); |
| 1037 | 1053 | ||
| 1038 | /* FIXME race? */ | ||
| 1039 | spin_lock_irqsave(&dev->lock, flags); | 1054 | spin_lock_irqsave(&dev->lock, flags); |
| 1040 | list_add_tail(&ptask->pt_link, &dev->sent_list); | 1055 | |
| 1056 | /* If the AT tasklet already ran, we may be last user. */ | ||
| 1057 | free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link)); | ||
| 1058 | if (!free) | ||
| 1059 | list_add_tail(&ptask->pt_link, &dev->sent_list); | ||
| 1060 | |||
| 1041 | spin_unlock_irqrestore(&dev->lock, flags); | 1061 | spin_unlock_irqrestore(&dev->lock, flags); |
| 1042 | 1062 | ||
| 1043 | dev->netdev->trans_start = jiffies; | 1063 | dev->netdev->trans_start = jiffies; |
| 1064 | out: | ||
| 1065 | if (free) | ||
| 1066 | fwnet_free_ptask(ptask); | ||
| 1044 | 1067 | ||
| 1045 | return 0; | 1068 | return 0; |
| 1046 | } | 1069 | } |
| @@ -1298,6 +1321,8 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) | |||
| 1298 | spin_unlock_irqrestore(&dev->lock, flags); | 1321 | spin_unlock_irqrestore(&dev->lock, flags); |
| 1299 | 1322 | ||
| 1300 | ptask->max_payload = max_payload; | 1323 | ptask->max_payload = max_payload; |
| 1324 | INIT_LIST_HEAD(&ptask->pt_link); | ||
| 1325 | |||
| 1301 | fwnet_send_packet(ptask); | 1326 | fwnet_send_packet(ptask); |
| 1302 | 1327 | ||
| 1303 | return NETDEV_TX_OK; | 1328 | return NETDEV_TX_OK; |
