| From stern@rowland.harvard.edu Wed Apr 11 09:06:33 2007 |
| From: Alan Stern <stern@rowland.harvard.edu> |
| Date: Wed, 11 Apr 2007 12:06:16 -0400 (EDT) |
| Subject: USB: fix signed jiffies issue in autosuspend logic |
| To: Greg KH <gregkh@suse.de> |
| Cc: greg@kroah.com, <david-b@pacbell.net>, <linux-usb-devel@lists.sourceforge.net>, <oneukum@suse.de> |
| Message-ID: <Pine.LNX.4.44L0.0704111203150.4242-100000@iolanthe.rowland.org> |
| |
| |
| This patch (as897) changes the autosuspend timer code to use the |
| standard types and macros in dealing with jiffies values. |
| |
| Signed-off-by: Alan Stern <stern@rowland.harvard.edu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| |
| --- |
| drivers/usb/core/driver.c | 17 ++++++++++++----- |
| 1 file changed, 12 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/usb/core/driver.c |
| +++ b/drivers/usb/core/driver.c |
| @@ -932,7 +932,7 @@ static int autosuspend_check(struct usb_ |
| { |
| int i; |
| struct usb_interface *intf; |
| - long suspend_time; |
| + unsigned long suspend_time; |
| |
| /* For autosuspend, fail fast if anything is in use or autosuspend |
| * is disabled. Also fail if any interfaces require remote wakeup |
| @@ -964,11 +964,18 @@ static int autosuspend_check(struct usb_ |
| /* If everything is okay but the device hasn't been idle for long |
| * enough, queue a delayed autosuspend request. |
| */ |
| - suspend_time -= jiffies; |
| - if (suspend_time > 0) { |
| - if (!timer_pending(&udev->autosuspend.timer)) |
| + if (time_after(suspend_time, jiffies)) { |
| + if (!timer_pending(&udev->autosuspend.timer)) { |
| + |
| + /* The value of jiffies may change between the |
| + * time_after() comparison above and the subtraction |
| + * below. That's okay; the system behaves sanely |
| + * when a timer is registered for the present moment |
| + * or for the past. |
| + */ |
| queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, |
| - suspend_time); |
| + suspend_time - jiffies); |
| + } |
| return -EAGAIN; |
| } |
| return 0; |