aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/uhci-hcd.c288
-rw-r--r--drivers/usb/host/uhci-hcd.h10
-rw-r--r--drivers/usb/host/uhci-hub.c6
3 files changed, 202 insertions, 102 deletions
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 57b36dcea5d0..730ba3a621ae 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -109,28 +109,113 @@ static inline void restart_timer(struct uhci_hcd *uhci)
109#include "uhci-debug.c" 109#include "uhci-debug.c"
110#include "uhci-q.c" 110#include "uhci-q.c"
111 111
112/*
113 * Make sure the controller is completely inactive, unable to
114 * generate interrupts or do DMA.
115 */
112static void reset_hc(struct uhci_hcd *uhci) 116static void reset_hc(struct uhci_hcd *uhci)
113{ 117{
114 unsigned long io_addr = uhci->io_addr; 118 /* Turn off PIRQ enable and SMI enable. (This also turns off the
119 * BIOS's USB Legacy Support.) Turn off all the R/WC bits too.
120 */
121 pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
122 USBLEGSUP_RWC);
115 123
116 /* Turn off PIRQ, SMI, and all interrupts. This also turns off 124 /* Reset the HC - this will force us to get a
117 * the BIOS's USB Legacy Support. 125 * new notification of any already connected
126 * ports due to the virtual disconnect that it
127 * implies.
118 */ 128 */
119 pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0); 129 outw(USBCMD_HCRESET, uhci->io_addr + USBCMD);
120 outw(0, uhci->io_addr + USBINTR); 130 mb();
131 udelay(5);
132 if (inw(uhci->io_addr + USBCMD) & USBCMD_HCRESET)
133 dev_warn(uhci_dev(uhci), "HCRESET not completed yet!\n");
121 134
122 /* Global reset for 50ms */ 135 /* Just to be safe, disable interrupt requests and
123 outw(USBCMD_GRESET, io_addr + USBCMD); 136 * make sure the controller is stopped.
124 msleep(50); 137 */
125 outw(0, io_addr + USBCMD); 138 outw(0, uhci->io_addr + USBINTR);
139 outw(0, uhci->io_addr + USBCMD);
126 140
127 /* Another 10ms delay */
128 msleep(10);
129 uhci->resume_detect = 0; 141 uhci->resume_detect = 0;
130 uhci->is_stopped = UHCI_IS_STOPPED; 142 uhci->port_c_suspend = uhci->suspended_ports =
143 uhci->resuming_ports = 0;
131 uhci->rh_state = UHCI_RH_RESET; 144 uhci->rh_state = UHCI_RH_RESET;
145 uhci->is_stopped = UHCI_IS_STOPPED;
146 uhci_to_hcd(uhci)->state = HC_STATE_HALT;
132} 147}
133 148
149/*
150 * Initialize a controller that was newly discovered or has just been
151 * resumed. In either case we can't be sure of its previous state.
152 */
153static void check_and_reset_hc(struct uhci_hcd *uhci)
154{
155 u16 legsup;
156 unsigned int cmd, intr;
157
158 /*
159 * When restarting a suspended controller, we expect all the
160 * settings to be the same as we left them:
161 *
162 * PIRQ and SMI disabled, no R/WC bits set in USBLEGSUP;
163 * Controller is stopped and configured with EGSM set;
164 * No interrupts enabled except possibly Resume Detect.
165 *
166 * If any of these conditions are violated we do a complete reset.
167 */
168 pci_read_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, &legsup);
169 if (legsup & ~USBLEGSUP_RO) {
170 dev_dbg(uhci_dev(uhci), "%s: legsup = 0x%04x\n",
171 __FUNCTION__, legsup);
172 goto reset_needed;
173 }
174
175 cmd = inw(uhci->io_addr + USBCMD);
176 if ((cmd & USBCMD_RS) || !(cmd & USBCMD_CF) || !(cmd & USBCMD_EGSM)) {
177 dev_dbg(uhci_dev(uhci), "%s: cmd = 0x%04x\n",
178 __FUNCTION__, cmd);
179 goto reset_needed;
180 }
181
182 intr = inw(uhci->io_addr + USBINTR);
183 if (intr & (~USBINTR_RESUME)) {
184 dev_dbg(uhci_dev(uhci), "%s: intr = 0x%04x\n",
185 __FUNCTION__, intr);
186 goto reset_needed;
187 }
188 return;
189
190reset_needed:
191 dev_dbg(uhci_dev(uhci), "Performing full reset\n");
192 reset_hc(uhci);
193}
194
195/*
196 * Store the basic register settings needed by the controller.
197 */
198static void configure_hc(struct uhci_hcd *uhci)
199{
200 /* Set the frame length to the default: 1 ms exactly */
201 outb(USBSOF_DEFAULT, uhci->io_addr + USBSOF);
202
203 /* Store the frame list base address */
204 outl(uhci->fl->dma_handle, uhci->io_addr + USBFLBASEADD);
205
206 /* Set the current frame number */
207 outw(uhci->frame_number, uhci->io_addr + USBFRNUM);
208
209 /* Mark controller as running before we enable interrupts */
210 uhci_to_hcd(uhci)->state = HC_STATE_RUNNING;
211 mb();
212
213 /* Enable PIRQ */
214 pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
215 USBLEGSUP_DEFAULT);
216}
217
218
134static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci) 219static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci)
135{ 220{
136 int port; 221 int port;
@@ -163,7 +248,7 @@ static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci)
163 return 0; 248 return 0;
164} 249}
165 250
166static void suspend_hc(struct uhci_hcd *uhci, enum uhci_rh_state new_state) 251static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state)
167__releases(uhci->lock) 252__releases(uhci->lock)
168__acquires(uhci->lock) 253__acquires(uhci->lock)
169{ 254{
@@ -189,6 +274,7 @@ __acquires(uhci->lock)
189 0 : USBINTR_RESUME); 274 0 : USBINTR_RESUME);
190 outw(int_enable, uhci->io_addr + USBINTR); 275 outw(int_enable, uhci->io_addr + USBINTR);
191 outw(USBCMD_EGSM | USBCMD_CF, uhci->io_addr + USBCMD); 276 outw(USBCMD_EGSM | USBCMD_CF, uhci->io_addr + USBCMD);
277 mb();
192 udelay(5); 278 udelay(5);
193 279
194 /* If we're auto-stopping then no devices have been attached 280 /* If we're auto-stopping then no devices have been attached
@@ -215,7 +301,22 @@ __acquires(uhci->lock)
215 uhci_scan_schedule(uhci, NULL); 301 uhci_scan_schedule(uhci, NULL);
216} 302}
217 303
218static void wakeup_hc(struct uhci_hcd *uhci) 304static void start_rh(struct uhci_hcd *uhci)
305{
306 uhci->rh_state = UHCI_RH_RUNNING;
307 uhci->is_stopped = 0;
308 smp_wmb();
309
310 /* Mark it configured and running with a 64-byte max packet.
311 * All interrupts are enabled, even though RESUME won't do anything.
312 */
313 outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, uhci->io_addr + USBCMD);
314 outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
315 uhci->io_addr + USBINTR);
316 mb();
317}
318
319static void wakeup_rh(struct uhci_hcd *uhci)
219__releases(uhci->lock) 320__releases(uhci->lock)
220__acquires(uhci->lock) 321__acquires(uhci->lock)
221{ 322{
@@ -237,62 +338,13 @@ __acquires(uhci->lock)
237 338
238 /* End Global Resume and wait for EOP to be sent */ 339 /* End Global Resume and wait for EOP to be sent */
239 outw(USBCMD_CF, uhci->io_addr + USBCMD); 340 outw(USBCMD_CF, uhci->io_addr + USBCMD);
341 mb();
240 udelay(4); 342 udelay(4);
241 if (inw(uhci->io_addr + USBCMD) & USBCMD_FGR) 343 if (inw(uhci->io_addr + USBCMD) & USBCMD_FGR)
242 dev_warn(uhci_dev(uhci), "FGR not stopped yet!\n"); 344 dev_warn(uhci_dev(uhci), "FGR not stopped yet!\n");
243 } 345 }
244 346
245 uhci->rh_state = UHCI_RH_RUNNING; 347 start_rh(uhci);
246 uhci->is_stopped = 0;
247 smp_wmb();
248
249 /* Mark it configured and running with a 64-byte max packet.
250 * All interrupts are enabled, even though RD won't do anything.
251 */
252 outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, uhci->io_addr + USBCMD);
253 outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
254 uhci->io_addr + USBINTR);
255}
256
257static int start_hc(struct uhci_hcd *uhci)
258{
259 unsigned long io_addr = uhci->io_addr;
260 int timeout = 10;
261
262 /*
263 * Reset the HC - this will force us to get a
264 * new notification of any already connected
265 * ports due to the virtual disconnect that it
266 * implies.
267 */
268 outw(USBCMD_HCRESET, io_addr + USBCMD);
269 while (inw(io_addr + USBCMD) & USBCMD_HCRESET) {
270 if (--timeout < 0) {
271 dev_err(uhci_dev(uhci), "USBCMD_HCRESET timed out!\n");
272 return -ETIMEDOUT;
273 }
274 msleep(1);
275 }
276
277 /* Mark controller as running before we enable interrupts */
278 uhci_to_hcd(uhci)->state = HC_STATE_RUNNING;
279
280 /* Turn on PIRQ and all interrupts */
281 pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP,
282 USBLEGSUP_DEFAULT);
283 outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
284 io_addr + USBINTR);
285
286 /* Start at frame 0 */
287 outw(0, io_addr + USBFRNUM);
288 outl(uhci->fl->dma_handle, io_addr + USBFLBASEADD);
289
290 /* Run and mark it configured with a 64-byte max packet */
291 uhci->rh_state = UHCI_RH_RUNNING;
292 outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, io_addr + USBCMD);
293 uhci->is_stopped = 0;
294
295 return 0;
296} 348}
297 349
298static void rh_state_transitions(struct uhci_hcd *uhci) 350static void rh_state_transitions(struct uhci_hcd *uhci)
@@ -311,13 +363,13 @@ static void rh_state_transitions(struct uhci_hcd *uhci)
311 if (any_ports_active(uhci)) 363 if (any_ports_active(uhci))
312 uhci->rh_state = UHCI_RH_RUNNING; 364 uhci->rh_state = UHCI_RH_RUNNING;
313 else if (time_after_eq(jiffies, uhci->auto_stop_time)) 365 else if (time_after_eq(jiffies, uhci->auto_stop_time))
314 suspend_hc(uhci, UHCI_RH_AUTO_STOPPED); 366 suspend_rh(uhci, UHCI_RH_AUTO_STOPPED);
315 break; 367 break;
316 368
317 case UHCI_RH_AUTO_STOPPED: 369 case UHCI_RH_AUTO_STOPPED:
318 /* wakeup if requested by a device */ 370 /* wakeup if requested by a device */
319 if (uhci->resume_detect) 371 if (uhci->resume_detect)
320 wakeup_hc(uhci); 372 wakeup_rh(uhci);
321 break; 373 break;
322 374
323 default: 375 default:
@@ -336,7 +388,7 @@ static void stall_callback(unsigned long _uhci)
336 388
337 /* Poll for and perform state transitions */ 389 /* Poll for and perform state transitions */
338 rh_state_transitions(uhci); 390 rh_state_transitions(uhci);
339 if (unlikely(uhci->suspended_ports)) 391 if (uhci->suspended_ports && !uhci->hc_inaccessible)
340 uhci_check_ports(uhci); 392 uhci_check_ports(uhci);
341 393
342 restart_timer(uhci); 394 restart_timer(uhci);
@@ -346,7 +398,6 @@ static void stall_callback(unsigned long _uhci)
346static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) 398static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
347{ 399{
348 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 400 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
349 unsigned long io_addr = uhci->io_addr;
350 unsigned short status; 401 unsigned short status;
351 402
352 /* 403 /*
@@ -354,10 +405,10 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
354 * interrupt cause. Contrary to the UHCI specification, the 405 * interrupt cause. Contrary to the UHCI specification, the
355 * "HC Halted" status bit is persistent: it is RO, not R/WC. 406 * "HC Halted" status bit is persistent: it is RO, not R/WC.
356 */ 407 */
357 status = inw(io_addr + USBSTS); 408 status = inw(uhci->io_addr + USBSTS);
358 if (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */ 409 if (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */
359 return IRQ_NONE; 410 return IRQ_NONE;
360 outw(status, io_addr + USBSTS); /* Clear it */ 411 outw(status, uhci->io_addr + USBSTS); /* Clear it */
361 412
362 if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) { 413 if (status & ~(USBSTS_USBINT | USBSTS_ERROR | USBSTS_RD)) {
363 if (status & USBSTS_HSE) 414 if (status & USBSTS_HSE)
@@ -440,10 +491,10 @@ static int uhci_reset(struct usb_hcd *hcd)
440 491
441 uhci->io_addr = (unsigned long) hcd->rsrc_start; 492 uhci->io_addr = (unsigned long) hcd->rsrc_start;
442 493
443 /* Kick BIOS off this hardware and reset, so we won't get 494 /* Kick BIOS off this hardware and reset if the controller
444 * interrupts from any previous setup. 495 * isn't already safely quiescent.
445 */ 496 */
446 reset_hc(uhci); 497 check_and_reset_hc(uhci);
447 return 0; 498 return 0;
448} 499}
449 500
@@ -634,11 +685,12 @@ static int uhci_start(struct usb_hcd *hcd)
634 685
635 /* 686 /*
636 * Some architectures require a full mb() to enforce completion of 687 * Some architectures require a full mb() to enforce completion of
637 * the memory writes above before the I/O transfers in start_hc(). 688 * the memory writes above before the I/O transfers in configure_hc().
638 */ 689 */
639 mb(); 690 mb();
640 if ((retval = start_hc(uhci)) != 0) 691
641 goto err_alloc_skelqh; 692 configure_hc(uhci);
693 start_rh(uhci);
642 694
643 restart_timer(uhci); 695 restart_timer(uhci);
644 696
@@ -656,9 +708,8 @@ static int uhci_start(struct usb_hcd *hcd)
656 * error exits: 708 * error exits:
657 */ 709 */
658err_start_root_hub: 710err_start_root_hub:
659 reset_hc(uhci);
660
661 del_timer_sync(&uhci->stall_timer); 711 del_timer_sync(&uhci->stall_timer);
712 reset_hc(uhci);
662 713
663err_alloc_skelqh: 714err_alloc_skelqh:
664 for (i = 0; i < UHCI_NUM_SKELQH; i++) 715 for (i = 0; i < UHCI_NUM_SKELQH; i++)
@@ -699,9 +750,9 @@ static void uhci_stop(struct usb_hcd *hcd)
699 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 750 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
700 751
701 del_timer_sync(&uhci->stall_timer); 752 del_timer_sync(&uhci->stall_timer);
702 reset_hc(uhci);
703 753
704 spin_lock_irq(&uhci->lock); 754 spin_lock_irq(&uhci->lock);
755 reset_hc(uhci);
705 uhci_scan_schedule(uhci, NULL); 756 uhci_scan_schedule(uhci, NULL);
706 spin_unlock_irq(&uhci->lock); 757 spin_unlock_irq(&uhci->lock);
707 758
@@ -709,12 +760,47 @@ static void uhci_stop(struct usb_hcd *hcd)
709} 760}
710 761
711#ifdef CONFIG_PM 762#ifdef CONFIG_PM
763static int uhci_rh_suspend(struct usb_hcd *hcd)
764{
765 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
766
767 spin_lock_irq(&uhci->lock);
768 suspend_rh(uhci, UHCI_RH_SUSPENDED);
769 spin_unlock_irq(&uhci->lock);
770 return 0;
771}
772
773static int uhci_rh_resume(struct usb_hcd *hcd)
774{
775 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
776
777 spin_lock_irq(&uhci->lock);
778 wakeup_rh(uhci);
779 spin_unlock_irq(&uhci->lock);
780 return 0;
781}
782
712static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message) 783static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
713{ 784{
714 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 785 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
715 786
787 dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__);
788
716 spin_lock_irq(&uhci->lock); 789 spin_lock_irq(&uhci->lock);
717 suspend_hc(uhci, UHCI_RH_SUSPENDED); 790
791#ifndef CONFIG_USB_SUSPEND
792 /* Otherwise this would never happen */
793 suspend_rh(uhci, UHCI_RH_SUSPENDED);
794#endif
795
796 /* All PCI host controllers are required to disable IRQ generation
797 * at the source, so we must turn off PIRQ.
798 */
799 pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
800 uhci->hc_inaccessible = 1;
801
802 /* FIXME: Enable non-PME# remote wakeup? */
803
718 spin_unlock_irq(&uhci->lock); 804 spin_unlock_irq(&uhci->lock);
719 return 0; 805 return 0;
720} 806}
@@ -723,28 +809,28 @@ static int uhci_resume(struct usb_hcd *hcd)
723{ 809{
724 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 810 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
725 811
812 dev_dbg(uhci_dev(uhci), "%s\n", __FUNCTION__);
813
726 spin_lock_irq(&uhci->lock); 814 spin_lock_irq(&uhci->lock);
727 if (uhci->rh_state == UHCI_RH_SUSPENDED) {
728 815
729 /* 816 /* FIXME: Disable non-PME# remote wakeup? */
730 * Some systems don't maintain the UHCI register values 817
731 * during a PM suspend/resume cycle, so reinitialize 818 uhci->hc_inaccessible = 0;
732 * the Frame Number, Framelist Base Address, Interrupt 819
733 * Enable, and Legacy Support registers. 820 /* The BIOS may have changed the controller settings during a
734 */ 821 * system wakeup. Check it and reconfigure to avoid problems.
735 pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 822 */
736 0); 823 check_and_reset_hc(uhci);
737 outw(uhci->frame_number, uhci->io_addr + USBFRNUM); 824 configure_hc(uhci);
738 outl(uhci->fl->dma_handle, uhci->io_addr + USBFLBASEADD); 825
739 outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | 826#ifndef CONFIG_USB_SUSPEND
740 USBINTR_SP, uhci->io_addr + USBINTR); 827 /* Otherwise this would never happen */
741 pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 828 wakeup_rh(uhci);
742 USBLEGSUP_DEFAULT); 829#endif
743 wakeup_hc(uhci); 830 if (uhci->rh_state == UHCI_RH_RESET)
744 } 831 suspend_rh(uhci, UHCI_RH_SUSPENDED);
745 spin_unlock_irq(&uhci->lock);
746 832
747 hcd->state = HC_STATE_RUNNING; 833 spin_unlock_irq(&uhci->lock);
748 return 0; 834 return 0;
749} 835}
750#endif 836#endif
@@ -792,6 +878,8 @@ static const struct hc_driver uhci_driver = {
792#ifdef CONFIG_PM 878#ifdef CONFIG_PM
793 .suspend = uhci_suspend, 879 .suspend = uhci_suspend,
794 .resume = uhci_resume, 880 .resume = uhci_resume,
881 .hub_suspend = uhci_rh_suspend,
882 .hub_resume = uhci_rh_resume,
795#endif 883#endif
796 .stop = uhci_stop, 884 .stop = uhci_stop,
797 885
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index 4bac57c74ec2..827df5e06800 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -41,6 +41,7 @@
41#define USBFRNUM 6 41#define USBFRNUM 6
42#define USBFLBASEADD 8 42#define USBFLBASEADD 8
43#define USBSOF 12 43#define USBSOF 12
44#define USBSOF_DEFAULT 64 /* Frame length is exactly 1 ms */
44 45
45/* USB port status and control registers */ 46/* USB port status and control registers */
46#define USBPORTSC1 16 47#define USBPORTSC1 16
@@ -66,6 +67,8 @@
66/* Legacy support register */ 67/* Legacy support register */
67#define USBLEGSUP 0xc0 68#define USBLEGSUP 0xc0
68#define USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */ 69#define USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */
70#define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */
71#define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */
69 72
70#define UHCI_NULL_DATA_SIZE 0x7FF /* for UHCI controller TD */ 73#define UHCI_NULL_DATA_SIZE 0x7FF /* for UHCI controller TD */
71 74
@@ -325,8 +328,9 @@ static inline int __interval_to_skel(int interval)
325 */ 328 */
326enum uhci_rh_state { 329enum uhci_rh_state {
327 /* In the next 4 states the HC must be halted */ 330 /* In the next 4 states the HC must be halted */
328 UHCI_RH_RESET, 331 UHCI_RH_RESET, /* These two must come first */
329 UHCI_RH_SUSPENDED, 332 UHCI_RH_SUSPENDED,
333
330 UHCI_RH_AUTO_STOPPED, 334 UHCI_RH_AUTO_STOPPED,
331 UHCI_RH_RESUMING, 335 UHCI_RH_RESUMING,
332 336
@@ -334,7 +338,8 @@ enum uhci_rh_state {
334 * can legally appear either way */ 338 * can legally appear either way */
335 UHCI_RH_SUSPENDING, 339 UHCI_RH_SUSPENDING,
336 340
337 /* In the next two states it's an error if the HC is halted */ 341 /* In the next two states it's an error if the HC is halted.
342 * These two must come last */
338 UHCI_RH_RUNNING, /* The normal state */ 343 UHCI_RH_RUNNING, /* The normal state */
339 UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */ 344 UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */
340}; 345};
@@ -376,6 +381,7 @@ struct uhci_hcd {
376 unsigned int scan_in_progress:1; /* Schedule scan is running */ 381 unsigned int scan_in_progress:1; /* Schedule scan is running */
377 unsigned int need_rescan:1; /* Redo the schedule scan */ 382 unsigned int need_rescan:1; /* Redo the schedule scan */
378 unsigned int resume_detect:1; /* Need a Global Resume */ 383 unsigned int resume_detect:1; /* Need a Global Resume */
384 unsigned int hc_inaccessible:1; /* HC is suspended or dead */
379 385
380 /* Support for port suspend/resume/reset */ 386 /* Support for port suspend/resume/reset */
381 unsigned long port_c_suspend; /* Bit-arrays of ports */ 387 unsigned long port_c_suspend; /* Bit-arrays of ports */
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
index fc34fee2ab07..13652de52203 100644
--- a/drivers/usb/host/uhci-hub.c
+++ b/drivers/usb/host/uhci-hub.c
@@ -54,6 +54,9 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
54 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 54 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
55 int port; 55 int port;
56 56
57 if (uhci->hc_inaccessible)
58 return 0;
59
57 *buf = 0; 60 *buf = 0;
58 for (port = 0; port < uhci->rh_numports; ++port) { 61 for (port = 0; port < uhci->rh_numports; ++port) {
59 if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & RWC_BITS) || 62 if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & RWC_BITS) ||
@@ -150,6 +153,9 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
150 u16 wPortChange, wPortStatus; 153 u16 wPortChange, wPortStatus;
151 unsigned long flags; 154 unsigned long flags;
152 155
156 if (uhci->hc_inaccessible)
157 return -ETIMEDOUT;
158
153 spin_lock_irqsave(&uhci->lock, flags); 159 spin_lock_irqsave(&uhci->lock, flags);
154 switch (typeReq) { 160 switch (typeReq) {
155 161