]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
USB: ehci - fix timer regression
authorDavid Brownell <david-b@pacbell.net>
Fri, 4 Jul 2008 05:20:28 +0000 (05:20 +0000)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 24 Jul 2008 16:14:04 +0000 (09:14 -0700)
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

index bf92d209a1a9bad0091983ce0d35ff5ee0fc011e..888e81e607c84b7a1a4b77f33c04ae5a588c4da6 100644 (file)
@@ -176,6 +176,15 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action)
 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, enum ehci_timer_action action)
                        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);
        }
 }