USB: EHCI: don't lose events during a scan
This patch (as1584) fixes a minor bug that has been present in ehci-hcd since the beginning. Scanning the schedules for URB completions is single-threaded. If a completion interrupt occurs while an URB is being given back, the interrupt handler realizes that a scan is in progress on another CPU and avoids starting a new one. This means that completion events can be lost. If an URB completes after it has been scanned but while a scan is still in progress, the driver won't notice and won't rescan the completed URB. The patch fixes the problem by adding a new flag to indicate that another scan is needed after the current scan is done. The flag gets set whenever a completion interrupt occurs while a scan is in progress. The rescan will see the completion, thus preventing it from getting lost. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
32830f2076
commit
361aabf395
@ -400,14 +400,21 @@ static void ehci_work (struct ehci_hcd *ehci)
|
||||
* it reports urb completions. this flag guards against bogus
|
||||
* attempts at re-entrant schedule scanning.
|
||||
*/
|
||||
if (ehci->scanning)
|
||||
if (ehci->scanning) {
|
||||
ehci->need_rescan = true;
|
||||
return;
|
||||
ehci->scanning = 1;
|
||||
}
|
||||
ehci->scanning = true;
|
||||
|
||||
rescan:
|
||||
ehci->need_rescan = false;
|
||||
if (ehci->async_count)
|
||||
scan_async(ehci);
|
||||
if (ehci->next_uframe != -1)
|
||||
scan_periodic (ehci);
|
||||
ehci->scanning = 0;
|
||||
if (ehci->need_rescan)
|
||||
goto rescan;
|
||||
ehci->scanning = false;
|
||||
|
||||
/* the IO watchdog guards against hardware or driver bugs that
|
||||
* misplace IRQs, and should let us run completely without IRQs.
|
||||
|
@ -113,7 +113,8 @@ struct ehci_hcd { /* one per controller */
|
||||
enum ehci_rh_state rh_state;
|
||||
|
||||
/* general schedule support */
|
||||
unsigned scanning:1;
|
||||
bool scanning:1;
|
||||
bool need_rescan:1;
|
||||
bool intr_unlinking:1;
|
||||
bool async_unlinking:1;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user