Messages in this thread Patch in this message | | | Date | Tue, 22 Jul 2008 16:14:55 -0700 | From | Greg KH <> | Subject | [patch 11/47] USB: ehci - fix timer regression |
| |
2.6.25-stable review patch. If anyone has any objections, please let us know.
------------------ From: David Brownell <david-b@pacbell.net>
commit 056761e55c8687ddf3db14226213f2e8dc2689bc upstream
This patch fixes a regression in the EHCI driver's TIMER_IO_WATCHDOG behavior. The patch "USB: EHCI: add separate IAA watchdog timer" changed how that timer is handled, so that short timeouts on the remaining timer (unfortunately, overloaded) would never be used.
This takes a more direct approach, reorganizing the code slightly to be explicit about only the I/O watchdog role now being overridable. It also replaces a now-obsolete comment describing older timer behavior.
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: Leonid <leonidv11@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
--- drivers/usb/host/ehci.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
--- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -176,6 +176,15 @@ timer_action_done (struct ehci_hcd *ehci static inline void timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) { + /* Don't override timeouts which shrink or (later) disable + * the async ring; just the I/O watchdog. Note that if a + * SHRINK were pending, OFF would never be requested. + */ + if (timer_pending(&ehci->watchdog) + && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF)) + & ehci->actions)) + return; + if (!test_and_set_bit (action, &ehci->actions)) { unsigned long t; @@ -191,15 +200,7 @@ timer_action (struct ehci_hcd *ehci, enu t = EHCI_SHRINK_JIFFIES; break; } - t += jiffies; - // all timings except IAA watchdog can be overridden. - // async queue SHRINK often precedes IAA. while it's ready - // to go OFF neither can matter, and afterwards the IO - // watchdog stops unless there's still periodic traffic. - if (time_before_eq(t, ehci->watchdog.expires) - && timer_pending (&ehci->watchdog)) - return; - mod_timer (&ehci->watchdog, t); + mod_timer(&ehci->watchdog, t + jiffies); } } --
| |