On Fri, 5 Oct 2007, Oliver Neukum wrote:
> Am Freitag 05 Oktober 2007 schrieb Alan Stern:
> > As far as the race is concerned... In practice it shouldn't matter
> > unless autosuspend_delay is set to 0. I suppose autosuspend_check()
> > could take an extra "reschedule" flag. If the flag was set, the
> > routine would schedule another autosuspend attempt (with a 1-second
> > delay) if the idle-time period had already expired.
>
> OK. Like this?
I had in mind something a little more cautious, like this:
Alan Stern
Index: usb-2.6/drivers/usb/core/driver.c
===================================================================
--- usb-2.6.orig/drivers/usb/core/driver.c
+++ usb-2.6/drivers/usb/core/driver.c
@@ -935,7 +935,7 @@ done:
#ifdef CONFIG_USB_SUSPEND
/* Internal routine to check whether we may autosuspend a device. */
-static int autosuspend_check(struct usb_device *udev)
+static int autosuspend_check(struct usb_device *udev, int reschedule)
{
int i;
struct usb_interface *intf;
@@ -981,9 +981,15 @@ 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.
+ * enough, queue a delayed autosuspend request. If the device
+ * _has_ been idle for long enough and the reschedule flag is set,
+ * likewise queue a delayed (1 second) autosuspend request.
*/
- if (time_after(suspend_time, jiffies)) {
+ if (time_after(suspend_time, jiffies))
+ reschedule = 1;
+ else
+ suspend_time = jiffies + HZ;
+ if (reschedule) {
if (!timer_pending(&udev->autosuspend.timer)) {
/* The value of jiffies may change between the
@@ -993,7 +999,7 @@ static int autosuspend_check(struct usb_
* or for the past.
*/
queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend,
- round_jiffies_relative(suspend_time - jiffies));
+ round_jiffies(suspend_time));
}
return -EAGAIN;
}
@@ -1002,7 +1008,7 @@ static int autosuspend_check(struct usb_
#else
-static inline int autosuspend_check(struct usb_device *udev)
+static inline int autosuspend_check(struct usb_device *udev, int reschedule)
{
return 0;
}
@@ -1059,7 +1065,7 @@ static int usb_suspend_both(struct usb_d
udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
if (udev->auto_pm) {
- status = autosuspend_check(udev);
+ status = autosuspend_check(udev, 0);
if (status < 0)
goto done;
}
@@ -1085,7 +1091,7 @@ static int usb_suspend_both(struct usb_d
/* Try another autosuspend when the interfaces aren't busy */
if (udev->auto_pm)
- autosuspend_check(udev);
+ autosuspend_check(udev, status == -EBUSY);
/* If the suspend succeeded then prevent any more URB submissions,
* flush any outstanding URBs, and propagate the suspend up the tree.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
linux-usb-devel@xxxxxxxxxxxxxxxxxxxxx
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel
[Home]
[Video for Linux]
[Photo]
[Yosemite Forum]
[Yosemite Photos]
[Video Projectors]
[PDAs]
[Hacking TiVo]
[Linux Kernel]
[Linux SCSI]
[XFree86]
[Devices]
[Big List of Linux Books]
[Free Dating]