diff options
| -rw-r--r-- | drivers/firewire/net.c | 160 |
1 files changed, 90 insertions, 70 deletions
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 18fdd9703b4..1a467a91fb0 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/bug.h> | 9 | #include <linux/bug.h> |
| 10 | #include <linux/delay.h> | ||
| 10 | #include <linux/device.h> | 11 | #include <linux/device.h> |
| 11 | #include <linux/firewire.h> | 12 | #include <linux/firewire.h> |
| 12 | #include <linux/firewire-constants.h> | 13 | #include <linux/firewire-constants.h> |
| @@ -26,8 +27,14 @@ | |||
| 26 | #include <asm/unaligned.h> | 27 | #include <asm/unaligned.h> |
| 27 | #include <net/arp.h> | 28 | #include <net/arp.h> |
| 28 | 29 | ||
| 29 | #define FWNET_MAX_FRAGMENTS 25 /* arbitrary limit */ | 30 | /* rx limits */ |
| 30 | #define FWNET_ISO_PAGE_COUNT (PAGE_SIZE < 16 * 1024 ? 4 : 2) | 31 | #define FWNET_MAX_FRAGMENTS 30 /* arbitrary, > TX queue depth */ |
| 32 | #define FWNET_ISO_PAGE_COUNT (PAGE_SIZE < 16*1024 ? 4 : 2) | ||
| 33 | |||
| 34 | /* tx limits */ | ||
| 35 | #define FWNET_MAX_QUEUED_DATAGRAMS 20 /* < 64 = number of tlabels */ | ||
| 36 | #define FWNET_MIN_QUEUED_DATAGRAMS 10 /* should keep AT DMA busy enough */ | ||
| 37 | #define FWNET_TX_QUEUE_LEN FWNET_MAX_QUEUED_DATAGRAMS /* ? */ | ||
| 31 | 38 | ||
| 32 | #define IEEE1394_BROADCAST_CHANNEL 31 | 39 | #define IEEE1394_BROADCAST_CHANNEL 31 |
| 33 | #define IEEE1394_ALL_NODES (0xffc0 | 0x003f) | 40 | #define IEEE1394_ALL_NODES (0xffc0 | 0x003f) |
| @@ -169,15 +176,8 @@ struct fwnet_device { | |||
| 169 | struct fw_address_handler handler; | 176 | struct fw_address_handler handler; |
| 170 | u64 local_fifo; | 177 | u64 local_fifo; |
| 171 | 178 | ||
| 172 | /* List of packets to be sent */ | 179 | /* Number of tx datagrams that have been queued but not yet acked */ |
| 173 | struct list_head packet_list; | 180 | int queued_datagrams; |
| 174 | /* | ||
| 175 | * List of packets that were broadcasted. When we get an ISO interrupt | ||
| 176 | * one of them has been sent | ||
| 177 | */ | ||
| 178 | struct list_head broadcasted_list; | ||
| 179 | /* List of packets that have been sent but not yet acked */ | ||
| 180 | struct list_head sent_list; | ||
| 181 | 181 | ||
| 182 | struct list_head peer_list; | 182 | struct list_head peer_list; |
| 183 | struct fw_card *card; | 183 | struct fw_card *card; |
| @@ -195,7 +195,7 @@ struct fwnet_peer { | |||
| 195 | unsigned pdg_size; /* pd_list size */ | 195 | unsigned pdg_size; /* pd_list size */ |
| 196 | 196 | ||
| 197 | u16 datagram_label; /* outgoing datagram label */ | 197 | u16 datagram_label; /* outgoing datagram label */ |
| 198 | unsigned max_payload; /* includes RFC2374_FRAG_HDR_SIZE overhead */ | 198 | u16 max_payload; /* includes RFC2374_FRAG_HDR_SIZE overhead */ |
| 199 | int node_id; | 199 | int node_id; |
| 200 | int generation; | 200 | int generation; |
| 201 | unsigned speed; | 201 | unsigned speed; |
| @@ -203,22 +203,18 @@ struct fwnet_peer { | |||
| 203 | 203 | ||
| 204 | /* This is our task struct. It's used for the packet complete callback. */ | 204 | /* This is our task struct. It's used for the packet complete callback. */ |
| 205 | struct fwnet_packet_task { | 205 | struct fwnet_packet_task { |
| 206 | /* | ||
| 207 | * ptask can actually be on dev->packet_list, dev->broadcasted_list, | ||
| 208 | * or dev->sent_list depending on its current state. | ||
| 209 | */ | ||
| 210 | struct list_head pt_link; | ||
| 211 | struct fw_transaction transaction; | 206 | struct fw_transaction transaction; |
| 212 | struct rfc2734_header hdr; | 207 | struct rfc2734_header hdr; |
| 213 | struct sk_buff *skb; | 208 | struct sk_buff *skb; |
| 214 | struct fwnet_device *dev; | 209 | struct fwnet_device *dev; |
| 215 | 210 | ||
| 216 | int outstanding_pkts; | 211 | int outstanding_pkts; |
| 217 | unsigned max_payload; | ||
| 218 | u64 fifo_addr; | 212 | u64 fifo_addr; |
| 219 | u16 dest_node; | 213 | u16 dest_node; |
| 214 | u16 max_payload; | ||
| 220 | u8 generation; | 215 | u8 generation; |
| 221 | u8 speed; | 216 | u8 speed; |
| 217 | u8 enqueued; | ||
| 222 | }; | 218 | }; |
| 223 | 219 | ||
| 224 | /* | 220 | /* |
| @@ -650,8 +646,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
| 650 | net->stats.rx_packets++; | 646 | net->stats.rx_packets++; |
| 651 | net->stats.rx_bytes += skb->len; | 647 | net->stats.rx_bytes += skb->len; |
| 652 | } | 648 | } |
| 653 | if (netif_queue_stopped(net)) | ||
| 654 | netif_wake_queue(net); | ||
| 655 | 649 | ||
| 656 | return 0; | 650 | return 0; |
| 657 | 651 | ||
| @@ -660,8 +654,6 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
| 660 | net->stats.rx_dropped++; | 654 | net->stats.rx_dropped++; |
| 661 | 655 | ||
| 662 | dev_kfree_skb_any(skb); | 656 | dev_kfree_skb_any(skb); |
| 663 | if (netif_queue_stopped(net)) | ||
| 664 | netif_wake_queue(net); | ||
| 665 | 657 | ||
| 666 | return -ENOENT; | 658 | return -ENOENT; |
| 667 | } | 659 | } |
| @@ -793,15 +785,10 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
| 793 | * Datagram is not complete, we're done for the | 785 | * Datagram is not complete, we're done for the |
| 794 | * moment. | 786 | * moment. |
| 795 | */ | 787 | */ |
| 796 | spin_unlock_irqrestore(&dev->lock, flags); | 788 | retval = 0; |
| 797 | |||
| 798 | return 0; | ||
| 799 | fail: | 789 | fail: |
| 800 | spin_unlock_irqrestore(&dev->lock, flags); | 790 | spin_unlock_irqrestore(&dev->lock, flags); |
| 801 | 791 | ||
| 802 | if (netif_queue_stopped(net)) | ||
| 803 | netif_wake_queue(net); | ||
| 804 | |||
| 805 | return retval; | 792 | return retval; |
| 806 | } | 793 | } |
| 807 | 794 | ||
| @@ -901,11 +888,19 @@ static void fwnet_free_ptask(struct fwnet_packet_task *ptask) | |||
| 901 | kmem_cache_free(fwnet_packet_task_cache, ptask); | 888 | kmem_cache_free(fwnet_packet_task_cache, ptask); |
| 902 | } | 889 | } |
| 903 | 890 | ||
| 891 | /* Caller must hold dev->lock. */ | ||
| 892 | static void dec_queued_datagrams(struct fwnet_device *dev) | ||
| 893 | { | ||
| 894 | if (--dev->queued_datagrams == FWNET_MIN_QUEUED_DATAGRAMS) | ||
| 895 | netif_wake_queue(dev->netdev); | ||
| 896 | } | ||
| 897 | |||
| 904 | static int fwnet_send_packet(struct fwnet_packet_task *ptask); | 898 | static int fwnet_send_packet(struct fwnet_packet_task *ptask); |
| 905 | 899 | ||
| 906 | static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | 900 | static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) |
| 907 | { | 901 | { |
| 908 | struct fwnet_device *dev = ptask->dev; | 902 | struct fwnet_device *dev = ptask->dev; |
| 903 | struct sk_buff *skb = ptask->skb; | ||
| 909 | unsigned long flags; | 904 | unsigned long flags; |
| 910 | bool free; | 905 | bool free; |
| 911 | 906 | ||
| @@ -914,10 +909,14 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | |||
| 914 | ptask->outstanding_pkts--; | 909 | ptask->outstanding_pkts--; |
| 915 | 910 | ||
| 916 | /* Check whether we or the networking TX soft-IRQ is last user. */ | 911 | /* Check whether we or the networking TX soft-IRQ is last user. */ |
| 917 | free = (ptask->outstanding_pkts == 0 && !list_empty(&ptask->pt_link)); | 912 | free = (ptask->outstanding_pkts == 0 && ptask->enqueued); |
| 913 | if (free) | ||
| 914 | dec_queued_datagrams(dev); | ||
| 918 | 915 | ||
| 919 | if (ptask->outstanding_pkts == 0) | 916 | if (ptask->outstanding_pkts == 0) { |
| 920 | list_del(&ptask->pt_link); | 917 | dev->netdev->stats.tx_packets++; |
| 918 | dev->netdev->stats.tx_bytes += skb->len; | ||
| 919 | } | ||
| 921 | 920 | ||
| 922 | spin_unlock_irqrestore(&dev->lock, flags); | 921 | spin_unlock_irqrestore(&dev->lock, flags); |
| 923 | 922 | ||
| @@ -926,7 +925,6 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | |||
| 926 | u16 fg_off; | 925 | u16 fg_off; |
| 927 | u16 datagram_label; | 926 | u16 datagram_label; |
| 928 | u16 lf; | 927 | u16 lf; |
| 929 | struct sk_buff *skb; | ||
| 930 | 928 | ||
| 931 | /* Update the ptask to point to the next fragment and send it */ | 929 | /* Update the ptask to point to the next fragment and send it */ |
| 932 | lf = fwnet_get_hdr_lf(&ptask->hdr); | 930 | lf = fwnet_get_hdr_lf(&ptask->hdr); |
| @@ -953,7 +951,7 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | |||
| 953 | datagram_label = fwnet_get_hdr_dgl(&ptask->hdr); | 951 | datagram_label = fwnet_get_hdr_dgl(&ptask->hdr); |
| 954 | break; | 952 | break; |
| 955 | } | 953 | } |
| 956 | skb = ptask->skb; | 954 | |
| 957 | skb_pull(skb, ptask->max_payload); | 955 | skb_pull(skb, ptask->max_payload); |
| 958 | if (ptask->outstanding_pkts > 1) { | 956 | if (ptask->outstanding_pkts > 1) { |
| 959 | fwnet_make_sf_hdr(&ptask->hdr, RFC2374_HDR_INTFRAG, | 957 | fwnet_make_sf_hdr(&ptask->hdr, RFC2374_HDR_INTFRAG, |
| @@ -970,6 +968,31 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) | |||
| 970 | fwnet_free_ptask(ptask); | 968 | fwnet_free_ptask(ptask); |
| 971 | } | 969 | } |
| 972 | 970 | ||
| 971 | static void fwnet_transmit_packet_failed(struct fwnet_packet_task *ptask) | ||
| 972 | { | ||
| 973 | struct fwnet_device *dev = ptask->dev; | ||
| 974 | unsigned long flags; | ||
| 975 | bool free; | ||
| 976 | |||
| 977 | spin_lock_irqsave(&dev->lock, flags); | ||
| 978 | |||
| 979 | /* One fragment failed; don't try to send remaining fragments. */ | ||
| 980 | ptask->outstanding_pkts = 0; | ||
| 981 | |||
| 982 | /* Check whether we or the networking TX soft-IRQ is last user. */ | ||
| 983 | free = ptask->enqueued; | ||
| 984 | if (free) | ||
| 985 | dec_queued_datagrams(dev); | ||
| 986 | |||
| 987 | dev->netdev->stats.tx_dropped++; | ||
| 988 | dev->netdev->stats.tx_errors++; | ||
| 989 | |||
| 990 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 991 | |||
| 992 | if (free) | ||
| 993 | fwnet_free_ptask(ptask); | ||
| 994 | } | ||
| 995 | |||
| 973 | static void fwnet_write_complete(struct fw_card *card, int rcode, | 996 | static void fwnet_write_complete(struct fw_card *card, int rcode, |
| 974 | void *payload, size_t length, void *data) | 997 | void *payload, size_t length, void *data) |
| 975 | { | 998 | { |
| @@ -977,11 +1000,12 @@ static void fwnet_write_complete(struct fw_card *card, int rcode, | |||
| 977 | 1000 | ||
| 978 | ptask = data; | 1001 | ptask = data; |
| 979 | 1002 | ||
| 980 | if (rcode == RCODE_COMPLETE) | 1003 | if (rcode == RCODE_COMPLETE) { |
| 981 | fwnet_transmit_packet_done(ptask); | 1004 | fwnet_transmit_packet_done(ptask); |
| 982 | else | 1005 | } else { |
| 983 | fw_error("fwnet_write_complete: failed: %x\n", rcode); | 1006 | fw_error("fwnet_write_complete: failed: %x\n", rcode); |
| 984 | /* ??? error recovery */ | 1007 | fwnet_transmit_packet_failed(ptask); |
| 1008 | } | ||
| 985 | } | 1009 | } |
| 986 | 1010 | ||
| 987 | static int fwnet_send_packet(struct fwnet_packet_task *ptask) | 1011 | static int fwnet_send_packet(struct fwnet_packet_task *ptask) |
| @@ -1039,9 +1063,11 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) | |||
| 1039 | spin_lock_irqsave(&dev->lock, flags); | 1063 | spin_lock_irqsave(&dev->lock, flags); |
| 1040 | 1064 | ||
| 1041 | /* If the AT tasklet already ran, we may be last user. */ | 1065 | /* If the AT tasklet already ran, we may be last user. */ |
| 1042 | free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link)); | 1066 | free = (ptask->outstanding_pkts == 0 && !ptask->enqueued); |
| 1043 | if (!free) | 1067 | if (!free) |
| 1044 | list_add_tail(&ptask->pt_link, &dev->broadcasted_list); | 1068 | ptask->enqueued = true; |
| 1069 | else | ||
| 1070 | dec_queued_datagrams(dev); | ||
| 1045 | 1071 | ||
| 1046 | spin_unlock_irqrestore(&dev->lock, flags); | 1072 | spin_unlock_irqrestore(&dev->lock, flags); |
| 1047 | 1073 | ||
| @@ -1056,9 +1082,11 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) | |||
| 1056 | spin_lock_irqsave(&dev->lock, flags); | 1082 | spin_lock_irqsave(&dev->lock, flags); |
| 1057 | 1083 | ||
| 1058 | /* If the AT tasklet already ran, we may be last user. */ | 1084 | /* If the AT tasklet already ran, we may be last user. */ |
| 1059 | free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link)); | 1085 | free = (ptask->outstanding_pkts == 0 && !ptask->enqueued); |
| 1060 | if (!free) | 1086 | if (!free) |
| 1061 | list_add_tail(&ptask->pt_link, &dev->sent_list); | 1087 | ptask->enqueued = true; |
| 1088 | else | ||
| 1089 | dec_queued_datagrams(dev); | ||
| 1062 | 1090 | ||
| 1063 | spin_unlock_irqrestore(&dev->lock, flags); | 1091 | spin_unlock_irqrestore(&dev->lock, flags); |
| 1064 | 1092 | ||
| @@ -1224,6 +1252,15 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) | |||
| 1224 | struct fwnet_peer *peer; | 1252 | struct fwnet_peer *peer; |
| 1225 | unsigned long flags; | 1253 | unsigned long flags; |
| 1226 | 1254 | ||
| 1255 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1256 | |||
| 1257 | /* Can this happen? */ | ||
| 1258 | if (netif_queue_stopped(dev->netdev)) { | ||
| 1259 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1260 | |||
| 1261 | return NETDEV_TX_BUSY; | ||
| 1262 | } | ||
| 1263 | |||
| 1227 | ptask = kmem_cache_alloc(fwnet_packet_task_cache, GFP_ATOMIC); | 1264 | ptask = kmem_cache_alloc(fwnet_packet_task_cache, GFP_ATOMIC); |
| 1228 | if (ptask == NULL) | 1265 | if (ptask == NULL) |
| 1229 | goto fail; | 1266 | goto fail; |
| @@ -1242,9 +1279,6 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) | |||
| 1242 | proto = hdr_buf.h_proto; | 1279 | proto = hdr_buf.h_proto; |
| 1243 | dg_size = skb->len; | 1280 | dg_size = skb->len; |
| 1244 | 1281 | ||
| 1245 | /* serialize access to peer, including peer->datagram_label */ | ||
| 1246 | spin_lock_irqsave(&dev->lock, flags); | ||
| 1247 | |||
| 1248 | /* | 1282 | /* |
| 1249 | * Set the transmission type for the packet. ARP packets and IP | 1283 | * Set the transmission type for the packet. ARP packets and IP |
| 1250 | * broadcast packets are sent via GASP. | 1284 | * broadcast packets are sent via GASP. |
| @@ -1266,7 +1300,7 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) | |||
| 1266 | 1300 | ||
| 1267 | peer = fwnet_peer_find_by_guid(dev, be64_to_cpu(guid)); | 1301 | peer = fwnet_peer_find_by_guid(dev, be64_to_cpu(guid)); |
| 1268 | if (!peer || peer->fifo == FWNET_NO_FIFO_ADDR) | 1302 | if (!peer || peer->fifo == FWNET_NO_FIFO_ADDR) |
| 1269 | goto fail_unlock; | 1303 | goto fail; |
| 1270 | 1304 | ||
| 1271 | generation = peer->generation; | 1305 | generation = peer->generation; |
| 1272 | dest_node = peer->node_id; | 1306 | dest_node = peer->node_id; |
| @@ -1320,18 +1354,21 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net) | |||
| 1320 | max_payload += RFC2374_FRAG_HDR_SIZE; | 1354 | max_payload += RFC2374_FRAG_HDR_SIZE; |
| 1321 | } | 1355 | } |
| 1322 | 1356 | ||
| 1357 | if (++dev->queued_datagrams == FWNET_MAX_QUEUED_DATAGRAMS) | ||
| 1358 | netif_stop_queue(dev->netdev); | ||
| 1359 | |||
| 1323 | spin_unlock_irqrestore(&dev->lock, flags); | 1360 | spin_unlock_irqrestore(&dev->lock, flags); |
| 1324 | 1361 | ||
| 1325 | ptask->max_payload = max_payload; | 1362 | ptask->max_payload = max_payload; |
| 1326 | INIT_LIST_HEAD(&ptask->pt_link); | 1363 | ptask->enqueued = 0; |
| 1327 | 1364 | ||
| 1328 | fwnet_send_packet(ptask); | 1365 | fwnet_send_packet(ptask); |
| 1329 | 1366 | ||
| 1330 | return NETDEV_TX_OK; | 1367 | return NETDEV_TX_OK; |
| 1331 | 1368 | ||
| 1332 | fail_unlock: | ||
| 1333 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1334 | fail: | 1369 | fail: |
| 1370 | spin_unlock_irqrestore(&dev->lock, flags); | ||
| 1371 | |||
| 1335 | if (ptask) | 1372 | if (ptask) |
| 1336 | kmem_cache_free(fwnet_packet_task_cache, ptask); | 1373 | kmem_cache_free(fwnet_packet_task_cache, ptask); |
| 1337 | 1374 | ||
| @@ -1377,7 +1414,7 @@ static void fwnet_init_dev(struct net_device *net) | |||
| 1377 | net->addr_len = FWNET_ALEN; | 1414 | net->addr_len = FWNET_ALEN; |
| 1378 | net->hard_header_len = FWNET_HLEN; | 1415 | net->hard_header_len = FWNET_HLEN; |
| 1379 | net->type = ARPHRD_IEEE1394; | 1416 | net->type = ARPHRD_IEEE1394; |
| 1380 | net->tx_queue_len = 10; | 1417 | net->tx_queue_len = FWNET_TX_QUEUE_LEN; |
| 1381 | } | 1418 | } |
| 1382 | 1419 | ||
| 1383 | /* caller must hold fwnet_device_mutex */ | 1420 | /* caller must hold fwnet_device_mutex */ |
| @@ -1457,14 +1494,9 @@ static int fwnet_probe(struct device *_dev) | |||
| 1457 | dev->broadcast_rcv_context = NULL; | 1494 | dev->broadcast_rcv_context = NULL; |
| 1458 | dev->broadcast_xmt_max_payload = 0; | 1495 | dev->broadcast_xmt_max_payload = 0; |
| 1459 | dev->broadcast_xmt_datagramlabel = 0; | 1496 | dev->broadcast_xmt_datagramlabel = 0; |
| 1460 | |||
| 1461 | dev->local_fifo = FWNET_NO_FIFO_ADDR; | 1497 | dev->local_fifo = FWNET_NO_FIFO_ADDR; |
| 1462 | 1498 | dev->queued_datagrams = 0; | |
| 1463 | INIT_LIST_HEAD(&dev->packet_list); | ||
| 1464 | INIT_LIST_HEAD(&dev->broadcasted_list); | ||
| 1465 | INIT_LIST_HEAD(&dev->sent_list); | ||
| 1466 | INIT_LIST_HEAD(&dev->peer_list); | 1499 | INIT_LIST_HEAD(&dev->peer_list); |
| 1467 | |||
| 1468 | dev->card = card; | 1500 | dev->card = card; |
| 1469 | dev->netdev = net; | 1501 | dev->netdev = net; |
| 1470 | 1502 | ||
| @@ -1522,7 +1554,7 @@ static int fwnet_remove(struct device *_dev) | |||
| 1522 | struct fwnet_peer *peer = dev_get_drvdata(_dev); | 1554 | struct fwnet_peer *peer = dev_get_drvdata(_dev); |
| 1523 | struct fwnet_device *dev = peer->dev; | 1555 | struct fwnet_device *dev = peer->dev; |
| 1524 | struct net_device *net; | 1556 | struct net_device *net; |
| 1525 | struct fwnet_packet_task *ptask, *pt_next; | 1557 | int i; |
| 1526 | 1558 | ||
| 1527 | mutex_lock(&fwnet_device_mutex); | 1559 | mutex_lock(&fwnet_device_mutex); |
| 1528 | 1560 | ||
| @@ -1540,21 +1572,9 @@ static int fwnet_remove(struct device *_dev) | |||
| 1540 | dev->card); | 1572 | dev->card); |
| 1541 | fw_iso_context_destroy(dev->broadcast_rcv_context); | 1573 | fw_iso_context_destroy(dev->broadcast_rcv_context); |
| 1542 | } | 1574 | } |
| 1543 | list_for_each_entry_safe(ptask, pt_next, | 1575 | for (i = 0; dev->queued_datagrams && i < 5; i++) |
| 1544 | &dev->packet_list, pt_link) { | 1576 | ssleep(1); |
| 1545 | dev_kfree_skb_any(ptask->skb); | 1577 | WARN_ON(dev->queued_datagrams); |
| 1546 | kmem_cache_free(fwnet_packet_task_cache, ptask); | ||
| 1547 | } | ||
| 1548 | list_for_each_entry_safe(ptask, pt_next, | ||
| 1549 | &dev->broadcasted_list, pt_link) { | ||
| 1550 | dev_kfree_skb_any(ptask->skb); | ||
| 1551 | kmem_cache_free(fwnet_packet_task_cache, ptask); | ||
| 1552 | } | ||
| 1553 | list_for_each_entry_safe(ptask, pt_next, | ||
| 1554 | &dev->sent_list, pt_link) { | ||
| 1555 | dev_kfree_skb_any(ptask->skb); | ||
| 1556 | kmem_cache_free(fwnet_packet_task_cache, ptask); | ||
| 1557 | } | ||
| 1558 | list_del(&dev->dev_link); | 1578 | list_del(&dev->dev_link); |
| 1559 | 1579 | ||
| 1560 | free_netdev(net); | 1580 | free_netdev(net); |
