Skip to content

Commit

Permalink
i4l: fix random freezes with AVM B1 drivers
Browse files Browse the repository at this point in the history
This fix the same issue which was debbuged for the C4 controller for the B1
versions.

The capilib_ function modify or traverse a linked list without locking.

This patch extends the existing locking to the calls of these function to
prevent access to a list which is in the middle of a modification.

Signed-off-by: Karsten Keil <kkeil@suse.de>
C: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Karsten Keil authored and Linus Torvalds committed Oct 18, 2007
1 parent 0c42ea3 commit 9713d9e
Showing 1 changed file with 13 additions and 15 deletions.
28 changes: 13 additions & 15 deletions drivers/isdn/hardware/avm/b1.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,12 +321,15 @@ void b1_reset_ctr(struct capi_ctr *ctrl)
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
avmcard *card = cinfo->card;
unsigned int port = card->port;
unsigned long flags;

b1_reset(port);
b1_reset(port);

memset(cinfo->version, 0, sizeof(cinfo->version));
spin_lock_irqsave(&card->lock, flags);
capilib_release(&cinfo->ncci_head);
spin_unlock_irqrestore(&card->lock, flags);
capi_ctr_reseted(ctrl);
}

Expand Down Expand Up @@ -361,9 +364,8 @@ void b1_release_appl(struct capi_ctr *ctrl, u16 appl)
unsigned int port = card->port;
unsigned long flags;

capilib_release_appl(&cinfo->ncci_head, appl);

spin_lock_irqsave(&card->lock, flags);
capilib_release_appl(&cinfo->ncci_head, appl);
b1_put_byte(port, SEND_RELEASE);
b1_put_word(port, appl);
spin_unlock_irqrestore(&card->lock, flags);
Expand All @@ -380,27 +382,27 @@ u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
u16 dlen, retval;

spin_lock_irqsave(&card->lock, flags);
if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
retval = capilib_data_b3_req(&cinfo->ncci_head,
CAPIMSG_APPID(skb->data),
CAPIMSG_NCCI(skb->data),
CAPIMSG_MSGID(skb->data));
if (retval != CAPI_NOERROR)
if (retval != CAPI_NOERROR) {
spin_unlock_irqrestore(&card->lock, flags);
return retval;
}

dlen = CAPIMSG_DATALEN(skb->data);

spin_lock_irqsave(&card->lock, flags);
b1_put_byte(port, SEND_DATA_B3_REQ);
b1_put_slice(port, skb->data, len);
b1_put_slice(port, skb->data + len, dlen);
spin_unlock_irqrestore(&card->lock, flags);
} else {
spin_lock_irqsave(&card->lock, flags);
b1_put_byte(port, SEND_MESSAGE);
b1_put_slice(port, skb->data, len);
spin_unlock_irqrestore(&card->lock, flags);
}
spin_unlock_irqrestore(&card->lock, flags);

dev_kfree_skb_any(skb);
return CAPI_NOERROR;
Expand Down Expand Up @@ -534,17 +536,17 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)

ApplId = (unsigned) b1_get_word(card->port);
MsgLen = b1_get_slice(card->port, card->msgbuf);
spin_unlock_irqrestore(&card->lock, flags);
if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
printk(KERN_ERR "%s: incoming packet dropped\n",
card->name);
spin_unlock_irqrestore(&card->lock, flags);
} else {
memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
CAPIMSG_NCCI(skb->data),
CAPIMSG_MSGID(skb->data));

spin_unlock_irqrestore(&card->lock, flags);
capi_ctr_handle_message(ctrl, ApplId, skb);
}
break;
Expand All @@ -554,21 +556,17 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr)
ApplId = b1_get_word(card->port);
NCCI = b1_get_word(card->port);
WindowSize = b1_get_word(card->port);
spin_unlock_irqrestore(&card->lock, flags);

capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);

spin_unlock_irqrestore(&card->lock, flags);
break;

case RECEIVE_FREE_NCCI:

ApplId = b1_get_word(card->port);
NCCI = b1_get_word(card->port);
spin_unlock_irqrestore(&card->lock, flags);

if (NCCI != 0xffffffff)
capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
spin_unlock_irqrestore(&card->lock, flags);
break;

case RECEIVE_START:
Expand Down

0 comments on commit 9713d9e

Please sign in to comment.