aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-06-21 16:25:35 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-07-12 19:34:39 -0400
commitcfa59dab27d1b282886e7772a8f9548236883892 (patch)
treeaaf71c0fb69d5133bfc71451d6541f1b49494dbb /drivers/usb
parente7e6da9eb189dfa221e3bf9c21d58f02adc8983c (diff)
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: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/core/hcd.c5
-rw-r--r--drivers/usb/gadget/dummy_hcd.c3
-rw-r--r--drivers/usb/host/ehci-hub.c4
-rw-r--r--drivers/usb/host/uhci-hcd.c5
4 files changed, 11 insertions, 6 deletions
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 5254c50086a8..963520fbef90 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1291,6 +1291,7 @@ int hcd_bus_resume(struct usb_device *rhdev)
1291{ 1291{
1292 struct usb_hcd *hcd = container_of(rhdev->bus, struct usb_hcd, self); 1292 struct usb_hcd *hcd = container_of(rhdev->bus, struct usb_hcd, self);
1293 int status; 1293 int status;
1294 int old_state = hcd->state;
1294 1295
1295 dev_dbg(&rhdev->dev, "usb %s%s\n", 1296 dev_dbg(&rhdev->dev, "usb %s%s\n",
1296 rhdev->auto_pm ? "auto-" : "", "resume"); 1297 rhdev->auto_pm ? "auto-" : "", "resume");
@@ -1309,9 +1310,11 @@ int hcd_bus_resume(struct usb_device *rhdev)
1309 : USB_STATE_ADDRESS); 1310 : USB_STATE_ADDRESS);
1310 hcd->state = HC_STATE_RUNNING; 1311 hcd->state = HC_STATE_RUNNING;
1311 } else { 1312 } else {
1313 hcd->state = old_state;
1312 dev_dbg(&rhdev->dev, "bus %s fail, err %d\n", 1314 dev_dbg(&rhdev->dev, "bus %s fail, err %d\n",
1313 "resume", status); 1315 "resume", status);
1314 usb_hc_died(hcd); 1316 if (status != -ESHUTDOWN)
1317 usb_hc_died(hcd);
1315 } 1318 }
1316 return status; 1319 return status;
1317} 1320}
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index fcb5526cb085..9040b50d6425 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -1784,8 +1784,7 @@ static int dummy_bus_resume (struct usb_hcd *hcd)
1784 1784
1785 spin_lock_irq (&dum->lock); 1785 spin_lock_irq (&dum->lock);
1786 if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { 1786 if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
1787 dev_warn (&hcd->self.root_hub->dev, "HC isn't running!\n"); 1787 rc = -ESHUTDOWN;
1788 rc = -ENODEV;
1789 } else { 1788 } else {
1790 dum->rh_state = DUMMY_RH_RUNNING; 1789 dum->rh_state = DUMMY_RH_RUNNING;
1791 set_link_state (dum); 1790 set_link_state (dum);
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 71aeca019e88..0dcb4164dc83 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -199,6 +199,10 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
199 if (time_before (jiffies, ehci->next_statechange)) 199 if (time_before (jiffies, ehci->next_statechange))
200 msleep(5); 200 msleep(5);
201 spin_lock_irq (&ehci->lock); 201 spin_lock_irq (&ehci->lock);
202 if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) {
203 spin_unlock_irq(&ehci->lock);
204 return -ESHUTDOWN;
205 }
202 206
203 /* Ideally and we've got a real resume here, and no port's power 207 /* Ideally and we've got a real resume here, and no port's power
204 * was lost. (For PCI, that means Vaux was maintained.) But we 208 * was lost. (For PCI, that means Vaux was maintained.) But we
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index d22da26ff167..76c555a67dac 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -730,10 +730,9 @@ static int uhci_rh_resume(struct usb_hcd *hcd)
730 int rc = 0; 730 int rc = 0;
731 731
732 spin_lock_irq(&uhci->lock); 732 spin_lock_irq(&uhci->lock);
733 if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { 733 if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))
734 dev_warn(&hcd->self.root_hub->dev, "HC isn't running!\n");
735 rc = -ESHUTDOWN; 734 rc = -ESHUTDOWN;
736 } else if (!uhci->dead) 735 else if (!uhci->dead)
737 wakeup_rh(uhci); 736 wakeup_rh(uhci);
738 spin_unlock_irq(&uhci->lock); 737 spin_unlock_irq(&uhci->lock);
739 return rc; 738 return rc;