--- zzzz-none-000/linux-2.4.17/drivers/isdn/avmb1/capidrv.c 2001-12-21 17:41:54.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/drivers/isdn/avmb1/capidrv.c 2004-11-24 13:23:00.000000000 +0000 @@ -105,6 +105,7 @@ int oldstate; /* */ __u16 datahandle; + spinlock_t lock; struct ncci_datahandle_queue { struct ncci_datahandle_queue *next; __u16 datahandle; @@ -422,6 +423,7 @@ nccip->plcip = plcip; nccip->chan = plcip->chan; nccip->datahandle = 0; + nccip->lock = SPIN_LOCK_UNLOCKED; nccip->next = plcip->ncci_list; plcip->ncci_list = nccip; @@ -478,6 +480,7 @@ __u16 datahandle, int len) { struct ncci_datahandle_queue *n, **pp; + unsigned long flags; n = (struct ncci_datahandle_queue *) kmalloc(sizeof(struct ncci_datahandle_queue), GFP_ATOMIC); @@ -488,25 +491,31 @@ n->next = 0; n->datahandle = datahandle; n->len = len; + spin_lock_irqsave(&nccip->lock, flags); for (pp = &nccip->ackqueue; *pp; pp = &(*pp)->next) ; *pp = n; + spin_unlock_irqrestore(&nccip->lock, flags); return 0; } static int capidrv_del_ack(struct capidrv_ncci *nccip, __u16 datahandle) { struct ncci_datahandle_queue **pp, *p; + unsigned long flags; int len; + spin_lock_irqsave(&nccip->lock, flags); for (pp = &nccip->ackqueue; *pp; pp = &(*pp)->next) { if ((*pp)->datahandle == datahandle) { p = *pp; len = p->len; *pp = (*pp)->next; + spin_unlock_irqrestore(&nccip->lock, flags); kfree(p); return len; } } + spin_unlock_irqrestore(&nccip->lock, flags); return -1; } @@ -514,13 +523,25 @@ static void send_message(capidrv_contr * card, _cmsg * cmsg) { - struct sk_buff *skb; - size_t len; + struct sk_buff *skb; + size_t len; + u16 err; + capi_cmsg2message(cmsg, cmsg->buf); len = CAPIMSG_LEN(cmsg->buf); skb = alloc_skb(len, GFP_ATOMIC); + if(!skb) { + printk(KERN_ERR "no skb len(%d) memory\n", len); + return; + } memcpy(skb_put(skb, len), cmsg->buf, len); - (*capifuncs->capi_put_message) (global.appid, skb); + err = (*capifuncs->capi_put_message) (global.appid, skb); + if (err) { + printk(KERN_WARNING "%s: capi_put_message error: %04x\n", + __FUNCTION__, err); + kfree_skb(skb); + return; + } global.nsentctlpkt++; } @@ -2179,10 +2200,10 @@ free_ncci(card, card->bchans[card->nbchan-1].nccip); if (card->bchans[card->nbchan-1].plcip) free_plci(card, card->bchans[card->nbchan-1].plcip); - if (card->plci_list) - printk(KERN_ERR "capidrv: bug in free_plci()\n"); card->nbchan--; } + if (card->plci_list) + printk(KERN_ERR "capidrv: bug in free_plci()\n"); kfree(card->bchans); card->bchans = 0;