Root hubs can't be resumed if their parent controller device is still suspended. This patch (as925) adds a check for that condition in hcd_bus_resume() and prevents it from being treated as a fatal controller failure.
ehci-hcd is updated to add the corresponding test. Unnecessary debugging messages are removed from uhci-hcd and dummy-hcd. The error return code from dummy-hcd is changed to -ESHUTDOWN, the same as the others. ohci-hcd doesn't need any changes. Suspend handling in the non-PCI host drivers is somewhat hit-and-miss. This patch shouldn't have any effect on them. Signed-off-by: Alan Stern <[EMAIL PROTECTED]> --- This particular failure scenario is unlikely to occur; about the only thing that could cause it would be the ksuspend_usb thread trying to do something while it was supposed to be frozen. Still, I think it's good to make the drivers detect the error and return consistent codes... just in case. Index: usb-2.6/drivers/usb/core/hcd.c =================================================================== --- usb-2.6.orig/drivers/usb/core/hcd.c +++ usb-2.6/drivers/usb/core/hcd.c @@ -1276,6 +1276,7 @@ int hcd_bus_resume(struct usb_device *rh { struct usb_hcd *hcd = container_of(rhdev->bus, struct usb_hcd, self); int status; + int old_state = hcd->state; dev_dbg(&rhdev->dev, "usb %s%s\n", rhdev->auto_pm ? "auto-" : "", "resume"); @@ -1294,9 +1295,11 @@ int hcd_bus_resume(struct usb_device *rh : USB_STATE_ADDRESS); hcd->state = HC_STATE_RUNNING; } else { + hcd->state = old_state; dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", "resume", status); - usb_hc_died(hcd); + if (status != -ESHUTDOWN) + usb_hc_died(hcd); } return status; } Index: usb-2.6/drivers/usb/host/ehci-hub.c =================================================================== --- usb-2.6.orig/drivers/usb/host/ehci-hub.c +++ usb-2.6/drivers/usb/host/ehci-hub.c @@ -199,6 +199,10 @@ static int ehci_bus_resume (struct usb_h if (time_before (jiffies, ehci->next_statechange)) msleep(5); spin_lock_irq (&ehci->lock); + if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { + spin_unlock_irq(&ehci->lock); + return -ESHUTDOWN; + } /* Ideally and we've got a real resume here, and no port's power * was lost. (For PCI, that means Vaux was maintained.) But we Index: usb-2.6/drivers/usb/host/uhci-hcd.c =================================================================== --- usb-2.6.orig/drivers/usb/host/uhci-hcd.c +++ usb-2.6/drivers/usb/host/uhci-hcd.c @@ -730,10 +730,9 @@ static int uhci_rh_resume(struct usb_hcd int rc = 0; spin_lock_irq(&uhci->lock); - if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { - dev_warn(&hcd->self.root_hub->dev, "HC isn't running!\n"); + if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) rc = -ESHUTDOWN; - } else if (!uhci->dead) + else if (!uhci->dead) wakeup_rh(uhci); spin_unlock_irq(&uhci->lock); return rc; Index: usb-2.6/drivers/usb/gadget/dummy_hcd.c =================================================================== --- usb-2.6.orig/drivers/usb/gadget/dummy_hcd.c +++ usb-2.6/drivers/usb/gadget/dummy_hcd.c @@ -1784,8 +1784,7 @@ static int dummy_bus_resume (struct usb_ spin_lock_irq (&dum->lock); if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { - dev_warn (&hcd->self.root_hub->dev, "HC isn't running!\n"); - rc = -ENODEV; + rc = -ESHUTDOWN; } else { dum->rh_state = DUMMY_RH_RUNNING; set_link_state (dum); ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel