aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-06-11 14:56:22 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-07-12 18:16:36 -0400
commita455212d19d312f6a99b3a4a86fb79fb91dd76c7 (patch)
treecfd1cf74b6e51623813be2ec65e42f3756598252 /drivers
parent9525dcb30f5f412748f58a0537002ea47cfe55de (diff)
USB: EHCI: update toggle state for linked QHs
This is an update to the "usb-ehci-update-toggle-state-for-linked-qhs" patch. Since an HCD's endpoint_reset method can be called in interrupt context, it mustn't assume that interrupts are enabled or that it can sleep. So we revert to the original way of refreshing QHs' toggle bits. Now the endpoint_reset method merely clears the toggle flag in the device structure (as was done before) and starts an async QH unlink. When the QH is linked again, after the unlink finishes and an URB is queued, the qh_refresh() routine will update the QH's toggle bit. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Tested-by: David <david@unsolicited.net> CC: David Brownell <david-b@pacbell.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/host/ehci-hcd.c35
-rw-r--r--drivers/usb/host/ehci-q.c19
2 files changed, 34 insertions, 20 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 2b72473544d3..99c75603ec87 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1030,12 +1030,14 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
1030 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 1030 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
1031 struct ehci_qh *qh; 1031 struct ehci_qh *qh;
1032 int eptype = usb_endpoint_type(&ep->desc); 1032 int eptype = usb_endpoint_type(&ep->desc);
1033 int epnum = usb_endpoint_num(&ep->desc);
1034 int is_out = usb_endpoint_dir_out(&ep->desc);
1035 unsigned long flags;
1033 1036
1034 if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT) 1037 if (eptype != USB_ENDPOINT_XFER_BULK && eptype != USB_ENDPOINT_XFER_INT)
1035 return; 1038 return;
1036 1039
1037 rescan: 1040 spin_lock_irqsave(&ehci->lock, flags);
1038 spin_lock_irq(&ehci->lock);
1039 qh = ep->hcpriv; 1041 qh = ep->hcpriv;
1040 1042
1041 /* For Bulk and Interrupt endpoints we maintain the toggle state 1043 /* For Bulk and Interrupt endpoints we maintain the toggle state
@@ -1044,29 +1046,24 @@ ehci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep)
1044 * the toggle bit in the QH. 1046 * the toggle bit in the QH.
1045 */ 1047 */
1046 if (qh) { 1048 if (qh) {
1049 usb_settoggle(qh->dev, epnum, is_out, 0);
1047 if (!list_empty(&qh->qtd_list)) { 1050 if (!list_empty(&qh->qtd_list)) {
1048 WARN_ONCE(1, "clear_halt for a busy endpoint\n"); 1051 WARN_ONCE(1, "clear_halt for a busy endpoint\n");
1049 } else if (qh->qh_state == QH_STATE_IDLE) { 1052 } else if (qh->qh_state == QH_STATE_LINKED) {
1050 qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE); 1053
1051 } else { 1054 /* The toggle value in the QH can't be updated
1052 /* It's not safe to write into the overlay area 1055 * while the QH is active. Unlink it now;
1053 * while the QH is active. Unlink it first and 1056 * re-linking will call qh_refresh().
1054 * wait for the unlink to complete.
1055 */ 1057 */
1056 if (qh->qh_state == QH_STATE_LINKED) { 1058 if (eptype == USB_ENDPOINT_XFER_BULK) {
1057 if (eptype == USB_ENDPOINT_XFER_BULK) { 1059 unlink_async(ehci, qh);
1058 unlink_async(ehci, qh); 1060 } else {
1059 } else { 1061 intr_deschedule(ehci, qh);
1060 intr_deschedule(ehci, qh); 1062 (void) qh_schedule(ehci, qh);
1061 (void) qh_schedule(ehci, qh);
1062 }
1063 } 1063 }
1064 spin_unlock_irq(&ehci->lock);
1065 schedule_timeout_uninterruptible(1);
1066 goto rescan;
1067 } 1064 }
1068 } 1065 }
1069 spin_unlock_irq(&ehci->lock); 1066 spin_unlock_irqrestore(&ehci->lock, flags);
1070} 1067}
1071 1068
1072static int ehci_get_frame (struct usb_hcd *hcd) 1069static int ehci_get_frame (struct usb_hcd *hcd)
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 3192f683f807..1976b1b3778c 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -93,6 +93,22 @@ qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
93 qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma); 93 qh->hw_qtd_next = QTD_NEXT(ehci, qtd->qtd_dma);
94 qh->hw_alt_next = EHCI_LIST_END(ehci); 94 qh->hw_alt_next = EHCI_LIST_END(ehci);
95 95
96 /* Except for control endpoints, we make hardware maintain data
97 * toggle (like OHCI) ... here (re)initialize the toggle in the QH,
98 * and set the pseudo-toggle in udev. Only usb_clear_halt() will
99 * ever clear it.
100 */
101 if (!(qh->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) {
102 unsigned is_out, epnum;
103
104 is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8));
105 epnum = (hc32_to_cpup(ehci, &qh->hw_info1) >> 8) & 0x0f;
106 if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
107 qh->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
108 usb_settoggle (qh->dev, epnum, is_out, 1);
109 }
110 }
111
96 /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ 112 /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */
97 wmb (); 113 wmb ();
98 qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING); 114 qh->hw_token &= cpu_to_hc32(ehci, QTD_TOGGLE | QTD_STS_PING);
@@ -834,6 +850,7 @@ done:
834 qh->qh_state = QH_STATE_IDLE; 850 qh->qh_state = QH_STATE_IDLE;
835 qh->hw_info1 = cpu_to_hc32(ehci, info1); 851 qh->hw_info1 = cpu_to_hc32(ehci, info1);
836 qh->hw_info2 = cpu_to_hc32(ehci, info2); 852 qh->hw_info2 = cpu_to_hc32(ehci, info2);
853 usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
837 qh_refresh (ehci, qh); 854 qh_refresh (ehci, qh);
838 return qh; 855 return qh;
839} 856}
@@ -864,7 +881,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
864 } 881 }
865 } 882 }
866 883
867 /* clear halt and maybe recover from silicon quirk */ 884 /* clear halt and/or toggle; and maybe recover from silicon quirk */
868 if (qh->qh_state == QH_STATE_IDLE) 885 if (qh->qh_state == QH_STATE_IDLE)
869 qh_refresh (ehci, qh); 886 qh_refresh (ehci, qh);
870 887