aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-q.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2012-07-11 11:23:00 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-07-16 19:56:47 -0400
commit569b394f53f0abd177cc665c9b4ace89e3f4c7fb (patch)
tree030ce9c94e724f713155ffacc7caab7f459e9b96 /drivers/usb/host/ehci-q.c
parent361aabf395e4a23cf554cf4ec0c0c6963b8beb01 (diff)
USB: EHCI: always scan each interrupt QH
This patch (as1585) fixes a bug in ehci-hcd's scheme for scanning interrupt QHs. Currently a single routine takes care of scanning everything on the periodic schedule. Whenever an interrupt occurs, it scans all isochronous and interrupt URBs scheduled for frames that have elapsed since the last scan. This has two disadvantages. The first is relatively minor: An interrupt QH is likely to end up getting scanned multiple times, particularly if the last scan was not fairly recent. (The current code avoids this by maintaining a periodic_stamp in each interrupt QH.) The second is more serious. The periodic schedule wraps around. If the last scan occurred during frame N, and the next scan occurs when the schedule has gone through an entire cycle and is back at frame N, the scanning code won't look at any frames other than N. Consequently it won't see any QHs that completed during frame N-1 or earlier. The patch replaces the entire frame-based approach for scanning interrupt QHs with a new routine using a list-based approach, the same as for async QHs. This has a slight disadvantage, because it means that all interrupt QHs have to be scanned every time. But it is more robust than the current approach. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/ehci-q.c')
-rw-r--r--drivers/usb/host/ehci-q.c3
1 files changed, 1 insertions, 2 deletions
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index bae931767825..c9c7f7b3b7db 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -322,7 +322,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
322 * 322 *
323 * It's a bug for qh->qh_state to be anything other than 323 * It's a bug for qh->qh_state to be anything other than
324 * QH_STATE_IDLE, unless our caller is scan_async() or 324 * QH_STATE_IDLE, unless our caller is scan_async() or
325 * scan_periodic(). 325 * scan_intr().
326 */ 326 */
327 state = qh->qh_state; 327 state = qh->qh_state;
328 qh->qh_state = QH_STATE_COMPLETING; 328 qh->qh_state = QH_STATE_COMPLETING;
@@ -832,7 +832,6 @@ qh_make (
832 is_input, 0, 832 is_input, 0,
833 hb_mult(maxp) * max_packet(maxp))); 833 hb_mult(maxp) * max_packet(maxp)));
834 qh->start = NO_FRAME; 834 qh->start = NO_FRAME;
835 qh->stamp = ehci->periodic_stamp;
836 835
837 if (urb->dev->speed == USB_SPEED_HIGH) { 836 if (urb->dev->speed == USB_SPEED_HIGH) {
838 qh->c_usecs = 0; 837 qh->c_usecs = 0;