diff options
Diffstat (limited to 'drivers/isdn')
-rw-r--r-- | drivers/isdn/capi/capi.c | 54 | ||||
-rw-r--r-- | drivers/isdn/capi/capifs.c | 6 | ||||
-rw-r--r-- | drivers/isdn/divert/isdn_divert.c | 2 | ||||
-rw-r--r-- | drivers/isdn/gigaset/bas-gigaset.c | 298 | ||||
-rw-r--r-- | drivers/isdn/gigaset/common.c | 15 | ||||
-rw-r--r-- | drivers/isdn/gigaset/ev-layer.c | 13 | ||||
-rw-r--r-- | drivers/isdn/gigaset/gigaset.h | 1 | ||||
-rw-r--r-- | drivers/isdn/gigaset/interface.c | 10 | ||||
-rw-r--r-- | drivers/isdn/gigaset/proc.c | 21 | ||||
-rw-r--r-- | drivers/isdn/hardware/avm/b1pcmcia.c | 2 | ||||
-rw-r--r-- | drivers/isdn/hisax/hfc_pci.c | 2 | ||||
-rw-r--r-- | drivers/isdn/hisax/q931.c | 4 | ||||
-rw-r--r-- | drivers/isdn/hisax/sedlbauer_cs.c | 2 | ||||
-rw-r--r-- | drivers/isdn/hisax/teles3.c | 1 | ||||
-rw-r--r-- | drivers/isdn/hisax/telespci.c | 5 | ||||
-rw-r--r-- | drivers/isdn/i4l/isdn_common.c | 28 | ||||
-rw-r--r-- | drivers/isdn/i4l/isdn_tty.c | 2 | ||||
-rw-r--r-- | drivers/isdn/i4l/isdn_x25iface.c | 4 | ||||
-rw-r--r-- | drivers/isdn/sc/ioctl.c | 1 |
19 files changed, 288 insertions, 183 deletions
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 173c899a1fb4..2e541fa02024 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
@@ -87,6 +87,11 @@ struct capincci; | |||
87 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE | 87 | #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE |
88 | struct capiminor; | 88 | struct capiminor; |
89 | 89 | ||
90 | struct datahandle_queue { | ||
91 | struct list_head list; | ||
92 | u16 datahandle; | ||
93 | }; | ||
94 | |||
90 | struct capiminor { | 95 | struct capiminor { |
91 | struct list_head list; | 96 | struct list_head list; |
92 | struct capincci *nccip; | 97 | struct capincci *nccip; |
@@ -109,12 +114,9 @@ struct capiminor { | |||
109 | int outbytes; | 114 | int outbytes; |
110 | 115 | ||
111 | /* transmit path */ | 116 | /* transmit path */ |
112 | struct datahandle_queue { | 117 | struct list_head ackqueue; |
113 | struct datahandle_queue *next; | ||
114 | u16 datahandle; | ||
115 | } *ackqueue; | ||
116 | int nack; | 118 | int nack; |
117 | 119 | spinlock_t ackqlock; | |
118 | }; | 120 | }; |
119 | #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ | 121 | #endif /* CONFIG_ISDN_CAPI_MIDDLEWARE */ |
120 | 122 | ||
@@ -156,48 +158,54 @@ static LIST_HEAD(capiminor_list); | |||
156 | 158 | ||
157 | static int capincci_add_ack(struct capiminor *mp, u16 datahandle) | 159 | static int capincci_add_ack(struct capiminor *mp, u16 datahandle) |
158 | { | 160 | { |
159 | struct datahandle_queue *n, **pp; | 161 | struct datahandle_queue *n; |
162 | unsigned long flags; | ||
160 | 163 | ||
161 | n = kmalloc(sizeof(*n), GFP_ATOMIC); | 164 | n = kmalloc(sizeof(*n), GFP_ATOMIC); |
162 | if (!n) { | 165 | if (unlikely(!n)) { |
163 | printk(KERN_ERR "capi: alloc datahandle failed\n"); | 166 | printk(KERN_ERR "capi: alloc datahandle failed\n"); |
164 | return -1; | 167 | return -1; |
165 | } | 168 | } |
166 | n->next = NULL; | ||
167 | n->datahandle = datahandle; | 169 | n->datahandle = datahandle; |
168 | for (pp = &mp->ackqueue; *pp; pp = &(*pp)->next) ; | 170 | INIT_LIST_HEAD(&n->list); |
169 | *pp = n; | 171 | spin_lock_irqsave(&mp->ackqlock, flags); |
172 | list_add_tail(&n->list, &mp->ackqueue); | ||
170 | mp->nack++; | 173 | mp->nack++; |
174 | spin_unlock_irqrestore(&mp->ackqlock, flags); | ||
171 | return 0; | 175 | return 0; |
172 | } | 176 | } |
173 | 177 | ||
174 | static int capiminor_del_ack(struct capiminor *mp, u16 datahandle) | 178 | static int capiminor_del_ack(struct capiminor *mp, u16 datahandle) |
175 | { | 179 | { |
176 | struct datahandle_queue **pp, *p; | 180 | struct datahandle_queue *p, *tmp; |
181 | unsigned long flags; | ||
177 | 182 | ||
178 | for (pp = &mp->ackqueue; *pp; pp = &(*pp)->next) { | 183 | spin_lock_irqsave(&mp->ackqlock, flags); |
179 | if ((*pp)->datahandle == datahandle) { | 184 | list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) { |
180 | p = *pp; | 185 | if (p->datahandle == datahandle) { |
181 | *pp = (*pp)->next; | 186 | list_del(&p->list); |
182 | kfree(p); | 187 | kfree(p); |
183 | mp->nack--; | 188 | mp->nack--; |
189 | spin_unlock_irqrestore(&mp->ackqlock, flags); | ||
184 | return 0; | 190 | return 0; |
185 | } | 191 | } |
186 | } | 192 | } |
193 | spin_unlock_irqrestore(&mp->ackqlock, flags); | ||
187 | return -1; | 194 | return -1; |
188 | } | 195 | } |
189 | 196 | ||
190 | static void capiminor_del_all_ack(struct capiminor *mp) | 197 | static void capiminor_del_all_ack(struct capiminor *mp) |
191 | { | 198 | { |
192 | struct datahandle_queue **pp, *p; | 199 | struct datahandle_queue *p, *tmp; |
200 | unsigned long flags; | ||
193 | 201 | ||
194 | pp = &mp->ackqueue; | 202 | spin_lock_irqsave(&mp->ackqlock, flags); |
195 | while (*pp) { | 203 | list_for_each_entry_safe(p, tmp, &mp->ackqueue, list) { |
196 | p = *pp; | 204 | list_del(&p->list); |
197 | *pp = (*pp)->next; | ||
198 | kfree(p); | 205 | kfree(p); |
199 | mp->nack--; | 206 | mp->nack--; |
200 | } | 207 | } |
208 | spin_unlock_irqrestore(&mp->ackqlock, flags); | ||
201 | } | 209 | } |
202 | 210 | ||
203 | 211 | ||
@@ -220,6 +228,8 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) | |||
220 | mp->ncci = ncci; | 228 | mp->ncci = ncci; |
221 | mp->msgid = 0; | 229 | mp->msgid = 0; |
222 | atomic_set(&mp->ttyopencount,0); | 230 | atomic_set(&mp->ttyopencount,0); |
231 | INIT_LIST_HEAD(&mp->ackqueue); | ||
232 | spin_lock_init(&mp->ackqlock); | ||
223 | 233 | ||
224 | skb_queue_head_init(&mp->inqueue); | 234 | skb_queue_head_init(&mp->inqueue); |
225 | skb_queue_head_init(&mp->outqueue); | 235 | skb_queue_head_init(&mp->outqueue); |
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c index 0a37aded4b54..9ea6bd0ddc35 100644 --- a/drivers/isdn/capi/capifs.c +++ b/drivers/isdn/capi/capifs.c | |||
@@ -121,10 +121,10 @@ fail: | |||
121 | return -ENOMEM; | 121 | return -ENOMEM; |
122 | } | 122 | } |
123 | 123 | ||
124 | static struct super_block *capifs_get_sb(struct file_system_type *fs_type, | 124 | static int capifs_get_sb(struct file_system_type *fs_type, |
125 | int flags, const char *dev_name, void *data) | 125 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) |
126 | { | 126 | { |
127 | return get_sb_single(fs_type, flags, data, capifs_fill_super); | 127 | return get_sb_single(fs_type, flags, data, capifs_fill_super, mnt); |
128 | } | 128 | } |
129 | 129 | ||
130 | static struct file_system_type capifs_fs_type = { | 130 | static struct file_system_type capifs_fs_type = { |
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c index f1a1f9a9b88e..1f5ebe9ee72c 100644 --- a/drivers/isdn/divert/isdn_divert.c +++ b/drivers/isdn/divert/isdn_divert.c | |||
@@ -592,7 +592,7 @@ static int put_address(char *st, u_char *p, int len) | |||
592 | } /* put_address */ | 592 | } /* put_address */ |
593 | 593 | ||
594 | /*************************************/ | 594 | /*************************************/ |
595 | /* report a succesfull interrogation */ | 595 | /* report a successful interrogation */ |
596 | /*************************************/ | 596 | /*************************************/ |
597 | static int interrogate_success(isdn_ctrl *ic, struct call_struc *cs) | 597 | static int interrogate_success(isdn_ctrl *ic, struct call_struc *cs) |
598 | { char *src = ic->parm.dss1_io.data; | 598 | { char *src = ic->parm.dss1_io.data; |
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index eb41aba3ddef..8a45715dd4c1 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
@@ -65,23 +65,22 @@ static struct usb_device_id gigaset_table [] = { | |||
65 | 65 | ||
66 | MODULE_DEVICE_TABLE(usb, gigaset_table); | 66 | MODULE_DEVICE_TABLE(usb, gigaset_table); |
67 | 67 | ||
68 | /*======================= local function prototypes =============================*/ | 68 | /*======================= local function prototypes ==========================*/ |
69 | 69 | ||
70 | /* This function is called if a new device is connected to the USB port. It | 70 | /* function called if a new device belonging to this driver is connected */ |
71 | * checks whether this new device belongs to this driver. | ||
72 | */ | ||
73 | static int gigaset_probe(struct usb_interface *interface, | 71 | static int gigaset_probe(struct usb_interface *interface, |
74 | const struct usb_device_id *id); | 72 | const struct usb_device_id *id); |
75 | 73 | ||
76 | /* Function will be called if the device is unplugged */ | 74 | /* Function will be called if the device is unplugged */ |
77 | static void gigaset_disconnect(struct usb_interface *interface); | 75 | static void gigaset_disconnect(struct usb_interface *interface); |
78 | 76 | ||
79 | static void read_ctrl_callback(struct urb *, struct pt_regs *); | 77 | static int atread_submit(struct cardstate *, int); |
80 | static void stopurbs(struct bas_bc_state *); | 78 | static void stopurbs(struct bas_bc_state *); |
79 | static int req_submit(struct bc_state *, int, int, int); | ||
81 | static int atwrite_submit(struct cardstate *, unsigned char *, int); | 80 | static int atwrite_submit(struct cardstate *, unsigned char *, int); |
82 | static int start_cbsend(struct cardstate *); | 81 | static int start_cbsend(struct cardstate *); |
83 | 82 | ||
84 | /*==============================================================================*/ | 83 | /*============================================================================*/ |
85 | 84 | ||
86 | struct bas_cardstate { | 85 | struct bas_cardstate { |
87 | struct usb_device *udev; /* USB device pointer */ | 86 | struct usb_device *udev; /* USB device pointer */ |
@@ -91,6 +90,7 @@ struct bas_cardstate { | |||
91 | struct urb *urb_ctrl; /* control pipe default URB */ | 90 | struct urb *urb_ctrl; /* control pipe default URB */ |
92 | struct usb_ctrlrequest dr_ctrl; | 91 | struct usb_ctrlrequest dr_ctrl; |
93 | struct timer_list timer_ctrl; /* control request timeout */ | 92 | struct timer_list timer_ctrl; /* control request timeout */ |
93 | int retry_ctrl; | ||
94 | 94 | ||
95 | struct timer_list timer_atrdy; /* AT command ready timeout */ | 95 | struct timer_list timer_atrdy; /* AT command ready timeout */ |
96 | struct urb *urb_cmd_out; /* for sending AT commands */ | 96 | struct urb *urb_cmd_out; /* for sending AT commands */ |
@@ -307,6 +307,7 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag) | |||
307 | * hang up any existing connection because of an unrecoverable error | 307 | * hang up any existing connection because of an unrecoverable error |
308 | * This function may be called from any context and takes care of scheduling | 308 | * This function may be called from any context and takes care of scheduling |
309 | * the necessary actions for execution outside of interrupt context. | 309 | * the necessary actions for execution outside of interrupt context. |
310 | * cs->lock must not be held. | ||
310 | * argument: | 311 | * argument: |
311 | * B channel control structure | 312 | * B channel control structure |
312 | */ | 313 | */ |
@@ -325,14 +326,17 @@ static inline void error_hangup(struct bc_state *bcs) | |||
325 | 326 | ||
326 | /* error_reset | 327 | /* error_reset |
327 | * reset Gigaset device because of an unrecoverable error | 328 | * reset Gigaset device because of an unrecoverable error |
328 | * This function may be called from any context, and should take care of | 329 | * This function may be called from any context, and takes care of |
329 | * scheduling the necessary actions for execution outside of interrupt context. | 330 | * scheduling the necessary actions for execution outside of interrupt context. |
330 | * Right now, it just generates a kernel message calling for help. | 331 | * cs->lock must not be held. |
331 | * argument: | 332 | * argument: |
332 | * controller state structure | 333 | * controller state structure |
333 | */ | 334 | */ |
334 | static inline void error_reset(struct cardstate *cs) | 335 | static inline void error_reset(struct cardstate *cs) |
335 | { | 336 | { |
337 | /* close AT command channel to recover (ignore errors) */ | ||
338 | req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT); | ||
339 | |||
336 | //FIXME try to recover without bothering the user | 340 | //FIXME try to recover without bothering the user |
337 | dev_err(cs->dev, | 341 | dev_err(cs->dev, |
338 | "unrecoverable error - please disconnect Gigaset base to reset\n"); | 342 | "unrecoverable error - please disconnect Gigaset base to reset\n"); |
@@ -403,14 +407,30 @@ static void cmd_in_timeout(unsigned long data) | |||
403 | { | 407 | { |
404 | struct cardstate *cs = (struct cardstate *) data; | 408 | struct cardstate *cs = (struct cardstate *) data; |
405 | struct bas_cardstate *ucs = cs->hw.bas; | 409 | struct bas_cardstate *ucs = cs->hw.bas; |
410 | int rc; | ||
406 | 411 | ||
407 | if (!ucs->rcvbuf_size) { | 412 | if (!ucs->rcvbuf_size) { |
408 | gig_dbg(DEBUG_USBREQ, "%s: no receive in progress", __func__); | 413 | gig_dbg(DEBUG_USBREQ, "%s: no receive in progress", __func__); |
409 | return; | 414 | return; |
410 | } | 415 | } |
411 | 416 | ||
412 | dev_err(cs->dev, "timeout reading AT response\n"); | 417 | if (ucs->retry_cmd_in++ < BAS_RETRY) { |
413 | error_reset(cs); //FIXME retry? | 418 | dev_notice(cs->dev, "control read: timeout, retry %d\n", |
419 | ucs->retry_cmd_in); | ||
420 | rc = atread_submit(cs, BAS_TIMEOUT); | ||
421 | if (rc >= 0 || rc == -ENODEV) | ||
422 | /* resubmitted or disconnected */ | ||
423 | /* - bypass regular exit block */ | ||
424 | return; | ||
425 | } else { | ||
426 | dev_err(cs->dev, | ||
427 | "control read: timeout, giving up after %d tries\n", | ||
428 | ucs->retry_cmd_in); | ||
429 | } | ||
430 | kfree(ucs->rcvbuf); | ||
431 | ucs->rcvbuf = NULL; | ||
432 | ucs->rcvbuf_size = 0; | ||
433 | error_reset(cs); | ||
414 | } | 434 | } |
415 | 435 | ||
416 | /* set/clear bits in base connection state, return previous state | 436 | /* set/clear bits in base connection state, return previous state |
@@ -428,6 +448,96 @@ inline static int update_basstate(struct bas_cardstate *ucs, | |||
428 | return state; | 448 | return state; |
429 | } | 449 | } |
430 | 450 | ||
451 | /* read_ctrl_callback | ||
452 | * USB completion handler for control pipe input | ||
453 | * called by the USB subsystem in interrupt context | ||
454 | * parameter: | ||
455 | * urb USB request block | ||
456 | * urb->context = inbuf structure for controller state | ||
457 | */ | ||
458 | static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) | ||
459 | { | ||
460 | struct inbuf_t *inbuf = urb->context; | ||
461 | struct cardstate *cs = inbuf->cs; | ||
462 | struct bas_cardstate *ucs = cs->hw.bas; | ||
463 | int have_data = 0; | ||
464 | unsigned numbytes; | ||
465 | int rc; | ||
466 | |||
467 | update_basstate(ucs, 0, BS_ATRDPEND); | ||
468 | |||
469 | if (!ucs->rcvbuf_size) { | ||
470 | dev_warn(cs->dev, "%s: no receive in progress\n", __func__); | ||
471 | return; | ||
472 | } | ||
473 | |||
474 | del_timer(&ucs->timer_cmd_in); | ||
475 | |||
476 | switch (urb->status) { | ||
477 | case 0: /* normal completion */ | ||
478 | numbytes = urb->actual_length; | ||
479 | if (unlikely(numbytes != ucs->rcvbuf_size)) { | ||
480 | dev_warn(cs->dev, | ||
481 | "control read: received %d chars, expected %d\n", | ||
482 | numbytes, ucs->rcvbuf_size); | ||
483 | if (numbytes > ucs->rcvbuf_size) | ||
484 | numbytes = ucs->rcvbuf_size; | ||
485 | } | ||
486 | |||
487 | /* copy received bytes to inbuf */ | ||
488 | have_data = gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes); | ||
489 | |||
490 | if (unlikely(numbytes < ucs->rcvbuf_size)) { | ||
491 | /* incomplete - resubmit for remaining bytes */ | ||
492 | ucs->rcvbuf_size -= numbytes; | ||
493 | ucs->retry_cmd_in = 0; | ||
494 | rc = atread_submit(cs, BAS_TIMEOUT); | ||
495 | if (rc >= 0 || rc == -ENODEV) | ||
496 | /* resubmitted or disconnected */ | ||
497 | /* - bypass regular exit block */ | ||
498 | return; | ||
499 | error_reset(cs); | ||
500 | } | ||
501 | break; | ||
502 | |||
503 | case -ENOENT: /* cancelled */ | ||
504 | case -ECONNRESET: /* cancelled (async) */ | ||
505 | case -EINPROGRESS: /* pending */ | ||
506 | case -ENODEV: /* device removed */ | ||
507 | case -ESHUTDOWN: /* device shut down */ | ||
508 | /* no action necessary */ | ||
509 | gig_dbg(DEBUG_USBREQ, "%s: %s", | ||
510 | __func__, get_usb_statmsg(urb->status)); | ||
511 | break; | ||
512 | |||
513 | default: /* severe trouble */ | ||
514 | dev_warn(cs->dev, "control read: %s\n", | ||
515 | get_usb_statmsg(urb->status)); | ||
516 | if (ucs->retry_cmd_in++ < BAS_RETRY) { | ||
517 | dev_notice(cs->dev, "control read: retry %d\n", | ||
518 | ucs->retry_cmd_in); | ||
519 | rc = atread_submit(cs, BAS_TIMEOUT); | ||
520 | if (rc >= 0 || rc == -ENODEV) | ||
521 | /* resubmitted or disconnected */ | ||
522 | /* - bypass regular exit block */ | ||
523 | return; | ||
524 | } else { | ||
525 | dev_err(cs->dev, | ||
526 | "control read: giving up after %d tries\n", | ||
527 | ucs->retry_cmd_in); | ||
528 | } | ||
529 | error_reset(cs); | ||
530 | } | ||
531 | |||
532 | kfree(ucs->rcvbuf); | ||
533 | ucs->rcvbuf = NULL; | ||
534 | ucs->rcvbuf_size = 0; | ||
535 | if (have_data) { | ||
536 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); | ||
537 | gigaset_schedule_event(cs); | ||
538 | } | ||
539 | } | ||
540 | |||
431 | /* atread_submit | 541 | /* atread_submit |
432 | * submit an HD_READ_ATMESSAGE command URB and optionally start a timeout | 542 | * submit an HD_READ_ATMESSAGE command URB and optionally start a timeout |
433 | * parameters: | 543 | * parameters: |
@@ -466,7 +576,7 @@ static int atread_submit(struct cardstate *cs, int timeout) | |||
466 | if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) { | 576 | if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) { |
467 | update_basstate(ucs, 0, BS_ATRDPEND); | 577 | update_basstate(ucs, 0, BS_ATRDPEND); |
468 | dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n", | 578 | dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n", |
469 | get_usb_statmsg(ret)); | 579 | get_usb_rcmsg(ret)); |
470 | return ret; | 580 | return ret; |
471 | } | 581 | } |
472 | 582 | ||
@@ -611,9 +721,12 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
611 | kfree(ucs->rcvbuf); | 721 | kfree(ucs->rcvbuf); |
612 | ucs->rcvbuf = NULL; | 722 | ucs->rcvbuf = NULL; |
613 | ucs->rcvbuf_size = 0; | 723 | ucs->rcvbuf_size = 0; |
614 | if (rc != -ENODEV) | 724 | if (rc != -ENODEV) { |
615 | //FIXME corrective action? | 725 | //FIXME corrective action? |
726 | spin_unlock_irqrestore(&cs->lock, flags); | ||
616 | error_reset(cs); | 727 | error_reset(cs); |
728 | break; | ||
729 | } | ||
617 | } | 730 | } |
618 | spin_unlock_irqrestore(&cs->lock, flags); | 731 | spin_unlock_irqrestore(&cs->lock, flags); |
619 | break; | 732 | break; |
@@ -643,97 +756,6 @@ resubmit: | |||
643 | } | 756 | } |
644 | } | 757 | } |
645 | 758 | ||
646 | /* read_ctrl_callback | ||
647 | * USB completion handler for control pipe input | ||
648 | * called by the USB subsystem in interrupt context | ||
649 | * parameter: | ||
650 | * urb USB request block | ||
651 | * urb->context = inbuf structure for controller state | ||
652 | */ | ||
653 | static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) | ||
654 | { | ||
655 | struct inbuf_t *inbuf = urb->context; | ||
656 | struct cardstate *cs = inbuf->cs; | ||
657 | struct bas_cardstate *ucs = cs->hw.bas; | ||
658 | int have_data = 0; | ||
659 | unsigned numbytes; | ||
660 | int rc; | ||
661 | |||
662 | update_basstate(ucs, 0, BS_ATRDPEND); | ||
663 | |||
664 | if (!ucs->rcvbuf_size) { | ||
665 | dev_warn(cs->dev, "%s: no receive in progress\n", __func__); | ||
666 | return; | ||
667 | } | ||
668 | |||
669 | del_timer(&ucs->timer_cmd_in); | ||
670 | |||
671 | switch (urb->status) { | ||
672 | case 0: /* normal completion */ | ||
673 | numbytes = urb->actual_length; | ||
674 | if (unlikely(numbytes == 0)) { | ||
675 | dev_warn(cs->dev, | ||
676 | "control read: empty block received\n"); | ||
677 | goto retry; | ||
678 | } | ||
679 | if (unlikely(numbytes != ucs->rcvbuf_size)) { | ||
680 | dev_warn(cs->dev, | ||
681 | "control read: received %d chars, expected %d\n", | ||
682 | numbytes, ucs->rcvbuf_size); | ||
683 | if (numbytes > ucs->rcvbuf_size) | ||
684 | numbytes = ucs->rcvbuf_size; | ||
685 | } | ||
686 | |||
687 | /* copy received bytes to inbuf */ | ||
688 | have_data = gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes); | ||
689 | |||
690 | if (unlikely(numbytes < ucs->rcvbuf_size)) { | ||
691 | /* incomplete - resubmit for remaining bytes */ | ||
692 | ucs->rcvbuf_size -= numbytes; | ||
693 | ucs->retry_cmd_in = 0; | ||
694 | goto retry; | ||
695 | } | ||
696 | break; | ||
697 | |||
698 | case -ENOENT: /* cancelled */ | ||
699 | case -ECONNRESET: /* cancelled (async) */ | ||
700 | case -EINPROGRESS: /* pending */ | ||
701 | case -ENODEV: /* device removed */ | ||
702 | case -ESHUTDOWN: /* device shut down */ | ||
703 | /* no action necessary */ | ||
704 | gig_dbg(DEBUG_USBREQ, "%s: %s", | ||
705 | __func__, get_usb_statmsg(urb->status)); | ||
706 | break; | ||
707 | |||
708 | default: /* severe trouble */ | ||
709 | dev_warn(cs->dev, "control read: %s\n", | ||
710 | get_usb_statmsg(urb->status)); | ||
711 | retry: | ||
712 | if (ucs->retry_cmd_in++ < BAS_RETRY) { | ||
713 | dev_notice(cs->dev, "control read: retry %d\n", | ||
714 | ucs->retry_cmd_in); | ||
715 | rc = atread_submit(cs, BAS_TIMEOUT); | ||
716 | if (rc >= 0 || rc == -ENODEV) | ||
717 | /* resubmitted or disconnected */ | ||
718 | /* - bypass regular exit block */ | ||
719 | return; | ||
720 | } else { | ||
721 | dev_err(cs->dev, | ||
722 | "control read: giving up after %d tries\n", | ||
723 | ucs->retry_cmd_in); | ||
724 | } | ||
725 | error_reset(cs); | ||
726 | } | ||
727 | |||
728 | kfree(ucs->rcvbuf); | ||
729 | ucs->rcvbuf = NULL; | ||
730 | ucs->rcvbuf_size = 0; | ||
731 | if (have_data) { | ||
732 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); | ||
733 | gigaset_schedule_event(cs); | ||
734 | } | ||
735 | } | ||
736 | |||
737 | /* read_iso_callback | 759 | /* read_iso_callback |
738 | * USB completion handler for B channel isochronous input | 760 | * USB completion handler for B channel isochronous input |
739 | * called by the USB subsystem in interrupt context | 761 | * called by the USB subsystem in interrupt context |
@@ -1378,6 +1400,7 @@ static void req_timeout(unsigned long data) | |||
1378 | case HD_CLOSE_B1CHANNEL: | 1400 | case HD_CLOSE_B1CHANNEL: |
1379 | dev_err(bcs->cs->dev, "timeout closing channel %d\n", | 1401 | dev_err(bcs->cs->dev, "timeout closing channel %d\n", |
1380 | bcs->channel + 1); | 1402 | bcs->channel + 1); |
1403 | error_reset(bcs->cs); | ||
1381 | break; | 1404 | break; |
1382 | 1405 | ||
1383 | default: | 1406 | default: |
@@ -1396,22 +1419,61 @@ static void req_timeout(unsigned long data) | |||
1396 | static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs) | 1419 | static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs) |
1397 | { | 1420 | { |
1398 | struct bas_cardstate *ucs = urb->context; | 1421 | struct bas_cardstate *ucs = urb->context; |
1422 | int rc; | ||
1399 | unsigned long flags; | 1423 | unsigned long flags; |
1400 | 1424 | ||
1401 | spin_lock_irqsave(&ucs->lock, flags); | 1425 | /* check status */ |
1402 | if (urb->status && ucs->pending) { | 1426 | switch (urb->status) { |
1403 | dev_err(&ucs->interface->dev, | 1427 | case 0: /* normal completion */ |
1404 | "control request 0x%02x failed: %s\n", | 1428 | spin_lock_irqsave(&ucs->lock, flags); |
1405 | ucs->pending, get_usb_statmsg(urb->status)); | 1429 | switch (ucs->pending) { |
1406 | del_timer(&ucs->timer_ctrl); | 1430 | case HD_DEVICE_INIT_ACK: /* no reply expected */ |
1407 | ucs->pending = 0; | 1431 | del_timer(&ucs->timer_ctrl); |
1408 | } | 1432 | ucs->pending = 0; |
1409 | /* individual handling of specific request types */ | 1433 | break; |
1410 | switch (ucs->pending) { | 1434 | } |
1411 | case HD_DEVICE_INIT_ACK: /* no reply expected */ | 1435 | spin_unlock_irqrestore(&ucs->lock, flags); |
1412 | ucs->pending = 0; | 1436 | return; |
1437 | |||
1438 | case -ENOENT: /* cancelled */ | ||
1439 | case -ECONNRESET: /* cancelled (async) */ | ||
1440 | case -EINPROGRESS: /* pending */ | ||
1441 | case -ENODEV: /* device removed */ | ||
1442 | case -ESHUTDOWN: /* device shut down */ | ||
1443 | /* ignore silently */ | ||
1444 | gig_dbg(DEBUG_USBREQ, "%s: %s", | ||
1445 | __func__, get_usb_statmsg(urb->status)); | ||
1413 | break; | 1446 | break; |
1447 | |||
1448 | default: /* any failure */ | ||
1449 | if (++ucs->retry_ctrl > BAS_RETRY) { | ||
1450 | dev_err(&ucs->interface->dev, | ||
1451 | "control request 0x%02x failed: %s\n", | ||
1452 | ucs->dr_ctrl.bRequest, | ||
1453 | get_usb_statmsg(urb->status)); | ||
1454 | break; /* give up */ | ||
1455 | } | ||
1456 | dev_notice(&ucs->interface->dev, | ||
1457 | "control request 0x%02x: %s, retry %d\n", | ||
1458 | ucs->dr_ctrl.bRequest, get_usb_statmsg(urb->status), | ||
1459 | ucs->retry_ctrl); | ||
1460 | /* urb->dev is clobbered by USB subsystem */ | ||
1461 | urb->dev = ucs->udev; | ||
1462 | rc = usb_submit_urb(urb, SLAB_ATOMIC); | ||
1463 | if (unlikely(rc)) { | ||
1464 | dev_err(&ucs->interface->dev, | ||
1465 | "could not resubmit request 0x%02x: %s\n", | ||
1466 | ucs->dr_ctrl.bRequest, get_usb_rcmsg(rc)); | ||
1467 | break; | ||
1468 | } | ||
1469 | /* resubmitted */ | ||
1470 | return; | ||
1414 | } | 1471 | } |
1472 | |||
1473 | /* failed, clear pending request */ | ||
1474 | spin_lock_irqsave(&ucs->lock, flags); | ||
1475 | del_timer(&ucs->timer_ctrl); | ||
1476 | ucs->pending = 0; | ||
1415 | spin_unlock_irqrestore(&ucs->lock, flags); | 1477 | spin_unlock_irqrestore(&ucs->lock, flags); |
1416 | } | 1478 | } |
1417 | 1479 | ||
@@ -1455,9 +1517,11 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout) | |||
1455 | usb_sndctrlpipe(ucs->udev, 0), | 1517 | usb_sndctrlpipe(ucs->udev, 0), |
1456 | (unsigned char*) &ucs->dr_ctrl, NULL, 0, | 1518 | (unsigned char*) &ucs->dr_ctrl, NULL, 0, |
1457 | write_ctrl_callback, ucs); | 1519 | write_ctrl_callback, ucs); |
1458 | if ((ret = usb_submit_urb(ucs->urb_ctrl, SLAB_ATOMIC)) != 0) { | 1520 | ucs->retry_ctrl = 0; |
1521 | ret = usb_submit_urb(ucs->urb_ctrl, SLAB_ATOMIC); | ||
1522 | if (unlikely(ret)) { | ||
1459 | dev_err(bcs->cs->dev, "could not submit request 0x%02x: %s\n", | 1523 | dev_err(bcs->cs->dev, "could not submit request 0x%02x: %s\n", |
1460 | req, get_usb_statmsg(ret)); | 1524 | req, get_usb_rcmsg(ret)); |
1461 | spin_unlock_irqrestore(&ucs->lock, flags); | 1525 | spin_unlock_irqrestore(&ucs->lock, flags); |
1462 | return ret; | 1526 | return ret; |
1463 | } | 1527 | } |
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index e55767b2ccd3..2a56bf33a673 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
@@ -460,6 +460,9 @@ void gigaset_freecs(struct cardstate *cs) | |||
460 | 460 | ||
461 | switch (cs->cs_init) { | 461 | switch (cs->cs_init) { |
462 | default: | 462 | default: |
463 | /* clear device sysfs */ | ||
464 | gigaset_free_dev_sysfs(cs); | ||
465 | |||
463 | gigaset_if_free(cs); | 466 | gigaset_if_free(cs); |
464 | 467 | ||
465 | gig_dbg(DEBUG_INIT, "clearing hw"); | 468 | gig_dbg(DEBUG_INIT, "clearing hw"); |
@@ -699,6 +702,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
699 | cs->open_count = 0; | 702 | cs->open_count = 0; |
700 | cs->dev = NULL; | 703 | cs->dev = NULL; |
701 | cs->tty = NULL; | 704 | cs->tty = NULL; |
705 | cs->class = NULL; | ||
702 | cs->cidmode = cidmode != 0; | 706 | cs->cidmode = cidmode != 0; |
703 | 707 | ||
704 | //if(onechannel) { //FIXME | 708 | //if(onechannel) { //FIXME |
@@ -760,6 +764,9 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
760 | 764 | ||
761 | gigaset_if_init(cs); | 765 | gigaset_if_init(cs); |
762 | 766 | ||
767 | /* set up device sysfs */ | ||
768 | gigaset_init_dev_sysfs(cs); | ||
769 | |||
763 | spin_lock_irqsave(&cs->lock, flags); | 770 | spin_lock_irqsave(&cs->lock, flags); |
764 | cs->running = 1; | 771 | cs->running = 1; |
765 | spin_unlock_irqrestore(&cs->lock, flags); | 772 | spin_unlock_irqrestore(&cs->lock, flags); |
@@ -902,9 +909,6 @@ int gigaset_start(struct cardstate *cs) | |||
902 | 909 | ||
903 | wait_event(cs->waitqueue, !cs->waiting); | 910 | wait_event(cs->waitqueue, !cs->waiting); |
904 | 911 | ||
905 | /* set up device sysfs */ | ||
906 | gigaset_init_dev_sysfs(cs); | ||
907 | |||
908 | mutex_unlock(&cs->mutex); | 912 | mutex_unlock(&cs->mutex); |
909 | return 1; | 913 | return 1; |
910 | 914 | ||
@@ -969,9 +973,6 @@ void gigaset_stop(struct cardstate *cs) | |||
969 | //FIXME | 973 | //FIXME |
970 | } | 974 | } |
971 | 975 | ||
972 | /* clear device sysfs */ | ||
973 | gigaset_free_dev_sysfs(cs); | ||
974 | |||
975 | cleanup_cs(cs); | 976 | cleanup_cs(cs); |
976 | 977 | ||
977 | exit: | 978 | exit: |
@@ -980,7 +981,7 @@ exit: | |||
980 | EXPORT_SYMBOL_GPL(gigaset_stop); | 981 | EXPORT_SYMBOL_GPL(gigaset_stop); |
981 | 982 | ||
982 | static LIST_HEAD(drivers); | 983 | static LIST_HEAD(drivers); |
983 | static spinlock_t driver_lock = SPIN_LOCK_UNLOCKED; | 984 | static DEFINE_SPINLOCK(driver_lock); |
984 | 985 | ||
985 | struct cardstate *gigaset_get_cs_by_id(int id) | 986 | struct cardstate *gigaset_get_cs_by_id(int id) |
986 | { | 987 | { |
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index 18e05c09b71c..44f02dbd1111 100644 --- a/drivers/isdn/gigaset/ev-layer.c +++ b/drivers/isdn/gigaset/ev-layer.c | |||
@@ -1262,7 +1262,8 @@ static void do_action(int action, struct cardstate *cs, | |||
1262 | break; | 1262 | break; |
1263 | case ACT_HUPMODEM: | 1263 | case ACT_HUPMODEM: |
1264 | /* send "+++" (hangup in unimodem mode) */ | 1264 | /* send "+++" (hangup in unimodem mode) */ |
1265 | cs->ops->write_cmd(cs, "+++", 3, NULL); | 1265 | if (cs->connected) |
1266 | cs->ops->write_cmd(cs, "+++", 3, NULL); | ||
1266 | break; | 1267 | break; |
1267 | case ACT_RING: | 1268 | case ACT_RING: |
1268 | /* get fresh AT state structure for new CID */ | 1269 | /* get fresh AT state structure for new CID */ |
@@ -1294,7 +1295,6 @@ static void do_action(int action, struct cardstate *cs, | |||
1294 | break; | 1295 | break; |
1295 | case ACT_ICALL: | 1296 | case ACT_ICALL: |
1296 | handle_icall(cs, bcs, p_at_state); | 1297 | handle_icall(cs, bcs, p_at_state); |
1297 | at_state = *p_at_state; | ||
1298 | break; | 1298 | break; |
1299 | case ACT_FAILSDOWN: | 1299 | case ACT_FAILSDOWN: |
1300 | dev_warn(cs->dev, "Could not shut down the device.\n"); | 1300 | dev_warn(cs->dev, "Could not shut down the device.\n"); |
@@ -1334,10 +1334,8 @@ static void do_action(int action, struct cardstate *cs, | |||
1334 | */ | 1334 | */ |
1335 | at_state->pending_commands |= PC_DLE0; | 1335 | at_state->pending_commands |= PC_DLE0; |
1336 | atomic_set(&cs->commands_pending, 1); | 1336 | atomic_set(&cs->commands_pending, 1); |
1337 | } else { | 1337 | } else |
1338 | disconnect(p_at_state); | 1338 | disconnect(p_at_state); |
1339 | at_state = *p_at_state; | ||
1340 | } | ||
1341 | break; | 1339 | break; |
1342 | case ACT_FAKEDLE0: | 1340 | case ACT_FAKEDLE0: |
1343 | at_state->int_var[VAR_ZDLE] = 0; | 1341 | at_state->int_var[VAR_ZDLE] = 0; |
@@ -1354,10 +1352,8 @@ static void do_action(int action, struct cardstate *cs, | |||
1354 | at_state->cid = -1; | 1352 | at_state->cid = -1; |
1355 | if (bcs && cs->onechannel) | 1353 | if (bcs && cs->onechannel) |
1356 | at_state->pending_commands |= PC_DLE0; | 1354 | at_state->pending_commands |= PC_DLE0; |
1357 | else { | 1355 | else |
1358 | disconnect(p_at_state); | 1356 | disconnect(p_at_state); |
1359 | at_state = *p_at_state; | ||
1360 | } | ||
1361 | schedule_init(cs, MS_RECOVER); | 1357 | schedule_init(cs, MS_RECOVER); |
1362 | break; | 1358 | break; |
1363 | case ACT_FAILDLE0: | 1359 | case ACT_FAILDLE0: |
@@ -1410,7 +1406,6 @@ static void do_action(int action, struct cardstate *cs, | |||
1410 | 1406 | ||
1411 | case ACT_ABORTACCEPT: /* hangup/error/timeout during ICALL processing */ | 1407 | case ACT_ABORTACCEPT: /* hangup/error/timeout during ICALL processing */ |
1412 | disconnect(p_at_state); | 1408 | disconnect(p_at_state); |
1413 | at_state = *p_at_state; | ||
1414 | break; | 1409 | break; |
1415 | 1410 | ||
1416 | case ACT_ABORTDIAL: /* error/timeout during dial preparation */ | 1411 | case ACT_ABORTDIAL: /* error/timeout during dial preparation */ |
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index 22b9693f7c0a..8d63d822104f 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h | |||
@@ -445,6 +445,7 @@ struct cardstate { | |||
445 | struct gigaset_driver *driver; | 445 | struct gigaset_driver *driver; |
446 | unsigned minor_index; | 446 | unsigned minor_index; |
447 | struct device *dev; | 447 | struct device *dev; |
448 | struct class_device *class; | ||
448 | 449 | ||
449 | const struct gigaset_ops *ops; | 450 | const struct gigaset_ops *ops; |
450 | 451 | ||
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 08e4c4eea14d..74fd234956c8 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -625,7 +625,14 @@ void gigaset_if_init(struct cardstate *cs) | |||
625 | return; | 625 | return; |
626 | 626 | ||
627 | tasklet_init(&cs->if_wake_tasklet, &if_wake, (unsigned long) cs); | 627 | tasklet_init(&cs->if_wake_tasklet, &if_wake, (unsigned long) cs); |
628 | tty_register_device(drv->tty, cs->minor_index, NULL); | 628 | cs->class = tty_register_device(drv->tty, cs->minor_index, NULL); |
629 | |||
630 | if (!IS_ERR(cs->class)) | ||
631 | class_set_devdata(cs->class, cs); | ||
632 | else { | ||
633 | warn("could not register device to the tty subsystem"); | ||
634 | cs->class = NULL; | ||
635 | } | ||
629 | } | 636 | } |
630 | 637 | ||
631 | void gigaset_if_free(struct cardstate *cs) | 638 | void gigaset_if_free(struct cardstate *cs) |
@@ -638,6 +645,7 @@ void gigaset_if_free(struct cardstate *cs) | |||
638 | 645 | ||
639 | tasklet_disable(&cs->if_wake_tasklet); | 646 | tasklet_disable(&cs->if_wake_tasklet); |
640 | tasklet_kill(&cs->if_wake_tasklet); | 647 | tasklet_kill(&cs->if_wake_tasklet); |
648 | cs->class = NULL; | ||
641 | tty_unregister_device(drv->tty, cs->minor_index); | 649 | tty_unregister_device(drv->tty, cs->minor_index); |
642 | } | 650 | } |
643 | 651 | ||
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c index d267a636b53c..9ae3a7f3e7b3 100644 --- a/drivers/isdn/gigaset/proc.c +++ b/drivers/isdn/gigaset/proc.c | |||
@@ -16,12 +16,11 @@ | |||
16 | #include "gigaset.h" | 16 | #include "gigaset.h" |
17 | #include <linux/ctype.h> | 17 | #include <linux/ctype.h> |
18 | 18 | ||
19 | static ssize_t show_cidmode(struct device *dev, struct device_attribute *attr, | 19 | static ssize_t show_cidmode(struct class_device *class, char *buf) |
20 | char *buf) | ||
21 | { | 20 | { |
22 | int ret; | 21 | int ret; |
23 | unsigned long flags; | 22 | unsigned long flags; |
24 | struct cardstate *cs = dev_get_drvdata(dev); | 23 | struct cardstate *cs = class_get_devdata(class); |
25 | 24 | ||
26 | spin_lock_irqsave(&cs->lock, flags); | 25 | spin_lock_irqsave(&cs->lock, flags); |
27 | ret = sprintf(buf, "%u\n", cs->cidmode); | 26 | ret = sprintf(buf, "%u\n", cs->cidmode); |
@@ -30,10 +29,10 @@ static ssize_t show_cidmode(struct device *dev, struct device_attribute *attr, | |||
30 | return ret; | 29 | return ret; |
31 | } | 30 | } |
32 | 31 | ||
33 | static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, | 32 | static ssize_t set_cidmode(struct class_device *class, |
34 | const char *buf, size_t count) | 33 | const char *buf, size_t count) |
35 | { | 34 | { |
36 | struct cardstate *cs = dev_get_drvdata(dev); | 35 | struct cardstate *cs = class_get_devdata(class); |
37 | long int value; | 36 | long int value; |
38 | char *end; | 37 | char *end; |
39 | 38 | ||
@@ -65,18 +64,24 @@ static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, | |||
65 | return count; | 64 | return count; |
66 | } | 65 | } |
67 | 66 | ||
68 | static DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode); | 67 | static CLASS_DEVICE_ATTR(cidmode, S_IRUGO|S_IWUSR, show_cidmode, set_cidmode); |
69 | 68 | ||
70 | /* free sysfs for device */ | 69 | /* free sysfs for device */ |
71 | void gigaset_free_dev_sysfs(struct cardstate *cs) | 70 | void gigaset_free_dev_sysfs(struct cardstate *cs) |
72 | { | 71 | { |
72 | if (!cs->class) | ||
73 | return; | ||
74 | |||
73 | gig_dbg(DEBUG_INIT, "removing sysfs entries"); | 75 | gig_dbg(DEBUG_INIT, "removing sysfs entries"); |
74 | device_remove_file(cs->dev, &dev_attr_cidmode); | 76 | class_device_remove_file(cs->class, &class_device_attr_cidmode); |
75 | } | 77 | } |
76 | 78 | ||
77 | /* initialize sysfs for device */ | 79 | /* initialize sysfs for device */ |
78 | void gigaset_init_dev_sysfs(struct cardstate *cs) | 80 | void gigaset_init_dev_sysfs(struct cardstate *cs) |
79 | { | 81 | { |
82 | if (!cs->class) | ||
83 | return; | ||
84 | |||
80 | gig_dbg(DEBUG_INIT, "setting up sysfs"); | 85 | gig_dbg(DEBUG_INIT, "setting up sysfs"); |
81 | device_create_file(cs->dev, &dev_attr_cidmode); | 86 | class_device_create_file(cs->class, &class_device_attr_cidmode); |
82 | } | 87 | } |
diff --git a/drivers/isdn/hardware/avm/b1pcmcia.c b/drivers/isdn/hardware/avm/b1pcmcia.c index 9746cc5ffff8..ad5025155b4e 100644 --- a/drivers/isdn/hardware/avm/b1pcmcia.c +++ b/drivers/isdn/hardware/avm/b1pcmcia.c | |||
@@ -82,7 +82,7 @@ static int b1pcmcia_add_card(unsigned int port, unsigned irq, | |||
82 | card->irq = irq; | 82 | card->irq = irq; |
83 | card->cardtype = cardtype; | 83 | card->cardtype = cardtype; |
84 | 84 | ||
85 | retval = request_irq(card->irq, b1_interrupt, 0, card->name, card); | 85 | retval = request_irq(card->irq, b1_interrupt, SA_SHIRQ, card->name, card); |
86 | if (retval) { | 86 | if (retval) { |
87 | printk(KERN_ERR "b1pcmcia: unable to get IRQ %d.\n", | 87 | printk(KERN_ERR "b1pcmcia: unable to get IRQ %d.\n", |
88 | card->irq); | 88 | card->irq); |
diff --git a/drivers/isdn/hisax/hfc_pci.c b/drivers/isdn/hisax/hfc_pci.c index 91d25acb5ede..3622720f0505 100644 --- a/drivers/isdn/hisax/hfc_pci.c +++ b/drivers/isdn/hisax/hfc_pci.c | |||
@@ -1688,7 +1688,7 @@ setup_hfcpci(struct IsdnCard *card) | |||
1688 | printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); | 1688 | printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); |
1689 | return (0); | 1689 | return (0); |
1690 | } | 1690 | } |
1691 | cs->hw.hfcpci.pci_io = (char *) dev_hfcpci->resource[ 1].start; | 1691 | cs->hw.hfcpci.pci_io = (char *)(unsigned long)dev_hfcpci->resource[1].start; |
1692 | printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name); | 1692 | printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name); |
1693 | } else { | 1693 | } else { |
1694 | printk(KERN_WARNING "HFC-PCI: No PCI card found\n"); | 1694 | printk(KERN_WARNING "HFC-PCI: No PCI card found\n"); |
diff --git a/drivers/isdn/hisax/q931.c b/drivers/isdn/hisax/q931.c index abecabf8c271..aacbf0d14b64 100644 --- a/drivers/isdn/hisax/q931.c +++ b/drivers/isdn/hisax/q931.c | |||
@@ -1402,12 +1402,12 @@ dlogframe(struct IsdnCardState *cs, struct sk_buff *skb, int dir) | |||
1402 | } | 1402 | } |
1403 | /* No, locate it in the table */ | 1403 | /* No, locate it in the table */ |
1404 | if (cset == 0) { | 1404 | if (cset == 0) { |
1405 | for (i = 0; i < IESIZE; i++) | 1405 | for (i = 0; i < IESIZE_NI1; i++) |
1406 | if (*buf == ielist_ni1[i].nr) | 1406 | if (*buf == ielist_ni1[i].nr) |
1407 | break; | 1407 | break; |
1408 | 1408 | ||
1409 | /* When not found, give appropriate msg */ | 1409 | /* When not found, give appropriate msg */ |
1410 | if (i != IESIZE) { | 1410 | if (i != IESIZE_NI1) { |
1411 | dp += sprintf(dp, " %s\n", ielist_ni1[i].descr); | 1411 | dp += sprintf(dp, " %s\n", ielist_ni1[i].descr); |
1412 | dp += ielist_ni1[i].f(dp, buf); | 1412 | dp += ielist_ni1[i].f(dp, buf); |
1413 | } else | 1413 | } else |
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index 9bb18f3f7829..f9c14a2970bc 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c | |||
@@ -164,7 +164,7 @@ static int sedlbauer_probe(struct pcmcia_device *link) | |||
164 | link->priv = local; | 164 | link->priv = local; |
165 | 165 | ||
166 | /* Interrupt setup */ | 166 | /* Interrupt setup */ |
167 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | 167 | link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; |
168 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; | 168 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; |
169 | link->irq.Handler = NULL; | 169 | link->irq.Handler = NULL; |
170 | 170 | ||
diff --git a/drivers/isdn/hisax/teles3.c b/drivers/isdn/hisax/teles3.c index a3eaf4d65707..090abd16b4bc 100644 --- a/drivers/isdn/hisax/teles3.c +++ b/drivers/isdn/hisax/teles3.c | |||
@@ -369,6 +369,7 @@ setup_teles3(struct IsdnCard *card) | |||
369 | cs->hw.teles3.hscx[1] + 96); | 369 | cs->hw.teles3.hscx[1] + 96); |
370 | return (0); | 370 | return (0); |
371 | } | 371 | } |
372 | cs->irq_flags |= SA_SHIRQ; /* cardbus can share */ | ||
372 | } else { | 373 | } else { |
373 | if (cs->hw.teles3.cfg_reg) { | 374 | if (cs->hw.teles3.cfg_reg) { |
374 | if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { | 375 | if (cs->typ == ISDN_CTYPE_COMPAQ_ISA) { |
diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c index e2bb4fd8e25e..e82ab2251b82 100644 --- a/drivers/isdn/hisax/telespci.c +++ b/drivers/isdn/hisax/telespci.c | |||
@@ -311,8 +311,9 @@ setup_telespci(struct IsdnCard *card) | |||
311 | } | 311 | } |
312 | cs->hw.teles0.membase = ioremap(pci_resource_start(dev_tel, 0), | 312 | cs->hw.teles0.membase = ioremap(pci_resource_start(dev_tel, 0), |
313 | PAGE_SIZE); | 313 | PAGE_SIZE); |
314 | printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n", | 314 | printk(KERN_INFO "Found: Zoran, base-address: 0x%llx, irq: 0x%x\n", |
315 | pci_resource_start(dev_tel, 0), dev_tel->irq); | 315 | (unsigned long long)pci_resource_start(dev_tel, 0), |
316 | dev_tel->irq); | ||
316 | } else { | 317 | } else { |
317 | printk(KERN_WARNING "TelesPCI: No PCI card found\n"); | 318 | printk(KERN_WARNING "TelesPCI: No PCI card found\n"); |
318 | return(0); | 319 | return(0); |
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index 22759c01746a..eb21063e6f63 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c | |||
@@ -340,6 +340,16 @@ isdn_command(isdn_ctrl *cmd) | |||
340 | printk(KERN_WARNING "isdn_command command(%x) driver -1\n", cmd->command); | 340 | printk(KERN_WARNING "isdn_command command(%x) driver -1\n", cmd->command); |
341 | return(1); | 341 | return(1); |
342 | } | 342 | } |
343 | if (!dev->drv[cmd->driver]) { | ||
344 | printk(KERN_WARNING "isdn_command command(%x) dev->drv[%d] NULL\n", | ||
345 | cmd->command, cmd->driver); | ||
346 | return(1); | ||
347 | } | ||
348 | if (!dev->drv[cmd->driver]->interface) { | ||
349 | printk(KERN_WARNING "isdn_command command(%x) dev->drv[%d]->interface NULL\n", | ||
350 | cmd->command, cmd->driver); | ||
351 | return(1); | ||
352 | } | ||
343 | if (cmd->command == ISDN_CMD_SETL2) { | 353 | if (cmd->command == ISDN_CMD_SETL2) { |
344 | int idx = isdn_dc2minor(cmd->driver, cmd->arg & 255); | 354 | int idx = isdn_dc2minor(cmd->driver, cmd->arg & 255); |
345 | unsigned long l2prot = (cmd->arg >> 8) & 255; | 355 | unsigned long l2prot = (cmd->arg >> 8) & 255; |
@@ -933,7 +943,7 @@ isdn_readbchan_tty(int di, int channel, struct tty_struct *tty, int cisco_hack) | |||
933 | count_put = count_pull; | 943 | count_put = count_pull; |
934 | if(count_put > 1) | 944 | if(count_put > 1) |
935 | tty_insert_flip_string(tty, skb->data, count_put - 1); | 945 | tty_insert_flip_string(tty, skb->data, count_put - 1); |
936 | last = skb->data[count_put] - 1; | 946 | last = skb->data[count_put - 1]; |
937 | len -= count_put; | 947 | len -= count_put; |
938 | #ifdef CONFIG_ISDN_AUDIO | 948 | #ifdef CONFIG_ISDN_AUDIO |
939 | } | 949 | } |
@@ -1177,9 +1187,8 @@ isdn_write(struct file *file, const char __user *buf, size_t count, loff_t * off | |||
1177 | goto out; | 1187 | goto out; |
1178 | } | 1188 | } |
1179 | chidx = isdn_minor2chan(minor); | 1189 | chidx = isdn_minor2chan(minor); |
1180 | while (isdn_writebuf_stub(drvidx, chidx, buf, count) != count) | 1190 | while ((retval = isdn_writebuf_stub(drvidx, chidx, buf, count)) == 0) |
1181 | interruptible_sleep_on(&dev->drv[drvidx]->snd_waitq[chidx]); | 1191 | interruptible_sleep_on(&dev->drv[drvidx]->snd_waitq[chidx]); |
1182 | retval = count; | ||
1183 | goto out; | 1192 | goto out; |
1184 | } | 1193 | } |
1185 | if (minor <= ISDN_MINOR_CTRLMAX) { | 1194 | if (minor <= ISDN_MINOR_CTRLMAX) { |
@@ -1904,6 +1913,11 @@ isdn_free_channel(int di, int ch, int usage) | |||
1904 | { | 1913 | { |
1905 | int i; | 1914 | int i; |
1906 | 1915 | ||
1916 | if ((di < 0) || (ch < 0)) { | ||
1917 | printk(KERN_WARNING "%s: called with invalid drv(%d) or channel(%d)\n", | ||
1918 | __FUNCTION__, di, ch); | ||
1919 | return; | ||
1920 | } | ||
1907 | for (i = 0; i < ISDN_MAX_CHANNELS; i++) | 1921 | for (i = 0; i < ISDN_MAX_CHANNELS; i++) |
1908 | if (((!usage) || ((dev->usage[i] & ISDN_USAGE_MASK) == usage)) && | 1922 | if (((!usage) || ((dev->usage[i] & ISDN_USAGE_MASK) == usage)) && |
1909 | (dev->drvmap[i] == di) && | 1923 | (dev->drvmap[i] == di) && |
@@ -1919,7 +1933,8 @@ isdn_free_channel(int di, int ch, int usage) | |||
1919 | dev->v110[i] = NULL; | 1933 | dev->v110[i] = NULL; |
1920 | // 20.10.99 JIM, try to reinitialize v110 ! | 1934 | // 20.10.99 JIM, try to reinitialize v110 ! |
1921 | isdn_info_update(); | 1935 | isdn_info_update(); |
1922 | skb_queue_purge(&dev->drv[di]->rpqueue[ch]); | 1936 | if (dev->drv[di]) |
1937 | skb_queue_purge(&dev->drv[di]->rpqueue[ch]); | ||
1923 | } | 1938 | } |
1924 | } | 1939 | } |
1925 | 1940 | ||
@@ -1951,9 +1966,10 @@ isdn_writebuf_stub(int drvidx, int chan, const u_char __user * buf, int len) | |||
1951 | struct sk_buff *skb = alloc_skb(hl + len, GFP_ATOMIC); | 1966 | struct sk_buff *skb = alloc_skb(hl + len, GFP_ATOMIC); |
1952 | 1967 | ||
1953 | if (!skb) | 1968 | if (!skb) |
1954 | return 0; | 1969 | return -ENOMEM; |
1955 | skb_reserve(skb, hl); | 1970 | skb_reserve(skb, hl); |
1956 | copy_from_user(skb_put(skb, len), buf, len); | 1971 | if (copy_from_user(skb_put(skb, len), buf, len)) |
1972 | return -EFAULT; | ||
1957 | ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, 1, skb); | 1973 | ret = dev->drv[drvidx]->interface->writebuf_skb(drvidx, chan, 1, skb); |
1958 | if (ret <= 0) | 1974 | if (ret <= 0) |
1959 | dev_kfree_skb(skb); | 1975 | dev_kfree_skb(skb); |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 2ac90242d263..433389daedb2 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -82,7 +82,7 @@ isdn_tty_try_read(modem_info * info, struct sk_buff *skb) | |||
82 | int l = skb->len; | 82 | int l = skb->len; |
83 | unsigned char *dp = skb->data; | 83 | unsigned char *dp = skb->data; |
84 | while (--l) { | 84 | while (--l) { |
85 | if (*skb->data == DLE) | 85 | if (*dp == DLE) |
86 | tty_insert_flip_char(tty, DLE, 0); | 86 | tty_insert_flip_char(tty, DLE, 0); |
87 | tty_insert_flip_char(tty, *dp++, 0); | 87 | tty_insert_flip_char(tty, *dp++, 0); |
88 | } | 88 | } |
diff --git a/drivers/isdn/i4l/isdn_x25iface.c b/drivers/isdn/i4l/isdn_x25iface.c index 743ac4077f35..8b3efc243161 100644 --- a/drivers/isdn/i4l/isdn_x25iface.c +++ b/drivers/isdn/i4l/isdn_x25iface.c | |||
@@ -208,7 +208,7 @@ static int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb | |||
208 | */ | 208 | */ |
209 | static int isdn_x25iface_connect_ind(struct concap_proto *cprot) | 209 | static int isdn_x25iface_connect_ind(struct concap_proto *cprot) |
210 | { | 210 | { |
211 | struct sk_buff * skb = dev_alloc_skb(1); | 211 | struct sk_buff * skb; |
212 | enum wan_states *state_p | 212 | enum wan_states *state_p |
213 | = &( ( (ix25_pdata_t*) (cprot->proto_data) ) -> state); | 213 | = &( ( (ix25_pdata_t*) (cprot->proto_data) ) -> state); |
214 | IX25DEBUG( "isdn_x25iface_connect_ind %s \n" | 214 | IX25DEBUG( "isdn_x25iface_connect_ind %s \n" |
@@ -220,6 +220,8 @@ static int isdn_x25iface_connect_ind(struct concap_proto *cprot) | |||
220 | return -1; | 220 | return -1; |
221 | } | 221 | } |
222 | *state_p = WAN_CONNECTED; | 222 | *state_p = WAN_CONNECTED; |
223 | |||
224 | skb = dev_alloc_skb(1); | ||
223 | if( skb ){ | 225 | if( skb ){ |
224 | *( skb_put(skb, 1) ) = 0x01; | 226 | *( skb_put(skb, 1) ) = 0x01; |
225 | skb->protocol = x25_type_trans(skb, cprot->net_dev); | 227 | skb->protocol = x25_type_trans(skb, cprot->net_dev); |
diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c index f4f71226a078..57c4ab96d136 100644 --- a/drivers/isdn/sc/ioctl.c +++ b/drivers/isdn/sc/ioctl.c | |||
@@ -97,6 +97,7 @@ int sc_ioctl(int card, scs_ioctl *data) | |||
97 | 97 | ||
98 | case SCIOCSTART: | 98 | case SCIOCSTART: |
99 | { | 99 | { |
100 | kfree(rcvmsg); | ||
100 | pr_debug("%s: SCIOSTART: ioctl received\n", | 101 | pr_debug("%s: SCIOSTART: ioctl received\n", |
101 | sc_adapter[card]->devicename); | 102 | sc_adapter[card]->devicename); |
102 | if(sc_adapter[card]->EngineUp) { | 103 | if(sc_adapter[card]->EngineUp) { |