This is a note to let you know that I've just added the patch titled Subject: USB: autosuspend code consolidation
to my gregkh-2.6 tree. Its filename is usb-autosuspend-code-consolidation.patch This tree can be found at http://www.kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/patches/ >From [EMAIL PROTECTED] Mon Oct 30 14:06:47 2006 Date: Mon, 30 Oct 2006 17:06:45 -0500 (EST) From: Alan Stern <[EMAIL PROTECTED]> To: Greg KH <[EMAIL PROTECTED]>, Oliver Neukum <[EMAIL PROTECTED]> cc: USB development list <linux-usb-devel@lists.sourceforge.net> Subject: USB: autosuspend code consolidation Message-ID: <[EMAIL PROTECTED]> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII This patch (as813) gathers together common code for USB interface autosuspend/autoresume. It also adds some simple checking at the time an autosuspend request is made, to see whether the request will fail. This way we don't add a workqueue entry when it would end up doing nothing. Signed-off-by: Alan Stern <[EMAIL PROTECTED]> Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]> --- drivers/usb/core/driver.c | 112 +++++++++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 45 deletions(-) --- gregkh-2.6.orig/drivers/usb/core/driver.c +++ gregkh-2.6/drivers/usb/core/driver.c @@ -944,6 +944,36 @@ done: return status; } +/* Internal routine to check whether we may autosuspend a device. */ +static int autosuspend_check(struct usb_device *udev) +{ + int i; + struct usb_interface *intf; + + /* For autosuspend, fail fast if anything is in use. + * Also fail if any interfaces require remote wakeup but it + * isn't available. */ + udev->do_remote_wakeup = device_may_wakeup(&udev->dev); + if (udev->pm_usage_cnt > 0) + return -EBUSY; + if (udev->actconfig) { + for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { + intf = udev->actconfig->interface[i]; + if (!is_active(intf)) + continue; + if (intf->pm_usage_cnt > 0) + return -EBUSY; + if (intf->needs_remote_wakeup && + !udev->do_remote_wakeup) { + dev_dbg(&udev->dev, "remote wakeup needed " + "for autosuspend\n"); + return -EOPNOTSUPP; + } + } + } + return 0; +} + /** * usb_suspend_both - suspend a USB device and its interfaces * @udev: the usb_device to suspend @@ -995,28 +1025,10 @@ int usb_suspend_both(struct usb_device * udev->do_remote_wakeup = device_may_wakeup(&udev->dev); - /* For autosuspend, fail fast if anything is in use. - * Also fail if any interfaces require remote wakeup but it - * isn't available. */ if (udev->auto_pm) { - if (udev->pm_usage_cnt > 0) - return -EBUSY; - if (udev->actconfig) { - for (; i < udev->actconfig->desc.bNumInterfaces; i++) { - intf = udev->actconfig->interface[i]; - if (!is_active(intf)) - continue; - if (intf->pm_usage_cnt > 0) - return -EBUSY; - if (intf->needs_remote_wakeup && - !udev->do_remote_wakeup) { - dev_dbg(&udev->dev, - "remote wakeup needed for autosuspend\n"); - return -EOPNOTSUPP; - } - } - i = 0; - } + status = autosuspend_check(udev); + if (status < 0) + return status; } /* Suspend all the interfaces and then udev itself */ @@ -1155,7 +1167,7 @@ void usb_autosuspend_device(struct usb_d { usb_pm_lock(udev); udev->pm_usage_cnt -= dec_usage_cnt; - if (udev->pm_usage_cnt <= 0) + if (autosuspend_check(udev) == 0) queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, USB_AUTOSUSPEND_DELAY); usb_pm_unlock(udev); @@ -1204,6 +1216,33 @@ int usb_autoresume_device(struct usb_dev return status; } +/* Internal routine to adjust an interface's usage counter and change + * its device's autosuspend state. + */ +static int usb_autopm_do_interface(struct usb_interface *intf, + int inc_usage_cnt) +{ + struct usb_device *udev = interface_to_usbdev(intf); + int status = 0; + + usb_pm_lock(udev); + if (intf->condition == USB_INTERFACE_UNBOUND) + status = -ENODEV; + else { + intf->pm_usage_cnt += inc_usage_cnt; + if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) { + udev->auto_pm = 1; + status = usb_resume_both(udev); + if (status != 0) + intf->pm_usage_cnt -= inc_usage_cnt; + } else if (inc_usage_cnt <= 0 && autosuspend_check(udev) == 0) + queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, + USB_AUTOSUSPEND_DELAY); + } + usb_pm_unlock(udev); + return status; +} + /** * usb_autopm_put_interface - decrement a USB interface's PM-usage counter * @intf: the usb_interface whose counter should be decremented @@ -1237,17 +1276,11 @@ int usb_autoresume_device(struct usb_dev */ void usb_autopm_put_interface(struct usb_interface *intf) { - struct usb_device *udev = interface_to_usbdev(intf); + int status; - usb_pm_lock(udev); - if (intf->condition != USB_INTERFACE_UNBOUND && - --intf->pm_usage_cnt <= 0) { - queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, - USB_AUTOSUSPEND_DELAY); - } - usb_pm_unlock(udev); - // dev_dbg(&intf->dev, "%s: cnt %d\n", - // __FUNCTION__, intf->pm_usage_cnt); + status = usb_autopm_do_interface(intf, -1); + // dev_dbg(&intf->dev, "%s: status %d cnt %d\n", + // __FUNCTION__, status, intf->pm_usage_cnt); } EXPORT_SYMBOL_GPL(usb_autopm_put_interface); @@ -1284,20 +1317,9 @@ EXPORT_SYMBOL_GPL(usb_autopm_put_interfa */ int usb_autopm_get_interface(struct usb_interface *intf) { - struct usb_device *udev = interface_to_usbdev(intf); - int status; + int status; - usb_pm_lock(udev); - if (intf->condition == USB_INTERFACE_UNBOUND) - status = -ENODEV; - else { - ++intf->pm_usage_cnt; - udev->auto_pm = 1; - status = usb_resume_both(udev); - if (status != 0) - --intf->pm_usage_cnt; - } - usb_pm_unlock(udev); + status = usb_autopm_do_interface(intf, 1); // dev_dbg(&intf->dev, "%s: status %d cnt %d\n", // __FUNCTION__, status, intf->pm_usage_cnt); return status; Patches currently in gregkh-2.6 which might be from [EMAIL PROTECTED] are usb/ehci-hcd-fix-budget_pool-allocation-for-machines-with-multiple-ehci-controllers.patch usb/usb-core-don-t-match-interface-descriptors-for-vendor-specific-devices.patch usb/usb-hid-handle-stall-on-interrupt-endpoint.patch usb/usb-takes-31-devices-per-hub.patch usb/usb-hub-root-hub-code-takes-more-than-15-devices.patch usb/usb-ohci-disable-rhsc-inside-interrupt-handler.patch usb/usb-ohci-fix-root-hub-resume-bug.patch usb/usb-ohci-hcd-fix-compiler-warning.patch usb/usb-ohci-remove-stale-testing-code-from-root-hub-resume.patch usb/usb-autosuspend-code-consolidation.patch usb/usb-expand-autosuspend-autoresume-api.patch g-usb-hub-autosuspend-autoresume.patch g-ehci-repair-remote-wakeup-support.patch ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel