Okay guys, it turns out that doing what you want isn't so hard if you
don't mind being a little bit unorthodox.
How do you like this patch? It goes on top of the one Greg already has in
his tree.
Those FIXMEs are okay, at least for now. The device lock is currently
needed only by the hub driver, which does have suspend/resume support.
If you want, this can be made to work without dropping and reacquiring
dev->sem. It would mean exporting a currently-private subroutine from the
driver core.
Alan Stern
Index: usb-2.6/drivers/usb/core/usb.c
===================================================================
--- usb-2.6.orig/drivers/usb/core/usb.c
+++ usb-2.6/drivers/usb/core/usb.c
@@ -1030,9 +1030,16 @@ static int usb_generic_suspend(struct de
else
mark_quiesced(intf);
} else {
- // FIXME else if there's no suspend method, disconnect...
- dev_warn(dev, "no %s?\n", "suspend");
- mark_quiesced(intf);
+ dev_warn(dev, "no suspend? unbinding...\n");
+ up(&dev->sem);
+
+ /*
+ * FIXME: You're not supposed to do this without holding
+ * the USB device lock. But we can't just grab the lock
+ * because our caller might already be holding it.
+ */
+ usb_driver_release_interface(driver, intf);
+ down(&dev->sem);
status = 0;
}
return status;
@@ -1059,9 +1066,22 @@ static int usb_generic_resume(struct dev
return usb_resume_device (to_usb_device(dev));
}
- if ((dev->driver == NULL) ||
- (dev->driver_data == &usb_generic_driver_data))
+ /* try to bind interfaces that have no driver */
+ if (dev->driver == NULL) {
+ up(&dev->sem);
+
+ /*
+ * FIXME: You're not supposed to do this without holding
+ * the USB device lock. But we can't just grab the lock
+ * because our caller might already be holding it.
+ */
+ device_attach(dev);
+ down(&dev->sem);
return 0;
+ }
+
+ if (dev->driver_data == &usb_generic_driver_data)
+ return 0; /* Shouldn't happen */
intf = to_usb_interface(dev);
driver = to_usb_driver(dev->driver);
@@ -1081,7 +1101,7 @@ static int usb_generic_resume(struct dev
mark_quiesced(intf);
}
} else
- dev_warn(dev, "no %s?\n", "resume");
+ dev_warn(dev, "no resume?\n");
return 0;
}
Index: usb-2.6/drivers/usb/core/hub.c
===================================================================
--- usb-2.6.orig/drivers/usb/core/hub.c
+++ usb-2.6/drivers/usb/core/hub.c
@@ -1893,12 +1893,6 @@ int usb_resume_device(struct usb_device
dev_dbg(&udev->dev, "can't resume, status %d\n",
status);
- /* rebind drivers that had no suspend() */
- if (status == 0) {
- usb_unlock_device(udev);
- bus_rescan_devices(&usb_bus_type);
- usb_lock_device(udev);
- }
return status;
}
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel