Skip to content

Commit

Permalink
USB: Don't resume root hub if the controller is suspended
Browse files Browse the repository at this point in the history
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 <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Jul 12, 2007
1 parent e7e6da9 commit cfa59da
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 6 deletions.
5 changes: 4 additions & 1 deletion drivers/usb/core/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1291,6 +1291,7 @@ int hcd_bus_resume(struct usb_device *rhdev)
{
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");
Expand All @@ -1309,9 +1310,11 @@ int hcd_bus_resume(struct usb_device *rhdev)
: 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;
}
Expand Down
3 changes: 1 addition & 2 deletions drivers/usb/gadget/dummy_hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1784,8 +1784,7 @@ static int dummy_bus_resume (struct usb_hcd *hcd)

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);
Expand Down
4 changes: 4 additions & 0 deletions drivers/usb/host/ehci-hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
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
Expand Down
5 changes: 2 additions & 3 deletions drivers/usb/host/uhci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -730,10 +730,9 @@ static int uhci_rh_resume(struct usb_hcd *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;
Expand Down

0 comments on commit cfa59da

Please sign in to comment.