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 _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel