diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2009-08-19 12:22:06 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-09-23 09:46:37 -0400 |
commit | 3a44494e233c0fdd818d485cfea8998500543589 (patch) | |
tree | 04b66268a2efc1236d3f9e477a04dc2d3ec87582 /drivers/usb/host/ehci.h | |
parent | 04c4ab17c7c39603c5017bee20d3b8ccb2f19816 (diff) |
USB: EHCI: rescan the queue after an unlink
This patch (as1280) fixes an obscure bug in ehci-hcd's dequeuing logic
for async URBs. If a later URB is unlinked and the completion
routine unlinks an earlier URB, then the earlier URB won't be given
back in a timely manner because the endpoint queue isn't rescanned as
it should be.
Similar bugs occur if an endpoint is reset or a halt is cleared while
a completion routine is running, because the subroutines don't test
for the COMPLETING state.
All these problems are solved by adding a new needs_rescan flag to the
ehci_qh structure. If the flag is set while scanning through an idle
QH, the scan will be repeated. If the QH isn't idle then an unlink
cycle will be initiated, and the proper action will be taken when it
becomes idle.
Also, an unnecessary test is removed from qh_link_async(): That
routine is never called if the QH's state isn't IDLE.
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.h')
-rw-r--r-- | drivers/usb/host/ehci.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index ec3dba6b8e48..064e76821ff5 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -341,6 +341,7 @@ struct ehci_qh { | |||
341 | u32 refcount; | 341 | u32 refcount; |
342 | unsigned stamp; | 342 | unsigned stamp; |
343 | 343 | ||
344 | u8 needs_rescan; /* Dequeue during giveback */ | ||
344 | u8 qh_state; | 345 | u8 qh_state; |
345 | #define QH_STATE_LINKED 1 /* HC sees this */ | 346 | #define QH_STATE_LINKED 1 /* HC sees this */ |
346 | #define QH_STATE_UNLINK 2 /* HC may still see this */ | 347 | #define QH_STATE_UNLINK 2 /* HC may still see this */ |