Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cfa59dab authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

USB: Don't resume root hub if the controller is suspended



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: default avatarAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent e7e6da9e
Loading
Loading
Loading
Loading
+4 −1
Original line number Original line Diff line number Diff line
@@ -1291,6 +1291,7 @@ int hcd_bus_resume(struct usb_device *rhdev)
{
{
	struct usb_hcd	*hcd = container_of(rhdev->bus, struct usb_hcd, self);
	struct usb_hcd	*hcd = container_of(rhdev->bus, struct usb_hcd, self);
	int		status;
	int		status;
	int		old_state = hcd->state;


	dev_dbg(&rhdev->dev, "usb %s%s\n",
	dev_dbg(&rhdev->dev, "usb %s%s\n",
			rhdev->auto_pm ? "auto-" : "", "resume");
			rhdev->auto_pm ? "auto-" : "", "resume");
@@ -1309,8 +1310,10 @@ int hcd_bus_resume(struct usb_device *rhdev)
				: USB_STATE_ADDRESS);
				: USB_STATE_ADDRESS);
		hcd->state = HC_STATE_RUNNING;
		hcd->state = HC_STATE_RUNNING;
	} else {
	} else {
		hcd->state = old_state;
		dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",
		dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",
				"resume", status);
				"resume", status);
		if (status != -ESHUTDOWN)
			usb_hc_died(hcd);
			usb_hc_died(hcd);
	}
	}
	return status;
	return status;
+1 −2
Original line number Original line Diff line number Diff line
@@ -1784,8 +1784,7 @@ static int dummy_bus_resume (struct usb_hcd *hcd)


	spin_lock_irq (&dum->lock);
	spin_lock_irq (&dum->lock);
	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
		dev_warn (&hcd->self.root_hub->dev, "HC isn't running!\n");
		rc = -ESHUTDOWN;
		rc = -ENODEV;
	} else {
	} else {
		dum->rh_state = DUMMY_RH_RUNNING;
		dum->rh_state = DUMMY_RH_RUNNING;
		set_link_state (dum);
		set_link_state (dum);
+4 −0
Original line number Original line Diff line number Diff line
@@ -199,6 +199,10 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
	if (time_before (jiffies, ehci->next_statechange))
	if (time_before (jiffies, ehci->next_statechange))
		msleep(5);
		msleep(5);
	spin_lock_irq (&ehci->lock);
	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
	/* 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
	 * was lost.  (For PCI, that means Vaux was maintained.)  But we
+2 −3
Original line number Original line Diff line number Diff line
@@ -730,10 +730,9 @@ static int uhci_rh_resume(struct usb_hcd *hcd)
	int rc = 0;
	int rc = 0;


	spin_lock_irq(&uhci->lock);
	spin_lock_irq(&uhci->lock);
	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
	if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
		dev_warn(&hcd->self.root_hub->dev, "HC isn't running!\n");
		rc = -ESHUTDOWN;
		rc = -ESHUTDOWN;
	} else if (!uhci->dead)
	else if (!uhci->dead)
		wakeup_rh(uhci);
		wakeup_rh(uhci);
	spin_unlock_irq(&uhci->lock);
	spin_unlock_irq(&uhci->lock);
	return rc;
	return rc;