aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/uhci-hcd.c70
-rw-r--r--drivers/usb/host/uhci-hcd.h12
-rw-r--r--drivers/usb/host/uhci-hub.c67
-rw-r--r--drivers/usb/host/uhci-q.c3
4 files changed, 92 insertions, 60 deletions
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 82e608a4bbd0..25a718eb1d0f 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -84,6 +84,8 @@ static char *errbuf;
84 84
85static kmem_cache_t *uhci_up_cachep; /* urb_priv */ 85static kmem_cache_t *uhci_up_cachep; /* urb_priv */
86 86
87static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state);
88static void wakeup_rh(struct uhci_hcd *uhci);
87static void uhci_get_current_frame_number(struct uhci_hcd *uhci); 89static void uhci_get_current_frame_number(struct uhci_hcd *uhci);
88 90
89/* If a transfer is still active after this much time, turn off FSBR */ 91/* If a transfer is still active after this much time, turn off FSBR */
@@ -133,12 +135,12 @@ static void reset_hc(struct uhci_hcd *uhci)
133 outw(0, uhci->io_addr + USBINTR); 135 outw(0, uhci->io_addr + USBINTR);
134 outw(0, uhci->io_addr + USBCMD); 136 outw(0, uhci->io_addr + USBCMD);
135 137
136 uhci->resume_detect = 0;
137 uhci->port_c_suspend = uhci->suspended_ports = 138 uhci->port_c_suspend = uhci->suspended_ports =
138 uhci->resuming_ports = 0; 139 uhci->resuming_ports = 0;
139 uhci->rh_state = UHCI_RH_RESET; 140 uhci->rh_state = UHCI_RH_RESET;
140 uhci->is_stopped = UHCI_IS_STOPPED; 141 uhci->is_stopped = UHCI_IS_STOPPED;
141 uhci_to_hcd(uhci)->state = HC_STATE_HALT; 142 uhci_to_hcd(uhci)->state = HC_STATE_HALT;
143 uhci_to_hcd(uhci)->poll_rh = 0;
142} 144}
143 145
144/* 146/*
@@ -148,6 +150,7 @@ static void hc_died(struct uhci_hcd *uhci)
148{ 150{
149 reset_hc(uhci); 151 reset_hc(uhci);
150 uhci->hc_inaccessible = 1; 152 uhci->hc_inaccessible = 1;
153 del_timer(&uhci->stall_timer);
151} 154}
152 155
153/* 156/*
@@ -302,14 +305,14 @@ __acquires(uhci->lock)
302 305
303 uhci->rh_state = new_state; 306 uhci->rh_state = new_state;
304 uhci->is_stopped = UHCI_IS_STOPPED; 307 uhci->is_stopped = UHCI_IS_STOPPED;
305 uhci->resume_detect = 0; 308 del_timer(&uhci->stall_timer);
309 uhci_to_hcd(uhci)->poll_rh = !int_enable;
306 310
307 uhci_scan_schedule(uhci, NULL); 311 uhci_scan_schedule(uhci, NULL);
308} 312}
309 313
310static void start_rh(struct uhci_hcd *uhci) 314static void start_rh(struct uhci_hcd *uhci)
311{ 315{
312 uhci->rh_state = UHCI_RH_RUNNING;
313 uhci->is_stopped = 0; 316 uhci->is_stopped = 0;
314 smp_wmb(); 317 smp_wmb();
315 318
@@ -320,6 +323,9 @@ static void start_rh(struct uhci_hcd *uhci)
320 outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP, 323 outw(USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP,
321 uhci->io_addr + USBINTR); 324 uhci->io_addr + USBINTR);
322 mb(); 325 mb();
326 uhci->rh_state = UHCI_RH_RUNNING;
327 uhci_to_hcd(uhci)->poll_rh = 1;
328 restart_timer(uhci);
323} 329}
324 330
325static void wakeup_rh(struct uhci_hcd *uhci) 331static void wakeup_rh(struct uhci_hcd *uhci)
@@ -353,36 +359,9 @@ __acquires(uhci->lock)
353 } 359 }
354 360
355 start_rh(uhci); 361 start_rh(uhci);
356}
357
358static void rh_state_transitions(struct uhci_hcd *uhci)
359{
360 switch (uhci->rh_state) {
361 case UHCI_RH_RUNNING:
362 /* are any devices attached? */
363 if (!any_ports_active(uhci)) {
364 uhci->rh_state = UHCI_RH_RUNNING_NODEVS;
365 uhci->auto_stop_time = jiffies + HZ;
366 }
367 break;
368 362
369 case UHCI_RH_RUNNING_NODEVS: 363 /* Restart root hub polling */
370 /* auto-stop if nothing connected for 1 second */ 364 mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
371 if (any_ports_active(uhci))
372 uhci->rh_state = UHCI_RH_RUNNING;
373 else if (time_after_eq(jiffies, uhci->auto_stop_time))
374 suspend_rh(uhci, UHCI_RH_AUTO_STOPPED);
375 break;
376
377 case UHCI_RH_AUTO_STOPPED:
378 /* wakeup if requested by a device */
379 if (uhci->resume_detect)
380 wakeup_rh(uhci);
381 break;
382
383 default:
384 break;
385 }
386} 365}
387 366
388static void stall_callback(unsigned long _uhci) 367static void stall_callback(unsigned long _uhci)
@@ -394,14 +373,8 @@ static void stall_callback(unsigned long _uhci)
394 uhci_scan_schedule(uhci, NULL); 373 uhci_scan_schedule(uhci, NULL);
395 check_fsbr(uhci); 374 check_fsbr(uhci);
396 375
397 /* Poll for and perform state transitions */ 376 if (!uhci->is_stopped)
398 if (!uhci->hc_inaccessible) { 377 restart_timer(uhci);
399 rh_state_transitions(uhci);
400 if (uhci->suspended_ports)
401 uhci_check_ports(uhci);
402 }
403
404 restart_timer(uhci);
405 spin_unlock_irqrestore(&uhci->lock, flags); 378 spin_unlock_irqrestore(&uhci->lock, flags);
406} 379}
407 380
@@ -443,7 +416,7 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
443 } 416 }
444 417
445 if (status & USBSTS_RD) 418 if (status & USBSTS_RD)
446 uhci->resume_detect = 1; 419 usb_hcd_poll_rh_status(hcd);
447 420
448 spin_lock_irqsave(&uhci->lock, flags); 421 spin_lock_irqsave(&uhci->lock, flags);
449 uhci_scan_schedule(uhci, regs); 422 uhci_scan_schedule(uhci, regs);
@@ -542,6 +515,7 @@ static int uhci_start(struct usb_hcd *hcd)
542 struct dentry *dentry; 515 struct dentry *dentry;
543 516
544 io_size = (unsigned) hcd->rsrc_len; 517 io_size = (unsigned) hcd->rsrc_len;
518 hcd->uses_new_polling = 1;
545 if (pci_find_capability(to_pci_dev(uhci_dev(uhci)), PCI_CAP_ID_PM)) 519 if (pci_find_capability(to_pci_dev(uhci_dev(uhci)), PCI_CAP_ID_PM))
546 hcd->can_wakeup = 1; /* Assume it supports PME# */ 520 hcd->can_wakeup = 1; /* Assume it supports PME# */
547 521
@@ -714,8 +688,6 @@ static int uhci_start(struct usb_hcd *hcd)
714 configure_hc(uhci); 688 configure_hc(uhci);
715 start_rh(uhci); 689 start_rh(uhci);
716 690
717 restart_timer(uhci);
718
719 udev->speed = USB_SPEED_FULL; 691 udev->speed = USB_SPEED_FULL;
720 692
721 if (usb_hcd_register_root_hub(udev, hcd) != 0) { 693 if (usb_hcd_register_root_hub(udev, hcd) != 0) {
@@ -730,8 +702,8 @@ static int uhci_start(struct usb_hcd *hcd)
730 * error exits: 702 * error exits:
731 */ 703 */
732err_start_root_hub: 704err_start_root_hub:
733 del_timer_sync(&uhci->stall_timer);
734 reset_hc(uhci); 705 reset_hc(uhci);
706 del_timer_sync(&uhci->stall_timer);
735 707
736err_alloc_skelqh: 708err_alloc_skelqh:
737 for (i = 0; i < UHCI_NUM_SKELQH; i++) 709 for (i = 0; i < UHCI_NUM_SKELQH; i++)
@@ -771,13 +743,12 @@ static void uhci_stop(struct usb_hcd *hcd)
771{ 743{
772 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 744 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
773 745
774 del_timer_sync(&uhci->stall_timer);
775
776 spin_lock_irq(&uhci->lock); 746 spin_lock_irq(&uhci->lock);
777 reset_hc(uhci); 747 reset_hc(uhci);
778 uhci_scan_schedule(uhci, NULL); 748 uhci_scan_schedule(uhci, NULL);
779 spin_unlock_irq(&uhci->lock); 749 spin_unlock_irq(&uhci->lock);
780 750
751 del_timer_sync(&uhci->stall_timer);
781 release_uhci(uhci); 752 release_uhci(uhci);
782} 753}
783 754
@@ -844,6 +815,8 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
844 815
845done: 816done:
846 spin_unlock_irq(&uhci->lock); 817 spin_unlock_irq(&uhci->lock);
818 if (rc == 0)
819 del_timer_sync(&hcd->rh_timer);
847 return rc; 820 return rc;
848} 821}
849 822
@@ -875,6 +848,9 @@ static int uhci_resume(struct usb_hcd *hcd)
875 suspend_rh(uhci, UHCI_RH_SUSPENDED); 848 suspend_rh(uhci, UHCI_RH_SUSPENDED);
876 849
877 spin_unlock_irq(&uhci->lock); 850 spin_unlock_irq(&uhci->lock);
851
852 if (hcd->poll_rh)
853 usb_hcd_poll_rh_status(hcd);
878 return 0; 854 return 0;
879} 855}
880#endif 856#endif
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index 827df5e06800..d7c67b73eb7a 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -327,18 +327,19 @@ static inline int __interval_to_skel(int interval)
327 * driver learns to autosuspend.) 327 * driver learns to autosuspend.)
328 */ 328 */
329enum uhci_rh_state { 329enum uhci_rh_state {
330 /* In the next 4 states the HC must be halted */ 330 /* In the following states the HC must be halted.
331 UHCI_RH_RESET, /* These two must come first */ 331 * These two must come first */
332 UHCI_RH_RESET,
332 UHCI_RH_SUSPENDED, 333 UHCI_RH_SUSPENDED,
333 334
334 UHCI_RH_AUTO_STOPPED, 335 UHCI_RH_AUTO_STOPPED,
335 UHCI_RH_RESUMING, 336 UHCI_RH_RESUMING,
336 337
337 /* In the next state the HC changes from running to halted, so it 338 /* In this state the HC changes from running to halted,
338 * can legally appear either way */ 339 * so it can legally appear either way. */
339 UHCI_RH_SUSPENDING, 340 UHCI_RH_SUSPENDING,
340 341
341 /* In the next two states it's an error if the HC is halted. 342 /* In the following states it's an error if the HC is halted.
342 * These two must come last */ 343 * These two must come last */
343 UHCI_RH_RUNNING, /* The normal state */ 344 UHCI_RH_RUNNING, /* The normal state */
344 UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */ 345 UHCI_RH_RUNNING_NODEVS, /* Running with no devices attached */
@@ -380,7 +381,6 @@ struct uhci_hcd {
380 381
381 unsigned int scan_in_progress:1; /* Schedule scan is running */ 382 unsigned int scan_in_progress:1; /* Schedule scan is running */
382 unsigned int need_rescan:1; /* Redo the schedule scan */ 383 unsigned int need_rescan:1; /* Redo the schedule scan */
383 unsigned int resume_detect:1; /* Need a Global Resume */
384 unsigned int hc_inaccessible:1; /* HC is suspended or dead */ 384 unsigned int hc_inaccessible:1; /* HC is suspended or dead */
385 385
386 /* Support for port suspend/resume/reset */ 386 /* Support for port suspend/resume/reset */
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
index 13652de52203..4eace2b19ddb 100644
--- a/drivers/usb/host/uhci-hub.c
+++ b/drivers/usb/host/uhci-hub.c
@@ -49,22 +49,16 @@ static int any_ports_active(struct uhci_hcd *uhci)
49 return 0; 49 return 0;
50} 50}
51 51
52static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf) 52static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf)
53{ 53{
54 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
55 int port; 54 int port;
56 55
57 if (uhci->hc_inaccessible)
58 return 0;
59
60 *buf = 0; 56 *buf = 0;
61 for (port = 0; port < uhci->rh_numports; ++port) { 57 for (port = 0; port < uhci->rh_numports; ++port) {
62 if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & RWC_BITS) || 58 if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & RWC_BITS) ||
63 test_bit(port, &uhci->port_c_suspend)) 59 test_bit(port, &uhci->port_c_suspend))
64 *buf |= (1 << (port + 1)); 60 *buf |= (1 << (port + 1));
65 } 61 }
66 if (*buf && uhci->is_stopped)
67 uhci->resume_detect = 1;
68 return !!*buf; 62 return !!*buf;
69} 63}
70 64
@@ -134,6 +128,11 @@ static void uhci_check_ports(struct uhci_hcd *uhci)
134 set_bit(port, &uhci->resuming_ports); 128 set_bit(port, &uhci->resuming_ports);
135 uhci->ports_timeout = jiffies + 129 uhci->ports_timeout = jiffies +
136 msecs_to_jiffies(20); 130 msecs_to_jiffies(20);
131
132 /* Make sure we see the port again
133 * after the resuming period is over. */
134 mod_timer(&uhci_to_hcd(uhci)->rh_timer,
135 uhci->ports_timeout);
137 } else if (time_after_eq(jiffies, 136 } else if (time_after_eq(jiffies,
138 uhci->ports_timeout)) { 137 uhci->ports_timeout)) {
139 uhci_finish_suspend(uhci, port, port_addr); 138 uhci_finish_suspend(uhci, port, port_addr);
@@ -142,6 +141,60 @@ static void uhci_check_ports(struct uhci_hcd *uhci)
142 } 141 }
143} 142}
144 143
144static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
145{
146 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
147 unsigned long flags;
148 int status;
149
150 spin_lock_irqsave(&uhci->lock, flags);
151 if (uhci->hc_inaccessible) {
152 status = 0;
153 goto done;
154 }
155
156 uhci_check_ports(uhci);
157 status = get_hub_status_data(uhci, buf);
158
159 switch (uhci->rh_state) {
160 case UHCI_RH_SUSPENDING:
161 case UHCI_RH_SUSPENDED:
162 /* if port change, ask to be resumed */
163 if (status)
164 usb_hcd_resume_root_hub(hcd);
165 break;
166
167 case UHCI_RH_AUTO_STOPPED:
168 /* if port change, auto start */
169 if (status)
170 wakeup_rh(uhci);
171 break;
172
173 case UHCI_RH_RUNNING:
174 /* are any devices attached? */
175 if (!any_ports_active(uhci)) {
176 uhci->rh_state = UHCI_RH_RUNNING_NODEVS;
177 uhci->auto_stop_time = jiffies + HZ;
178 }
179 break;
180
181 case UHCI_RH_RUNNING_NODEVS:
182 /* auto-stop if nothing connected for 1 second */
183 if (any_ports_active(uhci))
184 uhci->rh_state = UHCI_RH_RUNNING;
185 else if (time_after_eq(jiffies, uhci->auto_stop_time))
186 suspend_rh(uhci, UHCI_RH_AUTO_STOPPED);
187 break;
188
189 default:
190 break;
191 }
192
193done:
194 spin_unlock_irqrestore(&uhci->lock, flags);
195 return status;
196}
197
145/* size of returned buffer is part of USB spec */ 198/* size of returned buffer is part of USB spec */
146static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, 199static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
147 u16 wIndex, char *buf, u16 wLength) 200 u16 wIndex, char *buf, u16 wLength)
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index f5c75885f7be..77f264851e98 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -32,6 +32,8 @@ static void uhci_free_pending_tds(struct uhci_hcd *uhci);
32 */ 32 */
33static inline void uhci_set_next_interrupt(struct uhci_hcd *uhci) 33static inline void uhci_set_next_interrupt(struct uhci_hcd *uhci)
34{ 34{
35 if (uhci->is_stopped)
36 mod_timer(&uhci->stall_timer, jiffies);
35 uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC); 37 uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC);
36} 38}
37 39
@@ -1497,6 +1499,7 @@ static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs)
1497 rescan: 1499 rescan:
1498 uhci->need_rescan = 0; 1500 uhci->need_rescan = 0;
1499 1501
1502 uhci_clear_next_interrupt(uhci);
1500 uhci_get_current_frame_number(uhci); 1503 uhci_get_current_frame_number(uhci);
1501 1504
1502 if (uhci->frame_number + uhci->is_stopped != uhci->qh_remove_age) 1505 if (uhci->frame_number + uhci->is_stopped != uhci->qh_remove_age)