diff options
Diffstat (limited to 'drivers/isdn')
32 files changed, 393 insertions, 736 deletions
diff --git a/drivers/isdn/act2000/act2000.h b/drivers/isdn/act2000/act2000.h index d4c50512a1ff..88c9423500d8 100644 --- a/drivers/isdn/act2000/act2000.h +++ b/drivers/isdn/act2000/act2000.h | |||
@@ -141,9 +141,9 @@ typedef struct irq_data_isa { | |||
141 | __u8 rcvhdr[8]; | 141 | __u8 rcvhdr[8]; |
142 | } irq_data_isa; | 142 | } irq_data_isa; |
143 | 143 | ||
144 | typedef union irq_data { | 144 | typedef union act2000_irq_data { |
145 | irq_data_isa isa; | 145 | irq_data_isa isa; |
146 | } irq_data; | 146 | } act2000_irq_data; |
147 | 147 | ||
148 | /* | 148 | /* |
149 | * Per card driver data | 149 | * Per card driver data |
@@ -176,7 +176,7 @@ typedef struct act2000_card { | |||
176 | char *status_buf_read; | 176 | char *status_buf_read; |
177 | char *status_buf_write; | 177 | char *status_buf_write; |
178 | char *status_buf_end; | 178 | char *status_buf_end; |
179 | irq_data idat; /* Data used for IRQ handler */ | 179 | act2000_irq_data idat; /* Data used for IRQ handler */ |
180 | isdn_if interface; /* Interface to upper layer */ | 180 | isdn_if interface; /* Interface to upper layer */ |
181 | char regname[35]; /* Name used for request_region */ | 181 | char regname[35]; /* Name used for request_region */ |
182 | } act2000_card; | 182 | } act2000_card; |
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/avm/Kconfig b/drivers/isdn/hardware/avm/Kconfig index 5dbcbe3a54a6..b99b906ea9b1 100644 --- a/drivers/isdn/hardware/avm/Kconfig +++ b/drivers/isdn/hardware/avm/Kconfig | |||
@@ -36,12 +36,13 @@ config ISDN_DRV_AVMB1_T1ISA | |||
36 | 36 | ||
37 | config ISDN_DRV_AVMB1_B1PCMCIA | 37 | config ISDN_DRV_AVMB1_B1PCMCIA |
38 | tristate "AVM B1/M1/M2 PCMCIA support" | 38 | tristate "AVM B1/M1/M2 PCMCIA support" |
39 | depends on PCMCIA | ||
39 | help | 40 | help |
40 | Enable support for the PCMCIA version of the AVM B1 card. | 41 | Enable support for the PCMCIA version of the AVM B1 card. |
41 | 42 | ||
42 | config ISDN_DRV_AVMB1_AVM_CS | 43 | config ISDN_DRV_AVMB1_AVM_CS |
43 | tristate "AVM B1/M1/M2 PCMCIA cs module" | 44 | tristate "AVM B1/M1/M2 PCMCIA cs module" |
44 | depends on ISDN_DRV_AVMB1_B1PCMCIA && PCMCIA | 45 | depends on ISDN_DRV_AVMB1_B1PCMCIA |
45 | help | 46 | help |
46 | Enable the PCMCIA client driver for the AVM B1/M1/M2 | 47 | Enable the PCMCIA client driver for the AVM B1/M1/M2 |
47 | PCMCIA cards. | 48 | PCMCIA cards. |
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index 09b1795516f4..91f06a3ef002 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <asm/io.h> | 20 | #include <asm/io.h> |
21 | #include <asm/system.h> | 21 | #include <asm/system.h> |
22 | 22 | ||
23 | #include <pcmcia/cs.h> | ||
24 | #include <pcmcia/cistpl.h> | 23 | #include <pcmcia/cistpl.h> |
25 | #include <pcmcia/ciscode.h> | 24 | #include <pcmcia/ciscode.h> |
26 | #include <pcmcia/ds.h> | 25 | #include <pcmcia/ds.h> |
@@ -39,87 +38,32 @@ MODULE_LICENSE("GPL"); | |||
39 | 38 | ||
40 | /*====================================================================*/ | 39 | /*====================================================================*/ |
41 | 40 | ||
42 | /* | ||
43 | The event() function is this driver's Card Services event handler. | ||
44 | It will be called by Card Services when an appropriate card status | ||
45 | event is received. The config() and release() entry points are | ||
46 | used to configure or release a socket, in response to card insertion | ||
47 | and ejection events. They are invoked from the skeleton event | ||
48 | handler. | ||
49 | */ | ||
50 | |||
51 | static int avmcs_config(struct pcmcia_device *link); | 41 | static int avmcs_config(struct pcmcia_device *link); |
52 | static void avmcs_release(struct pcmcia_device *link); | 42 | static void avmcs_release(struct pcmcia_device *link); |
53 | |||
54 | /* | ||
55 | The attach() and detach() entry points are used to create and destroy | ||
56 | "instances" of the driver, where each instance represents everything | ||
57 | needed to manage one actual PCMCIA card. | ||
58 | */ | ||
59 | |||
60 | static void avmcs_detach(struct pcmcia_device *p_dev); | 43 | static void avmcs_detach(struct pcmcia_device *p_dev); |
61 | 44 | ||
62 | /*====================================================================== | ||
63 | |||
64 | avmcs_attach() creates an "instance" of the driver, allocating | ||
65 | local data structures for one device. The device is registered | ||
66 | with Card Services. | ||
67 | |||
68 | The dev_link structure is initialized, but we don't actually | ||
69 | configure the card at this point -- we wait until we receive a | ||
70 | card insertion event. | ||
71 | |||
72 | ======================================================================*/ | ||
73 | |||
74 | static int avmcs_probe(struct pcmcia_device *p_dev) | 45 | static int avmcs_probe(struct pcmcia_device *p_dev) |
75 | { | 46 | { |
76 | |||
77 | /* The io structure describes IO port mapping */ | ||
78 | p_dev->resource[0]->end = 16; | ||
79 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | ||
80 | |||
81 | /* General socket configuration */ | 47 | /* General socket configuration */ |
82 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; | 48 | p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; |
83 | p_dev->conf.IntType = INT_MEMORY_AND_IO; | 49 | p_dev->config_index = 1; |
84 | p_dev->conf.ConfigIndex = 1; | 50 | p_dev->config_regs = PRESENT_OPTION; |
85 | p_dev->conf.Present = PRESENT_OPTION; | ||
86 | 51 | ||
87 | return avmcs_config(p_dev); | 52 | return avmcs_config(p_dev); |
88 | } /* avmcs_attach */ | 53 | } /* avmcs_attach */ |
89 | 54 | ||
90 | /*====================================================================== | ||
91 | |||
92 | This deletes a driver "instance". The device is de-registered | ||
93 | with Card Services. If it has been released, all local data | ||
94 | structures are freed. Otherwise, the structures will be freed | ||
95 | when the device is released. | ||
96 | |||
97 | ======================================================================*/ | ||
98 | 55 | ||
99 | static void avmcs_detach(struct pcmcia_device *link) | 56 | static void avmcs_detach(struct pcmcia_device *link) |
100 | { | 57 | { |
101 | avmcs_release(link); | 58 | avmcs_release(link); |
102 | } /* avmcs_detach */ | 59 | } /* avmcs_detach */ |
103 | 60 | ||
104 | /*====================================================================== | 61 | static int avmcs_configcheck(struct pcmcia_device *p_dev, void *priv_data) |
105 | |||
106 | avmcs_config() is scheduled to run after a CARD_INSERTION event | ||
107 | is received, to configure the PCMCIA socket, and to make the | ||
108 | ethernet device available to the system. | ||
109 | |||
110 | ======================================================================*/ | ||
111 | |||
112 | static int avmcs_configcheck(struct pcmcia_device *p_dev, | ||
113 | cistpl_cftable_entry_t *cf, | ||
114 | cistpl_cftable_entry_t *dflt, | ||
115 | unsigned int vcc, | ||
116 | void *priv_data) | ||
117 | { | 62 | { |
118 | if (cf->io.nwin <= 0) | 63 | p_dev->resource[0]->end = 16; |
119 | return -ENODEV; | 64 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
65 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | ||
120 | 66 | ||
121 | p_dev->resource[0]->start = cf->io.win[0].base; | ||
122 | p_dev->resource[0]->end = cf->io.win[0].len; | ||
123 | return pcmcia_request_io(p_dev); | 67 | return pcmcia_request_io(p_dev); |
124 | } | 68 | } |
125 | 69 | ||
@@ -150,7 +94,7 @@ static int avmcs_config(struct pcmcia_device *link) | |||
150 | /* | 94 | /* |
151 | * configure the PCMCIA socket | 95 | * configure the PCMCIA socket |
152 | */ | 96 | */ |
153 | i = pcmcia_request_configuration(link, &link->conf); | 97 | i = pcmcia_enable_device(link); |
154 | if (i != 0) { | 98 | if (i != 0) { |
155 | pcmcia_disable_device(link); | 99 | pcmcia_disable_device(link); |
156 | break; | 100 | break; |
@@ -197,13 +141,6 @@ static int avmcs_config(struct pcmcia_device *link) | |||
197 | 141 | ||
198 | } /* avmcs_config */ | 142 | } /* avmcs_config */ |
199 | 143 | ||
200 | /*====================================================================== | ||
201 | |||
202 | After a card is removed, avmcs_release() will unregister the net | ||
203 | device, and release the PCMCIA configuration. If the device is | ||
204 | still open, this will be postponed until it is closed. | ||
205 | |||
206 | ======================================================================*/ | ||
207 | 144 | ||
208 | static void avmcs_release(struct pcmcia_device *link) | 145 | static void avmcs_release(struct pcmcia_device *link) |
209 | { | 146 | { |
@@ -222,9 +159,7 @@ MODULE_DEVICE_TABLE(pcmcia, avmcs_ids); | |||
222 | 159 | ||
223 | static struct pcmcia_driver avmcs_driver = { | 160 | static struct pcmcia_driver avmcs_driver = { |
224 | .owner = THIS_MODULE, | 161 | .owner = THIS_MODULE, |
225 | .drv = { | 162 | .name = "avm_cs", |
226 | .name = "avm_cs", | ||
227 | }, | ||
228 | .probe = avmcs_probe, | 163 | .probe = avmcs_probe, |
229 | .remove = avmcs_detach, | 164 | .remove = avmcs_detach, |
230 | .id_table = avmcs_ids, | 165 | .id_table = avmcs_ids, |
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c index 7715d3242ec8..d3530f6e8115 100644 --- a/drivers/isdn/hardware/avm/c4.c +++ b/drivers/isdn/hardware/avm/c4.c | |||
@@ -1273,6 +1273,7 @@ static int __devinit c4_probe(struct pci_dev *dev, | |||
1273 | if (retval != 0) { | 1273 | if (retval != 0) { |
1274 | printk(KERN_ERR "c4: no AVM-C%d at i/o %#x, irq %d detected, mem %#x\n", | 1274 | printk(KERN_ERR "c4: no AVM-C%d at i/o %#x, irq %d detected, mem %#x\n", |
1275 | nr, param.port, param.irq, param.membase); | 1275 | nr, param.port, param.irq, param.membase); |
1276 | pci_disable_device(dev); | ||
1276 | return -ENODEV; | 1277 | return -ENODEV; |
1277 | } | 1278 | } |
1278 | return 0; | 1279 | return 0; |
diff --git a/drivers/isdn/hardware/avm/t1pci.c b/drivers/isdn/hardware/avm/t1pci.c index 5a3f83098018..a79eb5afb92d 100644 --- a/drivers/isdn/hardware/avm/t1pci.c +++ b/drivers/isdn/hardware/avm/t1pci.c | |||
@@ -210,6 +210,7 @@ static int __devinit t1pci_probe(struct pci_dev *dev, | |||
210 | if (retval != 0) { | 210 | if (retval != 0) { |
211 | printk(KERN_ERR "t1pci: no AVM-T1-PCI at i/o %#x, irq %d detected, mem %#x\n", | 211 | printk(KERN_ERR "t1pci: no AVM-T1-PCI at i/o %#x, irq %d detected, mem %#x\n", |
212 | param.port, param.irq, param.membase); | 212 | param.port, param.irq, param.membase); |
213 | pci_disable_device(dev); | ||
213 | return -ENODEV; | 214 | return -ENODEV; |
214 | } | 215 | } |
215 | return 0; | 216 | return 0; |
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/hardware/eicon/divasmain.c b/drivers/isdn/hardware/eicon/divasmain.c index ed9c55506797..f332b60eff6b 100644 --- a/drivers/isdn/hardware/eicon/divasmain.c +++ b/drivers/isdn/hardware/eicon/divasmain.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <asm/uaccess.h> | 15 | #include <asm/uaccess.h> |
16 | #include <asm/io.h> | 16 | #include <asm/io.h> |
17 | #include <linux/ioport.h> | 17 | #include <linux/ioport.h> |
18 | #include <linux/workqueue.h> | ||
19 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
20 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
21 | #include <linux/list.h> | 20 | #include <linux/list.h> |
@@ -546,7 +545,6 @@ void diva_os_remove_soft_isr(diva_os_soft_isr_t * psoft_isr) | |||
546 | void *mem; | 545 | void *mem; |
547 | 546 | ||
548 | tasklet_kill(&pdpc->divas_task); | 547 | tasklet_kill(&pdpc->divas_task); |
549 | flush_scheduled_work(); | ||
550 | mem = psoft_isr->object; | 548 | mem = psoft_isr->object; |
551 | psoft_isr->object = NULL; | 549 | psoft_isr->object = NULL; |
552 | diva_os_free(0, mem); | 550 | diva_os_free(0, mem); |
diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c index d2dd61d65d51..af25e1f3efd4 100644 --- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c +++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c | |||
@@ -1094,6 +1094,7 @@ inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1094 | pr_info("mISDN: do not have informations about adapter at %s\n", | 1094 | pr_info("mISDN: do not have informations about adapter at %s\n", |
1095 | pci_name(pdev)); | 1095 | pci_name(pdev)); |
1096 | kfree(card); | 1096 | kfree(card); |
1097 | pci_disable_device(pdev); | ||
1097 | return -EINVAL; | 1098 | return -EINVAL; |
1098 | } else | 1099 | } else |
1099 | pr_notice("mISDN: found adapter %s at %s\n", | 1100 | pr_notice("mISDN: found adapter %s at %s\n", |
@@ -1103,7 +1104,7 @@ inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1103 | pci_set_drvdata(pdev, card); | 1104 | pci_set_drvdata(pdev, card); |
1104 | err = setup_instance(card); | 1105 | err = setup_instance(card); |
1105 | if (err) { | 1106 | if (err) { |
1106 | pci_disable_device(card->pdev); | 1107 | pci_disable_device(pdev); |
1107 | kfree(card); | 1108 | kfree(card); |
1108 | pci_set_drvdata(pdev, NULL); | 1109 | pci_set_drvdata(pdev, NULL); |
1109 | } else if (ent->driver_data == INF_SCT_1) { | 1110 | } else if (ent->driver_data == INF_SCT_1) { |
@@ -1114,6 +1115,7 @@ inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1114 | sc = kzalloc(sizeof(struct inf_hw), GFP_KERNEL); | 1115 | sc = kzalloc(sizeof(struct inf_hw), GFP_KERNEL); |
1115 | if (!sc) { | 1116 | if (!sc) { |
1116 | release_card(card); | 1117 | release_card(card); |
1118 | pci_disable_device(pdev); | ||
1117 | return -ENOMEM; | 1119 | return -ENOMEM; |
1118 | } | 1120 | } |
1119 | sc->irq = card->irq; | 1121 | sc->irq = card->irq; |
@@ -1121,6 +1123,7 @@ inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1121 | sc->ci = card->ci + i; | 1123 | sc->ci = card->ci + i; |
1122 | err = setup_instance(sc); | 1124 | err = setup_instance(sc); |
1123 | if (err) { | 1125 | if (err) { |
1126 | pci_disable_device(pdev); | ||
1124 | kfree(sc); | 1127 | kfree(sc); |
1125 | release_card(card); | 1128 | release_card(card); |
1126 | break; | 1129 | break; |
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index 94263c22b874..ac4dd7857cbd 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <asm/io.h> | 20 | #include <asm/io.h> |
21 | #include <asm/system.h> | 21 | #include <asm/system.h> |
22 | 22 | ||
23 | #include <pcmcia/cs.h> | ||
24 | #include <pcmcia/cistpl.h> | 23 | #include <pcmcia/cistpl.h> |
25 | #include <pcmcia/ds.h> | 24 | #include <pcmcia/ds.h> |
26 | #include "hisax_cfg.h" | 25 | #include "hisax_cfg.h" |
@@ -40,67 +39,22 @@ module_param(isdnprot, int, 0); | |||
40 | 39 | ||
41 | /*====================================================================*/ | 40 | /*====================================================================*/ |
42 | 41 | ||
43 | /* | ||
44 | The event() function is this driver's Card Services event handler. | ||
45 | It will be called by Card Services when an appropriate card status | ||
46 | event is received. The config() and release() entry points are | ||
47 | used to configure or release a socket, in response to card insertion | ||
48 | and ejection events. They are invoked from the skeleton event | ||
49 | handler. | ||
50 | */ | ||
51 | |||
52 | static int avma1cs_config(struct pcmcia_device *link) __devinit ; | 42 | static int avma1cs_config(struct pcmcia_device *link) __devinit ; |
53 | static void avma1cs_release(struct pcmcia_device *link); | 43 | static void avma1cs_release(struct pcmcia_device *link); |
54 | |||
55 | /* | ||
56 | The attach() and detach() entry points are used to create and destroy | ||
57 | "instances" of the driver, where each instance represents everything | ||
58 | needed to manage one actual PCMCIA card. | ||
59 | */ | ||
60 | |||
61 | static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ; | 44 | static void avma1cs_detach(struct pcmcia_device *p_dev) __devexit ; |
62 | 45 | ||
63 | |||
64 | /*====================================================================== | ||
65 | |||
66 | avma1cs_attach() creates an "instance" of the driver, allocating | ||
67 | local data structures for one device. The device is registered | ||
68 | with Card Services. | ||
69 | |||
70 | The dev_link structure is initialized, but we don't actually | ||
71 | configure the card at this point -- we wait until we receive a | ||
72 | card insertion event. | ||
73 | |||
74 | ======================================================================*/ | ||
75 | |||
76 | static int __devinit avma1cs_probe(struct pcmcia_device *p_dev) | 46 | static int __devinit avma1cs_probe(struct pcmcia_device *p_dev) |
77 | { | 47 | { |
78 | dev_dbg(&p_dev->dev, "avma1cs_attach()\n"); | 48 | dev_dbg(&p_dev->dev, "avma1cs_attach()\n"); |
79 | 49 | ||
80 | /* The io structure describes IO port mapping */ | ||
81 | p_dev->resource[0]->end = 16; | ||
82 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | ||
83 | p_dev->resource[1]->end = 16; | ||
84 | p_dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_16; | ||
85 | |||
86 | /* General socket configuration */ | 50 | /* General socket configuration */ |
87 | p_dev->conf.Attributes = CONF_ENABLE_IRQ; | 51 | p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; |
88 | p_dev->conf.IntType = INT_MEMORY_AND_IO; | 52 | p_dev->config_index = 1; |
89 | p_dev->conf.ConfigIndex = 1; | 53 | p_dev->config_regs = PRESENT_OPTION; |
90 | p_dev->conf.Present = PRESENT_OPTION; | ||
91 | 54 | ||
92 | return avma1cs_config(p_dev); | 55 | return avma1cs_config(p_dev); |
93 | } /* avma1cs_attach */ | 56 | } /* avma1cs_attach */ |
94 | 57 | ||
95 | /*====================================================================== | ||
96 | |||
97 | This deletes a driver "instance". The device is de-registered | ||
98 | with Card Services. If it has been released, all local data | ||
99 | structures are freed. Otherwise, the structures will be freed | ||
100 | when the device is released. | ||
101 | |||
102 | ======================================================================*/ | ||
103 | |||
104 | static void __devexit avma1cs_detach(struct pcmcia_device *link) | 58 | static void __devexit avma1cs_detach(struct pcmcia_device *link) |
105 | { | 59 | { |
106 | dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link); | 60 | dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link); |
@@ -108,26 +62,13 @@ static void __devexit avma1cs_detach(struct pcmcia_device *link) | |||
108 | kfree(link->priv); | 62 | kfree(link->priv); |
109 | } /* avma1cs_detach */ | 63 | } /* avma1cs_detach */ |
110 | 64 | ||
111 | /*====================================================================== | 65 | static int avma1cs_configcheck(struct pcmcia_device *p_dev, void *priv_data) |
112 | |||
113 | avma1cs_config() is scheduled to run after a CARD_INSERTION event | ||
114 | is received, to configure the PCMCIA socket, and to make the | ||
115 | ethernet device available to the system. | ||
116 | |||
117 | ======================================================================*/ | ||
118 | |||
119 | static int avma1cs_configcheck(struct pcmcia_device *p_dev, | ||
120 | cistpl_cftable_entry_t *cf, | ||
121 | cistpl_cftable_entry_t *dflt, | ||
122 | unsigned int vcc, | ||
123 | void *priv_data) | ||
124 | { | 66 | { |
125 | if (cf->io.nwin <= 0) | 67 | p_dev->resource[0]->end = 16; |
126 | return -ENODEV; | 68 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; |
127 | 69 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | |
128 | p_dev->resource[0]->start = cf->io.win[0].base; | ||
129 | p_dev->resource[0]->end = cf->io.win[0].len; | ||
130 | p_dev->io_lines = 5; | 70 | p_dev->io_lines = 5; |
71 | |||
131 | return pcmcia_request_io(p_dev); | 72 | return pcmcia_request_io(p_dev); |
132 | } | 73 | } |
133 | 74 | ||
@@ -161,7 +102,7 @@ static int __devinit avma1cs_config(struct pcmcia_device *link) | |||
161 | /* | 102 | /* |
162 | * configure the PCMCIA socket | 103 | * configure the PCMCIA socket |
163 | */ | 104 | */ |
164 | i = pcmcia_request_configuration(link, &link->conf); | 105 | i = pcmcia_enable_device(link); |
165 | if (i != 0) { | 106 | if (i != 0) { |
166 | pcmcia_disable_device(link); | 107 | pcmcia_disable_device(link); |
167 | break; | 108 | break; |
@@ -175,9 +116,6 @@ static int __devinit avma1cs_config(struct pcmcia_device *link) | |||
175 | return -ENODEV; | 116 | return -ENODEV; |
176 | } | 117 | } |
177 | 118 | ||
178 | printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n", | ||
179 | (unsigned int) link->resource[0]->start, link->irq); | ||
180 | |||
181 | icard.para[0] = link->irq; | 119 | icard.para[0] = link->irq; |
182 | icard.para[1] = link->resource[0]->start; | 120 | icard.para[1] = link->resource[0]->start; |
183 | icard.protocol = isdnprot; | 121 | icard.protocol = isdnprot; |
@@ -196,14 +134,6 @@ static int __devinit avma1cs_config(struct pcmcia_device *link) | |||
196 | return 0; | 134 | return 0; |
197 | } /* avma1cs_config */ | 135 | } /* avma1cs_config */ |
198 | 136 | ||
199 | /*====================================================================== | ||
200 | |||
201 | After a card is removed, avma1cs_release() will unregister the net | ||
202 | device, and release the PCMCIA configuration. If the device is | ||
203 | still open, this will be postponed until it is closed. | ||
204 | |||
205 | ======================================================================*/ | ||
206 | |||
207 | static void avma1cs_release(struct pcmcia_device *link) | 137 | static void avma1cs_release(struct pcmcia_device *link) |
208 | { | 138 | { |
209 | unsigned long minor = (unsigned long) link->priv; | 139 | unsigned long minor = (unsigned long) link->priv; |
@@ -216,7 +146,6 @@ static void avma1cs_release(struct pcmcia_device *link) | |||
216 | pcmcia_disable_device(link); | 146 | pcmcia_disable_device(link); |
217 | } /* avma1cs_release */ | 147 | } /* avma1cs_release */ |
218 | 148 | ||
219 | |||
220 | static struct pcmcia_device_id avma1cs_ids[] = { | 149 | static struct pcmcia_device_id avma1cs_ids[] = { |
221 | PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb), | 150 | PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb), |
222 | PCMCIA_DEVICE_PROD_ID12("ISDN", "CARD", 0x8d9761c8, 0x01c5aa7b), | 151 | PCMCIA_DEVICE_PROD_ID12("ISDN", "CARD", 0x8d9761c8, 0x01c5aa7b), |
@@ -226,19 +155,15 @@ MODULE_DEVICE_TABLE(pcmcia, avma1cs_ids); | |||
226 | 155 | ||
227 | static struct pcmcia_driver avma1cs_driver = { | 156 | static struct pcmcia_driver avma1cs_driver = { |
228 | .owner = THIS_MODULE, | 157 | .owner = THIS_MODULE, |
229 | .drv = { | 158 | .name = "avma1_cs", |
230 | .name = "avma1_cs", | ||
231 | }, | ||
232 | .probe = avma1cs_probe, | 159 | .probe = avma1cs_probe, |
233 | .remove = __devexit_p(avma1cs_detach), | 160 | .remove = __devexit_p(avma1cs_detach), |
234 | .id_table = avma1cs_ids, | 161 | .id_table = avma1cs_ids, |
235 | }; | 162 | }; |
236 | 163 | ||
237 | /*====================================================================*/ | ||
238 | |||
239 | static int __init init_avma1_cs(void) | 164 | static int __init init_avma1_cs(void) |
240 | { | 165 | { |
241 | return(pcmcia_register_driver(&avma1cs_driver)); | 166 | return pcmcia_register_driver(&avma1cs_driver); |
242 | } | 167 | } |
243 | 168 | ||
244 | static void __exit exit_avma1_cs(void) | 169 | static void __exit exit_avma1_cs(void) |
diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c index 6f9afcd5ca4e..b133378d4dc9 100644 --- a/drivers/isdn/hisax/config.c +++ b/drivers/isdn/hisax/config.c | |||
@@ -801,6 +801,16 @@ static void closecard(int cardnr) | |||
801 | ll_unload(csta); | 801 | ll_unload(csta); |
802 | } | 802 | } |
803 | 803 | ||
804 | static irqreturn_t card_irq(int intno, void *dev_id) | ||
805 | { | ||
806 | struct IsdnCardState *cs = dev_id; | ||
807 | irqreturn_t ret = cs->irq_func(intno, cs); | ||
808 | |||
809 | if (ret == IRQ_HANDLED) | ||
810 | cs->irq_cnt++; | ||
811 | return ret; | ||
812 | } | ||
813 | |||
804 | static int init_card(struct IsdnCardState *cs) | 814 | static int init_card(struct IsdnCardState *cs) |
805 | { | 815 | { |
806 | int irq_cnt, cnt = 3, ret; | 816 | int irq_cnt, cnt = 3, ret; |
@@ -809,10 +819,10 @@ static int init_card(struct IsdnCardState *cs) | |||
809 | ret = cs->cardmsg(cs, CARD_INIT, NULL); | 819 | ret = cs->cardmsg(cs, CARD_INIT, NULL); |
810 | return(ret); | 820 | return(ret); |
811 | } | 821 | } |
812 | irq_cnt = kstat_irqs(cs->irq); | 822 | irq_cnt = cs->irq_cnt = 0; |
813 | printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ], | 823 | printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ], |
814 | cs->irq, irq_cnt); | 824 | cs->irq, irq_cnt); |
815 | if (request_irq(cs->irq, cs->irq_func, cs->irq_flags, "HiSax", cs)) { | 825 | if (request_irq(cs->irq, card_irq, cs->irq_flags, "HiSax", cs)) { |
816 | printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n", | 826 | printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n", |
817 | cs->irq); | 827 | cs->irq); |
818 | return 1; | 828 | return 1; |
@@ -822,8 +832,8 @@ static int init_card(struct IsdnCardState *cs) | |||
822 | /* Timeout 10ms */ | 832 | /* Timeout 10ms */ |
823 | msleep(10); | 833 | msleep(10); |
824 | printk(KERN_INFO "%s: IRQ %d count %d\n", | 834 | printk(KERN_INFO "%s: IRQ %d count %d\n", |
825 | CardType[cs->typ], cs->irq, kstat_irqs(cs->irq)); | 835 | CardType[cs->typ], cs->irq, cs->irq_cnt); |
826 | if (kstat_irqs(cs->irq) == irq_cnt) { | 836 | if (cs->irq_cnt == irq_cnt) { |
827 | printk(KERN_WARNING | 837 | printk(KERN_WARNING |
828 | "%s: IRQ(%d) getting no interrupts during init %d\n", | 838 | "%s: IRQ(%d) getting no interrupts during init %d\n", |
829 | CardType[cs->typ], cs->irq, 4 - cnt); | 839 | CardType[cs->typ], cs->irq, 4 - cnt); |
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index b3c08aaf41c4..496d477af0f8 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <asm/io.h> | 46 | #include <asm/io.h> |
47 | #include <asm/system.h> | 47 | #include <asm/system.h> |
48 | 48 | ||
49 | #include <pcmcia/cs.h> | ||
50 | #include <pcmcia/cistpl.h> | 49 | #include <pcmcia/cistpl.h> |
51 | #include <pcmcia/cisreg.h> | 50 | #include <pcmcia/cisreg.h> |
52 | #include <pcmcia/ds.h> | 51 | #include <pcmcia/ds.h> |
@@ -64,26 +63,8 @@ MODULE_LICENSE("Dual MPL/GPL"); | |||
64 | static int protocol = 2; /* EURO-ISDN Default */ | 63 | static int protocol = 2; /* EURO-ISDN Default */ |
65 | module_param(protocol, int, 0); | 64 | module_param(protocol, int, 0); |
66 | 65 | ||
67 | /*====================================================================*/ | ||
68 | |||
69 | /* | ||
70 | The event() function is this driver's Card Services event handler. | ||
71 | It will be called by Card Services when an appropriate card status | ||
72 | event is received. The config() and release() entry points are | ||
73 | used to configure or release a socket, in response to card insertion | ||
74 | and ejection events. They are invoked from the elsa_cs event | ||
75 | handler. | ||
76 | */ | ||
77 | |||
78 | static int elsa_cs_config(struct pcmcia_device *link) __devinit ; | 66 | static int elsa_cs_config(struct pcmcia_device *link) __devinit ; |
79 | static void elsa_cs_release(struct pcmcia_device *link); | 67 | static void elsa_cs_release(struct pcmcia_device *link); |
80 | |||
81 | /* | ||
82 | The attach() and detach() entry points are used to create and destroy | ||
83 | "instances" of the driver, where each instance represents everything | ||
84 | needed to manage one actual PCMCIA card. | ||
85 | */ | ||
86 | |||
87 | static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit; | 68 | static void elsa_cs_detach(struct pcmcia_device *p_dev) __devexit; |
88 | 69 | ||
89 | typedef struct local_info_t { | 70 | typedef struct local_info_t { |
@@ -92,18 +73,6 @@ typedef struct local_info_t { | |||
92 | int cardnr; | 73 | int cardnr; |
93 | } local_info_t; | 74 | } local_info_t; |
94 | 75 | ||
95 | /*====================================================================== | ||
96 | |||
97 | elsa_cs_attach() creates an "instance" of the driver, allocatingx | ||
98 | local data structures for one device. The device is registered | ||
99 | with Card Services. | ||
100 | |||
101 | The dev_link structure is initialized, but we don't actually | ||
102 | configure the card at this point -- we wait until we receive a | ||
103 | card insertion event. | ||
104 | |||
105 | ======================================================================*/ | ||
106 | |||
107 | static int __devinit elsa_cs_probe(struct pcmcia_device *link) | 76 | static int __devinit elsa_cs_probe(struct pcmcia_device *link) |
108 | { | 77 | { |
109 | local_info_t *local; | 78 | local_info_t *local; |
@@ -119,31 +88,9 @@ static int __devinit elsa_cs_probe(struct pcmcia_device *link) | |||
119 | 88 | ||
120 | local->cardnr = -1; | 89 | local->cardnr = -1; |
121 | 90 | ||
122 | /* | ||
123 | General socket configuration defaults can go here. In this | ||
124 | client, we assume very little, and rely on the CIS for almost | ||
125 | everything. In most clients, many details (i.e., number, sizes, | ||
126 | and attributes of IO windows) are fixed by the nature of the | ||
127 | device, and can be hard-wired here. | ||
128 | */ | ||
129 | link->resource[0]->end = 8; | ||
130 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; | ||
131 | |||
132 | link->conf.Attributes = CONF_ENABLE_IRQ; | ||
133 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
134 | |||
135 | return elsa_cs_config(link); | 91 | return elsa_cs_config(link); |
136 | } /* elsa_cs_attach */ | 92 | } /* elsa_cs_attach */ |
137 | 93 | ||
138 | /*====================================================================== | ||
139 | |||
140 | This deletes a driver "instance". The device is de-registered | ||
141 | with Card Services. If it has been released, all local data | ||
142 | structures are freed. Otherwise, the structures will be freed | ||
143 | when the device is released. | ||
144 | |||
145 | ======================================================================*/ | ||
146 | |||
147 | static void __devexit elsa_cs_detach(struct pcmcia_device *link) | 94 | static void __devexit elsa_cs_detach(struct pcmcia_device *link) |
148 | { | 95 | { |
149 | local_info_t *info = link->priv; | 96 | local_info_t *info = link->priv; |
@@ -156,27 +103,17 @@ static void __devexit elsa_cs_detach(struct pcmcia_device *link) | |||
156 | kfree(info); | 103 | kfree(info); |
157 | } /* elsa_cs_detach */ | 104 | } /* elsa_cs_detach */ |
158 | 105 | ||
159 | /*====================================================================== | 106 | static int elsa_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data) |
160 | |||
161 | elsa_cs_config() is scheduled to run after a CARD_INSERTION event | ||
162 | is received, to configure the PCMCIA socket, and to make the | ||
163 | device available to the system. | ||
164 | |||
165 | ======================================================================*/ | ||
166 | |||
167 | static int elsa_cs_configcheck(struct pcmcia_device *p_dev, | ||
168 | cistpl_cftable_entry_t *cf, | ||
169 | cistpl_cftable_entry_t *dflt, | ||
170 | unsigned int vcc, | ||
171 | void *priv_data) | ||
172 | { | 107 | { |
173 | int j; | 108 | int j; |
174 | 109 | ||
175 | p_dev->io_lines = 3; | 110 | p_dev->io_lines = 3; |
111 | p_dev->resource[0]->end = 8; | ||
112 | p_dev->resource[0]->flags &= IO_DATA_PATH_WIDTH; | ||
113 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; | ||
176 | 114 | ||
177 | if ((cf->io.nwin > 0) && cf->io.win[0].base) { | 115 | if ((p_dev->resource[0]->end) && p_dev->resource[0]->start) { |
178 | printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); | 116 | printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); |
179 | p_dev->resource[0]->start = cf->io.win[0].base; | ||
180 | if (!pcmcia_request_io(p_dev)) | 117 | if (!pcmcia_request_io(p_dev)) |
181 | return 0; | 118 | return 0; |
182 | } else { | 119 | } else { |
@@ -199,6 +136,8 @@ static int __devinit elsa_cs_config(struct pcmcia_device *link) | |||
199 | dev_dbg(&link->dev, "elsa_config(0x%p)\n", link); | 136 | dev_dbg(&link->dev, "elsa_config(0x%p)\n", link); |
200 | dev = link->priv; | 137 | dev = link->priv; |
201 | 138 | ||
139 | link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; | ||
140 | |||
202 | i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL); | 141 | i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL); |
203 | if (i != 0) | 142 | if (i != 0) |
204 | goto failed; | 143 | goto failed; |
@@ -206,21 +145,10 @@ static int __devinit elsa_cs_config(struct pcmcia_device *link) | |||
206 | if (!link->irq) | 145 | if (!link->irq) |
207 | goto failed; | 146 | goto failed; |
208 | 147 | ||
209 | i = pcmcia_request_configuration(link, &link->conf); | 148 | i = pcmcia_enable_device(link); |
210 | if (i != 0) | 149 | if (i != 0) |
211 | goto failed; | 150 | goto failed; |
212 | 151 | ||
213 | /* Finally, report what we've done */ | ||
214 | dev_info(&link->dev, "index 0x%02x: ", | ||
215 | link->conf.ConfigIndex); | ||
216 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | ||
217 | printk(", irq %d", link->irq); | ||
218 | if (link->resource[0]) | ||
219 | printk(" & %pR", link->resource[0]); | ||
220 | if (link->resource[1]) | ||
221 | printk(" & %pR", link->resource[1]); | ||
222 | printk("\n"); | ||
223 | |||
224 | icard.para[0] = link->irq; | 152 | icard.para[0] = link->irq; |
225 | icard.para[1] = link->resource[0]->start; | 153 | icard.para[1] = link->resource[0]->start; |
226 | icard.protocol = protocol; | 154 | icard.protocol = protocol; |
@@ -240,14 +168,6 @@ failed: | |||
240 | return -ENODEV; | 168 | return -ENODEV; |
241 | } /* elsa_cs_config */ | 169 | } /* elsa_cs_config */ |
242 | 170 | ||
243 | /*====================================================================== | ||
244 | |||
245 | After a card is removed, elsa_cs_release() will unregister the net | ||
246 | device, and release the PCMCIA configuration. If the device is | ||
247 | still open, this will be postponed until it is closed. | ||
248 | |||
249 | ======================================================================*/ | ||
250 | |||
251 | static void elsa_cs_release(struct pcmcia_device *link) | 171 | static void elsa_cs_release(struct pcmcia_device *link) |
252 | { | 172 | { |
253 | local_info_t *local = link->priv; | 173 | local_info_t *local = link->priv; |
@@ -291,9 +211,7 @@ MODULE_DEVICE_TABLE(pcmcia, elsa_ids); | |||
291 | 211 | ||
292 | static struct pcmcia_driver elsa_cs_driver = { | 212 | static struct pcmcia_driver elsa_cs_driver = { |
293 | .owner = THIS_MODULE, | 213 | .owner = THIS_MODULE, |
294 | .drv = { | 214 | .name = "elsa_cs", |
295 | .name = "elsa_cs", | ||
296 | }, | ||
297 | .probe = elsa_cs_probe, | 215 | .probe = elsa_cs_probe, |
298 | .remove = __devexit_p(elsa_cs_detach), | 216 | .remove = __devexit_p(elsa_cs_detach), |
299 | .id_table = elsa_ids, | 217 | .id_table = elsa_ids, |
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/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index 832a87855ffb..32ab3924aa73 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h | |||
@@ -959,6 +959,7 @@ struct IsdnCardState { | |||
959 | u_long event; | 959 | u_long event; |
960 | struct work_struct tqueue; | 960 | struct work_struct tqueue; |
961 | struct timer_list dbusytimer; | 961 | struct timer_list dbusytimer; |
962 | unsigned int irq_cnt; | ||
962 | #ifdef ERROR_STATISTIC | 963 | #ifdef ERROR_STATISTIC |
963 | int err_crc; | 964 | int err_crc; |
964 | int err_tx; | 965 | int err_tx; |
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index a024192b672a..360204bc2777 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <asm/io.h> | 46 | #include <asm/io.h> |
47 | #include <asm/system.h> | 47 | #include <asm/system.h> |
48 | 48 | ||
49 | #include <pcmcia/cs.h> | ||
50 | #include <pcmcia/cistpl.h> | 49 | #include <pcmcia/cistpl.h> |
51 | #include <pcmcia/cisreg.h> | 50 | #include <pcmcia/cisreg.h> |
52 | #include <pcmcia/ds.h> | 51 | #include <pcmcia/ds.h> |
@@ -64,26 +63,9 @@ MODULE_LICENSE("Dual MPL/GPL"); | |||
64 | static int protocol = 2; /* EURO-ISDN Default */ | 63 | static int protocol = 2; /* EURO-ISDN Default */ |
65 | module_param(protocol, int, 0); | 64 | module_param(protocol, int, 0); |
66 | 65 | ||
67 | /*====================================================================*/ | ||
68 | |||
69 | /* | ||
70 | The event() function is this driver's Card Services event handler. | ||
71 | It will be called by Card Services when an appropriate card status | ||
72 | event is received. The config() and release() entry points are | ||
73 | used to configure or release a socket, in response to card | ||
74 | insertion and ejection events. They are invoked from the sedlbauer | ||
75 | event handler. | ||
76 | */ | ||
77 | |||
78 | static int sedlbauer_config(struct pcmcia_device *link) __devinit ; | 66 | static int sedlbauer_config(struct pcmcia_device *link) __devinit ; |
79 | static void sedlbauer_release(struct pcmcia_device *link); | 67 | static void sedlbauer_release(struct pcmcia_device *link); |
80 | 68 | ||
81 | /* | ||
82 | The attach() and detach() entry points are used to create and destroy | ||
83 | "instances" of the driver, where each instance represents everything | ||
84 | needed to manage one actual PCMCIA card. | ||
85 | */ | ||
86 | |||
87 | static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit; | 69 | static void sedlbauer_detach(struct pcmcia_device *p_dev) __devexit; |
88 | 70 | ||
89 | typedef struct local_info_t { | 71 | typedef struct local_info_t { |
@@ -92,18 +74,6 @@ typedef struct local_info_t { | |||
92 | int cardnr; | 74 | int cardnr; |
93 | } local_info_t; | 75 | } local_info_t; |
94 | 76 | ||
95 | /*====================================================================== | ||
96 | |||
97 | sedlbauer_attach() creates an "instance" of the driver, allocating | ||
98 | local data structures for one device. The device is registered | ||
99 | with Card Services. | ||
100 | |||
101 | The dev_link structure is initialized, but we don't actually | ||
102 | configure the card at this point -- we wait until we receive a | ||
103 | card insertion event. | ||
104 | |||
105 | ======================================================================*/ | ||
106 | |||
107 | static int __devinit sedlbauer_probe(struct pcmcia_device *link) | 77 | static int __devinit sedlbauer_probe(struct pcmcia_device *link) |
108 | { | 78 | { |
109 | local_info_t *local; | 79 | local_info_t *local; |
@@ -118,35 +88,9 @@ static int __devinit sedlbauer_probe(struct pcmcia_device *link) | |||
118 | local->p_dev = link; | 88 | local->p_dev = link; |
119 | link->priv = local; | 89 | link->priv = local; |
120 | 90 | ||
121 | /* | ||
122 | General socket configuration defaults can go here. In this | ||
123 | client, we assume very little, and rely on the CIS for almost | ||
124 | everything. In most clients, many details (i.e., number, sizes, | ||
125 | and attributes of IO windows) are fixed by the nature of the | ||
126 | device, and can be hard-wired here. | ||
127 | */ | ||
128 | |||
129 | /* from old sedl_cs | ||
130 | */ | ||
131 | /* The io structure describes IO port mapping */ | ||
132 | link->resource[0]->end = 8; | ||
133 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | ||
134 | |||
135 | link->conf.Attributes = 0; | ||
136 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
137 | |||
138 | return sedlbauer_config(link); | 91 | return sedlbauer_config(link); |
139 | } /* sedlbauer_attach */ | 92 | } /* sedlbauer_attach */ |
140 | 93 | ||
141 | /*====================================================================== | ||
142 | |||
143 | This deletes a driver "instance". The device is de-registered | ||
144 | with Card Services. If it has been released, all local data | ||
145 | structures are freed. Otherwise, the structures will be freed | ||
146 | when the device is released. | ||
147 | |||
148 | ======================================================================*/ | ||
149 | |||
150 | static void __devexit sedlbauer_detach(struct pcmcia_device *link) | 94 | static void __devexit sedlbauer_detach(struct pcmcia_device *link) |
151 | { | 95 | { |
152 | dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link); | 96 | dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link); |
@@ -158,70 +102,15 @@ static void __devexit sedlbauer_detach(struct pcmcia_device *link) | |||
158 | kfree(link->priv); | 102 | kfree(link->priv); |
159 | } /* sedlbauer_detach */ | 103 | } /* sedlbauer_detach */ |
160 | 104 | ||
161 | /*====================================================================== | 105 | static int sedlbauer_config_check(struct pcmcia_device *p_dev, void *priv_data) |
162 | |||
163 | sedlbauer_config() is scheduled to run after a CARD_INSERTION event | ||
164 | is received, to configure the PCMCIA socket, and to make the | ||
165 | device available to the system. | ||
166 | |||
167 | ======================================================================*/ | ||
168 | static int sedlbauer_config_check(struct pcmcia_device *p_dev, | ||
169 | cistpl_cftable_entry_t *cfg, | ||
170 | cistpl_cftable_entry_t *dflt, | ||
171 | unsigned int vcc, | ||
172 | void *priv_data) | ||
173 | { | 106 | { |
174 | if (cfg->index == 0) | 107 | if (p_dev->config_index == 0) |
175 | return -ENODEV; | 108 | return -EINVAL; |
176 | |||
177 | /* Does this card need audio output? */ | ||
178 | if (cfg->flags & CISTPL_CFTABLE_AUDIO) { | ||
179 | p_dev->conf.Attributes |= CONF_ENABLE_SPKR; | ||
180 | p_dev->conf.Status = CCSR_AUDIO_ENA; | ||
181 | } | ||
182 | 109 | ||
183 | /* Use power settings for Vcc and Vpp if present */ | 110 | p_dev->io_lines = 3; |
184 | /* Note that the CIS values need to be rescaled */ | 111 | return pcmcia_request_io(p_dev); |
185 | if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { | ||
186 | if (vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) | ||
187 | return -ENODEV; | ||
188 | } else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) { | ||
189 | if (vcc != dflt->vcc.param[CISTPL_POWER_VNOM]/10000) | ||
190 | return -ENODEV; | ||
191 | } | ||
192 | |||
193 | if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
194 | p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
195 | else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
196 | p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
197 | |||
198 | p_dev->conf.Attributes |= CONF_ENABLE_IRQ; | ||
199 | |||
200 | /* IO window settings */ | ||
201 | p_dev->resource[0]->end = p_dev->resource[1]->end = 0; | ||
202 | if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) { | ||
203 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io; | ||
204 | p_dev->resource[0]->start = io->win[0].base; | ||
205 | p_dev->resource[0]->end = io->win[0].len; | ||
206 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; | ||
207 | p_dev->resource[0]->flags |= | ||
208 | pcmcia_io_cfg_data_width(io->flags); | ||
209 | if (io->nwin > 1) { | ||
210 | p_dev->resource[1]->flags = p_dev->resource[0]->flags; | ||
211 | p_dev->resource[1]->start = io->win[1].base; | ||
212 | p_dev->resource[1]->end = io->win[1].len; | ||
213 | } | ||
214 | /* This reserves IO space but doesn't actually enable it */ | ||
215 | p_dev->io_lines = 3; | ||
216 | if (pcmcia_request_io(p_dev) != 0) | ||
217 | return -ENODEV; | ||
218 | } | ||
219 | |||
220 | return 0; | ||
221 | } | 112 | } |
222 | 113 | ||
223 | |||
224 | |||
225 | static int __devinit sedlbauer_config(struct pcmcia_device *link) | 114 | static int __devinit sedlbauer_config(struct pcmcia_device *link) |
226 | { | 115 | { |
227 | int ret; | 116 | int ret; |
@@ -229,44 +118,17 @@ static int __devinit sedlbauer_config(struct pcmcia_device *link) | |||
229 | 118 | ||
230 | dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link); | 119 | dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link); |
231 | 120 | ||
232 | /* | 121 | link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC | |
233 | In this loop, we scan the CIS for configuration table entries, | 122 | CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IO; |
234 | each of which describes a valid card configuration, including | 123 | |
235 | voltage, IO window, memory window, and interrupt settings. | ||
236 | |||
237 | We make no assumptions about the card to be configured: we use | ||
238 | just the information available in the CIS. In an ideal world, | ||
239 | this would work for any PCMCIA card, but it requires a complete | ||
240 | and accurate CIS. In practice, a driver usually "knows" most of | ||
241 | these things without consulting the CIS, and most client drivers | ||
242 | will only use the CIS to fill in implementation-defined details. | ||
243 | */ | ||
244 | ret = pcmcia_loop_config(link, sedlbauer_config_check, NULL); | 124 | ret = pcmcia_loop_config(link, sedlbauer_config_check, NULL); |
245 | if (ret) | 125 | if (ret) |
246 | goto failed; | 126 | goto failed; |
247 | 127 | ||
248 | /* | 128 | ret = pcmcia_enable_device(link); |
249 | This actually configures the PCMCIA socket -- setting up | ||
250 | the I/O windows and the interrupt mapping, and putting the | ||
251 | card and host interface into "Memory and IO" mode. | ||
252 | */ | ||
253 | ret = pcmcia_request_configuration(link, &link->conf); | ||
254 | if (ret) | 129 | if (ret) |
255 | goto failed; | 130 | goto failed; |
256 | 131 | ||
257 | /* Finally, report what we've done */ | ||
258 | dev_info(&link->dev, "index 0x%02x:", | ||
259 | link->conf.ConfigIndex); | ||
260 | if (link->conf.Vpp) | ||
261 | printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); | ||
262 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | ||
263 | printk(", irq %d", link->irq); | ||
264 | if (link->resource[0]) | ||
265 | printk(" & %pR", link->resource[0]); | ||
266 | if (link->resource[1]) | ||
267 | printk(" & %pR", link->resource[1]); | ||
268 | printk("\n"); | ||
269 | |||
270 | icard.para[0] = link->irq; | 132 | icard.para[0] = link->irq; |
271 | icard.para[1] = link->resource[0]->start; | 133 | icard.para[1] = link->resource[0]->start; |
272 | icard.protocol = protocol; | 134 | icard.protocol = protocol; |
@@ -290,14 +152,6 @@ failed: | |||
290 | 152 | ||
291 | } /* sedlbauer_config */ | 153 | } /* sedlbauer_config */ |
292 | 154 | ||
293 | /*====================================================================== | ||
294 | |||
295 | After a card is removed, sedlbauer_release() will unregister the | ||
296 | device, and release the PCMCIA configuration. If the device is | ||
297 | still open, this will be postponed until it is closed. | ||
298 | |||
299 | ======================================================================*/ | ||
300 | |||
301 | static void sedlbauer_release(struct pcmcia_device *link) | 155 | static void sedlbauer_release(struct pcmcia_device *link) |
302 | { | 156 | { |
303 | local_info_t *local = link->priv; | 157 | local_info_t *local = link->priv; |
@@ -346,9 +200,7 @@ MODULE_DEVICE_TABLE(pcmcia, sedlbauer_ids); | |||
346 | 200 | ||
347 | static struct pcmcia_driver sedlbauer_driver = { | 201 | static struct pcmcia_driver sedlbauer_driver = { |
348 | .owner = THIS_MODULE, | 202 | .owner = THIS_MODULE, |
349 | .drv = { | 203 | .name = "sedlbauer_cs", |
350 | .name = "sedlbauer_cs", | ||
351 | }, | ||
352 | .probe = sedlbauer_probe, | 204 | .probe = sedlbauer_probe, |
353 | .remove = __devexit_p(sedlbauer_detach), | 205 | .remove = __devexit_p(sedlbauer_detach), |
354 | .id_table = sedlbauer_ids, | 206 | .id_table = sedlbauer_ids, |
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index 7296102ca255..282a4467ef19 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <asm/io.h> | 27 | #include <asm/io.h> |
28 | #include <asm/system.h> | 28 | #include <asm/system.h> |
29 | 29 | ||
30 | #include <pcmcia/cs.h> | ||
31 | #include <pcmcia/cistpl.h> | 30 | #include <pcmcia/cistpl.h> |
32 | #include <pcmcia/cisreg.h> | 31 | #include <pcmcia/cisreg.h> |
33 | #include <pcmcia/ds.h> | 32 | #include <pcmcia/ds.h> |
@@ -45,26 +44,8 @@ MODULE_LICENSE("GPL"); | |||
45 | static int protocol = 2; /* EURO-ISDN Default */ | 44 | static int protocol = 2; /* EURO-ISDN Default */ |
46 | module_param(protocol, int, 0); | 45 | module_param(protocol, int, 0); |
47 | 46 | ||
48 | /*====================================================================*/ | ||
49 | |||
50 | /* | ||
51 | The event() function is this driver's Card Services event handler. | ||
52 | It will be called by Card Services when an appropriate card status | ||
53 | event is received. The config() and release() entry points are | ||
54 | used to configure or release a socket, in response to card insertion | ||
55 | and ejection events. They are invoked from the teles_cs event | ||
56 | handler. | ||
57 | */ | ||
58 | |||
59 | static int teles_cs_config(struct pcmcia_device *link) __devinit ; | 47 | static int teles_cs_config(struct pcmcia_device *link) __devinit ; |
60 | static void teles_cs_release(struct pcmcia_device *link); | 48 | static void teles_cs_release(struct pcmcia_device *link); |
61 | |||
62 | /* | ||
63 | The attach() and detach() entry points are used to create and destroy | ||
64 | "instances" of the driver, where each instance represents everything | ||
65 | needed to manage one actual PCMCIA card. | ||
66 | */ | ||
67 | |||
68 | static void teles_detach(struct pcmcia_device *p_dev) __devexit ; | 49 | static void teles_detach(struct pcmcia_device *p_dev) __devexit ; |
69 | 50 | ||
70 | typedef struct local_info_t { | 51 | typedef struct local_info_t { |
@@ -73,18 +54,6 @@ typedef struct local_info_t { | |||
73 | int cardnr; | 54 | int cardnr; |
74 | } local_info_t; | 55 | } local_info_t; |
75 | 56 | ||
76 | /*====================================================================== | ||
77 | |||
78 | teles_attach() creates an "instance" of the driver, allocatingx | ||
79 | local data structures for one device. The device is registered | ||
80 | with Card Services. | ||
81 | |||
82 | The dev_link structure is initialized, but we don't actually | ||
83 | configure the card at this point -- we wait until we receive a | ||
84 | card insertion event. | ||
85 | |||
86 | ======================================================================*/ | ||
87 | |||
88 | static int __devinit teles_probe(struct pcmcia_device *link) | 57 | static int __devinit teles_probe(struct pcmcia_device *link) |
89 | { | 58 | { |
90 | local_info_t *local; | 59 | local_info_t *local; |
@@ -99,31 +68,11 @@ static int __devinit teles_probe(struct pcmcia_device *link) | |||
99 | local->p_dev = link; | 68 | local->p_dev = link; |
100 | link->priv = local; | 69 | link->priv = local; |
101 | 70 | ||
102 | /* | 71 | link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; |
103 | General socket configuration defaults can go here. In this | ||
104 | client, we assume very little, and rely on the CIS for almost | ||
105 | everything. In most clients, many details (i.e., number, sizes, | ||
106 | and attributes of IO windows) are fixed by the nature of the | ||
107 | device, and can be hard-wired here. | ||
108 | */ | ||
109 | link->resource[0]->end = 96; | ||
110 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; | ||
111 | |||
112 | link->conf.Attributes = CONF_ENABLE_IRQ; | ||
113 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
114 | 72 | ||
115 | return teles_cs_config(link); | 73 | return teles_cs_config(link); |
116 | } /* teles_attach */ | 74 | } /* teles_attach */ |
117 | 75 | ||
118 | /*====================================================================== | ||
119 | |||
120 | This deletes a driver "instance". The device is de-registered | ||
121 | with Card Services. If it has been released, all local data | ||
122 | structures are freed. Otherwise, the structures will be freed | ||
123 | when the device is released. | ||
124 | |||
125 | ======================================================================*/ | ||
126 | |||
127 | static void __devexit teles_detach(struct pcmcia_device *link) | 76 | static void __devexit teles_detach(struct pcmcia_device *link) |
128 | { | 77 | { |
129 | local_info_t *info = link->priv; | 78 | local_info_t *info = link->priv; |
@@ -136,27 +85,17 @@ static void __devexit teles_detach(struct pcmcia_device *link) | |||
136 | kfree(info); | 85 | kfree(info); |
137 | } /* teles_detach */ | 86 | } /* teles_detach */ |
138 | 87 | ||
139 | /*====================================================================== | 88 | static int teles_cs_configcheck(struct pcmcia_device *p_dev, void *priv_data) |
140 | |||
141 | teles_cs_config() is scheduled to run after a CARD_INSERTION event | ||
142 | is received, to configure the PCMCIA socket, and to make the | ||
143 | device available to the system. | ||
144 | |||
145 | ======================================================================*/ | ||
146 | |||
147 | static int teles_cs_configcheck(struct pcmcia_device *p_dev, | ||
148 | cistpl_cftable_entry_t *cf, | ||
149 | cistpl_cftable_entry_t *dflt, | ||
150 | unsigned int vcc, | ||
151 | void *priv_data) | ||
152 | { | 89 | { |
153 | int j; | 90 | int j; |
154 | 91 | ||
155 | p_dev->io_lines = 5; | 92 | p_dev->io_lines = 5; |
93 | p_dev->resource[0]->end = 96; | ||
94 | p_dev->resource[0]->flags &= IO_DATA_PATH_WIDTH; | ||
95 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; | ||
156 | 96 | ||
157 | if ((cf->io.nwin > 0) && cf->io.win[0].base) { | 97 | if ((p_dev->resource[0]->end) && p_dev->resource[0]->start) { |
158 | printk(KERN_INFO "(teles_cs: looks like the 96 model)\n"); | 98 | printk(KERN_INFO "(teles_cs: looks like the 96 model)\n"); |
159 | p_dev->resource[0]->start = cf->io.win[0].base; | ||
160 | if (!pcmcia_request_io(p_dev)) | 99 | if (!pcmcia_request_io(p_dev)) |
161 | return 0; | 100 | return 0; |
162 | } else { | 101 | } else { |
@@ -186,21 +125,10 @@ static int __devinit teles_cs_config(struct pcmcia_device *link) | |||
186 | if (!link->irq) | 125 | if (!link->irq) |
187 | goto cs_failed; | 126 | goto cs_failed; |
188 | 127 | ||
189 | i = pcmcia_request_configuration(link, &link->conf); | 128 | i = pcmcia_enable_device(link); |
190 | if (i != 0) | 129 | if (i != 0) |
191 | goto cs_failed; | 130 | goto cs_failed; |
192 | 131 | ||
193 | /* Finally, report what we've done */ | ||
194 | dev_info(&link->dev, "index 0x%02x:", | ||
195 | link->conf.ConfigIndex); | ||
196 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | ||
197 | printk(", irq %d", link->irq); | ||
198 | if (link->resource[0]) | ||
199 | printk(" & %pR", link->resource[0]); | ||
200 | if (link->resource[1]) | ||
201 | printk(" & %pR", link->resource[1]); | ||
202 | printk("\n"); | ||
203 | |||
204 | icard.para[0] = link->irq; | 132 | icard.para[0] = link->irq; |
205 | icard.para[1] = link->resource[0]->start; | 133 | icard.para[1] = link->resource[0]->start; |
206 | icard.protocol = protocol; | 134 | icard.protocol = protocol; |
@@ -222,14 +150,6 @@ cs_failed: | |||
222 | return -ENODEV; | 150 | return -ENODEV; |
223 | } /* teles_cs_config */ | 151 | } /* teles_cs_config */ |
224 | 152 | ||
225 | /*====================================================================== | ||
226 | |||
227 | After a card is removed, teles_cs_release() will unregister the net | ||
228 | device, and release the PCMCIA configuration. If the device is | ||
229 | still open, this will be postponed until it is closed. | ||
230 | |||
231 | ======================================================================*/ | ||
232 | |||
233 | static void teles_cs_release(struct pcmcia_device *link) | 153 | static void teles_cs_release(struct pcmcia_device *link) |
234 | { | 154 | { |
235 | local_info_t *local = link->priv; | 155 | local_info_t *local = link->priv; |
@@ -273,9 +193,7 @@ MODULE_DEVICE_TABLE(pcmcia, teles_ids); | |||
273 | 193 | ||
274 | static struct pcmcia_driver teles_cs_driver = { | 194 | static struct pcmcia_driver teles_cs_driver = { |
275 | .owner = THIS_MODULE, | 195 | .owner = THIS_MODULE, |
276 | .drv = { | 196 | .name = "teles_cs", |
277 | .name = "teles_cs", | ||
278 | }, | ||
279 | .probe = teles_probe, | 197 | .probe = teles_probe, |
280 | .remove = __devexit_p(teles_detach), | 198 | .remove = __devexit_p(teles_detach), |
281 | .id_table = teles_ids, | 199 | .id_table = teles_ids, |
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/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c index de43c8c70ad0..859c81e9483b 100644 --- a/drivers/isdn/mISDN/timerdev.c +++ b/drivers/isdn/mISDN/timerdev.c | |||
@@ -267,6 +267,7 @@ static const struct file_operations mISDN_fops = { | |||
267 | .unlocked_ioctl = mISDN_ioctl, | 267 | .unlocked_ioctl = mISDN_ioctl, |
268 | .open = mISDN_open, | 268 | .open = mISDN_open, |
269 | .release = mISDN_close, | 269 | .release = mISDN_close, |
270 | .llseek = no_llseek, | ||
270 | }; | 271 | }; |
271 | 272 | ||
272 | static struct miscdevice mISDNtimer = { | 273 | static struct miscdevice mISDNtimer = { |
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 *); |
diff --git a/drivers/isdn/sc/interrupt.c b/drivers/isdn/sc/interrupt.c index 485be8b1e1b3..f0225bc0f267 100644 --- a/drivers/isdn/sc/interrupt.c +++ b/drivers/isdn/sc/interrupt.c | |||
@@ -112,11 +112,19 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst) | |||
112 | } | 112 | } |
113 | else if(callid>=0x0000 && callid<=0x7FFF) | 113 | else if(callid>=0x0000 && callid<=0x7FFF) |
114 | { | 114 | { |
115 | int len; | ||
116 | |||
115 | pr_debug("%s: Got Incoming Call\n", | 117 | pr_debug("%s: Got Incoming Call\n", |
116 | sc_adapter[card]->devicename); | 118 | sc_adapter[card]->devicename); |
117 | strcpy(setup.phone,&(rcvmsg.msg_data.byte_array[4])); | 119 | len = strlcpy(setup.phone, &(rcvmsg.msg_data.byte_array[4]), |
118 | strcpy(setup.eazmsn, | 120 | sizeof(setup.phone)); |
119 | sc_adapter[card]->channel[rcvmsg.phy_link_no-1].dn); | 121 | if (len >= sizeof(setup.phone)) |
122 | continue; | ||
123 | len = strlcpy(setup.eazmsn, | ||
124 | sc_adapter[card]->channel[rcvmsg.phy_link_no - 1].dn, | ||
125 | sizeof(setup.eazmsn)); | ||
126 | if (len >= sizeof(setup.eazmsn)) | ||
127 | continue; | ||
120 | setup.si1 = 7; | 128 | setup.si1 = 7; |
121 | setup.si2 = 0; | 129 | setup.si2 = 0; |
122 | setup.plan = 0; | 130 | setup.plan = 0; |
@@ -176,7 +184,9 @@ irqreturn_t interrupt_handler(int dummy, void *card_inst) | |||
176 | * Handle a GetMyNumber Rsp | 184 | * Handle a GetMyNumber Rsp |
177 | */ | 185 | */ |
178 | if (IS_CE_MESSAGE(rcvmsg,Call,0,GetMyNumber)){ | 186 | if (IS_CE_MESSAGE(rcvmsg,Call,0,GetMyNumber)){ |
179 | strcpy(sc_adapter[card]->channel[rcvmsg.phy_link_no-1].dn,rcvmsg.msg_data.byte_array); | 187 | strlcpy(sc_adapter[card]->channel[rcvmsg.phy_link_no - 1].dn, |
188 | rcvmsg.msg_data.byte_array, | ||
189 | sizeof(rcvmsg.msg_data.byte_array)); | ||
180 | continue; | 190 | continue; |
181 | } | 191 | } |
182 | 192 | ||