aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/gigaset
diff options
context:
space:
mode:
authorTilman Schmidt <tilman@imap.cc>2006-04-22 05:35:30 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-04-22 12:19:52 -0400
commit73a88814542d3f5b8973f3db9d7f380bd29957c4 (patch)
tree92bf889724f3fbadbe2a2a4ce5ac1f92bf3a8e30 /drivers/isdn/gigaset
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')
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c597
-rw-r--r--drivers/isdn/gigaset/common.c3
-rw-r--r--drivers/isdn/gigaset/ev-layer.c3
-rw-r--r--drivers/isdn/gigaset/gigaset.h7
-rw-r--r--drivers/isdn/gigaset/i4l.c2
-rw-r--r--drivers/isdn/gigaset/isocdata.c10
6 files changed, 342 insertions, 280 deletions
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index f86ed6af3aa2..eb41aba3ddef 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -5,8 +5,6 @@
5 * Tilman Schmidt <tilman@imap.cc>, 5 * Tilman Schmidt <tilman@imap.cc>,
6 * Stefan Eilers. 6 * Stefan Eilers.
7 * 7 *
8 * Based on usb-gigaset.c.
9 *
10 * ===================================================================== 8 * =====================================================================
11 * This program is free software; you can redistribute it and/or 9 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as 10 * modify it under the terms of the GNU General Public License as
@@ -46,19 +44,20 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode");
46#define GIGASET_DEVFSNAME "gig/bas/" 44#define GIGASET_DEVFSNAME "gig/bas/"
47#define GIGASET_DEVNAME "ttyGB" 45#define GIGASET_DEVNAME "ttyGB"
48 46
49#define IF_WRITEBUF 256 //FIXME 47/* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */
48#define IF_WRITEBUF 264
50 49
51/* Values for the Gigaset 307x */ 50/* Values for the Gigaset 307x */
52#define USB_GIGA_VENDOR_ID 0x0681 51#define USB_GIGA_VENDOR_ID 0x0681
53#define USB_GIGA_PRODUCT_ID 0x0001 52#define USB_3070_PRODUCT_ID 0x0001
54#define USB_4175_PRODUCT_ID 0x0002 53#define USB_3075_PRODUCT_ID 0x0002
55#define USB_SX303_PRODUCT_ID 0x0021 54#define USB_SX303_PRODUCT_ID 0x0021
56#define USB_SX353_PRODUCT_ID 0x0022 55#define USB_SX353_PRODUCT_ID 0x0022
57 56
58/* table of devices that work with this driver */ 57/* table of devices that work with this driver */
59static struct usb_device_id gigaset_table [] = { 58static struct usb_device_id gigaset_table [] = {
60 { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_GIGA_PRODUCT_ID) }, 59 { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3070_PRODUCT_ID) },
61 { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_4175_PRODUCT_ID) }, 60 { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3075_PRODUCT_ID) },
62 { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX303_PRODUCT_ID) }, 61 { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX303_PRODUCT_ID) },
63 { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX353_PRODUCT_ID) }, 62 { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX353_PRODUCT_ID) },
64 { } /* Terminating entry */ 63 { } /* Terminating entry */
@@ -77,6 +76,10 @@ static int gigaset_probe(struct usb_interface *interface,
77/* Function will be called if the device is unplugged */ 76/* Function will be called if the device is unplugged */
78static void gigaset_disconnect(struct usb_interface *interface); 77static void gigaset_disconnect(struct usb_interface *interface);
79 78
79static void read_ctrl_callback(struct urb *, struct pt_regs *);
80static void stopurbs(struct bas_bc_state *);
81static int atwrite_submit(struct cardstate *, unsigned char *, int);
82static int start_cbsend(struct cardstate *);
80 83
81/*==============================================================================*/ 84/*==============================================================================*/
82 85
@@ -111,12 +114,14 @@ struct bas_cardstate {
111}; 114};
112 115
113/* status of direct USB connection to 307x base (bits in basstate) */ 116/* status of direct USB connection to 307x base (bits in basstate) */
114#define BS_ATOPEN 0x001 117#define BS_ATOPEN 0x001 /* AT channel open */
115#define BS_B1OPEN 0x002 118#define BS_B1OPEN 0x002 /* B channel 1 open */
116#define BS_B2OPEN 0x004 119#define BS_B2OPEN 0x004 /* B channel 2 open */
117#define BS_ATREADY 0x008 120#define BS_ATREADY 0x008 /* base ready for AT command */
118#define BS_INIT 0x010 121#define BS_INIT 0x010 /* base has signalled INIT_OK */
119#define BS_ATTIMER 0x020 122#define BS_ATTIMER 0x020 /* waiting for HD_READY_SEND_ATDATA */
123#define BS_ATRDPEND 0x040 /* urb_cmd_in in use */
124#define BS_ATWRPEND 0x080 /* urb_cmd_out in use */
120 125
121 126
122static struct gigaset_driver *driver = NULL; 127static struct gigaset_driver *driver = NULL;
@@ -130,6 +135,47 @@ static struct usb_driver gigaset_usb_driver = {
130 .id_table = gigaset_table, 135 .id_table = gigaset_table,
131}; 136};
132 137
138/* get message text for usb_submit_urb return code
139 */
140static char *get_usb_rcmsg(int rc)
141{
142 static char unkmsg[28];
143
144 switch (rc) {
145 case 0:
146 return "success";
147 case -ENOMEM:
148 return "out of memory";
149 case -ENODEV:
150 return "device not present";
151 case -ENOENT:
152 return "endpoint not present";
153 case -ENXIO:
154 return "URB type not supported";
155 case -EINVAL:
156 return "invalid argument";
157 case -EAGAIN:
158 return "start frame too early or too much scheduled";
159 case -EFBIG:
160 return "too many isochronous frames requested";
161 case -EPIPE:
162 return "endpoint stalled";
163 case -EMSGSIZE:
164 return "invalid packet size";
165 case -ENOSPC:
166 return "would overcommit USB bandwidth";
167 case -ESHUTDOWN:
168 return "device shut down";
169 case -EPERM:
170 return "reject flag set";
171 case -EHOSTUNREACH:
172 return "device suspended";
173 default:
174 snprintf(unkmsg, sizeof(unkmsg), "unknown error %d", rc);
175 return unkmsg;
176 }
177}
178
133/* get message text for USB status code 179/* get message text for USB status code
134 */ 180 */
135static char *get_usb_statmsg(int status) 181static char *get_usb_statmsg(int status)
@@ -140,43 +186,37 @@ static char *get_usb_statmsg(int status)
140 case 0: 186 case 0:
141 return "success"; 187 return "success";
142 case -ENOENT: 188 case -ENOENT:
143 return "canceled"; 189 return "unlinked (sync)";
144 case -ECONNRESET:
145 return "canceled (async)";
146 case -EINPROGRESS: 190 case -EINPROGRESS:
147 return "pending"; 191 return "pending";
148 case -EPROTO: 192 case -EPROTO:
149 return "bit stuffing or unknown USB error"; 193 return "bit stuffing error, timeout, or unknown USB error";
150 case -EILSEQ: 194 case -EILSEQ:
151 return "Illegal byte sequence (CRC mismatch)"; 195 return "CRC mismatch, timeout, or unknown USB error";
152 case -EPIPE:
153 return "babble detect or endpoint stalled";
154 case -ENOSR:
155 return "buffer error";
156 case -ETIMEDOUT: 196 case -ETIMEDOUT:
157 return "timed out"; 197 return "timed out";
158 case -ENODEV: 198 case -EPIPE:
159 return "device not present"; 199 return "endpoint stalled";
200 case -ECOMM:
201 return "IN buffer overrun";
202 case -ENOSR:
203 return "OUT buffer underrun";
204 case -EOVERFLOW:
205 return "too much data";
160 case -EREMOTEIO: 206 case -EREMOTEIO:
161 return "short packet detected"; 207 return "short packet detected";
208 case -ENODEV:
209 return "device removed";
162 case -EXDEV: 210 case -EXDEV:
163 return "partial isochronous transfer"; 211 return "partial isochronous transfer";
164 case -EINVAL: 212 case -EINVAL:
165 return "invalid argument"; 213 return "invalid argument";
166 case -ENXIO: 214 case -ECONNRESET:
167 return "URB already queued"; 215 return "unlinked (async)";
168 case -EAGAIN:
169 return "isochronous start frame too early or too much scheduled";
170 case -EFBIG:
171 return "too many isochronous frames requested";
172 case -EMSGSIZE:
173 return "endpoint message size zero";
174 case -ESHUTDOWN: 216 case -ESHUTDOWN:
175 return "endpoint shutdown"; 217 return "device shut down";
176 case -EBUSY:
177 return "another request pending";
178 default: 218 default:
179 snprintf(unkmsg, sizeof(unkmsg), "unknown error %d", status); 219 snprintf(unkmsg, sizeof(unkmsg), "unknown status %d", status);
180 return unkmsg; 220 return unkmsg;
181 } 221 }
182} 222}
@@ -277,18 +317,17 @@ static inline void error_hangup(struct bc_state *bcs)
277 gig_dbg(DEBUG_ANY, "%s: scheduling HUP for channel %d", 317 gig_dbg(DEBUG_ANY, "%s: scheduling HUP for channel %d",
278 __func__, bcs->channel); 318 __func__, bcs->channel);
279 319
280 if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) { 320 if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL))
281 //FIXME what should we do? 321 dev_err(cs->dev, "event queue full\n");
282 return;
283 }
284 322
285 gigaset_schedule_event(cs); 323 gigaset_schedule_event(cs);
286} 324}
287 325
288/* error_reset 326/* error_reset
289 * reset Gigaset device because of an unrecoverable error 327 * reset Gigaset device because of an unrecoverable error
290 * This function may be called from any context and takes care of scheduling 328 * This function may be called from any context, and should take care of
291 * the necessary actions for execution outside of interrupt context. 329 * scheduling the necessary actions for execution outside of interrupt context.
330 * Right now, it just generates a kernel message calling for help.
292 * argument: 331 * argument:
293 * controller state structure 332 * controller state structure
294 */ 333 */
@@ -364,36 +403,38 @@ static void cmd_in_timeout(unsigned long data)
364{ 403{
365 struct cardstate *cs = (struct cardstate *) data; 404 struct cardstate *cs = (struct cardstate *) data;
366 struct bas_cardstate *ucs = cs->hw.bas; 405 struct bas_cardstate *ucs = cs->hw.bas;
367 unsigned long flags;
368 406
369 spin_lock_irqsave(&cs->lock, flags);
370 if (unlikely(!cs->connected)) {
371 gig_dbg(DEBUG_USBREQ, "%s: disconnected", __func__);
372 spin_unlock_irqrestore(&cs->lock, flags);
373 return;
374 }
375 if (!ucs->rcvbuf_size) { 407 if (!ucs->rcvbuf_size) {
376 gig_dbg(DEBUG_USBREQ, "%s: no receive in progress", __func__); 408 gig_dbg(DEBUG_USBREQ, "%s: no receive in progress", __func__);
377 spin_unlock_irqrestore(&cs->lock, flags);
378 return; 409 return;
379 } 410 }
380 spin_unlock_irqrestore(&cs->lock, flags);
381 411
382 dev_err(cs->dev, "timeout reading AT response\n"); 412 dev_err(cs->dev, "timeout reading AT response\n");
383 error_reset(cs); //FIXME retry? 413 error_reset(cs); //FIXME retry?
384} 414}
385 415
416/* set/clear bits in base connection state, return previous state
417 */
418inline static int update_basstate(struct bas_cardstate *ucs,
419 int set, int clear)
420{
421 unsigned long flags;
422 int state;
386 423
387static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs); 424 spin_lock_irqsave(&ucs->lock, flags);
425 state = atomic_read(&ucs->basstate);
426 atomic_set(&ucs->basstate, (state & ~clear) | set);
427 spin_unlock_irqrestore(&ucs->lock, flags);
428 return state;
429}
388 430
389/* atread_submit 431/* atread_submit
390 * submit an HD_READ_ATMESSAGE command URB 432 * submit an HD_READ_ATMESSAGE command URB and optionally start a timeout
391 * parameters: 433 * parameters:
392 * cs controller state structure 434 * cs controller state structure
393 * timeout timeout in 1/10 sec., 0: none 435 * timeout timeout in 1/10 sec., 0: none
394 * return value: 436 * return value:
395 * 0 on success 437 * 0 on success
396 * -EINVAL if a NULL pointer is encountered somewhere
397 * -EBUSY if another request is pending 438 * -EBUSY if another request is pending
398 * any URB submission error code 439 * any URB submission error code
399 */ 440 */
@@ -405,7 +446,7 @@ static int atread_submit(struct cardstate *cs, int timeout)
405 gig_dbg(DEBUG_USBREQ, "-------> HD_READ_ATMESSAGE (%d)", 446 gig_dbg(DEBUG_USBREQ, "-------> HD_READ_ATMESSAGE (%d)",
406 ucs->rcvbuf_size); 447 ucs->rcvbuf_size);
407 448
408 if (ucs->urb_cmd_in->status == -EINPROGRESS) { 449 if (update_basstate(ucs, BS_ATRDPEND, 0) & BS_ATRDPEND) {
409 dev_err(cs->dev, 450 dev_err(cs->dev,
410 "could not submit HD_READ_ATMESSAGE: URB busy\n"); 451 "could not submit HD_READ_ATMESSAGE: URB busy\n");
411 return -EBUSY; 452 return -EBUSY;
@@ -423,6 +464,7 @@ static int atread_submit(struct cardstate *cs, int timeout)
423 read_ctrl_callback, cs->inbuf); 464 read_ctrl_callback, cs->inbuf);
424 465
425 if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) { 466 if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) {
467 update_basstate(ucs, 0, BS_ATRDPEND);
426 dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n", 468 dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n",
427 get_usb_statmsg(ret)); 469 get_usb_statmsg(ret));
428 return ret; 470 return ret;
@@ -438,26 +480,6 @@ static int atread_submit(struct cardstate *cs, int timeout)
438 return 0; 480 return 0;
439} 481}
440 482
441static void stopurbs(struct bas_bc_state *);
442static int start_cbsend(struct cardstate *);
443
444/* set/clear bits in base connection state
445 */
446inline static void update_basstate(struct bas_cardstate *ucs,
447 int set, int clear)
448{
449 unsigned long flags;
450 int state;
451
452 spin_lock_irqsave(&ucs->lock, flags);
453 state = atomic_read(&ucs->basstate);
454 state &= ~clear;
455 state |= set;
456 atomic_set(&ucs->basstate, state);
457 spin_unlock_irqrestore(&ucs->lock, flags);
458}
459
460
461/* read_int_callback 483/* read_int_callback
462 * USB completion handler for interrupt pipe input 484 * USB completion handler for interrupt pipe input
463 * called by the USB subsystem in interrupt context 485 * called by the USB subsystem in interrupt context
@@ -471,20 +493,25 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs)
471 struct bas_cardstate *ucs = cs->hw.bas; 493 struct bas_cardstate *ucs = cs->hw.bas;
472 struct bc_state *bcs; 494 struct bc_state *bcs;
473 unsigned long flags; 495 unsigned long flags;
474 int status; 496 int rc;
475 unsigned l; 497 unsigned l;
476 int channel; 498 int channel;
477 499
478 switch (urb->status) { 500 switch (urb->status) {
479 case 0: /* success */ 501 case 0: /* success */
480 break; 502 break;
481 case -ENOENT: /* canceled */ 503 case -ENOENT: /* cancelled */
482 case -ECONNRESET: /* canceled (async) */ 504 case -ECONNRESET: /* cancelled (async) */
483 case -EINPROGRESS: /* pending */ 505 case -EINPROGRESS: /* pending */
484 /* ignore silently */ 506 /* ignore silently */
485 gig_dbg(DEBUG_USBREQ, "%s: %s", 507 gig_dbg(DEBUG_USBREQ, "%s: %s",
486 __func__, get_usb_statmsg(urb->status)); 508 __func__, get_usb_statmsg(urb->status));
487 return; 509 return;
510 case -ENODEV: /* device removed */
511 case -ESHUTDOWN: /* device shut down */
512 //FIXME use this as disconnect indicator?
513 gig_dbg(DEBUG_USBREQ, "%s: device disconnected", __func__);
514 return;
488 default: /* severe trouble */ 515 default: /* severe trouble */
489 dev_warn(cs->dev, "interrupt read: %s\n", 516 dev_warn(cs->dev, "interrupt read: %s\n",
490 get_usb_statmsg(urb->status)); 517 get_usb_statmsg(urb->status));
@@ -492,6 +519,13 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs)
492 goto resubmit; 519 goto resubmit;
493 } 520 }
494 521
522 /* drop incomplete packets even if the missing bytes wouldn't matter */
523 if (unlikely(urb->actual_length < 3)) {
524 dev_warn(cs->dev, "incomplete interrupt packet (%d bytes)\n",
525 urb->actual_length);
526 goto resubmit;
527 }
528
495 l = (unsigned) ucs->int_in_buf[1] + 529 l = (unsigned) ucs->int_in_buf[1] +
496 (((unsigned) ucs->int_in_buf[2]) << 8); 530 (((unsigned) ucs->int_in_buf[2]) << 8);
497 531
@@ -558,25 +592,28 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs)
558 } 592 }
559 spin_lock_irqsave(&cs->lock, flags); 593 spin_lock_irqsave(&cs->lock, flags);
560 if (ucs->rcvbuf_size) { 594 if (ucs->rcvbuf_size) {
561 spin_unlock_irqrestore(&cs->lock, flags); 595 /* throw away previous buffer - we have no queue */
562 dev_err(cs->dev, 596 dev_err(cs->dev,
563 "receive AT data overrun, %d bytes lost\n", l); 597 "receive AT data overrun, %d bytes lost\n",
564 error_reset(cs); //FIXME reschedule 598 ucs->rcvbuf_size);
565 break; 599 kfree(ucs->rcvbuf);
600 ucs->rcvbuf_size = 0;
566 } 601 }
567 if ((ucs->rcvbuf = kmalloc(l, GFP_ATOMIC)) == NULL) { 602 if ((ucs->rcvbuf = kmalloc(l, GFP_ATOMIC)) == NULL) {
568 spin_unlock_irqrestore(&cs->lock, flags); 603 spin_unlock_irqrestore(&cs->lock, flags);
569 dev_err(cs->dev, "out of memory, %d bytes lost\n", l); 604 dev_err(cs->dev, "out of memory receiving AT data\n");
570 error_reset(cs); //FIXME reschedule 605 error_reset(cs);
571 break; 606 break;
572 } 607 }
573 ucs->rcvbuf_size = l; 608 ucs->rcvbuf_size = l;
574 ucs->retry_cmd_in = 0; 609 ucs->retry_cmd_in = 0;
575 if ((status = atread_submit(cs, BAS_TIMEOUT)) < 0) { 610 if ((rc = atread_submit(cs, BAS_TIMEOUT)) < 0) {
576 kfree(ucs->rcvbuf); 611 kfree(ucs->rcvbuf);
577 ucs->rcvbuf = NULL; 612 ucs->rcvbuf = NULL;
578 ucs->rcvbuf_size = 0; 613 ucs->rcvbuf_size = 0;
579 error_reset(cs); //FIXME reschedule 614 if (rc != -ENODEV)
615 //FIXME corrective action?
616 error_reset(cs);
580 } 617 }
581 spin_unlock_irqrestore(&cs->lock, flags); 618 spin_unlock_irqrestore(&cs->lock, flags);
582 break; 619 break;
@@ -598,12 +635,10 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs)
598 check_pending(ucs); 635 check_pending(ucs);
599 636
600resubmit: 637resubmit:
601 spin_lock_irqsave(&cs->lock, flags); 638 rc = usb_submit_urb(urb, SLAB_ATOMIC);
602 status = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; 639 if (unlikely(rc != 0 && rc != -ENODEV)) {
603 spin_unlock_irqrestore(&cs->lock, flags);
604 if (unlikely(status)) {
605 dev_err(cs->dev, "could not resubmit interrupt URB: %s\n", 640 dev_err(cs->dev, "could not resubmit interrupt URB: %s\n",
606 get_usb_statmsg(status)); 641 get_usb_rcmsg(rc));
607 error_reset(cs); 642 error_reset(cs);
608 } 643 }
609} 644}
@@ -622,18 +657,12 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs)
622 struct bas_cardstate *ucs = cs->hw.bas; 657 struct bas_cardstate *ucs = cs->hw.bas;
623 int have_data = 0; 658 int have_data = 0;
624 unsigned numbytes; 659 unsigned numbytes;
625 unsigned long flags; 660 int rc;
626 661
627 spin_lock_irqsave(&cs->lock, flags); 662 update_basstate(ucs, 0, BS_ATRDPEND);
628 if (unlikely(!cs->connected)) {
629 warn("%s: disconnected", __func__);
630 spin_unlock_irqrestore(&cs->lock, flags);
631 return;
632 }
633 663
634 if (!ucs->rcvbuf_size) { 664 if (!ucs->rcvbuf_size) {
635 dev_warn(cs->dev, "%s: no receive in progress\n", __func__); 665 dev_warn(cs->dev, "%s: no receive in progress\n", __func__);
636 spin_unlock_irqrestore(&cs->lock, flags);
637 return; 666 return;
638 } 667 }
639 668
@@ -666,9 +695,11 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs)
666 } 695 }
667 break; 696 break;
668 697
669 case -ENOENT: /* canceled */ 698 case -ENOENT: /* cancelled */
670 case -ECONNRESET: /* canceled (async) */ 699 case -ECONNRESET: /* cancelled (async) */
671 case -EINPROGRESS: /* pending */ 700 case -EINPROGRESS: /* pending */
701 case -ENODEV: /* device removed */
702 case -ESHUTDOWN: /* device shut down */
672 /* no action necessary */ 703 /* no action necessary */
673 gig_dbg(DEBUG_USBREQ, "%s: %s", 704 gig_dbg(DEBUG_USBREQ, "%s: %s",
674 __func__, get_usb_statmsg(urb->status)); 705 __func__, get_usb_statmsg(urb->status));
@@ -681,11 +712,11 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs)
681 if (ucs->retry_cmd_in++ < BAS_RETRY) { 712 if (ucs->retry_cmd_in++ < BAS_RETRY) {
682 dev_notice(cs->dev, "control read: retry %d\n", 713 dev_notice(cs->dev, "control read: retry %d\n",
683 ucs->retry_cmd_in); 714 ucs->retry_cmd_in);
684 if (atread_submit(cs, BAS_TIMEOUT) >= 0) { 715 rc = atread_submit(cs, BAS_TIMEOUT);
685 /* resubmitted - bypass regular exit block */ 716 if (rc >= 0 || rc == -ENODEV)
686 spin_unlock_irqrestore(&cs->lock, flags); 717 /* resubmitted or disconnected */
718 /* - bypass regular exit block */
687 return; 719 return;
688 }
689 } else { 720 } else {
690 dev_err(cs->dev, 721 dev_err(cs->dev,
691 "control read: giving up after %d tries\n", 722 "control read: giving up after %d tries\n",
@@ -697,7 +728,6 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs)
697 kfree(ucs->rcvbuf); 728 kfree(ucs->rcvbuf);
698 ucs->rcvbuf = NULL; 729 ucs->rcvbuf = NULL;
699 ucs->rcvbuf_size = 0; 730 ucs->rcvbuf_size = 0;
700 spin_unlock_irqrestore(&cs->lock, flags);
701 if (have_data) { 731 if (have_data) {
702 gig_dbg(DEBUG_INTR, "%s-->BH", __func__); 732 gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
703 gigaset_schedule_event(cs); 733 gigaset_schedule_event(cs);
@@ -719,8 +749,11 @@ static void read_iso_callback(struct urb *urb, struct pt_regs *regs)
719 int i, rc; 749 int i, rc;
720 750
721 /* status codes not worth bothering the tasklet with */ 751 /* status codes not worth bothering the tasklet with */
722 if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || 752 if (unlikely(urb->status == -ENOENT ||
723 urb->status == -EINPROGRESS)) { 753 urb->status == -ECONNRESET ||
754 urb->status == -EINPROGRESS ||
755 urb->status == -ENODEV ||
756 urb->status == -ESHUTDOWN)) {
724 gig_dbg(DEBUG_ISO, "%s: %s", 757 gig_dbg(DEBUG_ISO, "%s: %s",
725 __func__, get_usb_statmsg(urb->status)); 758 __func__, get_usb_statmsg(urb->status));
726 return; 759 return;
@@ -740,9 +773,9 @@ static void read_iso_callback(struct urb *urb, struct pt_regs *regs)
740 for (i = 0; i < BAS_NUMFRAMES; i++) { 773 for (i = 0; i < BAS_NUMFRAMES; i++) {
741 ubc->isoinlost += urb->iso_frame_desc[i].actual_length; 774 ubc->isoinlost += urb->iso_frame_desc[i].actual_length;
742 if (unlikely(urb->iso_frame_desc[i].status != 0 && 775 if (unlikely(urb->iso_frame_desc[i].status != 0 &&
743 urb->iso_frame_desc[i].status != -EINPROGRESS)) { 776 urb->iso_frame_desc[i].status !=
777 -EINPROGRESS))
744 ubc->loststatus = urb->iso_frame_desc[i].status; 778 ubc->loststatus = urb->iso_frame_desc[i].status;
745 }
746 urb->iso_frame_desc[i].status = 0; 779 urb->iso_frame_desc[i].status = 0;
747 urb->iso_frame_desc[i].actual_length = 0; 780 urb->iso_frame_desc[i].actual_length = 0;
748 } 781 }
@@ -754,10 +787,10 @@ static void read_iso_callback(struct urb *urb, struct pt_regs *regs)
754 gig_dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit", 787 gig_dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit",
755 __func__); 788 __func__);
756 rc = usb_submit_urb(urb, SLAB_ATOMIC); 789 rc = usb_submit_urb(urb, SLAB_ATOMIC);
757 if (unlikely(rc != 0)) { 790 if (unlikely(rc != 0 && rc != -ENODEV)) {
758 dev_err(bcs->cs->dev, 791 dev_err(bcs->cs->dev,
759 "could not resubmit isochronous read " 792 "could not resubmit isochronous read "
760 "URB: %s\n", get_usb_statmsg(rc)); 793 "URB: %s\n", get_usb_rcmsg(rc));
761 dump_urb(DEBUG_ISO, "isoc read", urb); 794 dump_urb(DEBUG_ISO, "isoc read", urb);
762 error_hangup(bcs); 795 error_hangup(bcs);
763 } 796 }
@@ -780,8 +813,11 @@ static void write_iso_callback(struct urb *urb, struct pt_regs *regs)
780 unsigned long flags; 813 unsigned long flags;
781 814
782 /* status codes not worth bothering the tasklet with */ 815 /* status codes not worth bothering the tasklet with */
783 if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || 816 if (unlikely(urb->status == -ENOENT ||
784 urb->status == -EINPROGRESS)) { 817 urb->status == -ECONNRESET ||
818 urb->status == -EINPROGRESS ||
819 urb->status == -ENODEV ||
820 urb->status == -ESHUTDOWN)) {
785 gig_dbg(DEBUG_ISO, "%s: %s", 821 gig_dbg(DEBUG_ISO, "%s: %s",
786 __func__, get_usb_statmsg(urb->status)); 822 __func__, get_usb_statmsg(urb->status));
787 return; 823 return;
@@ -822,7 +858,6 @@ static int starturbs(struct bc_state *bcs)
822 for (k = 0; k < BAS_INURBS; k++) { 858 for (k = 0; k < BAS_INURBS; k++) {
823 urb = ubc->isoinurbs[k]; 859 urb = ubc->isoinurbs[k];
824 if (!urb) { 860 if (!urb) {
825 dev_err(bcs->cs->dev, "isoinurbs[%d]==NULL\n", k);
826 rc = -EFAULT; 861 rc = -EFAULT;
827 goto error; 862 goto error;
828 } 863 }
@@ -844,12 +879,8 @@ static int starturbs(struct bc_state *bcs)
844 } 879 }
845 880
846 dump_urb(DEBUG_ISO, "Initial isoc read", urb); 881 dump_urb(DEBUG_ISO, "Initial isoc read", urb);
847 if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { 882 if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0)
848 dev_err(bcs->cs->dev,
849 "could not submit isochronous read URB %d: %s\n",
850 k, get_usb_statmsg(rc));
851 goto error; 883 goto error;
852 }
853 } 884 }
854 885
855 /* initialize L2 transmission */ 886 /* initialize L2 transmission */
@@ -859,7 +890,6 @@ static int starturbs(struct bc_state *bcs)
859 for (k = 0; k < BAS_OUTURBS; ++k) { 890 for (k = 0; k < BAS_OUTURBS; ++k) {
860 urb = ubc->isoouturbs[k].urb; 891 urb = ubc->isoouturbs[k].urb;
861 if (!urb) { 892 if (!urb) {
862 dev_err(bcs->cs->dev, "isoouturbs[%d].urb==NULL\n", k);
863 rc = -EFAULT; 893 rc = -EFAULT;
864 goto error; 894 goto error;
865 } 895 }
@@ -885,12 +915,8 @@ static int starturbs(struct bc_state *bcs)
885 for (k = 0; k < 2; ++k) { 915 for (k = 0; k < 2; ++k) {
886 dump_urb(DEBUG_ISO, "Initial isoc write", urb); 916 dump_urb(DEBUG_ISO, "Initial isoc write", urb);
887 rc = usb_submit_urb(ubc->isoouturbs[k].urb, SLAB_ATOMIC); 917 rc = usb_submit_urb(ubc->isoouturbs[k].urb, SLAB_ATOMIC);
888 if (rc != 0) { 918 if (rc != 0)
889 dev_err(bcs->cs->dev,
890 "could not submit isochronous write URB %d: %s\n",
891 k, get_usb_statmsg(rc));
892 goto error; 919 goto error;
893 }
894 } 920 }
895 dump_urb(DEBUG_ISO, "Initial isoc write (free)", urb); 921 dump_urb(DEBUG_ISO, "Initial isoc write (free)", urb);
896 ubc->isooutfree = &ubc->isoouturbs[2]; 922 ubc->isooutfree = &ubc->isoouturbs[2];
@@ -916,15 +942,15 @@ static void stopurbs(struct bas_bc_state *ubc)
916 for (k = 0; k < BAS_INURBS; ++k) { 942 for (k = 0; k < BAS_INURBS; ++k) {
917 rc = usb_unlink_urb(ubc->isoinurbs[k]); 943 rc = usb_unlink_urb(ubc->isoinurbs[k]);
918 gig_dbg(DEBUG_ISO, 944 gig_dbg(DEBUG_ISO,
919 "%s: isoc input URB %d unlinked, result = %d", 945 "%s: isoc input URB %d unlinked, result = %s",
920 __func__, k, rc); 946 __func__, k, get_usb_rcmsg(rc));
921 } 947 }
922 948
923 for (k = 0; k < BAS_OUTURBS; ++k) { 949 for (k = 0; k < BAS_OUTURBS; ++k) {
924 rc = usb_unlink_urb(ubc->isoouturbs[k].urb); 950 rc = usb_unlink_urb(ubc->isoouturbs[k].urb);
925 gig_dbg(DEBUG_ISO, 951 gig_dbg(DEBUG_ISO,
926 "%s: isoc output URB %d unlinked, result = %d", 952 "%s: isoc output URB %d unlinked, result = %s",
927 __func__, k, rc); 953 __func__, k, get_usb_rcmsg(rc));
928 } 954 }
929} 955}
930 956
@@ -934,7 +960,7 @@ static void stopurbs(struct bas_bc_state *ubc)
934/* submit_iso_write_urb 960/* submit_iso_write_urb
935 * fill and submit the next isochronous write URB 961 * fill and submit the next isochronous write URB
936 * parameters: 962 * parameters:
937 * bcs B channel state structure 963 * ucx context structure containing URB
938 * return value: 964 * return value:
939 * number of frames submitted in URB 965 * number of frames submitted in URB
940 * 0 if URB not submitted because no data available (isooutbuf busy) 966 * 0 if URB not submitted because no data available (isooutbuf busy)
@@ -946,7 +972,6 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
946 struct bas_bc_state *ubc = ucx->bcs->hw.bas; 972 struct bas_bc_state *ubc = ucx->bcs->hw.bas;
947 struct usb_iso_packet_descriptor *ifd; 973 struct usb_iso_packet_descriptor *ifd;
948 int corrbytes, nframe, rc; 974 int corrbytes, nframe, rc;
949 unsigned long flags;
950 975
951 /* urb->dev is clobbered by USB subsystem */ 976 /* urb->dev is clobbered by USB subsystem */
952 urb->dev = ucx->bcs->cs->hw.bas->udev; 977 urb->dev = ucx->bcs->cs->hw.bas->udev;
@@ -992,20 +1017,22 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
992 ifd->status = 0; 1017 ifd->status = 0;
993 ifd->actual_length = 0; 1018 ifd->actual_length = 0;
994 } 1019 }
995 if ((urb->number_of_packets = nframe) > 0) { 1020 if (unlikely(nframe == 0))
996 spin_lock_irqsave(&ucx->bcs->cs->lock, flags); 1021 return 0; /* no data to send */
997 rc = ucx->bcs->cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; 1022 urb->number_of_packets = nframe;
998 spin_unlock_irqrestore(&ucx->bcs->cs->lock, flags);
999 1023
1000 if (rc) { 1024 rc = usb_submit_urb(urb, SLAB_ATOMIC);
1025 if (unlikely(rc)) {
1026 if (rc == -ENODEV)
1027 /* device removed - give up silently */
1028 gig_dbg(DEBUG_ISO, "%s: disconnected", __func__);
1029 else
1001 dev_err(ucx->bcs->cs->dev, 1030 dev_err(ucx->bcs->cs->dev,
1002 "could not submit isochronous write URB: %s\n", 1031 "could not submit isochronous write URB: %s\n",
1003 get_usb_statmsg(rc)); 1032 get_usb_rcmsg(rc));
1004 dump_urb(DEBUG_ISO, "isoc write", urb); 1033 return rc;
1005 return rc;
1006 }
1007 ++ubc->numsub;
1008 } 1034 }
1035 ++ubc->numsub;
1009 return nframe; 1036 return nframe;
1010} 1037}
1011 1038
@@ -1028,6 +1055,7 @@ static void write_iso_tasklet(unsigned long data)
1028 int i; 1055 int i;
1029 struct sk_buff *skb; 1056 struct sk_buff *skb;
1030 int len; 1057 int len;
1058 int rc;
1031 1059
1032 /* loop while completed URBs arrive in time */ 1060 /* loop while completed URBs arrive in time */
1033 for (;;) { 1061 for (;;) {
@@ -1057,7 +1085,8 @@ static void write_iso_tasklet(unsigned long data)
1057 ubc->isooutfree = NULL; 1085 ubc->isooutfree = NULL;
1058 spin_unlock_irqrestore(&ubc->isooutlock, flags); 1086 spin_unlock_irqrestore(&ubc->isooutlock, flags);
1059 if (next) { 1087 if (next) {
1060 if (submit_iso_write_urb(next) <= 0) { 1088 rc = submit_iso_write_urb(next);
1089 if (unlikely(rc <= 0 && rc != -ENODEV)) {
1061 /* could not submit URB, put it back */ 1090 /* could not submit URB, put it back */
1062 spin_lock_irqsave(&ubc->isooutlock, flags); 1091 spin_lock_irqsave(&ubc->isooutlock, flags);
1063 if (ubc->isooutfree == NULL) { 1092 if (ubc->isooutfree == NULL) {
@@ -1077,17 +1106,18 @@ static void write_iso_tasklet(unsigned long data)
1077 /* process completed URB */ 1106 /* process completed URB */
1078 urb = done->urb; 1107 urb = done->urb;
1079 switch (urb->status) { 1108 switch (urb->status) {
1109 case -EXDEV: /* partial completion */
1110 gig_dbg(DEBUG_ISO, "%s: URB partially completed",
1111 __func__);
1112 /* fall through - what's the difference anyway? */
1080 case 0: /* normal completion */ 1113 case 0: /* normal completion */
1081 break; 1114 /* inspect individual frames
1082 case -EXDEV: /* inspect individual frames */ 1115 * assumptions (for lack of documentation):
1083 /* assumptions (for lack of documentation): 1116 * - actual_length bytes of first frame in error are
1084 * - actual_length bytes of the frame in error are
1085 * successfully sent 1117 * successfully sent
1086 * - all following frames are not sent at all 1118 * - all following frames are not sent at all
1087 */ 1119 */
1088 gig_dbg(DEBUG_ISO, "%s: URB partially completed", 1120 offset = done->limit; /* default (no error) */
1089 __func__);
1090 offset = done->limit; /* just in case */
1091 for (i = 0; i < BAS_NUMFRAMES; i++) { 1121 for (i = 0; i < BAS_NUMFRAMES; i++) {
1092 ifd = &urb->iso_frame_desc[i]; 1122 ifd = &urb->iso_frame_desc[i];
1093 if (ifd->status || 1123 if (ifd->status ||
@@ -1122,7 +1152,7 @@ static void write_iso_tasklet(unsigned long data)
1122 } 1152 }
1123#endif 1153#endif
1124 break; 1154 break;
1125 case -EPIPE: //FIXME is this the code for "underrun"? 1155 case -EPIPE: /* stall - probably underrun */
1126 dev_err(cs->dev, "isochronous write stalled\n"); 1156 dev_err(cs->dev, "isochronous write stalled\n");
1127 error_hangup(bcs); 1157 error_hangup(bcs);
1128 break; 1158 break;
@@ -1142,7 +1172,8 @@ static void write_iso_tasklet(unsigned long data)
1142 spin_unlock_irqrestore(&ubc->isooutlock, flags); 1172 spin_unlock_irqrestore(&ubc->isooutlock, flags);
1143 if (next) { 1173 if (next) {
1144 /* only one URB still active - resubmit one */ 1174 /* only one URB still active - resubmit one */
1145 if (submit_iso_write_urb(next) <= 0) { 1175 rc = submit_iso_write_urb(next);
1176 if (unlikely(rc <= 0 && rc != -ENODEV)) {
1146 /* couldn't submit */ 1177 /* couldn't submit */
1147 error_hangup(bcs); 1178 error_hangup(bcs);
1148 } 1179 }
@@ -1222,10 +1253,9 @@ static void read_iso_tasklet(unsigned long data)
1222 break; 1253 break;
1223 case -ENOENT: 1254 case -ENOENT:
1224 case -ECONNRESET: 1255 case -ECONNRESET:
1225 gig_dbg(DEBUG_ISO, "%s: URB canceled", __func__); 1256 case -EINPROGRESS:
1226 continue; /* -> skip */ 1257 gig_dbg(DEBUG_ISO, "%s: %s",
1227 case -EINPROGRESS: /* huh? */ 1258 __func__, get_usb_statmsg(urb->status));
1228 gig_dbg(DEBUG_ISO, "%s: URB still pending", __func__);
1229 continue; /* -> skip */ 1259 continue; /* -> skip */
1230 case -EPIPE: 1260 case -EPIPE:
1231 dev_err(cs->dev, "isochronous read stalled\n"); 1261 dev_err(cs->dev, "isochronous read stalled\n");
@@ -1290,13 +1320,11 @@ static void read_iso_tasklet(unsigned long data)
1290 urb->dev = bcs->cs->hw.bas->udev; 1320 urb->dev = bcs->cs->hw.bas->udev;
1291 urb->transfer_flags = URB_ISO_ASAP; 1321 urb->transfer_flags = URB_ISO_ASAP;
1292 urb->number_of_packets = BAS_NUMFRAMES; 1322 urb->number_of_packets = BAS_NUMFRAMES;
1293 spin_lock_irqsave(&cs->lock, flags); 1323 rc = usb_submit_urb(urb, SLAB_ATOMIC);
1294 rc = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; 1324 if (unlikely(rc != 0 && rc != -ENODEV)) {
1295 spin_unlock_irqrestore(&cs->lock, flags);
1296 if (rc) {
1297 dev_err(cs->dev, 1325 dev_err(cs->dev,
1298 "could not resubmit isochronous read URB: %s\n", 1326 "could not resubmit isochronous read URB: %s\n",
1299 get_usb_statmsg(rc)); 1327 get_usb_rcmsg(rc));
1300 dump_urb(DEBUG_ISO, "resubmit iso read", urb); 1328 dump_urb(DEBUG_ISO, "resubmit iso read", urb);
1301 error_hangup(bcs); 1329 error_hangup(bcs);
1302 } 1330 }
@@ -1397,7 +1425,6 @@ static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs)
1397 * timeout timeout in seconds (0: no timeout) 1425 * timeout timeout in seconds (0: no timeout)
1398 * return value: 1426 * return value:
1399 * 0 on success 1427 * 0 on success
1400 * -EINVAL if a NULL pointer is encountered somewhere
1401 * -EBUSY if another request is pending 1428 * -EBUSY if another request is pending
1402 * any URB submission error code 1429 * any URB submission error code
1403 */ 1430 */
@@ -1418,12 +1445,6 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout)
1418 req, ucs->pending); 1445 req, ucs->pending);
1419 return -EBUSY; 1446 return -EBUSY;
1420 } 1447 }
1421 if (ucs->urb_ctrl->status == -EINPROGRESS) {
1422 spin_unlock_irqrestore(&ucs->lock, flags);
1423 dev_err(bcs->cs->dev,
1424 "could not submit request 0x%02x: URB busy\n", req);
1425 return -EBUSY;
1426 }
1427 1448
1428 ucs->dr_ctrl.bRequestType = OUT_VENDOR_REQ; 1449 ucs->dr_ctrl.bRequestType = OUT_VENDOR_REQ;
1429 ucs->dr_ctrl.bRequest = req; 1450 ucs->dr_ctrl.bRequest = req;
@@ -1465,22 +1486,36 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout)
1465static int gigaset_init_bchannel(struct bc_state *bcs) 1486static int gigaset_init_bchannel(struct bc_state *bcs)
1466{ 1487{
1467 int req, ret; 1488 int req, ret;
1489 unsigned long flags;
1490
1491 spin_lock_irqsave(&bcs->cs->lock, flags);
1492 if (unlikely(!bcs->cs->connected)) {
1493 gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__);
1494 spin_unlock_irqrestore(&bcs->cs->lock, flags);
1495 return -ENODEV;
1496 }
1468 1497
1469 if ((ret = starturbs(bcs)) < 0) { 1498 if ((ret = starturbs(bcs)) < 0) {
1470 dev_err(bcs->cs->dev, 1499 dev_err(bcs->cs->dev,
1471 "could not start isochronous I/O for channel %d\n", 1500 "could not start isochronous I/O for channel B%d: %s\n",
1472 bcs->channel + 1); 1501 bcs->channel + 1,
1473 error_hangup(bcs); 1502 ret == -EFAULT ? "null URB" : get_usb_rcmsg(ret));
1503 if (ret != -ENODEV)
1504 error_hangup(bcs);
1505 spin_unlock_irqrestore(&bcs->cs->lock, flags);
1474 return ret; 1506 return ret;
1475 } 1507 }
1476 1508
1477 req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL; 1509 req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL;
1478 if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) { 1510 if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) {
1479 dev_err(bcs->cs->dev, "could not open channel %d: %s\n", 1511 dev_err(bcs->cs->dev, "could not open channel B%d\n",
1480 bcs->channel + 1, get_usb_statmsg(ret)); 1512 bcs->channel + 1);
1481 stopurbs(bcs->hw.bas); 1513 stopurbs(bcs->hw.bas);
1482 error_hangup(bcs); 1514 if (ret != -ENODEV)
1515 error_hangup(bcs);
1483 } 1516 }
1517
1518 spin_unlock_irqrestore(&bcs->cs->lock, flags);
1484 return ret; 1519 return ret;
1485} 1520}
1486 1521
@@ -1497,19 +1532,30 @@ static int gigaset_init_bchannel(struct bc_state *bcs)
1497static int gigaset_close_bchannel(struct bc_state *bcs) 1532static int gigaset_close_bchannel(struct bc_state *bcs)
1498{ 1533{
1499 int req, ret; 1534 int req, ret;
1535 unsigned long flags;
1536
1537 spin_lock_irqsave(&bcs->cs->lock, flags);
1538 if (unlikely(!bcs->cs->connected)) {
1539 spin_unlock_irqrestore(&bcs->cs->lock, flags);
1540 gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__);
1541 return -ENODEV;
1542 }
1500 1543
1501 if (!(atomic_read(&bcs->cs->hw.bas->basstate) & 1544 if (!(atomic_read(&bcs->cs->hw.bas->basstate) &
1502 (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) { 1545 (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) {
1503 /* channel not running: just signal common.c */ 1546 /* channel not running: just signal common.c */
1547 spin_unlock_irqrestore(&bcs->cs->lock, flags);
1504 gigaset_bchannel_down(bcs); 1548 gigaset_bchannel_down(bcs);
1505 return 0; 1549 return 0;
1506 } 1550 }
1507 1551
1552 /* channel running: tell device to close it */
1508 req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL; 1553 req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL;
1509 if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) 1554 if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0)
1510 dev_err(bcs->cs->dev, 1555 dev_err(bcs->cs->dev, "closing channel B%d failed\n",
1511 "could not submit HD_CLOSE_BxCHANNEL request: %s\n", 1556 bcs->channel + 1);
1512 get_usb_statmsg(ret)); 1557
1558 spin_unlock_irqrestore(&bcs->cs->lock, flags);
1513 return ret; 1559 return ret;
1514} 1560}
1515 1561
@@ -1545,8 +1591,6 @@ static void complete_cb(struct cardstate *cs)
1545 kfree(cb); 1591 kfree(cb);
1546} 1592}
1547 1593
1548static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len);
1549
1550/* write_command_callback 1594/* write_command_callback
1551 * USB completion handler for AT command transmission 1595 * USB completion handler for AT command transmission
1552 * called by the USB subsystem in interrupt context 1596 * called by the USB subsystem in interrupt context
@@ -1560,13 +1604,17 @@ static void write_command_callback(struct urb *urb, struct pt_regs *regs)
1560 struct bas_cardstate *ucs = cs->hw.bas; 1604 struct bas_cardstate *ucs = cs->hw.bas;
1561 unsigned long flags; 1605 unsigned long flags;
1562 1606
1607 update_basstate(ucs, 0, BS_ATWRPEND);
1608
1563 /* check status */ 1609 /* check status */
1564 switch (urb->status) { 1610 switch (urb->status) {
1565 case 0: /* normal completion */ 1611 case 0: /* normal completion */
1566 break; 1612 break;
1567 case -ENOENT: /* canceled */ 1613 case -ENOENT: /* cancelled */
1568 case -ECONNRESET: /* canceled (async) */ 1614 case -ECONNRESET: /* cancelled (async) */
1569 case -EINPROGRESS: /* pending */ 1615 case -EINPROGRESS: /* pending */
1616 case -ENODEV: /* device removed */
1617 case -ESHUTDOWN: /* device shut down */
1570 /* ignore silently */ 1618 /* ignore silently */
1571 gig_dbg(DEBUG_USBREQ, "%s: %s", 1619 gig_dbg(DEBUG_USBREQ, "%s: %s",
1572 __func__, get_usb_statmsg(urb->status)); 1620 __func__, get_usb_statmsg(urb->status));
@@ -1627,19 +1675,17 @@ static void atrdy_timeout(unsigned long data)
1627 * len length of command to send 1675 * len length of command to send
1628 * return value: 1676 * return value:
1629 * 0 on success 1677 * 0 on success
1630 * -EFAULT if a NULL pointer is encountered somewhere
1631 * -EBUSY if another request is pending 1678 * -EBUSY if another request is pending
1632 * any URB submission error code 1679 * any URB submission error code
1633 */ 1680 */
1634static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) 1681static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len)
1635{ 1682{
1636 struct bas_cardstate *ucs = cs->hw.bas; 1683 struct bas_cardstate *ucs = cs->hw.bas;
1637 unsigned long flags; 1684 int rc;
1638 int ret;
1639 1685
1640 gig_dbg(DEBUG_USBREQ, "-------> HD_WRITE_ATMESSAGE (%d)", len); 1686 gig_dbg(DEBUG_USBREQ, "-------> HD_WRITE_ATMESSAGE (%d)", len);
1641 1687
1642 if (ucs->urb_cmd_out->status == -EINPROGRESS) { 1688 if (update_basstate(ucs, BS_ATWRPEND, 0) & BS_ATWRPEND) {
1643 dev_err(cs->dev, 1689 dev_err(cs->dev,
1644 "could not submit HD_WRITE_ATMESSAGE: URB busy\n"); 1690 "could not submit HD_WRITE_ATMESSAGE: URB busy\n");
1645 return -EBUSY; 1691 return -EBUSY;
@@ -1654,29 +1700,22 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len)
1654 usb_sndctrlpipe(ucs->udev, 0), 1700 usb_sndctrlpipe(ucs->udev, 0),
1655 (unsigned char*) &ucs->dr_cmd_out, buf, len, 1701 (unsigned char*) &ucs->dr_cmd_out, buf, len,
1656 write_command_callback, cs); 1702 write_command_callback, cs);
1657 1703 rc = usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC);
1658 spin_lock_irqsave(&cs->lock, flags); 1704 if (unlikely(rc)) {
1659 ret = cs->connected ? usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC) : -ENODEV; 1705 update_basstate(ucs, 0, BS_ATWRPEND);
1660 spin_unlock_irqrestore(&cs->lock, flags);
1661
1662 if (ret) {
1663 dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n", 1706 dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n",
1664 get_usb_statmsg(ret)); 1707 get_usb_rcmsg(rc));
1665 return ret; 1708 return rc;
1666 } 1709 }
1667 1710
1668 /* submitted successfully */ 1711 /* submitted successfully, start timeout if necessary */
1669 update_basstate(ucs, 0, BS_ATREADY); 1712 if (!(update_basstate(ucs, BS_ATTIMER, BS_ATREADY) & BS_ATTIMER)) {
1670
1671 /* start timeout if necessary */
1672 if (!(atomic_read(&ucs->basstate) & BS_ATTIMER)) {
1673 gig_dbg(DEBUG_OUTPUT, "setting ATREADY timeout of %d/10 secs", 1713 gig_dbg(DEBUG_OUTPUT, "setting ATREADY timeout of %d/10 secs",
1674 ATRDY_TIMEOUT); 1714 ATRDY_TIMEOUT);
1675 ucs->timer_atrdy.expires = jiffies + ATRDY_TIMEOUT * HZ / 10; 1715 ucs->timer_atrdy.expires = jiffies + ATRDY_TIMEOUT * HZ / 10;
1676 ucs->timer_atrdy.data = (unsigned long) cs; 1716 ucs->timer_atrdy.data = (unsigned long) cs;
1677 ucs->timer_atrdy.function = atrdy_timeout; 1717 ucs->timer_atrdy.function = atrdy_timeout;
1678 add_timer(&ucs->timer_atrdy); 1718 add_timer(&ucs->timer_atrdy);
1679 update_basstate(ucs, BS_ATTIMER, 0);
1680 } 1719 }
1681 return 0; 1720 return 0;
1682} 1721}
@@ -1702,7 +1741,6 @@ static int start_cbsend(struct cardstate *cs)
1702 gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "AT channel not open"); 1741 gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "AT channel not open");
1703 rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT); 1742 rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT);
1704 if (rc < 0) { 1743 if (rc < 0) {
1705 dev_err(cs->dev, "could not open AT channel\n");
1706 /* flush command queue */ 1744 /* flush command queue */
1707 spin_lock_irqsave(&cs->cmdlock, flags); 1745 spin_lock_irqsave(&cs->cmdlock, flags);
1708 while (cs->cmdbuf != NULL) 1746 while (cs->cmdbuf != NULL)
@@ -1786,8 +1824,14 @@ static int gigaset_write_cmd(struct cardstate *cs,
1786 cs->lastcmdbuf = cb; 1824 cs->lastcmdbuf = cb;
1787 spin_unlock_irqrestore(&cs->cmdlock, flags); 1825 spin_unlock_irqrestore(&cs->cmdlock, flags);
1788 1826
1827 spin_lock_irqsave(&cs->lock, flags);
1828 if (unlikely(!cs->connected)) {
1829 spin_unlock_irqrestore(&cs->lock, flags);
1830 gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__);
1831 return -ENODEV;
1832 }
1789 status = start_cbsend(cs); 1833 status = start_cbsend(cs);
1790 1834 spin_unlock_irqrestore(&cs->lock, flags);
1791 return status < 0 ? status : len; 1835 return status < 0 ? status : len;
1792} 1836}
1793 1837
@@ -1849,12 +1893,32 @@ static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])
1849 */ 1893 */
1850static int gigaset_freebcshw(struct bc_state *bcs) 1894static int gigaset_freebcshw(struct bc_state *bcs)
1851{ 1895{
1852 if (!bcs->hw.bas) 1896 struct bas_bc_state *ubc = bcs->hw.bas;
1897 int i;
1898
1899 if (!ubc)
1853 return 0; 1900 return 0;
1854 1901
1855 if (bcs->hw.bas->isooutbuf) 1902 /* kill URBs and tasklets before freeing - better safe than sorry */
1856 kfree(bcs->hw.bas->isooutbuf); 1903 atomic_set(&ubc->running, 0);
1857 kfree(bcs->hw.bas); 1904 for (i = 0; i < BAS_OUTURBS; ++i)
1905 if (ubc->isoouturbs[i].urb) {
1906 gig_dbg(DEBUG_INIT, "%s: killing iso out URB %d",
1907 __func__, i);
1908 usb_kill_urb(ubc->isoouturbs[i].urb);
1909 usb_free_urb(ubc->isoouturbs[i].urb);
1910 }
1911 for (i = 0; i < BAS_INURBS; ++i)
1912 if (ubc->isoinurbs[i]) {
1913 gig_dbg(DEBUG_INIT, "%s: killing iso in URB %d",
1914 __func__, i);
1915 usb_kill_urb(ubc->isoinurbs[i]);
1916 usb_free_urb(ubc->isoinurbs[i]);
1917 }
1918 tasklet_kill(&ubc->sent_tasklet);
1919 tasklet_kill(&ubc->rcvd_tasklet);
1920 kfree(ubc->isooutbuf);
1921 kfree(ubc);
1858 bcs->hw.bas = NULL; 1922 bcs->hw.bas = NULL;
1859 return 1; 1923 return 1;
1860} 1924}
@@ -1931,13 +1995,9 @@ static void gigaset_reinitbcshw(struct bc_state *bcs)
1931 1995
1932static void gigaset_freecshw(struct cardstate *cs) 1996static void gigaset_freecshw(struct cardstate *cs)
1933{ 1997{
1934 struct bas_cardstate *ucs = cs->hw.bas; 1998 /* timers, URBs and rcvbuf are disposed of in disconnect */
1935
1936 del_timer(&ucs->timer_ctrl);
1937 del_timer(&ucs->timer_atrdy);
1938 del_timer(&ucs->timer_cmd_in);
1939
1940 kfree(cs->hw.bas); 1999 kfree(cs->hw.bas);
2000 cs->hw.bas = NULL;
1941} 2001}
1942 2002
1943static int gigaset_initcshw(struct cardstate *cs) 2003static int gigaset_initcshw(struct cardstate *cs)
@@ -2041,23 +2101,13 @@ static int gigaset_probe(struct usb_interface *interface,
2041 struct bas_bc_state *ubc; 2101 struct bas_bc_state *ubc;
2042 struct usb_endpoint_descriptor *endpoint; 2102 struct usb_endpoint_descriptor *endpoint;
2043 int i, j; 2103 int i, j;
2044 int ret; 2104 int rc;
2045 2105
2046 gig_dbg(DEBUG_ANY, 2106 gig_dbg(DEBUG_ANY,
2047 "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", 2107 "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)",
2048 __func__, le16_to_cpu(udev->descriptor.idVendor), 2108 __func__, le16_to_cpu(udev->descriptor.idVendor),
2049 le16_to_cpu(udev->descriptor.idProduct)); 2109 le16_to_cpu(udev->descriptor.idProduct));
2050 2110
2051 /* See if the device offered us matches what we can accept */
2052 if ((le16_to_cpu(udev->descriptor.idVendor) != USB_GIGA_VENDOR_ID) ||
2053 (le16_to_cpu(udev->descriptor.idProduct) != USB_GIGA_PRODUCT_ID &&
2054 le16_to_cpu(udev->descriptor.idProduct) != USB_4175_PRODUCT_ID &&
2055 le16_to_cpu(udev->descriptor.idProduct) != USB_SX303_PRODUCT_ID &&
2056 le16_to_cpu(udev->descriptor.idProduct) != USB_SX353_PRODUCT_ID)) {
2057 gig_dbg(DEBUG_ANY, "%s: unmatched ID - exiting", __func__);
2058 return -ENODEV;
2059 }
2060
2061 /* set required alternate setting */ 2111 /* set required alternate setting */
2062 hostif = interface->cur_altsetting; 2112 hostif = interface->cur_altsetting;
2063 if (hostif->desc.bAlternateSetting != 3) { 2113 if (hostif->desc.bAlternateSetting != 3) {
@@ -2105,45 +2155,22 @@ static int gigaset_probe(struct usb_interface *interface,
2105 * - three for the different uses of the default control pipe 2155 * - three for the different uses of the default control pipe
2106 * - three for each isochronous pipe 2156 * - three for each isochronous pipe
2107 */ 2157 */
2108 ucs->urb_int_in = usb_alloc_urb(0, SLAB_KERNEL); 2158 if (!(ucs->urb_int_in = usb_alloc_urb(0, SLAB_KERNEL)) ||
2109 if (!ucs->urb_int_in) { 2159 !(ucs->urb_cmd_in = usb_alloc_urb(0, SLAB_KERNEL)) ||
2110 dev_err(cs->dev, "no free urbs available\n"); 2160 !(ucs->urb_cmd_out = usb_alloc_urb(0, SLAB_KERNEL)) ||
2111 goto error; 2161 !(ucs->urb_ctrl = usb_alloc_urb(0, SLAB_KERNEL)))
2112 } 2162 goto allocerr;
2113 ucs->urb_cmd_in = usb_alloc_urb(0, SLAB_KERNEL);
2114 if (!ucs->urb_cmd_in) {
2115 dev_err(cs->dev, "no free urbs available\n");
2116 goto error;
2117 }
2118 ucs->urb_cmd_out = usb_alloc_urb(0, SLAB_KERNEL);
2119 if (!ucs->urb_cmd_out) {
2120 dev_err(cs->dev, "no free urbs available\n");
2121 goto error;
2122 }
2123 ucs->urb_ctrl = usb_alloc_urb(0, SLAB_KERNEL);
2124 if (!ucs->urb_ctrl) {
2125 dev_err(cs->dev, "no free urbs available\n");
2126 goto error;
2127 }
2128 2163
2129 for (j = 0; j < 2; ++j) { 2164 for (j = 0; j < 2; ++j) {
2130 ubc = cs->bcs[j].hw.bas; 2165 ubc = cs->bcs[j].hw.bas;
2131 for (i = 0; i < BAS_OUTURBS; ++i) { 2166 for (i = 0; i < BAS_OUTURBS; ++i)
2132 ubc->isoouturbs[i].urb = 2167 if (!(ubc->isoouturbs[i].urb =
2133 usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL); 2168 usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL)))
2134 if (!ubc->isoouturbs[i].urb) { 2169 goto allocerr;
2135 dev_err(cs->dev, "no free urbs available\n"); 2170 for (i = 0; i < BAS_INURBS; ++i)
2136 goto error; 2171 if (!(ubc->isoinurbs[i] =
2137 } 2172 usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL)))
2138 } 2173 goto allocerr;
2139 for (i = 0; i < BAS_INURBS; ++i) {
2140 ubc->isoinurbs[i] =
2141 usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL);
2142 if (!ubc->isoinurbs[i]) {
2143 dev_err(cs->dev, "no free urbs available\n");
2144 goto error;
2145 }
2146 }
2147 } 2174 }
2148 2175
2149 ucs->rcvbuf = NULL; 2176 ucs->rcvbuf = NULL;
@@ -2156,15 +2183,14 @@ static int gigaset_probe(struct usb_interface *interface,
2156 (endpoint->bEndpointAddress) & 0x0f), 2183 (endpoint->bEndpointAddress) & 0x0f),
2157 ucs->int_in_buf, 3, read_int_callback, cs, 2184 ucs->int_in_buf, 3, read_int_callback, cs,
2158 endpoint->bInterval); 2185 endpoint->bInterval);
2159 ret = usb_submit_urb(ucs->urb_int_in, SLAB_KERNEL); 2186 if ((rc = usb_submit_urb(ucs->urb_int_in, SLAB_KERNEL)) != 0) {
2160 if (ret) {
2161 dev_err(cs->dev, "could not submit interrupt URB: %s\n", 2187 dev_err(cs->dev, "could not submit interrupt URB: %s\n",
2162 get_usb_statmsg(ret)); 2188 get_usb_rcmsg(rc));
2163 goto error; 2189 goto error;
2164 } 2190 }
2165 2191
2166 /* tell the device that the driver is ready */ 2192 /* tell the device that the driver is ready */
2167 if ((ret = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0)) != 0) 2193 if ((rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0)) != 0)
2168 goto error; 2194 goto error;
2169 2195
2170 /* tell common part that the device is ready */ 2196 /* tell common part that the device is ready */
@@ -2179,6 +2205,8 @@ static int gigaset_probe(struct usb_interface *interface,
2179 2205
2180 return 0; 2206 return 0;
2181 2207
2208allocerr:
2209 dev_err(cs->dev, "could not allocate URBs\n");
2182error: 2210error:
2183 freeurbs(cs); 2211 freeurbs(cs);
2184 usb_set_intfdata(interface, NULL); 2212 usb_set_intfdata(interface, NULL);
@@ -2193,19 +2221,34 @@ static void gigaset_disconnect(struct usb_interface *interface)
2193{ 2221{
2194 struct cardstate *cs; 2222 struct cardstate *cs;
2195 struct bas_cardstate *ucs; 2223 struct bas_cardstate *ucs;
2224 int j;
2196 2225
2197 cs = usb_get_intfdata(interface); 2226 cs = usb_get_intfdata(interface);
2198 2227
2199 ucs = cs->hw.bas; 2228 ucs = cs->hw.bas;
2200 2229
2201 dev_info(cs->dev, "disconnecting Gigaset base\n"); 2230 dev_info(cs->dev, "disconnecting Gigaset base\n");
2231
2232 /* mark base as not ready, all channels disconnected */
2233 atomic_set(&ucs->basstate, 0);
2234
2235 /* tell LL all channels are down */
2236 //FIXME shouldn't gigaset_stop() do this?
2237 for (j = 0; j < 2; ++j)
2238 gigaset_bchannel_down(cs->bcs + j);
2239
2240 /* stop driver (common part) */
2202 gigaset_stop(cs); 2241 gigaset_stop(cs);
2242
2243 /* stop timers and URBs, free ressources */
2244 del_timer_sync(&ucs->timer_ctrl);
2245 del_timer_sync(&ucs->timer_atrdy);
2246 del_timer_sync(&ucs->timer_cmd_in);
2203 freeurbs(cs); 2247 freeurbs(cs);
2204 usb_set_intfdata(interface, NULL); 2248 usb_set_intfdata(interface, NULL);
2205 kfree(ucs->rcvbuf); 2249 kfree(ucs->rcvbuf);
2206 ucs->rcvbuf = NULL; 2250 ucs->rcvbuf = NULL;
2207 ucs->rcvbuf_size = 0; 2251 ucs->rcvbuf_size = 0;
2208 atomic_set(&ucs->basstate, 0);
2209 usb_put_dev(ucs->udev); 2252 usb_put_dev(ucs->udev);
2210 ucs->interface = NULL; 2253 ucs->interface = NULL;
2211 ucs->udev = NULL; 2254 ucs->udev = NULL;
@@ -2277,6 +2320,8 @@ error: if (cardstate)
2277 */ 2320 */
2278static void __exit bas_gigaset_exit(void) 2321static void __exit bas_gigaset_exit(void)
2279{ 2322{
2323 struct bas_cardstate *ucs = cardstate->hw.bas;
2324
2280 gigaset_blockdriver(driver); /* => probe will fail 2325 gigaset_blockdriver(driver); /* => probe will fail
2281 * => no gigaset_start any more 2326 * => no gigaset_start any more
2282 */ 2327 */
@@ -2284,14 +2329,26 @@ static void __exit bas_gigaset_exit(void)
2284 gigaset_shutdown(cardstate); 2329 gigaset_shutdown(cardstate);
2285 /* from now on, no isdn callback should be possible */ 2330 /* from now on, no isdn callback should be possible */
2286 2331
2287 if (atomic_read(&cardstate->hw.bas->basstate) & BS_ATOPEN) { 2332 /* close all still open channels */
2288 gig_dbg(DEBUG_ANY, "closing AT channel"); 2333 if (atomic_read(&ucs->basstate) & BS_B1OPEN) {
2289 if (req_submit(cardstate->bcs, 2334 gig_dbg(DEBUG_INIT, "closing B1 channel");
2290 HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT) >= 0) { 2335 usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0),
2291 /* successfully submitted */ 2336 HD_CLOSE_B1CHANNEL, OUT_VENDOR_REQ, 0, 0,
2292 //FIXME wait for completion? 2337 NULL, 0, BAS_TIMEOUT);
2293 } 2338 }
2339 if (atomic_read(&ucs->basstate) & BS_B2OPEN) {
2340 gig_dbg(DEBUG_INIT, "closing B2 channel");
2341 usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0),
2342 HD_CLOSE_B2CHANNEL, OUT_VENDOR_REQ, 0, 0,
2343 NULL, 0, BAS_TIMEOUT);
2344 }
2345 if (atomic_read(&ucs->basstate) & BS_ATOPEN) {
2346 gig_dbg(DEBUG_INIT, "closing AT channel");
2347 usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0),
2348 HD_CLOSE_ATCHANNEL, OUT_VENDOR_REQ, 0, 0,
2349 NULL, 0, BAS_TIMEOUT);
2294 } 2350 }
2351 atomic_set(&ucs->basstate, 0);
2295 2352
2296 /* deregister this driver with the USB subsystem */ 2353 /* deregister this driver with the USB subsystem */
2297 usb_deregister(&gigaset_usb_driver); 2354 usb_deregister(&gigaset_usb_driver);
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c
index 749b3da1236e..e55767b2ccd3 100644
--- a/drivers/isdn/gigaset/common.c
+++ b/drivers/isdn/gigaset/common.c
@@ -781,8 +781,7 @@ error: if (cs)
781} 781}
782EXPORT_SYMBOL_GPL(gigaset_initcs); 782EXPORT_SYMBOL_GPL(gigaset_initcs);
783 783
784/* ReInitialize the b-channel structure */ 784/* ReInitialize the b-channel structure on hangup */
785/* e.g. called on hangup, disconnect */
786void gigaset_bcs_reinit(struct bc_state *bcs) 785void gigaset_bcs_reinit(struct bc_state *bcs)
787{ 786{
788 struct sk_buff *skb; 787 struct sk_buff *skb;
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c
index 1ba3424a286b..18e05c09b71c 100644
--- a/drivers/isdn/gigaset/ev-layer.c
+++ b/drivers/isdn/gigaset/ev-layer.c
@@ -373,6 +373,9 @@ struct reply_t gigaset_tab_cid_m10x[] = /* for M10x */
373 373
374 {EV_TIMEOUT, 750,750, -1, 0, 0, {ACT_CONNTIMEOUT}}, 374 {EV_TIMEOUT, 750,750, -1, 0, 0, {ACT_CONNTIMEOUT}},
375 375
376 /* B channel closed (general case) */
377 {EV_BC_CLOSED, -1, -1, -1, -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME
378
376 /* misc. */ 379 /* misc. */
377 {EV_PROTO_L2, -1, -1, -1, -1,-1, {ACT_PROTO_L2}}, //FIXME 380 {EV_PROTO_L2, -1, -1, -1, -1,-1, {ACT_PROTO_L2}}, //FIXME
378 381
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h
index 9d21ba8757b0..22b9693f7c0a 100644
--- a/drivers/isdn/gigaset/gigaset.h
+++ b/drivers/isdn/gigaset/gigaset.h
@@ -75,7 +75,7 @@ extern int gigaset_debuglevel; /* "needs" cast to (enum debuglevel) */
75 * e.g. 'insmod usb_gigaset.o debug=0x2c' will set DEBUG_OPEN, DEBUG_CMD and 75 * e.g. 'insmod usb_gigaset.o debug=0x2c' will set DEBUG_OPEN, DEBUG_CMD and
76 * DEBUG_INTR. 76 * DEBUG_INTR.
77 */ 77 */
78enum debuglevel { /* up to 24 bits (atomic_t) */ 78enum debuglevel {
79 DEBUG_REG = 0x0002, /* serial port I/O register operations */ 79 DEBUG_REG = 0x0002, /* serial port I/O register operations */
80 DEBUG_OPEN = 0x0004, /* open/close serial port */ 80 DEBUG_OPEN = 0x0004, /* open/close serial port */
81 DEBUG_INTR = 0x0008, /* interrupt processing */ 81 DEBUG_INTR = 0x0008, /* interrupt processing */
@@ -141,7 +141,7 @@ enum debuglevel { /* up to 24 bits (atomic_t) */
141 printk(KERN_DEBUG KBUILD_MODNAME ": " format "\n", \ 141 printk(KERN_DEBUG KBUILD_MODNAME ": " format "\n", \
142 ## arg); \ 142 ## arg); \
143 } while (0) 143 } while (0)
144#define DEBUG_DEFAULT (DEBUG_INIT | DEBUG_TRANSCMD | DEBUG_CMD | DEBUG_USBREQ) 144#define DEBUG_DEFAULT (DEBUG_TRANSCMD | DEBUG_CMD | DEBUG_USBREQ)
145 145
146#else 146#else
147 147
@@ -627,8 +627,7 @@ struct gigaset_ops {
627 /* Called by gigaset_freecs() for freeing bcs->hw.xxx */ 627 /* Called by gigaset_freecs() for freeing bcs->hw.xxx */
628 int (*freebcshw)(struct bc_state *bcs); 628 int (*freebcshw)(struct bc_state *bcs);
629 629
630 /* Called by gigaset_stop() or gigaset_bchannel_down() for resetting 630 /* Called by gigaset_bchannel_down() for resetting bcs->hw.xxx */
631 bcs->hw.xxx */
632 void (*reinitbcshw)(struct bc_state *bcs); 631 void (*reinitbcshw)(struct bc_state *bcs);
633 632
634 /* Called by gigaset_initcs() for setting up cs->hw.xxx */ 633 /* Called by gigaset_initcs() for setting up cs->hw.xxx */
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index 0815dbfb8291..1654fa413575 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -73,7 +73,7 @@ static int writebuf_from_LL(int driverID, int channel, int ack,
73 len, skblen, (unsigned) skb->head[0], (unsigned) skb->head[1]); 73 len, skblen, (unsigned) skb->head[0], (unsigned) skb->head[1]);
74 74
75 /* pass to device-specific module */ 75 /* pass to device-specific module */
76 return cs->ops->send_skb(bcs, skb); //FIXME cs->ops->send_skb() must handle !cs->connected correctly 76 return cs->ops->send_skb(bcs, skb);
77} 77}
78 78
79void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) 79void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c
index 45f017ed6e8c..8667daaa1a82 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)
992 int len = skb->len; 992 int len = skb->len;
993 unsigned long flags; 993 unsigned long flags;
994 994
995 spin_lock_irqsave(&bcs->cs->lock, flags);
996 if (!bcs->cs->connected) {
997 spin_unlock_irqrestore(&bcs->cs->lock, flags);
998 return -ENODEV;
999 }
1000
995 skb_queue_tail(&bcs->squeue, skb); 1001 skb_queue_tail(&bcs->squeue, skb);
996 gig_dbg(DEBUG_ISO, "%s: skb queued, qlen=%d", 1002 gig_dbg(DEBUG_ISO, "%s: skb queued, qlen=%d",
997 __func__, skb_queue_len(&bcs->squeue)); 1003 __func__, skb_queue_len(&bcs->squeue));
998 1004
999 /* tasklet submits URB if necessary */ 1005 /* tasklet submits URB if necessary */
1000 spin_lock_irqsave(&bcs->cs->lock, flags); 1006 tasklet_schedule(&bcs->hw.bas->sent_tasklet);
1001 if (bcs->cs->connected)
1002 tasklet_schedule(&bcs->hw.bas->sent_tasklet);
1003 spin_unlock_irqrestore(&bcs->cs->lock, flags); 1007 spin_unlock_irqrestore(&bcs->cs->lock, flags);
1004 1008
1005 return len; /* ok so far */ 1009 return len; /* ok so far */