summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2006-07-01 22:13:50 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-09-27 11:58:50 -0700
commit1c5df7e705671f11a71112eb3a1f9765cd1719f9 (patch)
tree40fcbab03d1c70fca992896feda057577edda5f2
parent114b368c07964caa3f4e1fa575b16e87fa11936c (diff)
usbcore: suspending devices with no driver
Since usb_generic can be unbound from a USB device, we need to be able to handle the possibility that a suspend or resume request arrives for a device with no driver. This patch (as735) arranges things so that resume requests will fail and suspend requests will use the standard USB port-suspend code. Attempts to suspend or resume an unbound interface are handled similarly (although the error caused by trying to resume an unbound interface is dropped by the calling routine). Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/core/driver.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index affbfb53eb5e..a5d11461f5a9 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -761,8 +761,12 @@ static int suspend_device(struct usb_device *udev, pm_message_t msg)
udev->state == USB_STATE_SUSPENDED)
goto done;
- if (udev->dev.driver == NULL)
+ /* For devices that don't have a driver, we do a standard suspend. */
+ if (udev->dev.driver == NULL) {
+ status = usb_port_suspend(udev);
goto done;
+ }
+
udriver = to_usb_device_driver(udev->dev.driver);
status = udriver->suspend(udev, msg);
@@ -782,8 +786,12 @@ static int resume_device(struct usb_device *udev)
udev->state != USB_STATE_SUSPENDED)
goto done;
- if (udev->dev.driver == NULL)
+ /* Can't resume it if it doesn't have a driver. */
+ if (udev->dev.driver == NULL) {
+ status = -ENOTCONN;
goto done;
+ }
+
udriver = to_usb_device_driver(udev->dev.driver);
status = udriver->resume(udev);
@@ -804,7 +812,7 @@ static int suspend_interface(struct usb_interface *intf, pm_message_t msg)
!is_active(intf))
goto done;
- if (intf->dev.driver == NULL)
+ if (intf->dev.driver == NULL) /* This can't happen */
goto done;
driver = to_usb_driver(intf->dev.driver);
@@ -838,8 +846,11 @@ static int resume_interface(struct usb_interface *intf)
is_active(intf))
goto done;
- if (intf->dev.driver == NULL)
+ /* Can't resume it if it doesn't have a driver. */
+ if (intf->dev.driver == NULL) {
+ status = -ENOTCONN;
goto done;
+ }
driver = to_usb_driver(intf->dev.driver);
if (driver->resume) {