diff options
Diffstat (limited to 'drivers/usb/host/ohci-hub.c')
-rw-r--r-- | drivers/usb/host/ohci-hub.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index e01e77bc324b..72e3b12a1926 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -53,6 +53,11 @@ static int ohci_bus_suspend (struct usb_hcd *hcd) | |||
53 | 53 | ||
54 | spin_lock_irqsave (&ohci->lock, flags); | 54 | spin_lock_irqsave (&ohci->lock, flags); |
55 | 55 | ||
56 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) { | ||
57 | spin_unlock_irqrestore (&ohci->lock, flags); | ||
58 | return -ESHUTDOWN; | ||
59 | } | ||
60 | |||
56 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); | 61 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); |
57 | switch (ohci->hc_control & OHCI_CTRL_HCFS) { | 62 | switch (ohci->hc_control & OHCI_CTRL_HCFS) { |
58 | case OHCI_USB_RESUME: | 63 | case OHCI_USB_RESUME: |
@@ -140,11 +145,19 @@ static int ohci_bus_resume (struct usb_hcd *hcd) | |||
140 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 145 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
141 | u32 temp, enables; | 146 | u32 temp, enables; |
142 | int status = -EINPROGRESS; | 147 | int status = -EINPROGRESS; |
148 | unsigned long flags; | ||
143 | 149 | ||
144 | if (time_before (jiffies, ohci->next_statechange)) | 150 | if (time_before (jiffies, ohci->next_statechange)) |
145 | msleep(5); | 151 | msleep(5); |
146 | 152 | ||
147 | spin_lock_irq (&ohci->lock); | 153 | spin_lock_irqsave (&ohci->lock, flags); |
154 | |||
155 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) { | ||
156 | spin_unlock_irqrestore (&ohci->lock, flags); | ||
157 | return -ESHUTDOWN; | ||
158 | } | ||
159 | |||
160 | |||
148 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); | 161 | ohci->hc_control = ohci_readl (ohci, &ohci->regs->control); |
149 | 162 | ||
150 | if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { | 163 | if (ohci->hc_control & (OHCI_CTRL_IR | OHCI_SCHED_ENABLES)) { |
@@ -179,7 +192,7 @@ static int ohci_bus_resume (struct usb_hcd *hcd) | |||
179 | ohci_dbg (ohci, "lost power\n"); | 192 | ohci_dbg (ohci, "lost power\n"); |
180 | status = -EBUSY; | 193 | status = -EBUSY; |
181 | } | 194 | } |
182 | spin_unlock_irq (&ohci->lock); | 195 | spin_unlock_irqrestore (&ohci->lock, flags); |
183 | if (status == -EBUSY) { | 196 | if (status == -EBUSY) { |
184 | (void) ohci_init (ohci); | 197 | (void) ohci_init (ohci); |
185 | return ohci_restart (ohci); | 198 | return ohci_restart (ohci); |
@@ -297,8 +310,8 @@ ohci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
297 | /* handle autosuspended root: finish resuming before | 310 | /* handle autosuspended root: finish resuming before |
298 | * letting khubd or root hub timer see state changes. | 311 | * letting khubd or root hub timer see state changes. |
299 | */ | 312 | */ |
300 | if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER | 313 | if (unlikely((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER |
301 | || !HC_IS_RUNNING(hcd->state)) { | 314 | || !HC_IS_RUNNING(hcd->state))) { |
302 | can_suspend = 0; | 315 | can_suspend = 0; |
303 | goto done; | 316 | goto done; |
304 | } | 317 | } |
@@ -508,6 +521,9 @@ static int ohci_hub_control ( | |||
508 | u32 temp; | 521 | u32 temp; |
509 | int retval = 0; | 522 | int retval = 0; |
510 | 523 | ||
524 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags))) | ||
525 | return -ESHUTDOWN; | ||
526 | |||
511 | switch (typeReq) { | 527 | switch (typeReq) { |
512 | case ClearHubFeature: | 528 | case ClearHubFeature: |
513 | switch (wValue) { | 529 | switch (wValue) { |