]> git.baikalelectronics.ru Git - kernel.git/commit
USB: EHCI: go back to using the system clock for QH unlinks
authorAlan Stern <stern@rowland.harvard.edu>
Tue, 5 Jul 2011 16:34:05 +0000 (12:34 -0400)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 8 Jul 2011 21:55:08 +0000 (14:55 -0700)
commitd560cd6040db2171041f6448787ae0efaacfe69a
tree646596c61f27983145b753549cc946e488c2a613
parent10425e105b557f797c2a4828b2b63dc8271b4f4f
USB: EHCI: go back to using the system clock for QH unlinks

This patch (as1477) fixes a problem affecting a few types of EHCI
controller.  Contrary to what one might expect, these controllers
automatically stop their internal frame counter when no ports are
enabled.  Since ehci-hcd currently relies on the frame counter for
determining when it should unlink QHs from the async schedule, those
controllers run into trouble: The frame counter stops and the QHs
never get unlinked.

Some systems have also experienced other problems traced back to
commit 256982fe0e7fd84c81d4cdaee62d26371c677d4f (USB: ehci-hcd unlink
speedups), which made the original switch from using the system clock
to using the frame counter.  It never became clear what the reason was
for these problems, but evidently it is related to use of the frame
counter.

To fix all these problems, this patch more or less reverts that commit
and goes back to using the system clock.  But this can't be done
cleanly because other changes have since been made to the scan_async()
subroutine.  One of these changes involved the tricky logic that tries
to avoid rescanning QHs that have already been seen when the scanning
loop is restarted, which happens whenever an URB is given back.
Switching back to clock-based unlinks would make this logic even more
complicated.

Therefore the new code doesn't rescan the entire async list whenever a
giveback occurs.  Instead it rescans only the current QH and continues
on from there.  This requires the use of a separate pointer to keep
track of the next QH to scan, since the current QH may be unlinked
while the scanning is in progress.  That new pointer must be global,
so that it can be adjusted forward whenever the _next_ QH gets
unlinked.  (uhci-hcd uses this same trick.)

Simplification of the scanning loop removes a level of indentation,
which accounts for the size of the patch.  The amount of code changed
is relatively small, and it isn't exactly a reversion of the
256982fe0e commit.

This fixes Bugzilla #32432.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: <stable@kernel.org>
Tested-by: Matej Kenda <matejken@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci.h