diff options
author | Karsten Wiese <fzu@wemgehoertderstaat.de> | 2009-02-08 16:07:58 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-02-27 14:40:50 -0800 |
commit | 9aa09d2f8f4bc440d6db1c3414d4009642875240 (patch) | |
tree | 11b8735a5ddb24fcb4b810b9af3959a8aae6a1ae /drivers/usb/host/ehci.h | |
parent | 9a6e184c804b33a2c2ea974efcd3c9798d30cb39 (diff) | |
download | op-kernel-dev-9aa09d2f8f4bc440d6db1c3414d4009642875240.zip op-kernel-dev-9aa09d2f8f4bc440d6db1c3414d4009642875240.tar.gz |
USB: EHCI: slow down ITD reuse
Currently ITDs are immediately recycled whenever their URB completes.
However, EHCI hardware can sometimes remember some ITD state. This
means that when the ITD is reused before end-of-frame it may sometimes
cause the hardware to reference bogus state.
This patch defers reusing such ITDs by moving them into a new ehci member
cached_itd_list. ITDs resting in cached_itd_list are moved back into their
stream's free_list once scan_periodic() detects that the active frame has
elapsed.
This makes the snd_usb_us122l driver (in kernel since .28) work right
when it's hooked up through EHCI.
[ dbrownell@users.sourceforge.net: comment fixups ]
Signed-off-by: Karsten Wiese <fzu@wemgehoertderstaat.de>
Tested-by: Philippe Carriere <philippe-f.carriere@wanadoo.fr>
Tested-by: Federico Briata <federicobriata@gmail.com>
Cc: stable <stable@kernel.org>
Signed-off-by: David Brownell <dbrownell@users.sourceforge.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 | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index fb7054cc..262b00c 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -87,6 +87,10 @@ struct ehci_hcd { /* one per controller */ int next_uframe; /* scan periodic, start here */ unsigned periodic_sched; /* periodic activity count */ + /* list of itds completed while clock_frame was still active */ + struct list_head cached_itd_list; + unsigned clock_frame; + /* per root hub port */ unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; @@ -220,6 +224,8 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) } } +static void free_cached_itd_list(struct ehci_hcd *ehci); + /*-------------------------------------------------------------------------*/ #include <linux/usb/ehci_def.h> |