diff options
Diffstat (limited to 'drivers/atm/solos-pci.c')
-rw-r--r-- | drivers/atm/solos-pci.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index ded76c4c9f4f..f46138ab38b6 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -383,7 +383,7 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb /* Anything but 'Showtime' is down */ if (strcmp(state_str, "Showtime")) { - card->atmdev[port]->signal = ATM_PHY_SIG_LOST; + atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_LOST); release_vccs(card->atmdev[port]); dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str); return 0; @@ -401,7 +401,7 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb snr[0]?", SNR ":"", snr, attn[0]?", Attn ":"", attn); card->atmdev[port]->link_rate = rate_down / 424; - card->atmdev[port]->signal = ATM_PHY_SIG_FOUND; + atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_FOUND); return 0; } @@ -444,6 +444,7 @@ static ssize_t console_show(struct device *dev, struct device_attribute *attr, struct atm_dev *atmdev = container_of(dev, struct atm_dev, class_dev); struct solos_card *card = atmdev->dev_data; struct sk_buff *skb; + unsigned int len; spin_lock(&card->cli_queue_lock); skb = skb_dequeue(&card->cli_queue[SOLOS_CHAN(atmdev)]); @@ -451,11 +452,12 @@ static ssize_t console_show(struct device *dev, struct device_attribute *attr, if(skb == NULL) return sprintf(buf, "No data.\n"); - memcpy(buf, skb->data, skb->len); - dev_dbg(&card->dev->dev, "len: %d\n", skb->len); + len = skb->len; + memcpy(buf, skb->data, len); + dev_dbg(&card->dev->dev, "len: %d\n", len); kfree_skb(skb); - return skb->len; + return len; } static int send_command(struct solos_card *card, int dev, const char *buf, size_t size) @@ -781,7 +783,8 @@ static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci) sk_for_each(s, node, head) { vcc = atm_sk(s); if (vcc->dev == dev && vcc->vci == vci && - vcc->vpi == vpi && vcc->qos.rxtp.traffic_class != ATM_NONE) + vcc->vpi == vpi && vcc->qos.rxtp.traffic_class != ATM_NONE && + test_bit(ATM_VF_READY, &vcc->flags)) goto out; } vcc = NULL; @@ -907,6 +910,10 @@ static void pclose(struct atm_vcc *vcc) clear_bit(ATM_VF_ADDR, &vcc->flags); clear_bit(ATM_VF_READY, &vcc->flags); + /* Hold up vcc_destroy_socket() (our caller) until solos_bh() in the + tasklet has finished processing any incoming packets (and, more to + the point, using the vcc pointer). */ + tasklet_unlock_wait(&card->tlet); return; } @@ -1246,7 +1253,7 @@ static int atm_init(struct solos_card *card) card->atmdev[i]->ci_range.vci_bits = 16; card->atmdev[i]->dev_data = card; card->atmdev[i]->phy_data = (void *)(unsigned long)i; - card->atmdev[i]->signal = ATM_PHY_SIG_UNKNOWN; + atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_UNKNOWN); skb = alloc_skb(sizeof(*header), GFP_ATOMIC); if (!skb) { |