aboutsummaryrefslogtreecommitdiffstats
path: root/usb.current
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2008-06-10 14:42:12 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2008-06-10 14:42:12 -0700
commit64474ad89fec7cee464c540cfe198fdec8994559 (patch)
tree61c39d865af589fb7b3fc37996a755b356bc98ba /usb.current
parent939a2cc953ce8e2a4f55e97482ffc14a20cbc247 (diff)
downloadpatches-64474ad89fec7cee464c540cfe198fdec8994559.tar.gz
usb patch
Diffstat (limited to 'usb.current')
-rw-r--r--usb.current/usb-don-t-use-reset-resume-if-drivers-don-t-support-it.patch91
1 files changed, 91 insertions, 0 deletions
diff --git a/usb.current/usb-don-t-use-reset-resume-if-drivers-don-t-support-it.patch b/usb.current/usb-don-t-use-reset-resume-if-drivers-don-t-support-it.patch
new file mode 100644
index 00000000000000..69c424c627379f
--- /dev/null
+++ b/usb.current/usb-don-t-use-reset-resume-if-drivers-don-t-support-it.patch
@@ -0,0 +1,91 @@
+From stern@rowland.harvard.edu Tue Jun 10 14:31:37 2008
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Tue, 10 Jun 2008 14:59:43 -0400 (EDT)
+Subject: USB: don't use reset-resume if drivers don't support it
+To: Greg KH <greg@kroah.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>, Oliver Neukum <oliver@neukum.org>, Pavel Machek <pavel@suse.cz>, USB list <linux-usb@vger.kernel.org>, Andrew Morton <akpm@linuxfoundation.org>, kernel list <linux-kernel@vger.kernel.org>, "Rafael J. Wysocki" <rjw@sisk.pl>
+Message-ID: <Pine.LNX.4.44L0.0806101454480.3658-100000@iolanthe.rowland.org>
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+This patch tries to identify which devices are able to accept
+reset-resume handling, by checking that there is at least one
+interface driver bound and that all of the drivers have a reset_resume
+method defined. If these conditions don't hold then during resume
+processing, the device is logicall disconnected.
+
+This is only a temporary fix. Later on we will explicitly unbind
+drivers that can't handle reset-resumes.
+
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Cc: Oliver Neukum <oliver@neukum.org>
+Cc: Pavel Machek <pavel@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/hub.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 44 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -644,6 +644,48 @@ static void hub_stop(struct usb_hub *hub
+
+ #ifdef CONFIG_PM
+
++/* Try to identify which devices need USB-PERSIST handling */
++static int persistent_device(struct usb_device *udev)
++{
++ int i;
++ int retval;
++ struct usb_host_config *actconfig;
++
++ /* Explicitly not marked persistent? */
++ if (!udev->persist_enabled)
++ return 0;
++
++ /* No active config? */
++ actconfig = udev->actconfig;
++ if (!actconfig)
++ return 0;
++
++ /* FIXME! We should check whether it's open here or not! */
++
++ /*
++ * Check that all the interface drivers have a
++ * 'reset_resume' entrypoint
++ */
++ retval = 0;
++ for (i = 0; i < actconfig->desc.bNumInterfaces; i++) {
++ struct usb_interface *intf;
++ struct usb_driver *driver;
++
++ intf = actconfig->interface[i];
++ if (!intf->dev.driver)
++ continue;
++ driver = to_usb_driver(intf->dev.driver);
++ if (!driver->reset_resume)
++ return 0;
++ /*
++ * We have at least one driver, and that one
++ * has a reset_resume method.
++ */
++ retval = 1;
++ }
++ return retval;
++}
++
+ static void hub_restart(struct usb_hub *hub, int type)
+ {
+ struct usb_device *hdev = hub->hdev;
+@@ -689,8 +731,8 @@ static void hub_restart(struct usb_hub *
+ * turn off the various status changes to prevent
+ * khubd from disconnecting it later.
+ */
+- if (udev->persist_enabled && status == 0 &&
+- !(portstatus & USB_PORT_STAT_ENABLE)) {
++ if (status == 0 && !(portstatus & USB_PORT_STAT_ENABLE) &&
++ persistent_device(udev)) {
+ if (portchange & USB_PORT_STAT_C_ENABLE)
+ clear_port_feature(hub->hdev, port1,
+ USB_PORT_FEAT_C_ENABLE);