diff options
author | Ming Lei <ming.lei@canonical.com> | 2013-07-03 14:53:10 (GMT) |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-12 18:43:48 (GMT) |
commit | 9118f9eb4f1e97a135de3f78853c411befcf9775 (patch) | |
tree | 1db640132f3a1dfbffbbe74ca2382c3239de8d90 /drivers/usb/host/ehci.h | |
parent | 35371e4fbc3e1863a6e7a79b8c17c25cc96a1380 (diff) | |
download | linux-9118f9eb4f1e97a135de3f78853c411befcf9775.tar.xz |
USB: EHCI: improve interrupt qh unlink
ehci-hcd currently unlinks an interrupt QH when it becomes empty, that
is, after its last URB completes. This works well because in almost
all cases, the completion handler for an interrupt URB resubmits the
URB; therefore the QH doesn't become empty and doesn't get unlinked.
When we start using tasklets for URB completion, this scheme won't work
as well. The resubmission won't occur until the tasklet runs, which
will be some time after the completion is queued with the tasklet.
During that delay, the QH will be empty and so will be unlinked
unnecessarily.
To prevent this problem, this patch adds a 5-ms time delay before empty
interrupt QHs are unlinked. Most often, during that time the interrupt
URB will be resubmitted and thus we can avoid unlinking the QH.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/ehci.h')
-rw-r--r-- | drivers/usb/host/ehci.h | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 64f9a08..9477520 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -88,6 +88,7 @@ enum ehci_hrtimer_event { EHCI_HRTIMER_POLL_DEAD, /* Wait for dead controller to stop */ EHCI_HRTIMER_UNLINK_INTR, /* Wait for interrupt QH unlink */ EHCI_HRTIMER_FREE_ITDS, /* Wait for unused iTDs and siTDs */ + EHCI_HRTIMER_START_UNLINK_INTR, /* Unlink empty interrupt QHs */ EHCI_HRTIMER_ASYNC_UNLINKS, /* Unlink empty async QHs */ EHCI_HRTIMER_IAA_WATCHDOG, /* Handle lost IAA interrupts */ EHCI_HRTIMER_DISABLE_PERIODIC, /* Wait to disable periodic sched */ @@ -143,7 +144,9 @@ struct ehci_hcd { /* one per controller */ unsigned i_thresh; /* uframes HC might cache */ union ehci_shadow *pshadow; /* mirror hw periodic table */ + struct list_head intr_unlink_wait; struct list_head intr_unlink; + unsigned intr_unlink_wait_cycle; unsigned intr_unlink_cycle; unsigned now_frame; /* frame from HC hardware */ unsigned last_iso_frame; /* last frame scanned for iso */ |