[PATCH] updates for "controller suspended" handling
authorDavid Brownell <david-b@pacbell.net>
Tue, 27 Sep 2005 17:38:54 +0000 (10:38 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 28 Oct 2005 23:47:41 +0000 (16:47 -0700)
Reject URBs to _all_ devices when their host controllers are suspended;
even root hub registers will be unavailable.  Also, don't reject urbs
to root hubs in other cases; the only upstream link is through that
controller (on PCI or whatever SOC bus is in use).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
 drivers/usb/core/hcd.c |   28 ++++++++++++----------------
 drivers/usb/core/urb.c |    3 ++-
 2 files changed, 14 insertions(+), 17 deletions(-)

drivers/usb/core/hcd.c
drivers/usb/core/urb.c

index de59bb515315d1b887acf3c91c537d1b61c796f3..b7bb8dd1894a434fb37e13acbf3c4acc733a8a5a 100644 (file)
@@ -458,22 +458,18 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
 
        default:
                /* non-generic request */
-               if (HC_IS_SUSPENDED (hcd->state))
-                       status = -EAGAIN;
-               else {
-                       switch (typeReq) {
-                       case GetHubStatus:
-                       case GetPortStatus:
-                               len = 4;
-                               break;
-                       case GetHubDescriptor:
-                               len = sizeof (struct usb_hub_descriptor);
-                               break;
-                       }
-                       status = hcd->driver->hub_control (hcd,
-                               typeReq, wValue, wIndex,
-                               tbuf, wLength);
+               switch (typeReq) {
+               case GetHubStatus:
+               case GetPortStatus:
+                       len = 4;
+                       break;
+               case GetHubDescriptor:
+                       len = sizeof (struct usb_hub_descriptor);
+                       break;
                }
+               status = hcd->driver->hub_control (hcd,
+                       typeReq, wValue, wIndex,
+                       tbuf, wLength);
                break;
 error:
                /* "protocol stall" on error */
@@ -487,7 +483,7 @@ error:
                                "CTRL: TypeReq=0x%x val=0x%x "
                                "idx=0x%x len=%d ==> %d\n",
                                typeReq, wValue, wIndex,
-                               wLength, urb->status);
+                               wLength, status);
                }
        }
        if (len) {
index b32898e0a27d1da41c256f346347275d495b268e..f2a1fed2a8024419e76e477fdd57bd8e55792f25 100644 (file)
@@ -237,7 +237,8 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
            (dev->state < USB_STATE_DEFAULT) ||
            (!dev->bus) || (dev->devnum <= 0))
                return -ENODEV;
-       if (dev->state == USB_STATE_SUSPENDED)
+       if (dev->bus->controller->power.power_state.event != PM_EVENT_ON
+                       || dev->state == USB_STATE_SUSPENDED)
                return -EHOSTUNREACH;
        if (!(op = dev->bus->op) || !op->submit_urb)
                return -ENODEV;