aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r--drivers/usb/host/ehci-hcd.c40
1 files changed, 20 insertions, 20 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 2b72473544d3..11c627ce6022 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -903,7 +903,8 @@ static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
903 /* already started */ 903 /* already started */
904 break; 904 break;
905 case QH_STATE_IDLE: 905 case QH_STATE_IDLE:
906 WARN_ON(1); 906 /* QH might be waiting for a Clear-TT-Buffer */
907 qh_completions(ehci, qh);
907 break; 908 break;
908 } 909 }
909 break; 910 break;
@@ -1003,6 +1004,8 @@ idle_timeout:
1003 schedule_timeout_uninterruptible(1); 1004 schedule_timeout_uninterruptible(1);
1004 goto rescan; 1005 goto rescan;
1005 case QH_STATE_IDLE: /* fully unlinked */ 1006 case QH_STATE_IDLE: /* fully unlinked */
1007 if (qh->clearing_tt)
1008 goto idle_timeout;
1006 if (list_empty (&qh->qtd_list)) { 1009 if (list_empty (&qh->qtd_list)) {
1007 qh_put (qh); 1010 qh_put (qh);
1008 break; 1011 break;
@@ -1030,12 +1033,14 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
1030 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 1033 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
1031 struct ehci_qh *qh; 1034 struct ehci_qh *qh;
1032 int eptype = usb_endpoint_type(&ep->desc); 1035 int eptype = usb_endpoint_type(&ep->desc);
1036 int epnum = usb_endpoint_num(&ep->desc);
1037 int is_out = usb_endpoint_dir_out(&ep->desc);
1038 unsigned long flags;
1033 1039
1034 if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT) 1040 if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
1035 return; 1041 return;
1036 1042
1037 rescan: 1043 spin_lock_irqsave(&ehci->lock, flags);
1038 spin_lock_irq(&ehci->lock);
1039 qh = ep->hcpriv; 1044 qh = ep->hcpriv;
1040 1045
1041 /* For Bulk and Interrupt endpoints we maintain the toggle state 1046 /* For Bulk and Interrupt endpoints we maintain the toggle state
@@ -1044,29 +1049,24 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
1044 * the toggle bit in the QH. 1049 * the toggle bit in the QH.
1045 */ 1050 */
1046 if (qh) { 1051 if (qh) {
1052 usb_settoggle(qh->dev, epnum, is_out, 0);
1047 if (!list_empty(&qh->qtd_list)) { 1053 if (!list_empty(&qh->qtd_list)) {
1048 WARN_ONCE(1, "clear_halt for a busy endpoint\n"); 1054 WARN_ONCE(1, "clear_halt for a busy endpoint\n");
1049 } else if (qh->qh_state == QH_STATE_IDLE) { 1055 } else if (qh->qh_state == QH_STATE_LINKED) {
1050 qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); 1056
1051 } else { 1057 /* The toggle value in the QH can't be updated
1052 /* It's not safe to write into the overlay area 1058 * while the QH is active. Unlink it now;
1053 * while the QH is active. Unlink it first and 1059 * re-linking will call qh_refresh().
1054 * wait for the unlink to complete.
1055 */ 1060 */
1056 if (qh->qh_state == QH_STATE_LINKED) { 1061 if (eptype == USB_ENDPOINT_XFER_BULK) {
1057 if (eptype == USB_ENDPOINT_XFER_BULK) { 1062 unlink_async(ehci, qh);
1058 unlink_async(ehci, qh); 1063 } else {
1059 } else { 1064 intr_deschedule(ehci, qh);
1060 intr_deschedule(ehci, qh); 1065 (void) qh_schedule(ehci, qh);
1061 (void) qh_schedule(ehci, qh);
1062 }
1063 } 1066 }
1064 spin_unlock_irq(&ehci->lock);
1065 schedule_timeout_uninterruptible(1);
1066 goto rescan;
1067 } 1067 }
1068 } 1068 }
1069 spin_unlock_irq(&ehci->lock); 1069 spin_unlock_irqrestore(&ehci->lock, flags);
1070} 1070}
1071 1071
1072static int ehci_get_frame (struct usb_hcd *hcd) 1072static int ehci_get_frame (struct usb_hcd *hcd)