diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 14:47:02 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 14:47:02 -0400 |
commit | 5f05647dd81c11a6a165ccc8f0c1370b16f3bcb0 (patch) | |
tree | 7851ef1c93aa1aba7ef327ca4b75fd35e6d10f29 /drivers/isdn | |
parent | 02f36038c568111ad4fc433f6fa760ff5e38fab4 (diff) | |
parent | ec37a48d1d16c30b655ac5280209edf52a6775d4 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1699 commits)
bnx2/bnx2x: Unsupported Ethtool operations should return -EINVAL.
vlan: Calling vlan_hwaccel_do_receive() is always valid.
tproxy: use the interface primary IP address as a default value for --on-ip
tproxy: added IPv6 support to the socket match
cxgb3: function namespace cleanup
tproxy: added IPv6 support to the TPROXY target
tproxy: added IPv6 socket lookup function to nf_tproxy_core
be2net: Changes to use only priority codes allowed by f/w
tproxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled
tproxy: added tproxy sockopt interface in the IPV6 layer
tproxy: added udp6_lib_lookup function
tproxy: added const specifiers to udp lookup functions
tproxy: split off ipv6 defragmentation to a separate module
l2tp: small cleanup
nf_nat: restrict ICMP translation for embedded header
can: mcp251x: fix generation of error frames
can: mcp251x: fix endless loop in interrupt handler if CANINTF_MERRF is set
can-raw: add msg_flags to distinguish local traffic
9p: client code cleanup
rds: make local functions/variables static
...
Fix up conflicts in net/core/dev.c, drivers/net/pcmcia/smc91c92_cs.c and
drivers/net/wireless/ath/ath9k/debug.c as per David
Diffstat (limited to 'drivers/isdn')
-rw-r--r-- | drivers/isdn/capi/capidrv.c | 17 | ||||
-rw-r--r-- | drivers/isdn/capi/kcapi.c | 19 | ||||
-rw-r--r-- | drivers/isdn/divert/isdn_divert.c | 6 | ||||
-rw-r--r-- | drivers/isdn/gigaset/bas-gigaset.c | 400 | ||||
-rw-r--r-- | drivers/isdn/gigaset/common.c | 26 | ||||
-rw-r--r-- | drivers/isdn/gigaset/gigaset.h | 3 | ||||
-rw-r--r-- | drivers/isdn/gigaset/i4l.c | 2 | ||||
-rw-r--r-- | drivers/isdn/gigaset/isocdata.c | 8 | ||||
-rw-r--r-- | drivers/isdn/hardware/eicon/debug.c | 2 | ||||
-rw-r--r-- | drivers/isdn/hardware/eicon/debuglib.h | 2 | ||||
-rw-r--r-- | drivers/isdn/hisax/hfc_sx.c | 13 | ||||
-rw-r--r-- | drivers/isdn/i4l/isdn_tty.c | 15 | ||||
-rw-r--r-- | drivers/isdn/mISDN/dsp_cmx.c | 1 | ||||
-rw-r--r-- | drivers/isdn/mISDN/l1oip_core.c | 2 | ||||
-rw-r--r-- | drivers/isdn/mISDN/stack.c | 7 | ||||
-rw-r--r-- | drivers/isdn/pcbit/edss1.c | 2 | ||||
-rw-r--r-- | drivers/isdn/pcbit/edss1.h | 2 |
17 files changed, 305 insertions, 222 deletions
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c index 2978bdaa6b88..e54e79d4e2c1 100644 --- a/drivers/isdn/capi/capidrv.c +++ b/drivers/isdn/capi/capidrv.c | |||
@@ -1515,8 +1515,13 @@ static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep) | |||
1515 | while (*s) { | 1515 | while (*s) { |
1516 | int digit1 = 0; | 1516 | int digit1 = 0; |
1517 | int digit2 = 0; | 1517 | int digit2 = 0; |
1518 | if (!isdigit(*s)) return -3; | 1518 | char *endp; |
1519 | while (isdigit(*s)) { digit1 = digit1*10 + (*s - '0'); s++; } | 1519 | |
1520 | digit1 = simple_strtoul(s, &endp, 10); | ||
1521 | if (s == endp) | ||
1522 | return -3; | ||
1523 | s = endp; | ||
1524 | |||
1520 | if (digit1 <= 0 || digit1 > 30) return -4; | 1525 | if (digit1 <= 0 || digit1 > 30) return -4; |
1521 | if (*s == 0 || *s == ',' || *s == ' ') { | 1526 | if (*s == 0 || *s == ',' || *s == ' ') { |
1522 | bmask |= (1 << digit1); | 1527 | bmask |= (1 << digit1); |
@@ -1526,8 +1531,12 @@ static int decodeFVteln(char *teln, unsigned long *bmaskp, int *activep) | |||
1526 | } | 1531 | } |
1527 | if (*s != '-') return -5; | 1532 | if (*s != '-') return -5; |
1528 | s++; | 1533 | s++; |
1529 | if (!isdigit(*s)) return -3; | 1534 | |
1530 | while (isdigit(*s)) { digit2 = digit2*10 + (*s - '0'); s++; } | 1535 | digit2 = simple_strtoul(s, &endp, 10); |
1536 | if (s == endp) | ||
1537 | return -3; | ||
1538 | s = endp; | ||
1539 | |||
1531 | if (digit2 <= 0 || digit2 > 30) return -4; | 1540 | if (digit2 <= 0 || digit2 > 30) return -4; |
1532 | if (*s == 0 || *s == ',' || *s == ' ') { | 1541 | if (*s == 0 || *s == ',' || *s == ' ') { |
1533 | if (digit1 > digit2) | 1542 | if (digit1 > digit2) |
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index b054494df846..3acf94cc5acd 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c | |||
@@ -98,6 +98,16 @@ static inline struct capi_ctr *get_capi_ctr_by_nr(u16 contr) | |||
98 | return capi_controller[contr - 1]; | 98 | return capi_controller[contr - 1]; |
99 | } | 99 | } |
100 | 100 | ||
101 | static inline struct capi20_appl *__get_capi_appl_by_nr(u16 applid) | ||
102 | { | ||
103 | lockdep_assert_held(&capi_controller_lock); | ||
104 | |||
105 | if (applid - 1 >= CAPI_MAXAPPL) | ||
106 | return NULL; | ||
107 | |||
108 | return capi_applications[applid - 1]; | ||
109 | } | ||
110 | |||
101 | static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid) | 111 | static inline struct capi20_appl *get_capi_appl_by_nr(u16 applid) |
102 | { | 112 | { |
103 | if (applid - 1 >= CAPI_MAXAPPL) | 113 | if (applid - 1 >= CAPI_MAXAPPL) |
@@ -185,10 +195,9 @@ static void notify_up(u32 contr) | |||
185 | ctr->state = CAPI_CTR_RUNNING; | 195 | ctr->state = CAPI_CTR_RUNNING; |
186 | 196 | ||
187 | for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { | 197 | for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { |
188 | ap = get_capi_appl_by_nr(applid); | 198 | ap = __get_capi_appl_by_nr(applid); |
189 | if (!ap) | 199 | if (ap) |
190 | continue; | 200 | register_appl(ctr, applid, &ap->rparam); |
191 | register_appl(ctr, applid, &ap->rparam); | ||
192 | } | 201 | } |
193 | 202 | ||
194 | wake_up_interruptible_all(&ctr->state_wait_queue); | 203 | wake_up_interruptible_all(&ctr->state_wait_queue); |
@@ -215,7 +224,7 @@ static void ctr_down(struct capi_ctr *ctr, int new_state) | |||
215 | memset(ctr->serial, 0, sizeof(ctr->serial)); | 224 | memset(ctr->serial, 0, sizeof(ctr->serial)); |
216 | 225 | ||
217 | for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { | 226 | for (applid = 1; applid <= CAPI_MAXAPPL; applid++) { |
218 | ap = get_capi_appl_by_nr(applid); | 227 | ap = __get_capi_appl_by_nr(applid); |
219 | if (ap) | 228 | if (ap) |
220 | capi_ctr_put(ctr); | 229 | capi_ctr_put(ctr); |
221 | } | 230 | } |
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c index 70cf6bac7a5a..48e6d220f62c 100644 --- a/drivers/isdn/divert/isdn_divert.c +++ b/drivers/isdn/divert/isdn_divert.c | |||
@@ -77,7 +77,7 @@ static void deflect_timer_expire(ulong arg) | |||
77 | 77 | ||
78 | case DEFLECT_ALERT: | 78 | case DEFLECT_ALERT: |
79 | cs->ics.command = ISDN_CMD_REDIR; /* protocol */ | 79 | cs->ics.command = ISDN_CMD_REDIR; /* protocol */ |
80 | strcpy(cs->ics.parm.setup.phone,cs->deflect_dest); | 80 | strlcpy(cs->ics.parm.setup.phone, cs->deflect_dest, sizeof(cs->ics.parm.setup.phone)); |
81 | strcpy(cs->ics.parm.setup.eazmsn,"Testtext delayed"); | 81 | strcpy(cs->ics.parm.setup.eazmsn,"Testtext delayed"); |
82 | divert_if.ll_cmd(&cs->ics); | 82 | divert_if.ll_cmd(&cs->ics); |
83 | spin_lock_irqsave(&divert_lock, flags); | 83 | spin_lock_irqsave(&divert_lock, flags); |
@@ -251,7 +251,7 @@ int deflect_extern_action(u_char cmd, ulong callid, char *to_nr) | |||
251 | 251 | ||
252 | case 2: /* redir */ | 252 | case 2: /* redir */ |
253 | del_timer(&cs->timer); | 253 | del_timer(&cs->timer); |
254 | strcpy(cs->ics.parm.setup.phone, to_nr); | 254 | strlcpy(cs->ics.parm.setup.phone, to_nr, sizeof(cs->ics.parm.setup.phone)); |
255 | strcpy(cs->ics.parm.setup.eazmsn, "Testtext manual"); | 255 | strcpy(cs->ics.parm.setup.eazmsn, "Testtext manual"); |
256 | ic.command = ISDN_CMD_REDIR; | 256 | ic.command = ISDN_CMD_REDIR; |
257 | if ((i = divert_if.ll_cmd(&ic))) | 257 | if ((i = divert_if.ll_cmd(&ic))) |
@@ -480,7 +480,7 @@ static int isdn_divert_icall(isdn_ctrl *ic) | |||
480 | if (!cs->timer.expires) | 480 | if (!cs->timer.expires) |
481 | { strcpy(ic->parm.setup.eazmsn,"Testtext direct"); | 481 | { strcpy(ic->parm.setup.eazmsn,"Testtext direct"); |
482 | ic->parm.setup.screen = dv->rule.screen; | 482 | ic->parm.setup.screen = dv->rule.screen; |
483 | strcpy(ic->parm.setup.phone,dv->rule.to_nr); | 483 | strlcpy(ic->parm.setup.phone, dv->rule.to_nr, sizeof(ic->parm.setup.phone)); |
484 | cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ | 484 | cs->akt_state = DEFLECT_AUTODEL; /* delete after timeout */ |
485 | cs->timer.expires = jiffies + (HZ * AUTODEL_TIME); | 485 | cs->timer.expires = jiffies + (HZ * AUTODEL_TIME); |
486 | retval = 5; | 486 | retval = 5; |
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 707d9c94cf9e..178942a2ee61 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
@@ -109,6 +109,9 @@ struct bas_cardstate { | |||
109 | 109 | ||
110 | struct urb *urb_int_in; /* URB for interrupt pipe */ | 110 | struct urb *urb_int_in; /* URB for interrupt pipe */ |
111 | unsigned char *int_in_buf; | 111 | unsigned char *int_in_buf; |
112 | struct work_struct int_in_wq; /* for usb_clear_halt() */ | ||
113 | struct timer_list timer_int_in; /* int read retry delay */ | ||
114 | int retry_int_in; | ||
112 | 115 | ||
113 | spinlock_t lock; /* locks all following */ | 116 | spinlock_t lock; /* locks all following */ |
114 | int basstate; /* bitmap (BS_*) */ | 117 | int basstate; /* bitmap (BS_*) */ |
@@ -169,7 +172,7 @@ static char *get_usb_rcmsg(int rc) | |||
169 | case -EAGAIN: | 172 | case -EAGAIN: |
170 | return "start frame too early or too much scheduled"; | 173 | return "start frame too early or too much scheduled"; |
171 | case -EFBIG: | 174 | case -EFBIG: |
172 | return "too many isochronous frames requested"; | 175 | return "too many isoc frames requested"; |
173 | case -EPIPE: | 176 | case -EPIPE: |
174 | return "endpoint stalled"; | 177 | return "endpoint stalled"; |
175 | case -EMSGSIZE: | 178 | case -EMSGSIZE: |
@@ -200,13 +203,13 @@ static char *get_usb_statmsg(int status) | |||
200 | case -ENOENT: | 203 | case -ENOENT: |
201 | return "unlinked (sync)"; | 204 | return "unlinked (sync)"; |
202 | case -EINPROGRESS: | 205 | case -EINPROGRESS: |
203 | return "pending"; | 206 | return "URB still pending"; |
204 | case -EPROTO: | 207 | case -EPROTO: |
205 | return "bit stuffing error, timeout, or unknown USB error"; | 208 | return "bitstuff error, timeout, or unknown USB error"; |
206 | case -EILSEQ: | 209 | case -EILSEQ: |
207 | return "CRC mismatch, timeout, or unknown USB error"; | 210 | return "CRC mismatch, timeout, or unknown USB error"; |
208 | case -ETIME: | 211 | case -ETIME: |
209 | return "timed out"; | 212 | return "USB response timeout"; |
210 | case -EPIPE: | 213 | case -EPIPE: |
211 | return "endpoint stalled"; | 214 | return "endpoint stalled"; |
212 | case -ECOMM: | 215 | case -ECOMM: |
@@ -214,15 +217,15 @@ static char *get_usb_statmsg(int status) | |||
214 | case -ENOSR: | 217 | case -ENOSR: |
215 | return "OUT buffer underrun"; | 218 | return "OUT buffer underrun"; |
216 | case -EOVERFLOW: | 219 | case -EOVERFLOW: |
217 | return "too much data"; | 220 | return "endpoint babble"; |
218 | case -EREMOTEIO: | 221 | case -EREMOTEIO: |
219 | return "short packet detected"; | 222 | return "short packet"; |
220 | case -ENODEV: | 223 | case -ENODEV: |
221 | return "device removed"; | 224 | return "device removed"; |
222 | case -EXDEV: | 225 | case -EXDEV: |
223 | return "partial isochronous transfer"; | 226 | return "partial isoc transfer"; |
224 | case -EINVAL: | 227 | case -EINVAL: |
225 | return "invalid argument"; | 228 | return "ISO madness"; |
226 | case -ECONNRESET: | 229 | case -ECONNRESET: |
227 | return "unlinked (async)"; | 230 | return "unlinked (async)"; |
228 | case -ESHUTDOWN: | 231 | case -ESHUTDOWN: |
@@ -350,7 +353,7 @@ static inline void error_hangup(struct bc_state *bcs) | |||
350 | * reset Gigaset device because of an unrecoverable error | 353 | * reset Gigaset device because of an unrecoverable error |
351 | * This function may be called from any context, and takes care of | 354 | * This function may be called from any context, and takes care of |
352 | * scheduling the necessary actions for execution outside of interrupt context. | 355 | * scheduling the necessary actions for execution outside of interrupt context. |
353 | * cs->lock must not be held. | 356 | * cs->hw.bas->lock must not be held. |
354 | * argument: | 357 | * argument: |
355 | * controller state structure | 358 | * controller state structure |
356 | */ | 359 | */ |
@@ -358,7 +361,9 @@ static inline void error_reset(struct cardstate *cs) | |||
358 | { | 361 | { |
359 | /* reset interrupt pipe to recover (ignore errors) */ | 362 | /* reset interrupt pipe to recover (ignore errors) */ |
360 | update_basstate(cs->hw.bas, BS_RESETTING, 0); | 363 | update_basstate(cs->hw.bas, BS_RESETTING, 0); |
361 | req_submit(cs->bcs, HD_RESET_INTERRUPT_PIPE, 0, BAS_TIMEOUT); | 364 | if (req_submit(cs->bcs, HD_RESET_INTERRUPT_PIPE, 0, BAS_TIMEOUT)) |
365 | /* submission failed, escalate to USB port reset */ | ||
366 | usb_queue_reset_device(cs->hw.bas->interface); | ||
362 | } | 367 | } |
363 | 368 | ||
364 | /* check_pending | 369 | /* check_pending |
@@ -438,23 +443,27 @@ static void cmd_in_timeout(unsigned long data) | |||
438 | return; | 443 | return; |
439 | } | 444 | } |
440 | 445 | ||
441 | if (ucs->retry_cmd_in++ < BAS_RETRY) { | 446 | if (ucs->retry_cmd_in++ >= BAS_RETRY) { |
442 | dev_notice(cs->dev, "control read: timeout, retry %d\n", | ||
443 | ucs->retry_cmd_in); | ||
444 | rc = atread_submit(cs, BAS_TIMEOUT); | ||
445 | if (rc >= 0 || rc == -ENODEV) | ||
446 | /* resubmitted or disconnected */ | ||
447 | /* - bypass regular exit block */ | ||
448 | return; | ||
449 | } else { | ||
450 | dev_err(cs->dev, | 447 | dev_err(cs->dev, |
451 | "control read: timeout, giving up after %d tries\n", | 448 | "control read: timeout, giving up after %d tries\n", |
452 | ucs->retry_cmd_in); | 449 | ucs->retry_cmd_in); |
450 | kfree(ucs->rcvbuf); | ||
451 | ucs->rcvbuf = NULL; | ||
452 | ucs->rcvbuf_size = 0; | ||
453 | error_reset(cs); | ||
454 | return; | ||
455 | } | ||
456 | |||
457 | gig_dbg(DEBUG_USBREQ, "%s: timeout, retry %d", | ||
458 | __func__, ucs->retry_cmd_in); | ||
459 | rc = atread_submit(cs, BAS_TIMEOUT); | ||
460 | if (rc < 0) { | ||
461 | kfree(ucs->rcvbuf); | ||
462 | ucs->rcvbuf = NULL; | ||
463 | ucs->rcvbuf_size = 0; | ||
464 | if (rc != -ENODEV) | ||
465 | error_reset(cs); | ||
453 | } | 466 | } |
454 | kfree(ucs->rcvbuf); | ||
455 | ucs->rcvbuf = NULL; | ||
456 | ucs->rcvbuf_size = 0; | ||
457 | error_reset(cs); | ||
458 | } | 467 | } |
459 | 468 | ||
460 | /* read_ctrl_callback | 469 | /* read_ctrl_callback |
@@ -470,18 +479,11 @@ static void read_ctrl_callback(struct urb *urb) | |||
470 | struct cardstate *cs = inbuf->cs; | 479 | struct cardstate *cs = inbuf->cs; |
471 | struct bas_cardstate *ucs = cs->hw.bas; | 480 | struct bas_cardstate *ucs = cs->hw.bas; |
472 | int status = urb->status; | 481 | int status = urb->status; |
473 | int have_data = 0; | ||
474 | unsigned numbytes; | 482 | unsigned numbytes; |
475 | int rc; | 483 | int rc; |
476 | 484 | ||
477 | update_basstate(ucs, 0, BS_ATRDPEND); | 485 | update_basstate(ucs, 0, BS_ATRDPEND); |
478 | wake_up(&ucs->waitqueue); | 486 | wake_up(&ucs->waitqueue); |
479 | |||
480 | if (!ucs->rcvbuf_size) { | ||
481 | dev_warn(cs->dev, "%s: no receive in progress\n", __func__); | ||
482 | return; | ||
483 | } | ||
484 | |||
485 | del_timer(&ucs->timer_cmd_in); | 487 | del_timer(&ucs->timer_cmd_in); |
486 | 488 | ||
487 | switch (status) { | 489 | switch (status) { |
@@ -495,19 +497,10 @@ static void read_ctrl_callback(struct urb *urb) | |||
495 | numbytes = ucs->rcvbuf_size; | 497 | numbytes = ucs->rcvbuf_size; |
496 | } | 498 | } |
497 | 499 | ||
498 | /* copy received bytes to inbuf */ | 500 | /* copy received bytes to inbuf, notify event layer */ |
499 | have_data = gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes); | 501 | if (gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes)) { |
500 | 502 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); | |
501 | if (unlikely(numbytes < ucs->rcvbuf_size)) { | 503 | gigaset_schedule_event(cs); |
502 | /* incomplete - resubmit for remaining bytes */ | ||
503 | ucs->rcvbuf_size -= numbytes; | ||
504 | ucs->retry_cmd_in = 0; | ||
505 | rc = atread_submit(cs, BAS_TIMEOUT); | ||
506 | if (rc >= 0 || rc == -ENODEV) | ||
507 | /* resubmitted or disconnected */ | ||
508 | /* - bypass regular exit block */ | ||
509 | return; | ||
510 | error_reset(cs); | ||
511 | } | 504 | } |
512 | break; | 505 | break; |
513 | 506 | ||
@@ -516,37 +509,32 @@ static void read_ctrl_callback(struct urb *urb) | |||
516 | case -EINPROGRESS: /* pending */ | 509 | case -EINPROGRESS: /* pending */ |
517 | case -ENODEV: /* device removed */ | 510 | case -ENODEV: /* device removed */ |
518 | case -ESHUTDOWN: /* device shut down */ | 511 | case -ESHUTDOWN: /* device shut down */ |
519 | /* no action necessary */ | 512 | /* no further action necessary */ |
520 | gig_dbg(DEBUG_USBREQ, "%s: %s", | 513 | gig_dbg(DEBUG_USBREQ, "%s: %s", |
521 | __func__, get_usb_statmsg(status)); | 514 | __func__, get_usb_statmsg(status)); |
522 | break; | 515 | break; |
523 | 516 | ||
524 | default: /* severe trouble */ | 517 | default: /* other errors: retry */ |
525 | dev_warn(cs->dev, "control read: %s\n", | ||
526 | get_usb_statmsg(status)); | ||
527 | if (ucs->retry_cmd_in++ < BAS_RETRY) { | 518 | if (ucs->retry_cmd_in++ < BAS_RETRY) { |
528 | dev_notice(cs->dev, "control read: retry %d\n", | 519 | gig_dbg(DEBUG_USBREQ, "%s: %s, retry %d", __func__, |
529 | ucs->retry_cmd_in); | 520 | get_usb_statmsg(status), ucs->retry_cmd_in); |
530 | rc = atread_submit(cs, BAS_TIMEOUT); | 521 | rc = atread_submit(cs, BAS_TIMEOUT); |
531 | if (rc >= 0 || rc == -ENODEV) | 522 | if (rc >= 0) |
532 | /* resubmitted or disconnected */ | 523 | /* successfully resubmitted, skip freeing */ |
533 | /* - bypass regular exit block */ | ||
534 | return; | 524 | return; |
535 | } else { | 525 | if (rc == -ENODEV) |
536 | dev_err(cs->dev, | 526 | /* disconnect, no further action necessary */ |
537 | "control read: giving up after %d tries\n", | 527 | break; |
538 | ucs->retry_cmd_in); | ||
539 | } | 528 | } |
529 | dev_err(cs->dev, "control read: %s, giving up after %d tries\n", | ||
530 | get_usb_statmsg(status), ucs->retry_cmd_in); | ||
540 | error_reset(cs); | 531 | error_reset(cs); |
541 | } | 532 | } |
542 | 533 | ||
534 | /* read finished, free buffer */ | ||
543 | kfree(ucs->rcvbuf); | 535 | kfree(ucs->rcvbuf); |
544 | ucs->rcvbuf = NULL; | 536 | ucs->rcvbuf = NULL; |
545 | ucs->rcvbuf_size = 0; | 537 | ucs->rcvbuf_size = 0; |
546 | if (have_data) { | ||
547 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); | ||
548 | gigaset_schedule_event(cs); | ||
549 | } | ||
550 | } | 538 | } |
551 | 539 | ||
552 | /* atread_submit | 540 | /* atread_submit |
@@ -605,14 +593,67 @@ static int atread_submit(struct cardstate *cs, int timeout) | |||
605 | 593 | ||
606 | if (timeout > 0) { | 594 | if (timeout > 0) { |
607 | gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); | 595 | gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); |
608 | ucs->timer_cmd_in.expires = jiffies + timeout * HZ / 10; | 596 | mod_timer(&ucs->timer_cmd_in, jiffies + timeout * HZ / 10); |
609 | ucs->timer_cmd_in.data = (unsigned long) cs; | ||
610 | ucs->timer_cmd_in.function = cmd_in_timeout; | ||
611 | add_timer(&ucs->timer_cmd_in); | ||
612 | } | 597 | } |
613 | return 0; | 598 | return 0; |
614 | } | 599 | } |
615 | 600 | ||
601 | /* int_in_work | ||
602 | * workqueue routine to clear halt on interrupt in endpoint | ||
603 | */ | ||
604 | |||
605 | static void int_in_work(struct work_struct *work) | ||
606 | { | ||
607 | struct bas_cardstate *ucs = | ||
608 | container_of(work, struct bas_cardstate, int_in_wq); | ||
609 | struct urb *urb = ucs->urb_int_in; | ||
610 | struct cardstate *cs = urb->context; | ||
611 | int rc; | ||
612 | |||
613 | /* clear halt condition */ | ||
614 | rc = usb_clear_halt(ucs->udev, urb->pipe); | ||
615 | gig_dbg(DEBUG_USBREQ, "clear_halt: %s", get_usb_rcmsg(rc)); | ||
616 | if (rc == 0) | ||
617 | /* success, resubmit interrupt read URB */ | ||
618 | rc = usb_submit_urb(urb, GFP_ATOMIC); | ||
619 | if (rc != 0 && rc != -ENODEV) { | ||
620 | dev_err(cs->dev, "clear halt failed: %s\n", get_usb_rcmsg(rc)); | ||
621 | rc = usb_lock_device_for_reset(ucs->udev, ucs->interface); | ||
622 | if (rc == 0) { | ||
623 | rc = usb_reset_device(ucs->udev); | ||
624 | usb_unlock_device(ucs->udev); | ||
625 | } | ||
626 | } | ||
627 | ucs->retry_int_in = 0; | ||
628 | } | ||
629 | |||
630 | /* int_in_resubmit | ||
631 | * timer routine for interrupt read delayed resubmit | ||
632 | * argument: | ||
633 | * controller state structure | ||
634 | */ | ||
635 | static void int_in_resubmit(unsigned long data) | ||
636 | { | ||
637 | struct cardstate *cs = (struct cardstate *) data; | ||
638 | struct bas_cardstate *ucs = cs->hw.bas; | ||
639 | int rc; | ||
640 | |||
641 | if (ucs->retry_int_in++ >= BAS_RETRY) { | ||
642 | dev_err(cs->dev, "interrupt read: giving up after %d tries\n", | ||
643 | ucs->retry_int_in); | ||
644 | usb_queue_reset_device(ucs->interface); | ||
645 | return; | ||
646 | } | ||
647 | |||
648 | gig_dbg(DEBUG_USBREQ, "%s: retry %d", __func__, ucs->retry_int_in); | ||
649 | rc = usb_submit_urb(ucs->urb_int_in, GFP_ATOMIC); | ||
650 | if (rc != 0 && rc != -ENODEV) { | ||
651 | dev_err(cs->dev, "could not resubmit interrupt URB: %s\n", | ||
652 | get_usb_rcmsg(rc)); | ||
653 | usb_queue_reset_device(ucs->interface); | ||
654 | } | ||
655 | } | ||
656 | |||
616 | /* read_int_callback | 657 | /* read_int_callback |
617 | * USB completion handler for interrupt pipe input | 658 | * USB completion handler for interrupt pipe input |
618 | * called by the USB subsystem in interrupt context | 659 | * called by the USB subsystem in interrupt context |
@@ -633,19 +674,29 @@ static void read_int_callback(struct urb *urb) | |||
633 | 674 | ||
634 | switch (status) { | 675 | switch (status) { |
635 | case 0: /* success */ | 676 | case 0: /* success */ |
677 | ucs->retry_int_in = 0; | ||
636 | break; | 678 | break; |
679 | case -EPIPE: /* endpoint stalled */ | ||
680 | schedule_work(&ucs->int_in_wq); | ||
681 | /* fall through */ | ||
637 | case -ENOENT: /* cancelled */ | 682 | case -ENOENT: /* cancelled */ |
638 | case -ECONNRESET: /* cancelled (async) */ | 683 | case -ECONNRESET: /* cancelled (async) */ |
639 | case -EINPROGRESS: /* pending */ | 684 | case -EINPROGRESS: /* pending */ |
640 | /* ignore silently */ | 685 | case -ENODEV: /* device removed */ |
686 | case -ESHUTDOWN: /* device shut down */ | ||
687 | /* no further action necessary */ | ||
641 | gig_dbg(DEBUG_USBREQ, "%s: %s", | 688 | gig_dbg(DEBUG_USBREQ, "%s: %s", |
642 | __func__, get_usb_statmsg(status)); | 689 | __func__, get_usb_statmsg(status)); |
643 | return; | 690 | return; |
644 | case -ENODEV: /* device removed */ | 691 | case -EPROTO: /* protocol error or unplug */ |
645 | case -ESHUTDOWN: /* device shut down */ | 692 | case -EILSEQ: |
646 | gig_dbg(DEBUG_USBREQ, "%s: device disconnected", __func__); | 693 | case -ETIME: |
694 | /* resubmit after delay */ | ||
695 | gig_dbg(DEBUG_USBREQ, "%s: %s", | ||
696 | __func__, get_usb_statmsg(status)); | ||
697 | mod_timer(&ucs->timer_int_in, jiffies + HZ / 10); | ||
647 | return; | 698 | return; |
648 | default: /* severe trouble */ | 699 | default: /* other errors: just resubmit */ |
649 | dev_warn(cs->dev, "interrupt read: %s\n", | 700 | dev_warn(cs->dev, "interrupt read: %s\n", |
650 | get_usb_statmsg(status)); | 701 | get_usb_statmsg(status)); |
651 | goto resubmit; | 702 | goto resubmit; |
@@ -723,6 +774,13 @@ static void read_int_callback(struct urb *urb) | |||
723 | break; | 774 | break; |
724 | } | 775 | } |
725 | spin_lock_irqsave(&cs->lock, flags); | 776 | spin_lock_irqsave(&cs->lock, flags); |
777 | if (ucs->basstate & BS_ATRDPEND) { | ||
778 | spin_unlock_irqrestore(&cs->lock, flags); | ||
779 | dev_warn(cs->dev, | ||
780 | "HD_RECEIVEATDATA_ACK(%d) during HD_READ_ATMESSAGE(%d) ignored\n", | ||
781 | l, ucs->rcvbuf_size); | ||
782 | break; | ||
783 | } | ||
726 | if (ucs->rcvbuf_size) { | 784 | if (ucs->rcvbuf_size) { |
727 | /* throw away previous buffer - we have no queue */ | 785 | /* throw away previous buffer - we have no queue */ |
728 | dev_err(cs->dev, | 786 | dev_err(cs->dev, |
@@ -735,7 +793,6 @@ static void read_int_callback(struct urb *urb) | |||
735 | if (ucs->rcvbuf == NULL) { | 793 | if (ucs->rcvbuf == NULL) { |
736 | spin_unlock_irqrestore(&cs->lock, flags); | 794 | spin_unlock_irqrestore(&cs->lock, flags); |
737 | dev_err(cs->dev, "out of memory receiving AT data\n"); | 795 | dev_err(cs->dev, "out of memory receiving AT data\n"); |
738 | error_reset(cs); | ||
739 | break; | 796 | break; |
740 | } | 797 | } |
741 | ucs->rcvbuf_size = l; | 798 | ucs->rcvbuf_size = l; |
@@ -745,13 +802,10 @@ static void read_int_callback(struct urb *urb) | |||
745 | kfree(ucs->rcvbuf); | 802 | kfree(ucs->rcvbuf); |
746 | ucs->rcvbuf = NULL; | 803 | ucs->rcvbuf = NULL; |
747 | ucs->rcvbuf_size = 0; | 804 | ucs->rcvbuf_size = 0; |
748 | if (rc != -ENODEV) { | ||
749 | spin_unlock_irqrestore(&cs->lock, flags); | ||
750 | error_reset(cs); | ||
751 | break; | ||
752 | } | ||
753 | } | 805 | } |
754 | spin_unlock_irqrestore(&cs->lock, flags); | 806 | spin_unlock_irqrestore(&cs->lock, flags); |
807 | if (rc < 0 && rc != -ENODEV) | ||
808 | error_reset(cs); | ||
755 | break; | 809 | break; |
756 | 810 | ||
757 | case HD_RESET_INTERRUPT_PIPE_ACK: | 811 | case HD_RESET_INTERRUPT_PIPE_ACK: |
@@ -818,6 +872,7 @@ static void read_iso_callback(struct urb *urb) | |||
818 | tasklet_hi_schedule(&ubc->rcvd_tasklet); | 872 | tasklet_hi_schedule(&ubc->rcvd_tasklet); |
819 | } else { | 873 | } else { |
820 | /* tasklet still busy, drop data and resubmit URB */ | 874 | /* tasklet still busy, drop data and resubmit URB */ |
875 | gig_dbg(DEBUG_ISO, "%s: overrun", __func__); | ||
821 | ubc->loststatus = status; | 876 | ubc->loststatus = status; |
822 | for (i = 0; i < BAS_NUMFRAMES; i++) { | 877 | for (i = 0; i < BAS_NUMFRAMES; i++) { |
823 | ubc->isoinlost += urb->iso_frame_desc[i].actual_length; | 878 | ubc->isoinlost += urb->iso_frame_desc[i].actual_length; |
@@ -833,13 +888,11 @@ static void read_iso_callback(struct urb *urb) | |||
833 | urb->dev = bcs->cs->hw.bas->udev; | 888 | urb->dev = bcs->cs->hw.bas->udev; |
834 | urb->transfer_flags = URB_ISO_ASAP; | 889 | urb->transfer_flags = URB_ISO_ASAP; |
835 | urb->number_of_packets = BAS_NUMFRAMES; | 890 | urb->number_of_packets = BAS_NUMFRAMES; |
836 | gig_dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit", | ||
837 | __func__); | ||
838 | rc = usb_submit_urb(urb, GFP_ATOMIC); | 891 | rc = usb_submit_urb(urb, GFP_ATOMIC); |
839 | if (unlikely(rc != 0 && rc != -ENODEV)) { | 892 | if (unlikely(rc != 0 && rc != -ENODEV)) { |
840 | dev_err(bcs->cs->dev, | 893 | dev_err(bcs->cs->dev, |
841 | "could not resubmit isochronous read " | 894 | "could not resubmit isoc read URB: %s\n", |
842 | "URB: %s\n", get_usb_rcmsg(rc)); | 895 | get_usb_rcmsg(rc)); |
843 | dump_urb(DEBUG_ISO, "isoc read", urb); | 896 | dump_urb(DEBUG_ISO, "isoc read", urb); |
844 | error_hangup(bcs); | 897 | error_hangup(bcs); |
845 | } | 898 | } |
@@ -1081,7 +1134,7 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | |||
1081 | gig_dbg(DEBUG_ISO, "%s: disconnected", __func__); | 1134 | gig_dbg(DEBUG_ISO, "%s: disconnected", __func__); |
1082 | else | 1135 | else |
1083 | dev_err(ucx->bcs->cs->dev, | 1136 | dev_err(ucx->bcs->cs->dev, |
1084 | "could not submit isochronous write URB: %s\n", | 1137 | "could not submit isoc write URB: %s\n", |
1085 | get_usb_rcmsg(rc)); | 1138 | get_usb_rcmsg(rc)); |
1086 | return rc; | 1139 | return rc; |
1087 | } | 1140 | } |
@@ -1126,7 +1179,7 @@ static void write_iso_tasklet(unsigned long data) | |||
1126 | ubc->isooutovfl = NULL; | 1179 | ubc->isooutovfl = NULL; |
1127 | spin_unlock_irqrestore(&ubc->isooutlock, flags); | 1180 | spin_unlock_irqrestore(&ubc->isooutlock, flags); |
1128 | if (ovfl) { | 1181 | if (ovfl) { |
1129 | dev_err(cs->dev, "isochronous write buffer underrun\n"); | 1182 | dev_err(cs->dev, "isoc write underrun\n"); |
1130 | error_hangup(bcs); | 1183 | error_hangup(bcs); |
1131 | break; | 1184 | break; |
1132 | } | 1185 | } |
@@ -1151,7 +1204,7 @@ static void write_iso_tasklet(unsigned long data) | |||
1151 | if (next) { | 1204 | if (next) { |
1152 | /* couldn't put it back */ | 1205 | /* couldn't put it back */ |
1153 | dev_err(cs->dev, | 1206 | dev_err(cs->dev, |
1154 | "losing isochronous write URB\n"); | 1207 | "losing isoc write URB\n"); |
1155 | error_hangup(bcs); | 1208 | error_hangup(bcs); |
1156 | } | 1209 | } |
1157 | } | 1210 | } |
@@ -1178,10 +1231,10 @@ static void write_iso_tasklet(unsigned long data) | |||
1178 | if (ifd->status || | 1231 | if (ifd->status || |
1179 | ifd->actual_length != ifd->length) { | 1232 | ifd->actual_length != ifd->length) { |
1180 | dev_warn(cs->dev, | 1233 | dev_warn(cs->dev, |
1181 | "isochronous write: frame %d: %s, " | 1234 | "isoc write: frame %d[%d/%d]: %s\n", |
1182 | "only %d of %d bytes sent\n", | 1235 | i, ifd->actual_length, |
1183 | i, get_usb_statmsg(ifd->status), | 1236 | ifd->length, |
1184 | ifd->actual_length, ifd->length); | 1237 | get_usb_statmsg(ifd->status)); |
1185 | offset = (ifd->offset + | 1238 | offset = (ifd->offset + |
1186 | ifd->actual_length) | 1239 | ifd->actual_length) |
1187 | % BAS_OUTBUFSIZE; | 1240 | % BAS_OUTBUFSIZE; |
@@ -1190,11 +1243,11 @@ static void write_iso_tasklet(unsigned long data) | |||
1190 | } | 1243 | } |
1191 | break; | 1244 | break; |
1192 | case -EPIPE: /* stall - probably underrun */ | 1245 | case -EPIPE: /* stall - probably underrun */ |
1193 | dev_err(cs->dev, "isochronous write stalled\n"); | 1246 | dev_err(cs->dev, "isoc write: stalled\n"); |
1194 | error_hangup(bcs); | 1247 | error_hangup(bcs); |
1195 | break; | 1248 | break; |
1196 | default: /* severe trouble */ | 1249 | default: /* other errors */ |
1197 | dev_warn(cs->dev, "isochronous write: %s\n", | 1250 | dev_warn(cs->dev, "isoc write: %s\n", |
1198 | get_usb_statmsg(status)); | 1251 | get_usb_statmsg(status)); |
1199 | } | 1252 | } |
1200 | 1253 | ||
@@ -1250,6 +1303,7 @@ static void read_iso_tasklet(unsigned long data) | |||
1250 | struct cardstate *cs = bcs->cs; | 1303 | struct cardstate *cs = bcs->cs; |
1251 | struct urb *urb; | 1304 | struct urb *urb; |
1252 | int status; | 1305 | int status; |
1306 | struct usb_iso_packet_descriptor *ifd; | ||
1253 | char *rcvbuf; | 1307 | char *rcvbuf; |
1254 | unsigned long flags; | 1308 | unsigned long flags; |
1255 | int totleft, numbytes, offset, frame, rc; | 1309 | int totleft, numbytes, offset, frame, rc; |
@@ -1267,8 +1321,7 @@ static void read_iso_tasklet(unsigned long data) | |||
1267 | ubc->isoindone = NULL; | 1321 | ubc->isoindone = NULL; |
1268 | if (unlikely(ubc->loststatus != -EINPROGRESS)) { | 1322 | if (unlikely(ubc->loststatus != -EINPROGRESS)) { |
1269 | dev_warn(cs->dev, | 1323 | dev_warn(cs->dev, |
1270 | "isochronous read overrun, " | 1324 | "isoc read overrun, URB dropped (status: %s, %d bytes)\n", |
1271 | "dropped URB with status: %s, %d bytes lost\n", | ||
1272 | get_usb_statmsg(ubc->loststatus), | 1325 | get_usb_statmsg(ubc->loststatus), |
1273 | ubc->isoinlost); | 1326 | ubc->isoinlost); |
1274 | ubc->loststatus = -EINPROGRESS; | 1327 | ubc->loststatus = -EINPROGRESS; |
@@ -1298,11 +1351,11 @@ static void read_iso_tasklet(unsigned long data) | |||
1298 | __func__, get_usb_statmsg(status)); | 1351 | __func__, get_usb_statmsg(status)); |
1299 | continue; /* -> skip */ | 1352 | continue; /* -> skip */ |
1300 | case -EPIPE: | 1353 | case -EPIPE: |
1301 | dev_err(cs->dev, "isochronous read stalled\n"); | 1354 | dev_err(cs->dev, "isoc read: stalled\n"); |
1302 | error_hangup(bcs); | 1355 | error_hangup(bcs); |
1303 | continue; /* -> skip */ | 1356 | continue; /* -> skip */ |
1304 | default: /* severe trouble */ | 1357 | default: /* other error */ |
1305 | dev_warn(cs->dev, "isochronous read: %s\n", | 1358 | dev_warn(cs->dev, "isoc read: %s\n", |
1306 | get_usb_statmsg(status)); | 1359 | get_usb_statmsg(status)); |
1307 | goto error; | 1360 | goto error; |
1308 | } | 1361 | } |
@@ -1310,40 +1363,52 @@ static void read_iso_tasklet(unsigned long data) | |||
1310 | rcvbuf = urb->transfer_buffer; | 1363 | rcvbuf = urb->transfer_buffer; |
1311 | totleft = urb->actual_length; | 1364 | totleft = urb->actual_length; |
1312 | for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) { | 1365 | for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) { |
1313 | numbytes = urb->iso_frame_desc[frame].actual_length; | 1366 | ifd = &urb->iso_frame_desc[frame]; |
1314 | if (unlikely(urb->iso_frame_desc[frame].status)) | 1367 | numbytes = ifd->actual_length; |
1368 | switch (ifd->status) { | ||
1369 | case 0: /* success */ | ||
1370 | break; | ||
1371 | case -EPROTO: /* protocol error or unplug */ | ||
1372 | case -EILSEQ: | ||
1373 | case -ETIME: | ||
1374 | /* probably just disconnected, ignore */ | ||
1375 | gig_dbg(DEBUG_ISO, | ||
1376 | "isoc read: frame %d[%d]: %s\n", | ||
1377 | frame, numbytes, | ||
1378 | get_usb_statmsg(ifd->status)); | ||
1379 | break; | ||
1380 | default: /* other error */ | ||
1381 | /* report, assume transferred bytes are ok */ | ||
1315 | dev_warn(cs->dev, | 1382 | dev_warn(cs->dev, |
1316 | "isochronous read: frame %d[%d]: %s\n", | 1383 | "isoc read: frame %d[%d]: %s\n", |
1317 | frame, numbytes, | 1384 | frame, numbytes, |
1318 | get_usb_statmsg( | 1385 | get_usb_statmsg(ifd->status)); |
1319 | urb->iso_frame_desc[frame].status)); | 1386 | } |
1320 | if (unlikely(numbytes > BAS_MAXFRAME)) | 1387 | if (unlikely(numbytes > BAS_MAXFRAME)) |
1321 | dev_warn(cs->dev, | 1388 | dev_warn(cs->dev, |
1322 | "isochronous read: frame %d: " | 1389 | "isoc read: frame %d[%d]: %s\n", |
1323 | "numbytes (%d) > BAS_MAXFRAME\n", | 1390 | frame, numbytes, |
1324 | frame, numbytes); | 1391 | "exceeds max frame size"); |
1325 | if (unlikely(numbytes > totleft)) { | 1392 | if (unlikely(numbytes > totleft)) { |
1326 | dev_warn(cs->dev, | 1393 | dev_warn(cs->dev, |
1327 | "isochronous read: frame %d: " | 1394 | "isoc read: frame %d[%d]: %s\n", |
1328 | "numbytes (%d) > totleft (%d)\n", | 1395 | frame, numbytes, |
1329 | frame, numbytes, totleft); | 1396 | "exceeds total transfer length"); |
1330 | numbytes = totleft; | 1397 | numbytes = totleft; |
1331 | } | 1398 | } |
1332 | offset = urb->iso_frame_desc[frame].offset; | 1399 | offset = ifd->offset; |
1333 | if (unlikely(offset + numbytes > BAS_INBUFSIZE)) { | 1400 | if (unlikely(offset + numbytes > BAS_INBUFSIZE)) { |
1334 | dev_warn(cs->dev, | 1401 | dev_warn(cs->dev, |
1335 | "isochronous read: frame %d: " | 1402 | "isoc read: frame %d[%d]: %s\n", |
1336 | "offset (%d) + numbytes (%d) " | 1403 | frame, numbytes, |
1337 | "> BAS_INBUFSIZE\n", | 1404 | "exceeds end of buffer"); |
1338 | frame, offset, numbytes); | ||
1339 | numbytes = BAS_INBUFSIZE - offset; | 1405 | numbytes = BAS_INBUFSIZE - offset; |
1340 | } | 1406 | } |
1341 | gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs); | 1407 | gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs); |
1342 | totleft -= numbytes; | 1408 | totleft -= numbytes; |
1343 | } | 1409 | } |
1344 | if (unlikely(totleft > 0)) | 1410 | if (unlikely(totleft > 0)) |
1345 | dev_warn(cs->dev, | 1411 | dev_warn(cs->dev, "isoc read: %d data bytes missing\n", |
1346 | "isochronous read: %d data bytes missing\n", | ||
1347 | totleft); | 1412 | totleft); |
1348 | 1413 | ||
1349 | error: | 1414 | error: |
@@ -1359,9 +1424,9 @@ error: | |||
1359 | rc = usb_submit_urb(urb, GFP_ATOMIC); | 1424 | rc = usb_submit_urb(urb, GFP_ATOMIC); |
1360 | if (unlikely(rc != 0 && rc != -ENODEV)) { | 1425 | if (unlikely(rc != 0 && rc != -ENODEV)) { |
1361 | dev_err(cs->dev, | 1426 | dev_err(cs->dev, |
1362 | "could not resubmit isochronous read URB: %s\n", | 1427 | "could not resubmit isoc read URB: %s\n", |
1363 | get_usb_rcmsg(rc)); | 1428 | get_usb_rcmsg(rc)); |
1364 | dump_urb(DEBUG_ISO, "resubmit iso read", urb); | 1429 | dump_urb(DEBUG_ISO, "resubmit isoc read", urb); |
1365 | error_hangup(bcs); | 1430 | error_hangup(bcs); |
1366 | } | 1431 | } |
1367 | } | 1432 | } |
@@ -1373,12 +1438,12 @@ error: | |||
1373 | /* req_timeout | 1438 | /* req_timeout |
1374 | * timeout routine for control output request | 1439 | * timeout routine for control output request |
1375 | * argument: | 1440 | * argument: |
1376 | * B channel control structure | 1441 | * controller state structure |
1377 | */ | 1442 | */ |
1378 | static void req_timeout(unsigned long data) | 1443 | static void req_timeout(unsigned long data) |
1379 | { | 1444 | { |
1380 | struct bc_state *bcs = (struct bc_state *) data; | 1445 | struct cardstate *cs = (struct cardstate *) data; |
1381 | struct bas_cardstate *ucs = bcs->cs->hw.bas; | 1446 | struct bas_cardstate *ucs = cs->hw.bas; |
1382 | int pending; | 1447 | int pending; |
1383 | unsigned long flags; | 1448 | unsigned long flags; |
1384 | 1449 | ||
@@ -1395,38 +1460,44 @@ static void req_timeout(unsigned long data) | |||
1395 | break; | 1460 | break; |
1396 | 1461 | ||
1397 | case HD_OPEN_ATCHANNEL: | 1462 | case HD_OPEN_ATCHANNEL: |
1398 | dev_err(bcs->cs->dev, "timeout opening AT channel\n"); | 1463 | dev_err(cs->dev, "timeout opening AT channel\n"); |
1399 | error_reset(bcs->cs); | 1464 | error_reset(cs); |
1400 | break; | 1465 | break; |
1401 | 1466 | ||
1402 | case HD_OPEN_B2CHANNEL: | ||
1403 | case HD_OPEN_B1CHANNEL: | 1467 | case HD_OPEN_B1CHANNEL: |
1404 | dev_err(bcs->cs->dev, "timeout opening channel %d\n", | 1468 | dev_err(cs->dev, "timeout opening channel 1\n"); |
1405 | bcs->channel + 1); | 1469 | error_hangup(&cs->bcs[0]); |
1406 | error_hangup(bcs); | 1470 | break; |
1471 | |||
1472 | case HD_OPEN_B2CHANNEL: | ||
1473 | dev_err(cs->dev, "timeout opening channel 2\n"); | ||
1474 | error_hangup(&cs->bcs[1]); | ||
1407 | break; | 1475 | break; |
1408 | 1476 | ||
1409 | case HD_CLOSE_ATCHANNEL: | 1477 | case HD_CLOSE_ATCHANNEL: |
1410 | dev_err(bcs->cs->dev, "timeout closing AT channel\n"); | 1478 | dev_err(cs->dev, "timeout closing AT channel\n"); |
1411 | error_reset(bcs->cs); | 1479 | error_reset(cs); |
1412 | break; | 1480 | break; |
1413 | 1481 | ||
1414 | case HD_CLOSE_B2CHANNEL: | ||
1415 | case HD_CLOSE_B1CHANNEL: | 1482 | case HD_CLOSE_B1CHANNEL: |
1416 | dev_err(bcs->cs->dev, "timeout closing channel %d\n", | 1483 | dev_err(cs->dev, "timeout closing channel 1\n"); |
1417 | bcs->channel + 1); | 1484 | error_reset(cs); |
1418 | error_reset(bcs->cs); | 1485 | break; |
1486 | |||
1487 | case HD_CLOSE_B2CHANNEL: | ||
1488 | dev_err(cs->dev, "timeout closing channel 2\n"); | ||
1489 | error_reset(cs); | ||
1419 | break; | 1490 | break; |
1420 | 1491 | ||
1421 | case HD_RESET_INTERRUPT_PIPE: | 1492 | case HD_RESET_INTERRUPT_PIPE: |
1422 | /* error recovery escalation */ | 1493 | /* error recovery escalation */ |
1423 | dev_err(bcs->cs->dev, | 1494 | dev_err(cs->dev, |
1424 | "reset interrupt pipe timeout, attempting USB reset\n"); | 1495 | "reset interrupt pipe timeout, attempting USB reset\n"); |
1425 | usb_queue_reset_device(bcs->cs->hw.bas->interface); | 1496 | usb_queue_reset_device(ucs->interface); |
1426 | break; | 1497 | break; |
1427 | 1498 | ||
1428 | default: | 1499 | default: |
1429 | dev_warn(bcs->cs->dev, "request 0x%02x timed out, clearing\n", | 1500 | dev_warn(cs->dev, "request 0x%02x timed out, clearing\n", |
1430 | pending); | 1501 | pending); |
1431 | } | 1502 | } |
1432 | 1503 | ||
@@ -1557,10 +1628,7 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout) | |||
1557 | 1628 | ||
1558 | if (timeout > 0) { | 1629 | if (timeout > 0) { |
1559 | gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); | 1630 | gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); |
1560 | ucs->timer_ctrl.expires = jiffies + timeout * HZ / 10; | 1631 | mod_timer(&ucs->timer_ctrl, jiffies + timeout * HZ / 10); |
1561 | ucs->timer_ctrl.data = (unsigned long) bcs; | ||
1562 | ucs->timer_ctrl.function = req_timeout; | ||
1563 | add_timer(&ucs->timer_ctrl); | ||
1564 | } | 1632 | } |
1565 | 1633 | ||
1566 | spin_unlock_irqrestore(&ucs->lock, flags); | 1634 | spin_unlock_irqrestore(&ucs->lock, flags); |
@@ -1590,21 +1658,20 @@ static int gigaset_init_bchannel(struct bc_state *bcs) | |||
1590 | 1658 | ||
1591 | if (cs->hw.bas->basstate & BS_SUSPEND) { | 1659 | if (cs->hw.bas->basstate & BS_SUSPEND) { |
1592 | dev_notice(cs->dev, | 1660 | dev_notice(cs->dev, |
1593 | "not starting isochronous I/O, " | 1661 | "not starting isoc I/O, suspend in progress\n"); |
1594 | "suspend in progress\n"); | ||
1595 | spin_unlock_irqrestore(&cs->lock, flags); | 1662 | spin_unlock_irqrestore(&cs->lock, flags); |
1596 | return -EHOSTUNREACH; | 1663 | return -EHOSTUNREACH; |
1597 | } | 1664 | } |
1598 | 1665 | ||
1599 | ret = starturbs(bcs); | 1666 | ret = starturbs(bcs); |
1600 | if (ret < 0) { | 1667 | if (ret < 0) { |
1668 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1601 | dev_err(cs->dev, | 1669 | dev_err(cs->dev, |
1602 | "could not start isochronous I/O for channel B%d: %s\n", | 1670 | "could not start isoc I/O for channel B%d: %s\n", |
1603 | bcs->channel + 1, | 1671 | bcs->channel + 1, |
1604 | ret == -EFAULT ? "null URB" : get_usb_rcmsg(ret)); | 1672 | ret == -EFAULT ? "null URB" : get_usb_rcmsg(ret)); |
1605 | if (ret != -ENODEV) | 1673 | if (ret != -ENODEV) |
1606 | error_hangup(bcs); | 1674 | error_hangup(bcs); |
1607 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1608 | return ret; | 1675 | return ret; |
1609 | } | 1676 | } |
1610 | 1677 | ||
@@ -1614,11 +1681,11 @@ static int gigaset_init_bchannel(struct bc_state *bcs) | |||
1614 | dev_err(cs->dev, "could not open channel B%d\n", | 1681 | dev_err(cs->dev, "could not open channel B%d\n", |
1615 | bcs->channel + 1); | 1682 | bcs->channel + 1); |
1616 | stopurbs(bcs->hw.bas); | 1683 | stopurbs(bcs->hw.bas); |
1617 | if (ret != -ENODEV) | ||
1618 | error_hangup(bcs); | ||
1619 | } | 1684 | } |
1620 | 1685 | ||
1621 | spin_unlock_irqrestore(&cs->lock, flags); | 1686 | spin_unlock_irqrestore(&cs->lock, flags); |
1687 | if (ret < 0 && ret != -ENODEV) | ||
1688 | error_hangup(bcs); | ||
1622 | return ret; | 1689 | return ret; |
1623 | } | 1690 | } |
1624 | 1691 | ||
@@ -1826,10 +1893,7 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) | |||
1826 | if (!(update_basstate(ucs, BS_ATTIMER, BS_ATREADY) & BS_ATTIMER)) { | 1893 | if (!(update_basstate(ucs, BS_ATTIMER, BS_ATREADY) & BS_ATTIMER)) { |
1827 | gig_dbg(DEBUG_OUTPUT, "setting ATREADY timeout of %d/10 secs", | 1894 | gig_dbg(DEBUG_OUTPUT, "setting ATREADY timeout of %d/10 secs", |
1828 | ATRDY_TIMEOUT); | 1895 | ATRDY_TIMEOUT); |
1829 | ucs->timer_atrdy.expires = jiffies + ATRDY_TIMEOUT * HZ / 10; | 1896 | mod_timer(&ucs->timer_atrdy, jiffies + ATRDY_TIMEOUT * HZ / 10); |
1830 | ucs->timer_atrdy.data = (unsigned long) cs; | ||
1831 | ucs->timer_atrdy.function = atrdy_timeout; | ||
1832 | add_timer(&ucs->timer_atrdy); | ||
1833 | } | 1897 | } |
1834 | return 0; | 1898 | return 0; |
1835 | } | 1899 | } |
@@ -1914,6 +1978,28 @@ static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb) | |||
1914 | * The next command will reopen the AT channel automatically. | 1978 | * The next command will reopen the AT channel automatically. |
1915 | */ | 1979 | */ |
1916 | if (cb->len == 3 && !memcmp(cb->buf, "+++", 3)) { | 1980 | if (cb->len == 3 && !memcmp(cb->buf, "+++", 3)) { |
1981 | /* If an HD_RECEIVEATDATA_ACK message remains unhandled | ||
1982 | * because of an error, the base never sends another one. | ||
1983 | * The response channel is thus effectively blocked. | ||
1984 | * Closing and reopening the AT channel does *not* clear | ||
1985 | * this condition. | ||
1986 | * As a stopgap measure, submit a zero-length AT read | ||
1987 | * before closing the AT channel. This has the undocumented | ||
1988 | * effect of triggering a new HD_RECEIVEATDATA_ACK message | ||
1989 | * from the base if necessary. | ||
1990 | * The subsequent AT channel close then discards any pending | ||
1991 | * messages. | ||
1992 | */ | ||
1993 | spin_lock_irqsave(&cs->lock, flags); | ||
1994 | if (!(cs->hw.bas->basstate & BS_ATRDPEND)) { | ||
1995 | kfree(cs->hw.bas->rcvbuf); | ||
1996 | cs->hw.bas->rcvbuf = NULL; | ||
1997 | cs->hw.bas->rcvbuf_size = 0; | ||
1998 | cs->hw.bas->retry_cmd_in = 0; | ||
1999 | atread_submit(cs, 0); | ||
2000 | } | ||
2001 | spin_unlock_irqrestore(&cs->lock, flags); | ||
2002 | |||
1917 | rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT); | 2003 | rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT); |
1918 | if (cb->wake_tasklet) | 2004 | if (cb->wake_tasklet) |
1919 | tasklet_schedule(cb->wake_tasklet); | 2005 | tasklet_schedule(cb->wake_tasklet); |
@@ -2010,7 +2096,7 @@ static int gigaset_freebcshw(struct bc_state *bcs) | |||
2010 | 2096 | ||
2011 | /* kill URBs and tasklets before freeing - better safe than sorry */ | 2097 | /* kill URBs and tasklets before freeing - better safe than sorry */ |
2012 | ubc->running = 0; | 2098 | ubc->running = 0; |
2013 | gig_dbg(DEBUG_INIT, "%s: killing iso URBs", __func__); | 2099 | gig_dbg(DEBUG_INIT, "%s: killing isoc URBs", __func__); |
2014 | for (i = 0; i < BAS_OUTURBS; ++i) { | 2100 | for (i = 0; i < BAS_OUTURBS; ++i) { |
2015 | usb_kill_urb(ubc->isoouturbs[i].urb); | 2101 | usb_kill_urb(ubc->isoouturbs[i].urb); |
2016 | usb_free_urb(ubc->isoouturbs[i].urb); | 2102 | usb_free_urb(ubc->isoouturbs[i].urb); |
@@ -2131,10 +2217,12 @@ static int gigaset_initcshw(struct cardstate *cs) | |||
2131 | ucs->pending = 0; | 2217 | ucs->pending = 0; |
2132 | 2218 | ||
2133 | ucs->basstate = 0; | 2219 | ucs->basstate = 0; |
2134 | init_timer(&ucs->timer_ctrl); | 2220 | setup_timer(&ucs->timer_ctrl, req_timeout, (unsigned long) cs); |
2135 | init_timer(&ucs->timer_atrdy); | 2221 | setup_timer(&ucs->timer_atrdy, atrdy_timeout, (unsigned long) cs); |
2136 | init_timer(&ucs->timer_cmd_in); | 2222 | setup_timer(&ucs->timer_cmd_in, cmd_in_timeout, (unsigned long) cs); |
2223 | setup_timer(&ucs->timer_int_in, int_in_resubmit, (unsigned long) cs); | ||
2137 | init_waitqueue_head(&ucs->waitqueue); | 2224 | init_waitqueue_head(&ucs->waitqueue); |
2225 | INIT_WORK(&ucs->int_in_wq, int_in_work); | ||
2138 | 2226 | ||
2139 | return 1; | 2227 | return 1; |
2140 | } | 2228 | } |
@@ -2282,6 +2370,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2282 | get_usb_rcmsg(rc)); | 2370 | get_usb_rcmsg(rc)); |
2283 | goto error; | 2371 | goto error; |
2284 | } | 2372 | } |
2373 | ucs->retry_int_in = 0; | ||
2285 | 2374 | ||
2286 | /* tell the device that the driver is ready */ | 2375 | /* tell the device that the driver is ready */ |
2287 | rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0); | 2376 | rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0); |
@@ -2334,10 +2423,12 @@ static void gigaset_disconnect(struct usb_interface *interface) | |||
2334 | /* stop driver (common part) */ | 2423 | /* stop driver (common part) */ |
2335 | gigaset_stop(cs); | 2424 | gigaset_stop(cs); |
2336 | 2425 | ||
2337 | /* stop timers and URBs, free ressources */ | 2426 | /* stop delayed work and URBs, free ressources */ |
2338 | del_timer_sync(&ucs->timer_ctrl); | 2427 | del_timer_sync(&ucs->timer_ctrl); |
2339 | del_timer_sync(&ucs->timer_atrdy); | 2428 | del_timer_sync(&ucs->timer_atrdy); |
2340 | del_timer_sync(&ucs->timer_cmd_in); | 2429 | del_timer_sync(&ucs->timer_cmd_in); |
2430 | del_timer_sync(&ucs->timer_int_in); | ||
2431 | cancel_work_sync(&ucs->int_in_wq); | ||
2341 | freeurbs(cs); | 2432 | freeurbs(cs); |
2342 | usb_set_intfdata(interface, NULL); | 2433 | usb_set_intfdata(interface, NULL); |
2343 | kfree(ucs->rcvbuf); | 2434 | kfree(ucs->rcvbuf); |
@@ -2400,10 +2491,14 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) | |||
2400 | /* in case of timeout, proceed anyway */ | 2491 | /* in case of timeout, proceed anyway */ |
2401 | } | 2492 | } |
2402 | 2493 | ||
2403 | /* kill all URBs and timers that might still be pending */ | 2494 | /* kill all URBs and delayed work that might still be pending */ |
2404 | usb_kill_urb(ucs->urb_ctrl); | 2495 | usb_kill_urb(ucs->urb_ctrl); |
2405 | usb_kill_urb(ucs->urb_int_in); | 2496 | usb_kill_urb(ucs->urb_int_in); |
2406 | del_timer_sync(&ucs->timer_ctrl); | 2497 | del_timer_sync(&ucs->timer_ctrl); |
2498 | del_timer_sync(&ucs->timer_atrdy); | ||
2499 | del_timer_sync(&ucs->timer_cmd_in); | ||
2500 | del_timer_sync(&ucs->timer_int_in); | ||
2501 | cancel_work_sync(&ucs->int_in_wq); | ||
2407 | 2502 | ||
2408 | gig_dbg(DEBUG_SUSPEND, "suspend complete"); | 2503 | gig_dbg(DEBUG_SUSPEND, "suspend complete"); |
2409 | return 0; | 2504 | return 0; |
@@ -2425,6 +2520,7 @@ static int gigaset_resume(struct usb_interface *intf) | |||
2425 | get_usb_rcmsg(rc)); | 2520 | get_usb_rcmsg(rc)); |
2426 | return rc; | 2521 | return rc; |
2427 | } | 2522 | } |
2523 | ucs->retry_int_in = 0; | ||
2428 | 2524 | ||
2429 | /* clear suspend flag to reallow activity */ | 2525 | /* clear suspend flag to reallow activity */ |
2430 | update_basstate(ucs, 0, BS_SUSPEND); | 2526 | update_basstate(ucs, 0, BS_SUSPEND); |
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 3ca561eccd9f..db621db67f61 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
@@ -1026,32 +1026,6 @@ struct cardstate *gigaset_get_cs_by_id(int id) | |||
1026 | return ret; | 1026 | return ret; |
1027 | } | 1027 | } |
1028 | 1028 | ||
1029 | void gigaset_debugdrivers(void) | ||
1030 | { | ||
1031 | unsigned long flags; | ||
1032 | static struct cardstate *cs; | ||
1033 | struct gigaset_driver *drv; | ||
1034 | unsigned i; | ||
1035 | |||
1036 | spin_lock_irqsave(&driver_lock, flags); | ||
1037 | list_for_each_entry(drv, &drivers, list) { | ||
1038 | gig_dbg(DEBUG_DRIVER, "driver %p", drv); | ||
1039 | spin_lock(&drv->lock); | ||
1040 | for (i = 0; i < drv->minors; ++i) { | ||
1041 | gig_dbg(DEBUG_DRIVER, " index %u", i); | ||
1042 | cs = drv->cs + i; | ||
1043 | gig_dbg(DEBUG_DRIVER, " cardstate %p", cs); | ||
1044 | gig_dbg(DEBUG_DRIVER, " flags 0x%02x", cs->flags); | ||
1045 | gig_dbg(DEBUG_DRIVER, " minor_index %u", | ||
1046 | cs->minor_index); | ||
1047 | gig_dbg(DEBUG_DRIVER, " driver %p", cs->driver); | ||
1048 | gig_dbg(DEBUG_DRIVER, " i4l id %d", cs->myid); | ||
1049 | } | ||
1050 | spin_unlock(&drv->lock); | ||
1051 | } | ||
1052 | spin_unlock_irqrestore(&driver_lock, flags); | ||
1053 | } | ||
1054 | |||
1055 | static struct cardstate *gigaset_get_cs_by_minor(unsigned minor) | 1029 | static struct cardstate *gigaset_get_cs_by_minor(unsigned minor) |
1056 | { | 1030 | { |
1057 | unsigned long flags; | 1031 | unsigned long flags; |
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index a69512fb1195..6dd360734cfd 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h | |||
@@ -70,7 +70,6 @@ enum debuglevel { | |||
70 | DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */ | 70 | DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */ |
71 | DEBUG_LLDATA = 0x00100, /* sent/received LL data */ | 71 | DEBUG_LLDATA = 0x00100, /* sent/received LL data */ |
72 | DEBUG_EVENT = 0x00200, /* event processing */ | 72 | DEBUG_EVENT = 0x00200, /* event processing */ |
73 | DEBUG_DRIVER = 0x00400, /* driver structure */ | ||
74 | DEBUG_HDLC = 0x00800, /* M10x HDLC processing */ | 73 | DEBUG_HDLC = 0x00800, /* M10x HDLC processing */ |
75 | DEBUG_CHANNEL = 0x01000, /* channel allocation/deallocation */ | 74 | DEBUG_CHANNEL = 0x01000, /* channel allocation/deallocation */ |
76 | DEBUG_TRANSCMD = 0x02000, /* AT-COMMANDS+RESPONSES */ | 75 | DEBUG_TRANSCMD = 0x02000, /* AT-COMMANDS+RESPONSES */ |
@@ -727,7 +726,7 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | |||
727 | 726 | ||
728 | /* Deallocate driver structure. */ | 727 | /* Deallocate driver structure. */ |
729 | void gigaset_freedriver(struct gigaset_driver *drv); | 728 | void gigaset_freedriver(struct gigaset_driver *drv); |
730 | void gigaset_debugdrivers(void); | 729 | |
731 | struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty); | 730 | struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty); |
732 | struct cardstate *gigaset_get_cs_by_id(int id); | 731 | struct cardstate *gigaset_get_cs_by_id(int id); |
733 | void gigaset_blockdriver(struct gigaset_driver *drv); | 732 | void gigaset_blockdriver(struct gigaset_driver *drv); |
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c index 34bca37d65b9..9bec8b969964 100644 --- a/drivers/isdn/gigaset/i4l.c +++ b/drivers/isdn/gigaset/i4l.c | |||
@@ -201,8 +201,6 @@ static int command_from_LL(isdn_ctrl *cntrl) | |||
201 | int i; | 201 | int i; |
202 | size_t l; | 202 | size_t l; |
203 | 203 | ||
204 | gigaset_debugdrivers(); | ||
205 | |||
206 | gig_dbg(DEBUG_CMD, "driver: %d, command: %d, arg: 0x%lx", | 204 | gig_dbg(DEBUG_CMD, "driver: %d, command: %d, arg: 0x%lx", |
207 | cntrl->driver, cntrl->command, cntrl->arg); | 205 | cntrl->driver, cntrl->command, cntrl->arg); |
208 | 206 | ||
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c index 2dfd346fc889..f39ccdf87a17 100644 --- a/drivers/isdn/gigaset/isocdata.c +++ b/drivers/isdn/gigaset/isocdata.c | |||
@@ -842,13 +842,14 @@ static inline void trans_receive(unsigned char *src, unsigned count, | |||
842 | 842 | ||
843 | if (unlikely(bcs->ignore)) { | 843 | if (unlikely(bcs->ignore)) { |
844 | bcs->ignore--; | 844 | bcs->ignore--; |
845 | hdlc_flush(bcs); | ||
846 | return; | 845 | return; |
847 | } | 846 | } |
848 | skb = bcs->rx_skb; | 847 | skb = bcs->rx_skb; |
849 | if (skb == NULL) | 848 | if (skb == NULL) { |
850 | skb = gigaset_new_rx_skb(bcs); | 849 | skb = gigaset_new_rx_skb(bcs); |
851 | bcs->hw.bas->goodbytes += skb->len; | 850 | if (skb == NULL) |
851 | return; | ||
852 | } | ||
852 | dobytes = bcs->rx_bufsize - skb->len; | 853 | dobytes = bcs->rx_bufsize - skb->len; |
853 | while (count > 0) { | 854 | while (count > 0) { |
854 | dst = skb_put(skb, count < dobytes ? count : dobytes); | 855 | dst = skb_put(skb, count < dobytes ? count : dobytes); |
@@ -860,6 +861,7 @@ static inline void trans_receive(unsigned char *src, unsigned count, | |||
860 | if (dobytes == 0) { | 861 | if (dobytes == 0) { |
861 | dump_bytes(DEBUG_STREAM_DUMP, | 862 | dump_bytes(DEBUG_STREAM_DUMP, |
862 | "rcv data", skb->data, skb->len); | 863 | "rcv data", skb->data, skb->len); |
864 | bcs->hw.bas->goodbytes += skb->len; | ||
863 | gigaset_skb_rcvd(bcs, skb); | 865 | gigaset_skb_rcvd(bcs, skb); |
864 | skb = gigaset_new_rx_skb(bcs); | 866 | skb = gigaset_new_rx_skb(bcs); |
865 | if (skb == NULL) | 867 | if (skb == NULL) |
diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c index 33ce89eed65b..362640120886 100644 --- a/drivers/isdn/hardware/eicon/debug.c +++ b/drivers/isdn/hardware/eicon/debug.c | |||
@@ -862,7 +862,7 @@ void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) { | |||
862 | diva_os_spin_lock_magic_t old_irql, old_irql1; | 862 | diva_os_spin_lock_magic_t old_irql, old_irql1; |
863 | dword sec, usec, logical, serial, org_mask; | 863 | dword sec, usec, logical, serial, org_mask; |
864 | int id, best_id = 0, free_id = -1; | 864 | int id, best_id = 0, free_id = -1; |
865 | char tmp[256]; | 865 | char tmp[128]; |
866 | diva_dbg_entry_head_t* pmsg = NULL; | 866 | diva_dbg_entry_head_t* pmsg = NULL; |
867 | int len; | 867 | int len; |
868 | word size; | 868 | word size; |
diff --git a/drivers/isdn/hardware/eicon/debuglib.h b/drivers/isdn/hardware/eicon/debuglib.h index 8ea587783e14..02eed6b4354c 100644 --- a/drivers/isdn/hardware/eicon/debuglib.h +++ b/drivers/isdn/hardware/eicon/debuglib.h | |||
@@ -249,7 +249,7 @@ typedef struct _DbgHandle_ | |||
249 | } regTime ; /* timestamp for registration */ | 249 | } regTime ; /* timestamp for registration */ |
250 | void *pIrp ; /* ptr to pending i/o request */ | 250 | void *pIrp ; /* ptr to pending i/o request */ |
251 | unsigned long dbgMask ; /* current debug mask */ | 251 | unsigned long dbgMask ; /* current debug mask */ |
252 | char drvName[16] ; /* ASCII name of registered driver */ | 252 | char drvName[128] ; /* ASCII name of registered driver */ |
253 | char drvTag[64] ; /* revision string */ | 253 | char drvTag[64] ; /* revision string */ |
254 | DbgEnd dbg_end ; /* function for debug closing */ | 254 | DbgEnd dbg_end ; /* function for debug closing */ |
255 | DbgLog dbg_prt ; /* function for debug appending */ | 255 | DbgLog dbg_prt ; /* function for debug appending */ |
diff --git a/drivers/isdn/hisax/hfc_sx.c b/drivers/isdn/hisax/hfc_sx.c index be5faf4aa868..5aa138eb0b3c 100644 --- a/drivers/isdn/hisax/hfc_sx.c +++ b/drivers/isdn/hisax/hfc_sx.c | |||
@@ -234,13 +234,14 @@ read_fifo(struct IsdnCardState *cs, u_char fifo, int trans_max) | |||
234 | count++; | 234 | count++; |
235 | if (count > trans_max) | 235 | if (count > trans_max) |
236 | count = trans_max; /* limit length */ | 236 | count = trans_max; /* limit length */ |
237 | if ((skb = dev_alloc_skb(count))) { | 237 | skb = dev_alloc_skb(count); |
238 | dst = skb_put(skb, count); | 238 | if (skb) { |
239 | while (count--) | 239 | dst = skb_put(skb, count); |
240 | while (count--) | ||
240 | *dst++ = Read_hfc(cs, HFCSX_FIF_DRD); | 241 | *dst++ = Read_hfc(cs, HFCSX_FIF_DRD); |
241 | return(skb); | 242 | return skb; |
242 | } | 243 | } else |
243 | else return(NULL); /* no memory */ | 244 | return NULL; /* no memory */ |
244 | } | 245 | } |
245 | 246 | ||
246 | do { | 247 | do { |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 51dc60da333b..c463162843ba 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/isdn.h> | 14 | #include <linux/isdn.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/smp_lock.h> | 17 | #include <linux/mutex.h> |
18 | #include "isdn_common.h" | 18 | #include "isdn_common.h" |
19 | #include "isdn_tty.h" | 19 | #include "isdn_tty.h" |
20 | #ifdef CONFIG_ISDN_AUDIO | 20 | #ifdef CONFIG_ISDN_AUDIO |
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | /* Prototypes */ | 29 | /* Prototypes */ |
30 | 30 | ||
31 | static DEFINE_MUTEX(modem_info_mutex); | ||
31 | static int isdn_tty_edit_at(const char *, int, modem_info *); | 32 | static int isdn_tty_edit_at(const char *, int, modem_info *); |
32 | static void isdn_tty_check_esc(const u_char *, u_char, int, int *, u_long *); | 33 | static void isdn_tty_check_esc(const u_char *, u_char, int, int *, u_long *); |
33 | static void isdn_tty_modem_reset_regs(modem_info *, int); | 34 | static void isdn_tty_modem_reset_regs(modem_info *, int); |
@@ -1354,14 +1355,14 @@ isdn_tty_tiocmget(struct tty_struct *tty, struct file *file) | |||
1354 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1355 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1355 | return -EIO; | 1356 | return -EIO; |
1356 | 1357 | ||
1357 | lock_kernel(); | 1358 | mutex_lock(&modem_info_mutex); |
1358 | #ifdef ISDN_DEBUG_MODEM_IOCTL | 1359 | #ifdef ISDN_DEBUG_MODEM_IOCTL |
1359 | printk(KERN_DEBUG "ttyI%d ioctl TIOCMGET\n", info->line); | 1360 | printk(KERN_DEBUG "ttyI%d ioctl TIOCMGET\n", info->line); |
1360 | #endif | 1361 | #endif |
1361 | 1362 | ||
1362 | control = info->mcr; | 1363 | control = info->mcr; |
1363 | status = info->msr; | 1364 | status = info->msr; |
1364 | unlock_kernel(); | 1365 | mutex_unlock(&modem_info_mutex); |
1365 | return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | 1366 | return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) |
1366 | | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | 1367 | | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) |
1367 | | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) | 1368 | | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) |
@@ -1385,7 +1386,7 @@ isdn_tty_tiocmset(struct tty_struct *tty, struct file *file, | |||
1385 | printk(KERN_DEBUG "ttyI%d ioctl TIOCMxxx: %x %x\n", info->line, set, clear); | 1386 | printk(KERN_DEBUG "ttyI%d ioctl TIOCMxxx: %x %x\n", info->line, set, clear); |
1386 | #endif | 1387 | #endif |
1387 | 1388 | ||
1388 | lock_kernel(); | 1389 | mutex_lock(&modem_info_mutex); |
1389 | if (set & TIOCM_RTS) | 1390 | if (set & TIOCM_RTS) |
1390 | info->mcr |= UART_MCR_RTS; | 1391 | info->mcr |= UART_MCR_RTS; |
1391 | if (set & TIOCM_DTR) { | 1392 | if (set & TIOCM_DTR) { |
@@ -1407,7 +1408,7 @@ isdn_tty_tiocmset(struct tty_struct *tty, struct file *file, | |||
1407 | isdn_tty_modem_hup(info, 1); | 1408 | isdn_tty_modem_hup(info, 1); |
1408 | } | 1409 | } |
1409 | } | 1410 | } |
1410 | unlock_kernel(); | 1411 | mutex_unlock(&modem_info_mutex); |
1411 | return 0; | 1412 | return 0; |
1412 | } | 1413 | } |
1413 | 1414 | ||
@@ -3515,7 +3516,7 @@ isdn_tty_parse_at(modem_info * info) | |||
3515 | { | 3516 | { |
3516 | atemu *m = &info->emu; | 3517 | atemu *m = &info->emu; |
3517 | char *p; | 3518 | char *p; |
3518 | char ds[40]; | 3519 | char ds[ISDN_MSNLEN]; |
3519 | 3520 | ||
3520 | #ifdef ISDN_DEBUG_AT | 3521 | #ifdef ISDN_DEBUG_AT |
3521 | printk(KERN_DEBUG "AT: '%s'\n", m->mdmcmd); | 3522 | printk(KERN_DEBUG "AT: '%s'\n", m->mdmcmd); |
@@ -3594,7 +3595,7 @@ isdn_tty_parse_at(modem_info * info) | |||
3594 | break; | 3595 | break; |
3595 | case '3': | 3596 | case '3': |
3596 | p++; | 3597 | p++; |
3597 | sprintf(ds, "\r\n%d", info->emu.charge); | 3598 | snprintf(ds, sizeof(ds), "\r\n%d", info->emu.charge); |
3598 | isdn_tty_at_cout(ds, info); | 3599 | isdn_tty_at_cout(ds, info); |
3599 | break; | 3600 | break; |
3600 | default:; | 3601 | default:; |
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c index 713ef2b805a2..76d9e673b4e1 100644 --- a/drivers/isdn/mISDN/dsp_cmx.c +++ b/drivers/isdn/mISDN/dsp_cmx.c | |||
@@ -1237,6 +1237,7 @@ dsp_cmx_receive(struct dsp *dsp, struct sk_buff *skb) | |||
1237 | if (dsp->cmx_delay) | 1237 | if (dsp->cmx_delay) |
1238 | dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) | 1238 | dsp->rx_W = (dsp->rx_R + dsp->cmx_delay) |
1239 | & CMX_BUFF_MASK; | 1239 | & CMX_BUFF_MASK; |
1240 | else | ||
1240 | dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1)) | 1241 | dsp->rx_W = (dsp->rx_R + (dsp_poll >> 1)) |
1241 | & CMX_BUFF_MASK; | 1242 | & CMX_BUFF_MASK; |
1242 | } else { | 1243 | } else { |
diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 22f38e48ac4e..5b59796ed250 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c | |||
@@ -972,7 +972,7 @@ channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq) | |||
972 | if (debug & DEBUG_L1OIP_SOCKET) | 972 | if (debug & DEBUG_L1OIP_SOCKET) |
973 | printk(KERN_DEBUG "%s: got new ip address from user " | 973 | printk(KERN_DEBUG "%s: got new ip address from user " |
974 | "space.\n", __func__); | 974 | "space.\n", __func__); |
975 | l1oip_socket_open(hc); | 975 | l1oip_socket_open(hc); |
976 | break; | 976 | break; |
977 | case MISDN_CTRL_UNSETPEER: | 977 | case MISDN_CTRL_UNSETPEER: |
978 | if (debug & DEBUG_L1OIP_SOCKET) | 978 | if (debug & DEBUG_L1OIP_SOCKET) |
diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c index b159bd59e64e..a5b632e67552 100644 --- a/drivers/isdn/mISDN/stack.c +++ b/drivers/isdn/mISDN/stack.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/mISDNif.h> | 19 | #include <linux/mISDNif.h> |
20 | #include <linux/kthread.h> | 20 | #include <linux/kthread.h> |
21 | #include <linux/smp_lock.h> | ||
22 | #include "core.h" | 21 | #include "core.h" |
23 | 22 | ||
24 | static u_int *debug; | 23 | static u_int *debug; |
@@ -205,13 +204,7 @@ mISDNStackd(void *data) | |||
205 | struct mISDNstack *st = data; | 204 | struct mISDNstack *st = data; |
206 | int err = 0; | 205 | int err = 0; |
207 | 206 | ||
208 | #ifdef CONFIG_SMP | ||
209 | lock_kernel(); | ||
210 | #endif | ||
211 | sigfillset(¤t->blocked); | 207 | sigfillset(¤t->blocked); |
212 | #ifdef CONFIG_SMP | ||
213 | unlock_kernel(); | ||
214 | #endif | ||
215 | if (*debug & DEBUG_MSG_THREAD) | 208 | if (*debug & DEBUG_MSG_THREAD) |
216 | printk(KERN_DEBUG "mISDNStackd %s started\n", | 209 | printk(KERN_DEBUG "mISDNStackd %s started\n", |
217 | dev_name(&st->dev->dev)); | 210 | dev_name(&st->dev->dev)); |
diff --git a/drivers/isdn/pcbit/edss1.c b/drivers/isdn/pcbit/edss1.c index d5920ae22d73..80c9c16fd5ef 100644 --- a/drivers/isdn/pcbit/edss1.c +++ b/drivers/isdn/pcbit/edss1.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include "callbacks.h" | 33 | #include "callbacks.h" |
34 | 34 | ||
35 | 35 | ||
36 | char * isdn_state_table[] = { | 36 | const char * const isdn_state_table[] = { |
37 | "Closed", | 37 | "Closed", |
38 | "Call initiated", | 38 | "Call initiated", |
39 | "Overlap sending", | 39 | "Overlap sending", |
diff --git a/drivers/isdn/pcbit/edss1.h b/drivers/isdn/pcbit/edss1.h index 0b64f97015d8..39f8346e28c5 100644 --- a/drivers/isdn/pcbit/edss1.h +++ b/drivers/isdn/pcbit/edss1.h | |||
@@ -90,7 +90,7 @@ struct fsm_timer_entry { | |||
90 | unsigned long timeout; /* in seconds */ | 90 | unsigned long timeout; /* in seconds */ |
91 | }; | 91 | }; |
92 | 92 | ||
93 | extern char * isdn_state_table[]; | 93 | extern const char * const isdn_state_table[]; |
94 | 94 | ||
95 | void pcbit_fsm_event(struct pcbit_dev *, struct pcbit_chan *, | 95 | void pcbit_fsm_event(struct pcbit_dev *, struct pcbit_chan *, |
96 | unsigned short event, struct callb_data *); | 96 | unsigned short event, struct callb_data *); |