aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-q.c
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/usb/host/ehci-q.c
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/usb/host/ehci-q.c')
-rw-r--r--drivers/usb/host/ehci-q.c19
1 files changed, 18 insertions, 1 deletions
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