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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
3a44494e23
commit
a448c9d8c5
@@ -299,7 +299,6 @@ __acquires(ehci->lock)
|
||||
static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);
|
||||
static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh);
|
||||
|
||||
static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
|
||||
static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh);
|
||||
|
||||
/*
|
||||
@@ -555,14 +554,9 @@ halt:
|
||||
* That should be rare for interrupt transfers,
|
||||
* except maybe high bandwidth ...
|
||||
*/
|
||||
if ((cpu_to_hc32(ehci, QH_SMASK)
|
||||
& hw->hw_info2) != 0) {
|
||||
intr_deschedule (ehci, qh);
|
||||
(void) qh_schedule (ehci, qh);
|
||||
} else {
|
||||
/* Tell the caller to start an unlink */
|
||||
qh->needs_rescan = 1;
|
||||
}
|
||||
|
||||
/* Tell the caller to start an unlink */
|
||||
qh->needs_rescan = 1;
|
||||
break;
|
||||
/* otherwise, unlink already started */
|
||||
}
|
||||
|
Reference in New Issue
Block a user