aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2005-09-05 13:59:51 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-09-12 15:23:40 -0400
commit1f09df8bfe358994fcb5f3dc4f890694c4069621 (patch)
treeb9778e010d4f85780fcc44b76ab49dc05dfe85fb
parentf1a15606d5be8490a122f1c94c554bd0f07d8d26 (diff)
[PATCH] USB UHCI: remove the FSBR kernel timer
This patch (as558) removes from the UHCI driver a kernel timer used for checking Full Speed Bandwidth Reclamation (FSBR). The checking can be done during normal root-hub polling; it doesn't need a separate timer. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/host/uhci-hcd.c62
-rw-r--r--drivers/usb/host/uhci-hcd.h11
-rw-r--r--drivers/usb/host/uhci-hub.c11
-rw-r--r--drivers/usb/host/uhci-q.c2
4 files changed, 32 insertions, 54 deletions
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index 0d5d2545bf07..0c024898cbea 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -97,14 +97,9 @@ static void uhci_get_current_frame_number(struct uhci_hcd *uhci);
97/* to make sure it doesn't hog all of the bandwidth */ 97/* to make sure it doesn't hog all of the bandwidth */
98#define DEPTH_INTERVAL 5 98#define DEPTH_INTERVAL 5
99 99
100static inline void restart_timer(struct uhci_hcd *uhci)
101{
102 mod_timer(&uhci->stall_timer, jiffies + msecs_to_jiffies(100));
103}
104
105#include "uhci-hub.c"
106#include "uhci-debug.c" 100#include "uhci-debug.c"
107#include "uhci-q.c" 101#include "uhci-q.c"
102#include "uhci-hub.c"
108 103
109/* 104/*
110 * Make sure the controller is completely inactive, unable to 105 * Make sure the controller is completely inactive, unable to
@@ -160,7 +155,6 @@ static void hc_died(struct uhci_hcd *uhci)
160{ 155{
161 reset_hc(uhci); 156 reset_hc(uhci);
162 uhci->hc_inaccessible = 1; 157 uhci->hc_inaccessible = 1;
163 del_timer(&uhci->stall_timer);
164} 158}
165 159
166/* 160/*
@@ -287,8 +281,11 @@ __acquires(uhci->lock)
287 /* Enable resume-detect interrupts if they work. 281 /* Enable resume-detect interrupts if they work.
288 * Then enter Global Suspend mode, still configured. 282 * Then enter Global Suspend mode, still configured.
289 */ 283 */
290 int_enable = (resume_detect_interrupts_are_broken(uhci) ? 284 uhci->working_RD = 1;
291 0 : USBINTR_RESUME); 285 int_enable = USBINTR_RESUME;
286 if (resume_detect_interrupts_are_broken(uhci)) {
287 uhci->working_RD = int_enable = 0;
288 }
292 outw(int_enable, uhci->io_addr + USBINTR); 289 outw(int_enable, uhci->io_addr + USBINTR);
293 outw(USBCMD_EGSM | USBCMD_CF, uhci->io_addr + USBCMD); 290 outw(USBCMD_EGSM | USBCMD_CF, uhci->io_addr + USBCMD);
294 mb(); 291 mb();
@@ -315,7 +312,6 @@ __acquires(uhci->lock)
315 312
316 uhci->rh_state = new_state; 313 uhci->rh_state = new_state;
317 uhci->is_stopped = UHCI_IS_STOPPED; 314 uhci->is_stopped = UHCI_IS_STOPPED;
318 del_timer(&uhci->stall_timer);
319 uhci_to_hcd(uhci)->poll_rh = !int_enable; 315 uhci_to_hcd(uhci)->poll_rh = !int_enable;
320 316
321 uhci_scan_schedule(uhci, NULL); 317 uhci_scan_schedule(uhci, NULL);
@@ -335,7 +331,6 @@ static void start_rh(struct uhci_hcd *uhci)
335 mb(); 331 mb();
336 uhci->rh_state = UHCI_RH_RUNNING; 332 uhci->rh_state = UHCI_RH_RUNNING;
337 uhci_to_hcd(uhci)->poll_rh = 1; 333 uhci_to_hcd(uhci)->poll_rh = 1;
338 restart_timer(uhci);
339} 334}
340 335
341static void wakeup_rh(struct uhci_hcd *uhci) 336static void wakeup_rh(struct uhci_hcd *uhci)
@@ -374,20 +369,6 @@ __acquires(uhci->lock)
374 mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies); 369 mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
375} 370}
376 371
377static void stall_callback(unsigned long _uhci)
378{
379 struct uhci_hcd *uhci = (struct uhci_hcd *) _uhci;
380 unsigned long flags;
381
382 spin_lock_irqsave(&uhci->lock, flags);
383 uhci_scan_schedule(uhci, NULL);
384 check_fsbr(uhci);
385
386 if (!uhci->is_stopped)
387 restart_timer(uhci);
388 spin_unlock_irqrestore(&uhci->lock, flags);
389}
390
391static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs) 372static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
392{ 373{
393 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 374 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
@@ -418,8 +399,10 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
418 "host controller halted, " 399 "host controller halted, "
419 "very bad!\n"); 400 "very bad!\n");
420 hc_died(uhci); 401 hc_died(uhci);
421 spin_unlock_irqrestore(&uhci->lock, flags); 402
422 return IRQ_HANDLED; 403 /* Force a callback in case there are
404 * pending unlinks */
405 mod_timer(&hcd->rh_timer, jiffies);
423 } 406 }
424 spin_unlock_irqrestore(&uhci->lock, flags); 407 spin_unlock_irqrestore(&uhci->lock, flags);
425 } 408 }
@@ -427,10 +410,11 @@ static irqreturn_t uhci_irq(struct usb_hcd *hcd, struct pt_regs *regs)
427 410
428 if (status & USBSTS_RD) 411 if (status & USBSTS_RD)
429 usb_hcd_poll_rh_status(hcd); 412 usb_hcd_poll_rh_status(hcd);
430 413 else {
431 spin_lock_irqsave(&uhci->lock, flags); 414 spin_lock_irqsave(&uhci->lock, flags);
432 uhci_scan_schedule(uhci, regs); 415 uhci_scan_schedule(uhci, regs);
433 spin_unlock_irqrestore(&uhci->lock, flags); 416 spin_unlock_irqrestore(&uhci->lock, flags);
417 }
434 418
435 return IRQ_HANDLED; 419 return IRQ_HANDLED;
436} 420}
@@ -595,10 +579,6 @@ static int uhci_start(struct usb_hcd *hcd)
595 579
596 init_waitqueue_head(&uhci->waitqh); 580 init_waitqueue_head(&uhci->waitqh);
597 581
598 init_timer(&uhci->stall_timer);
599 uhci->stall_timer.function = stall_callback;
600 uhci->stall_timer.data = (unsigned long) uhci;
601
602 uhci->fl = dma_alloc_coherent(uhci_dev(uhci), sizeof(*uhci->fl), 582 uhci->fl = dma_alloc_coherent(uhci_dev(uhci), sizeof(*uhci->fl),
603 &dma_handle, 0); 583 &dma_handle, 0);
604 if (!uhci->fl) { 584 if (!uhci->fl) {
@@ -745,11 +725,11 @@ static void uhci_stop(struct usb_hcd *hcd)
745 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 725 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
746 726
747 spin_lock_irq(&uhci->lock); 727 spin_lock_irq(&uhci->lock);
748 reset_hc(uhci); 728 if (!uhci->hc_inaccessible)
729 reset_hc(uhci);
749 uhci_scan_schedule(uhci, NULL); 730 uhci_scan_schedule(uhci, NULL);
750 spin_unlock_irq(&uhci->lock); 731 spin_unlock_irq(&uhci->lock);
751 732
752 del_timer_sync(&uhci->stall_timer);
753 release_uhci(uhci); 733 release_uhci(uhci);
754} 734}
755 735
@@ -811,13 +791,12 @@ static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message)
811 */ 791 */
812 pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0); 792 pci_write_config_word(to_pci_dev(uhci_dev(uhci)), USBLEGSUP, 0);
813 uhci->hc_inaccessible = 1; 793 uhci->hc_inaccessible = 1;
794 hcd->poll_rh = 0;
814 795
815 /* FIXME: Enable non-PME# remote wakeup? */ 796 /* FIXME: Enable non-PME# remote wakeup? */
816 797
817done: 798done:
818 spin_unlock_irq(&uhci->lock); 799 spin_unlock_irq(&uhci->lock);
819 if (rc == 0)
820 del_timer_sync(&hcd->rh_timer);
821 return rc; 800 return rc;
822} 801}
823 802
@@ -850,8 +829,11 @@ static int uhci_resume(struct usb_hcd *hcd)
850 829
851 spin_unlock_irq(&uhci->lock); 830 spin_unlock_irq(&uhci->lock);
852 831
853 if (hcd->poll_rh) 832 if (!uhci->working_RD) {
833 /* Suspended root hub needs to be polled */
834 hcd->poll_rh = 1;
854 usb_hcd_poll_rh_status(hcd); 835 usb_hcd_poll_rh_status(hcd);
836 }
855 return 0; 837 return 0;
856} 838}
857#endif 839#endif
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h
index bf9c5f9b508b..282f40b75881 100644
--- a/drivers/usb/host/uhci-hcd.h
+++ b/drivers/usb/host/uhci-hcd.h
@@ -345,9 +345,6 @@ enum uhci_rh_state {
345 345
346/* 346/*
347 * This describes the full uhci information. 347 * This describes the full uhci information.
348 *
349 * Note how the "proper" USB information is just
350 * a subset of what the full implementation needs.
351 */ 348 */
352struct uhci_hcd { 349struct uhci_hcd {
353 350
@@ -360,8 +357,6 @@ struct uhci_hcd {
360 struct dma_pool *qh_pool; 357 struct dma_pool *qh_pool;
361 struct dma_pool *td_pool; 358 struct dma_pool *td_pool;
362 359
363 struct usb_bus *bus;
364
365 struct uhci_td *term_td; /* Terminating TD, see UHCI bug */ 360 struct uhci_td *term_td; /* Terminating TD, see UHCI bug */
366 struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */ 361 struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */
367 362
@@ -380,6 +375,8 @@ struct uhci_hcd {
380 unsigned int scan_in_progress:1; /* Schedule scan is running */ 375 unsigned int scan_in_progress:1; /* Schedule scan is running */
381 unsigned int need_rescan:1; /* Redo the schedule scan */ 376 unsigned int need_rescan:1; /* Redo the schedule scan */
382 unsigned int hc_inaccessible:1; /* HC is suspended or dead */ 377 unsigned int hc_inaccessible:1; /* HC is suspended or dead */
378 unsigned int working_RD:1; /* Suspended root hub doesn't
379 need to be polled */
383 380
384 /* Support for port suspend/resume/reset */ 381 /* Support for port suspend/resume/reset */
385 unsigned long port_c_suspend; /* Bit-arrays of ports */ 382 unsigned long port_c_suspend; /* Bit-arrays of ports */
@@ -405,9 +402,7 @@ struct uhci_hcd {
405 /* List of URB's awaiting completion callback */ 402 /* List of URB's awaiting completion callback */
406 struct list_head complete_list; /* P: uhci->lock */ 403 struct list_head complete_list; /* P: uhci->lock */
407 404
408 int rh_numports; 405 int rh_numports; /* Number of root-hub ports */
409
410 struct timer_list stall_timer;
411 406
412 wait_queue_head_t waitqh; /* endpoint_disable waiters */ 407 wait_queue_head_t waitqh; /* endpoint_disable waiters */
413}; 408};
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
index 4eace2b19ddb..a71e48a66805 100644
--- a/drivers/usb/host/uhci-hub.c
+++ b/drivers/usb/host/uhci-hub.c
@@ -145,15 +145,16 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
145{ 145{
146 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 146 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
147 unsigned long flags; 147 unsigned long flags;
148 int status; 148 int status = 0;
149 149
150 spin_lock_irqsave(&uhci->lock, flags); 150 spin_lock_irqsave(&uhci->lock, flags);
151 if (uhci->hc_inaccessible) {
152 status = 0;
153 goto done;
154 }
155 151
152 uhci_scan_schedule(uhci, NULL);
153 if (uhci->hc_inaccessible)
154 goto done;
155 check_fsbr(uhci);
156 uhci_check_ports(uhci); 156 uhci_check_ports(uhci);
157
157 status = get_hub_status_data(uhci, buf); 158 status = get_hub_status_data(uhci, buf);
158 159
159 switch (uhci->rh_state) { 160 switch (uhci->rh_state) {
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index bbb36cd6ed61..ea0d168a8c67 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -33,7 +33,7 @@ static void uhci_free_pending_tds(struct uhci_hcd *uhci);
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) 35 if (uhci->is_stopped)
36 mod_timer(&uhci->stall_timer, jiffies); 36 mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies);
37 uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC); 37 uhci->term_td->status |= cpu_to_le32(TD_CTRL_IOC);
38} 38}
39 39