diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2012-11-29 18:15:30 -0500 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-12-01 19:06:03 -0500 |
commit | 213e85d389124f49c82d52cfb4473b8bb672f7c1 (patch) | |
tree | 3e433e2a17951b0ffc57a4a638ff0366ee437c07 /drivers/atm/solos-pci.c | |
parent | 5b4d72080f49498d2390563aa90f5bc31785406c (diff) |
solos-pci: clean up pclose() function
- Flush pending TX skbs from the queue rather than waiting for them all to
complete (suggested by Krzysztof Mazur <krzysiek@podlesie.net>).
- Clear ATM_VF_ADDR only when the PKT_PCLOSE packet has been submitted.
- Don't clear ATM_VF_READY at all — vcc_destroy_socket() does that for us.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/atm/solos-pci.c')
-rw-r--r-- | drivers/atm/solos-pci.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index f0863b443762..3f7c4ef1e111 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c | |||
@@ -868,9 +868,19 @@ static void pclose(struct atm_vcc *vcc) | |||
868 | { | 868 | { |
869 | struct solos_card *card = vcc->dev->dev_data; | 869 | struct solos_card *card = vcc->dev->dev_data; |
870 | unsigned char port = SOLOS_CHAN(vcc->dev); | 870 | unsigned char port = SOLOS_CHAN(vcc->dev); |
871 | struct sk_buff *skb; | 871 | struct sk_buff *skb, *tmpskb; |
872 | struct pkt_hdr *header; | 872 | struct pkt_hdr *header; |
873 | 873 | ||
874 | /* Remove any yet-to-be-transmitted packets from the pending queue */ | ||
875 | spin_lock(&card->tx_queue_lock); | ||
876 | skb_queue_walk_safe(&card->tx_queue[port], skb, tmpskb) { | ||
877 | if (SKB_CB(skb)->vcc == vcc) { | ||
878 | skb_unlink(skb, &card->tx_queue[port]); | ||
879 | solos_pop(vcc, skb); | ||
880 | } | ||
881 | } | ||
882 | spin_unlock(&card->tx_queue_lock); | ||
883 | |||
874 | skb = alloc_skb(sizeof(*header), GFP_ATOMIC); | 884 | skb = alloc_skb(sizeof(*header), GFP_ATOMIC); |
875 | if (!skb) { | 885 | if (!skb) { |
876 | dev_warn(&card->dev->dev, "Failed to allocate sk_buff in pclose()\n"); | 886 | dev_warn(&card->dev->dev, "Failed to allocate sk_buff in pclose()\n"); |
@@ -886,9 +896,6 @@ static void pclose(struct atm_vcc *vcc) | |||
886 | skb_get(skb); | 896 | skb_get(skb); |
887 | fpga_queue(card, port, skb, NULL); | 897 | fpga_queue(card, port, skb, NULL); |
888 | 898 | ||
889 | clear_bit(ATM_VF_ADDR, &vcc->flags); | ||
890 | clear_bit(ATM_VF_READY, &vcc->flags); | ||
891 | |||
892 | if (!wait_event_timeout(card->param_wq, !skb_shared(skb), 5 * HZ)) | 899 | if (!wait_event_timeout(card->param_wq, !skb_shared(skb), 5 * HZ)) |
893 | dev_warn(&card->dev->dev, | 900 | dev_warn(&card->dev->dev, |
894 | "Timeout waiting for VCC close on port %d\n", port); | 901 | "Timeout waiting for VCC close on port %d\n", port); |
@@ -899,6 +906,9 @@ static void pclose(struct atm_vcc *vcc) | |||
899 | tasklet has finished processing any incoming packets (and, more to | 906 | tasklet has finished processing any incoming packets (and, more to |
900 | the point, using the vcc pointer). */ | 907 | the point, using the vcc pointer). */ |
901 | tasklet_unlock_wait(&card->tlet); | 908 | tasklet_unlock_wait(&card->tlet); |
909 | |||
910 | clear_bit(ATM_VF_ADDR, &vcc->flags); | ||
911 | |||
902 | return; | 912 | return; |
903 | } | 913 | } |
904 | 914 | ||