aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-q.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-08-19 12:22:44 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 09:46:37 -0400
commita448c9d8c58ff7d3f8cc2a8f835065460099b22d (patch)
tree418610891b8dc271bbd798ff5c47d921be5f806d /drivers/usb/host/ehci-q.c
parent3a44494e233c0fdd818d485cfea8998500543589 (diff)
USB: EHCI: change deschedule logic for interrupt QHs
This patch (as1281) changes the way ehci-hcd deschedules interrupt QHs, copying the approach used for async QHs. The caller is no longer responsible for rescheduling the QH if its queue is non-empty; instead the reschedule is done directly by intr_deschedule(), after calling qh_completions(). This is exactly the same as how end_unlink_async() works. ehci_urb_dequeue() and intr_deschedule() now correctly handle the case where they are called while another interrupt URB for the same QH is being given back. This was a surprisingly large blind spot. And scan_periodic() now respects the new needs_rescan flag. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> 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.c12
1 files changed, 3 insertions, 9 deletions
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 57a84795c43f..00ad9ce392ed 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -299,7 +299,6 @@ __acquires(ehci->lock)
299static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh); 299static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);
300static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh); 300static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);
301 301
302static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
303static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh); 302static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
304 303
305/* 304/*
@@ -555,14 +554,9 @@ halt:
555 * That should be rare for interrupt transfers, 554 * That should be rare for interrupt transfers,
556 * except maybe high bandwidth ... 555 * except maybe high bandwidth ...
557 */ 556 */
558 if ((cpu_to_hc32(ehci, QH_SMASK) 557
559 & hw->hw_info2) != 0) { 558 /* Tell the caller to start an unlink */
560 intr_deschedule (ehci, qh); 559 qh->needs_rescan = 1;
561 (void) qh_schedule (ehci, qh);
562 } else {
563 /* Tell the caller to start an unlink */
564 qh->needs_rescan = 1;
565 }
566 break; 560 break;
567 /* otherwise, unlink already started */ 561 /* otherwise, unlink already started */
568 } 562 }