From 78ea2f7a4c26c07e1b12224d3a03b9970afed95e Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 27 Jan 2009 21:47:47 +1100 Subject: [PATCH] --- yaml --- r: 135321 b: refs/heads/master c: 1e615df654ef00a6354f32be08a8fb6a395b2ef1 h: refs/heads/master i: 135319: 2a9e802864a2a456e65cd45cab4ee6241b7522b8 v: v3 --- [refs] | 2 +- trunk/drivers/atm/solos-pci.c | 30 ++++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/[refs] b/[refs] index 1839a914551a..a1faf04d3598 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 87ebb18627930ce005beba227ca267b5b5372e06 +refs/heads/master: 1e615df654ef00a6354f32be08a8fb6a395b2ef1 diff --git a/trunk/drivers/atm/solos-pci.c b/trunk/drivers/atm/solos-pci.c index 4c87dfb01566..c289b6251c19 100644 --- a/trunk/drivers/atm/solos-pci.c +++ b/trunk/drivers/atm/solos-pci.c @@ -132,6 +132,7 @@ static int fpga_tx(struct solos_card *); static irqreturn_t solos_irq(int irq, void *dev_id); static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci); static int list_vccs(int vci); +static void release_vccs(struct atm_dev *dev); static int atm_init(struct solos_card *); static void atm_remove(struct solos_card *); static int send_command(struct solos_card *card, int dev, const char *buf, size_t size); @@ -332,7 +333,10 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb str = next_string(skb); if (!strcmp(str, "Showtime")) state = ATM_PHY_SIG_FOUND; - else state = ATM_PHY_SIG_LOST; + else { + state = ATM_PHY_SIG_LOST; + release_vccs(card->atmdev[port]); + } card->atmdev[port]->link_rate = rate_down; card->atmdev[port]->signal = state; @@ -683,7 +687,7 @@ static int list_vccs(int vci) vcc->vci); } } else { - for(i=0; i<32; i++){ + for(i = 0; i < VCC_HTABLE_SIZE; i++){ head = &vcc_hash[i]; sk_for_each(s, node, head) { num_found ++; @@ -699,6 +703,28 @@ static int list_vccs(int vci) return num_found; } +static void release_vccs(struct atm_dev *dev) +{ + int i; + + write_lock_irq(&vcc_sklist_lock); + for (i = 0; i < VCC_HTABLE_SIZE; i++) { + struct hlist_head *head = &vcc_hash[i]; + struct hlist_node *node, *tmp; + struct sock *s; + struct atm_vcc *vcc; + + sk_for_each_safe(s, node, tmp, head) { + vcc = atm_sk(s); + if (vcc->dev == dev) { + vcc_release_async(vcc, -EPIPE); + sk_del_node_init(s); + } + } + } + write_unlock_irq(&vcc_sklist_lock); +} + static int popen(struct atm_vcc *vcc) {