aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn')
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c106
1 files changed, 93 insertions, 13 deletions
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 540f6d0bb754..71e3fdee4410 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_*) */
@@ -595,6 +598,62 @@ static int atread_submit(struct cardstate *cs, int timeout)
595 return 0; 598 return 0;
596} 599}
597 600
601/* int_in_work
602 * workqueue routine to clear halt on interrupt in endpoint
603 */
604
605static 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 */
635static 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
598/* read_int_callback 657/* read_int_callback
599 * USB completion handler for interrupt pipe input 658 * USB completion handler for interrupt pipe input
600 * called by the USB subsystem in interrupt context 659 * called by the USB subsystem in interrupt context
@@ -615,19 +674,29 @@ static void read_int_callback(struct urb *urb)
615 674
616 switch (status) { 675 switch (status) {
617 case 0: /* success */ 676 case 0: /* success */
677 ucs->retry_int_in = 0;
618 break; 678 break;
679 case -EPIPE: /* endpoint stalled */
680 schedule_work(&ucs->int_in_wq);
681 /* fall through */
619 case -ENOENT: /* cancelled */ 682 case -ENOENT: /* cancelled */
620 case -ECONNRESET: /* cancelled (async) */ 683 case -ECONNRESET: /* cancelled (async) */
621 case -EINPROGRESS: /* pending */ 684 case -EINPROGRESS: /* pending */
622 /* ignore silently */ 685 case -ENODEV: /* device removed */
686 case -ESHUTDOWN: /* device shut down */
687 /* no further action necessary */
623 gig_dbg(DEBUG_USBREQ, "%s: %s", 688 gig_dbg(DEBUG_USBREQ, "%s: %s",
624 __func__, get_usb_statmsg(status)); 689 __func__, get_usb_statmsg(status));
625 return; 690 return;
626 case -ENODEV: /* device removed */ 691 case -EPROTO: /* protocol error or unplug */
627 case -ESHUTDOWN: /* device shut down */ 692 case -EILSEQ:
628 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);
629 return; 698 return;
630 default: /* severe trouble */ 699 default: /* other errors: just resubmit */
631 dev_warn(cs->dev, "interrupt read: %s\n", 700 dev_warn(cs->dev, "interrupt read: %s\n",
632 get_usb_statmsg(status)); 701 get_usb_statmsg(status));
633 goto resubmit; 702 goto resubmit;
@@ -705,6 +774,13 @@ static void read_int_callback(struct urb *urb)
705 break; 774 break;
706 } 775 }
707 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 }
708 if (ucs->rcvbuf_size) { 784 if (ucs->rcvbuf_size) {
709 /* throw away previous buffer - we have no queue */ 785 /* throw away previous buffer - we have no queue */
710 dev_err(cs->dev, 786 dev_err(cs->dev,
@@ -717,7 +793,6 @@ static void read_int_callback(struct urb *urb)
717 if (ucs->rcvbuf == NULL) { 793 if (ucs->rcvbuf == NULL) {
718 spin_unlock_irqrestore(&cs->lock, flags); 794 spin_unlock_irqrestore(&cs->lock, flags);
719 dev_err(cs->dev, "out of memory receiving AT data\n"); 795 dev_err(cs->dev, "out of memory receiving AT data\n");
720 error_reset(cs);
721 break; 796 break;
722 } 797 }
723 ucs->rcvbuf_size = l; 798 ucs->rcvbuf_size = l;
@@ -727,13 +802,10 @@ static void read_int_callback(struct urb *urb)
727 kfree(ucs->rcvbuf); 802 kfree(ucs->rcvbuf);
728 ucs->rcvbuf = NULL; 803 ucs->rcvbuf = NULL;
729 ucs->rcvbuf_size = 0; 804 ucs->rcvbuf_size = 0;
730 if (rc != -ENODEV) {
731 spin_unlock_irqrestore(&cs->lock, flags);
732 error_reset(cs);
733 break;
734 }
735 } 805 }
736 spin_unlock_irqrestore(&cs->lock, flags); 806 spin_unlock_irqrestore(&cs->lock, flags);
807 if (rc < 0 && rc != -ENODEV)
808 error_reset(cs);
737 break; 809 break;
738 810
739 case HD_RESET_INTERRUPT_PIPE_ACK: 811 case HD_RESET_INTERRUPT_PIPE_ACK:
@@ -2138,7 +2210,9 @@ static int gigaset_initcshw(struct cardstate *cs)
2138 setup_timer(&ucs->timer_ctrl, req_timeout, (unsigned long) cs); 2210 setup_timer(&ucs->timer_ctrl, req_timeout, (unsigned long) cs);
2139 setup_timer(&ucs->timer_atrdy, atrdy_timeout, (unsigned long) cs); 2211 setup_timer(&ucs->timer_atrdy, atrdy_timeout, (unsigned long) cs);
2140 setup_timer(&ucs->timer_cmd_in, cmd_in_timeout, (unsigned long) cs); 2212 setup_timer(&ucs->timer_cmd_in, cmd_in_timeout, (unsigned long) cs);
2213 setup_timer(&ucs->timer_int_in, int_in_resubmit, (unsigned long) cs);
2141 init_waitqueue_head(&ucs->waitqueue); 2214 init_waitqueue_head(&ucs->waitqueue);
2215 INIT_WORK(&ucs->int_in_wq, int_in_work);
2142 2216
2143 return 1; 2217 return 1;
2144} 2218}
@@ -2286,6 +2360,7 @@ static int gigaset_probe(struct usb_interface *interface,
2286 get_usb_rcmsg(rc)); 2360 get_usb_rcmsg(rc));
2287 goto error; 2361 goto error;
2288 } 2362 }
2363 ucs->retry_int_in = 0;
2289 2364
2290 /* tell the device that the driver is ready */ 2365 /* tell the device that the driver is ready */
2291 rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0); 2366 rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0);
@@ -2338,10 +2413,12 @@ static void gigaset_disconnect(struct usb_interface *interface)
2338 /* stop driver (common part) */ 2413 /* stop driver (common part) */
2339 gigaset_stop(cs); 2414 gigaset_stop(cs);
2340 2415
2341 /* stop timers and URBs, free ressources */ 2416 /* stop delayed work and URBs, free ressources */
2342 del_timer_sync(&ucs->timer_ctrl); 2417 del_timer_sync(&ucs->timer_ctrl);
2343 del_timer_sync(&ucs->timer_atrdy); 2418 del_timer_sync(&ucs->timer_atrdy);
2344 del_timer_sync(&ucs->timer_cmd_in); 2419 del_timer_sync(&ucs->timer_cmd_in);
2420 del_timer_sync(&ucs->timer_int_in);
2421 cancel_work_sync(&ucs->int_in_wq);
2345 freeurbs(cs); 2422 freeurbs(cs);
2346 usb_set_intfdata(interface, NULL); 2423 usb_set_intfdata(interface, NULL);
2347 kfree(ucs->rcvbuf); 2424 kfree(ucs->rcvbuf);
@@ -2404,12 +2481,14 @@ static int gigaset_suspend(struct usb_interface *intf, pm_message_t message)
2404 /* in case of timeout, proceed anyway */ 2481 /* in case of timeout, proceed anyway */
2405 } 2482 }
2406 2483
2407 /* kill all URBs and timers that might still be pending */ 2484 /* kill all URBs and delayed work that might still be pending */
2408 usb_kill_urb(ucs->urb_ctrl); 2485 usb_kill_urb(ucs->urb_ctrl);
2409 usb_kill_urb(ucs->urb_int_in); 2486 usb_kill_urb(ucs->urb_int_in);
2410 del_timer_sync(&ucs->timer_ctrl); 2487 del_timer_sync(&ucs->timer_ctrl);
2411 del_timer_sync(&ucs->timer_atrdy); 2488 del_timer_sync(&ucs->timer_atrdy);
2412 del_timer_sync(&ucs->timer_cmd_in); 2489 del_timer_sync(&ucs->timer_cmd_in);
2490 del_timer_sync(&ucs->timer_int_in);
2491 cancel_work_sync(&ucs->int_in_wq);
2413 2492
2414 gig_dbg(DEBUG_SUSPEND, "suspend complete"); 2493 gig_dbg(DEBUG_SUSPEND, "suspend complete");
2415 return 0; 2494 return 0;
@@ -2431,6 +2510,7 @@ static int gigaset_resume(struct usb_interface *intf)
2431 get_usb_rcmsg(rc)); 2510 get_usb_rcmsg(rc));
2432 return rc; 2511 return rc;
2433 } 2512 }
2513 ucs->retry_int_in = 0;
2434 2514
2435 /* clear suspend flag to reallow activity */ 2515 /* clear suspend flag to reallow activity */
2436 update_basstate(ucs, 0, BS_SUSPEND); 2516 update_basstate(ucs, 0, BS_SUSPEND);