summaryrefslogtreecommitdiffstats
path: root/drivers/isdn/gigaset/isocdata.c
diff options
context:
space:
mode:
authorTilman Schmidt <tilman@imap.cc>2006-04-22 02:35:30 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2006-04-22 09:19:52 -0700
commit73a88814542d3f5b8973f3db9d7f380bd29957c4 (patch)
tree92bf889724f3fbadbe2a2a4ce5ac1f92bf3a8e30 /drivers/isdn/gigaset/isocdata.c
parentf4ffaa452e71495a06376f12f772342bc57051fc (diff)
[PATCH] isdn4linux: Siemens Gigaset base driver: fix disconnect handling
Fix a possible Oops in the Siemens Gigaset base driver when the device is unplugged while an ISDN connection is still active, and makes sure that the isdn4linux link level (LL) is properly informed if a connection is broken by the USB cable being unplugged. - Avoid unsafe checks of URB status fields outside the URB completion handlers, keep track of in-use URBs myself instead. - If an isochronous transfer URB completes with status==0, also check the status of the frame descriptors. - Verify length of interrupt messages received from the device. - Align the length limit on transmitted AT commands with the device documentation. - In case of AT response receive overrun, keep newly arrived instead of old unread data. - Remove redundant check of device ID in the USB probe function. - Correct and improve some comments and formatting. Signed-off-by: Tilman Schmidt <tilman@imap.cc> Acked-by: Hansjoerg Lipp <hjlipp@web.de> Cc: Karsten Keil <kkeil@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/isdn/gigaset/isocdata.c')
-rw-r--r--drivers/isdn/gigaset/isocdata.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index 45f017ed6e8..8667daaa1a8 100644
--- a/drivers/isdn/gigaset/isocdata.c
+++ b/drivers/isdn/gigaset/isocdata.c
@@ -992,14 +992,18 @@ int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb)
int len = skb->len;
unsigned long flags;
+ spin_lock_irqsave(&bcs->cs->lock, flags);
+ if (!bcs->cs->connected) {
+ spin_unlock_irqrestore(&bcs->cs->lock, flags);
+ return -ENODEV;
+ }
+
skb_queue_tail(&bcs->squeue, skb);
gig_dbg(DEBUG_ISO, "%s: skb queued, qlen=%d",
__func__, skb_queue_len(&bcs->squeue));
/* tasklet submits URB if necessary */
- spin_lock_irqsave(&bcs->cs->lock, flags);
- if (bcs->cs->connected)
- tasklet_schedule(&bcs->hw.bas->sent_tasklet);
+ tasklet_schedule(&bcs->hw.bas->sent_tasklet);
spin_unlock_irqrestore(&bcs->cs->lock, flags);
return len; /* ok so far */