aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci.h
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-08-19 12:22:06 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 06:46:37 -0700
commit3a44494e233c0fdd818d485cfea8998500543589 (patch)
tree04b66268a2efc1236d3f9e477a04dc2d3ec87582 /drivers/usb/host/ehci.h
parent04c4ab17c7c39603c5017bee20d3b8ccb2f19816 (diff)
downloadkernel_samsung_smdk4412-3a44494e233c0fdd818d485cfea8998500543589.zip
kernel_samsung_smdk4412-3a44494e233c0fdd818d485cfea8998500543589.tar.gz
kernel_samsung_smdk4412-3a44494e233c0fdd818d485cfea8998500543589.tar.bz2
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.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index ec3dba6..064e768 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -341,6 +341,7 @@ struct ehci_qh {
u32 refcount;
unsigned stamp;
+ u8 needs_rescan; /* Dequeue during giveback */
u8 qh_state;
#define QH_STATE_LINKED 1 /* HC sees this */
#define QH_STATE_UNLINK 2 /* HC may still see this */