aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r--drivers/usb/host/ehci-hcd.c95
1 files changed, 58 insertions, 37 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d63177a8eaea..5ac918591131 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 2000-2004 by David Brownell 2 * Copyright (c) 2000-2004 by David Brownell
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the 5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your 6 * Free Software Foundation; either version 2 of the License, or (at your
@@ -70,7 +70,7 @@
70 * 2002-08-06 Handling for bulk and interrupt transfers is mostly shared; 70 * 2002-08-06 Handling for bulk and interrupt transfers is mostly shared;
71 * only scheduling is different, no arbitrary limitations. 71 * only scheduling is different, no arbitrary limitations.
72 * 2002-07-25 Sanity check PCI reads, mostly for better cardbus support, 72 * 2002-07-25 Sanity check PCI reads, mostly for better cardbus support,
73 * clean up HC run state handshaking. 73 * clean up HC run state handshaking.
74 * 2002-05-24 Preliminary FS/LS interrupts, using scheduling shortcuts 74 * 2002-05-24 Preliminary FS/LS interrupts, using scheduling shortcuts
75 * 2002-05-11 Clear TT errors for FS/LS ctrl/bulk. Fill in some other 75 * 2002-05-11 Clear TT errors for FS/LS ctrl/bulk. Fill in some other
76 * missing pieces: enabling 64bit dma, handoff from BIOS/SMM. 76 * missing pieces: enabling 64bit dma, handoff from BIOS/SMM.
@@ -111,7 +111,7 @@ static const char hcd_name [] = "ehci_hcd";
111#define EHCI_TUNE_MULT_TT 1 111#define EHCI_TUNE_MULT_TT 1
112#define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ 112#define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */
113 113
114#define EHCI_IAA_JIFFIES (HZ/100) /* arbitrary; ~10 msec */ 114#define EHCI_IAA_MSECS 10 /* arbitrary */
115#define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ 115#define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */
116#define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ 116#define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */
117#define EHCI_SHRINK_JIFFIES (HZ/200) /* async qh unlink delay */ 117#define EHCI_SHRINK_JIFFIES (HZ/200) /* async qh unlink delay */
@@ -254,6 +254,7 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
254 254
255/*-------------------------------------------------------------------------*/ 255/*-------------------------------------------------------------------------*/
256 256
257static void end_unlink_async (struct ehci_hcd *ehci, struct pt_regs *regs);
257static void ehci_work(struct ehci_hcd *ehci, struct pt_regs *regs); 258static void ehci_work(struct ehci_hcd *ehci, struct pt_regs *regs);
258 259
259#include "ehci-hub.c" 260#include "ehci-hub.c"
@@ -263,28 +264,39 @@ static void ehci_work(struct ehci_hcd *ehci, struct pt_regs *regs);
263 264
264/*-------------------------------------------------------------------------*/ 265/*-------------------------------------------------------------------------*/
265 266
266static void ehci_watchdog (unsigned long param) 267static void ehci_iaa_watchdog (unsigned long param)
267{ 268{
268 struct ehci_hcd *ehci = (struct ehci_hcd *) param; 269 struct ehci_hcd *ehci = (struct ehci_hcd *) param;
269 unsigned long flags; 270 unsigned long flags;
271 u32 status;
270 272
271 spin_lock_irqsave (&ehci->lock, flags); 273 spin_lock_irqsave (&ehci->lock, flags);
274 WARN_ON(!ehci->reclaim);
272 275
273 /* lost IAA irqs wedge things badly; seen with a vt8235 */ 276 /* lost IAA irqs wedge things badly; seen first with a vt8235 */
274 if (ehci->reclaim) { 277 if (ehci->reclaim) {
275 u32 status = readl (&ehci->regs->status); 278 status = readl (&ehci->regs->status);
276
277 if (status & STS_IAA) { 279 if (status & STS_IAA) {
278 ehci_vdbg (ehci, "lost IAA\n"); 280 ehci_vdbg (ehci, "lost IAA\n");
279 COUNT (ehci->stats.lost_iaa); 281 COUNT (ehci->stats.lost_iaa);
280 writel (STS_IAA, &ehci->regs->status); 282 writel (STS_IAA, &ehci->regs->status);
281 ehci->reclaim_ready = 1; 283 end_unlink_async (ehci, NULL);
282 } 284 }
283 } 285 }
284 286
285 /* stop async processing after it's idled a bit */ 287 spin_unlock_irqrestore (&ehci->lock, flags);
288}
289
290static void ehci_watchdog (unsigned long param)
291{
292 struct ehci_hcd *ehci = (struct ehci_hcd *) param;
293 unsigned long flags;
294
295 spin_lock_irqsave (&ehci->lock, flags);
296
297 /* stop async processing after it's idled a bit */
286 if (test_bit (TIMER_ASYNC_OFF, &ehci->actions)) 298 if (test_bit (TIMER_ASYNC_OFF, &ehci->actions))
287 start_unlink_async (ehci, ehci->async); 299 start_unlink_async (ehci, ehci->async);
288 300
289 /* ehci could run by timer, without IRQs ... */ 301 /* ehci could run by timer, without IRQs ... */
290 ehci_work (ehci, NULL); 302 ehci_work (ehci, NULL);
@@ -292,21 +304,20 @@ static void ehci_watchdog (unsigned long param)
292 spin_unlock_irqrestore (&ehci->lock, flags); 304 spin_unlock_irqrestore (&ehci->lock, flags);
293} 305}
294 306
295/* Reboot notifiers kick in for silicon on any bus (not just pci, etc). 307/* ehci_shutdown kick in for silicon on any bus (not just pci, etc).
296 * This forcibly disables dma and IRQs, helping kexec and other cases 308 * This forcibly disables dma and IRQs, helping kexec and other cases
297 * where the next system software may expect clean state. 309 * where the next system software may expect clean state.
298 */ 310 */
299static int 311static void
300ehci_reboot (struct notifier_block *self, unsigned long code, void *null) 312ehci_shutdown (struct usb_hcd *hcd)
301{ 313{
302 struct ehci_hcd *ehci; 314 struct ehci_hcd *ehci;
303 315
304 ehci = container_of (self, struct ehci_hcd, reboot_notifier); 316 ehci = hcd_to_ehci (hcd);
305 (void) ehci_halt (ehci); 317 (void) ehci_halt (ehci);
306 318
307 /* make BIOS/etc use companion controller during reboot */ 319 /* make BIOS/etc use companion controller during reboot */
308 writel (0, &ehci->regs->configured_flag); 320 writel (0, &ehci->regs->configured_flag);
309 return 0;
310} 321}
311 322
312static void ehci_port_power (struct ehci_hcd *ehci, int is_on) 323static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
@@ -334,8 +345,6 @@ static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
334static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs) 345static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs)
335{ 346{
336 timer_action_done (ehci, TIMER_IO_WATCHDOG); 347 timer_action_done (ehci, TIMER_IO_WATCHDOG);
337 if (ehci->reclaim_ready)
338 end_unlink_async (ehci, regs);
339 348
340 /* another CPU may drop ehci->lock during a schedule scan while 349 /* another CPU may drop ehci->lock during a schedule scan while
341 * it reports urb completions. this flag guards against bogus 350 * it reports urb completions. this flag guards against bogus
@@ -370,6 +379,7 @@ static void ehci_stop (struct usb_hcd *hcd)
370 379
371 /* no more interrupts ... */ 380 /* no more interrupts ... */
372 del_timer_sync (&ehci->watchdog); 381 del_timer_sync (&ehci->watchdog);
382 del_timer_sync (&ehci->iaa_watchdog);
373 383
374 spin_lock_irq(&ehci->lock); 384 spin_lock_irq(&ehci->lock);
375 if (HC_IS_RUNNING (hcd->state)) 385 if (HC_IS_RUNNING (hcd->state))
@@ -381,7 +391,6 @@ static void ehci_stop (struct usb_hcd *hcd)
381 391
382 /* let companion controllers work when we aren't */ 392 /* let companion controllers work when we aren't */
383 writel (0, &ehci->regs->configured_flag); 393 writel (0, &ehci->regs->configured_flag);
384 unregister_reboot_notifier (&ehci->reboot_notifier);
385 394
386 remove_debug_files (ehci); 395 remove_debug_files (ehci);
387 396
@@ -417,6 +426,10 @@ static int ehci_init(struct usb_hcd *hcd)
417 ehci->watchdog.function = ehci_watchdog; 426 ehci->watchdog.function = ehci_watchdog;
418 ehci->watchdog.data = (unsigned long) ehci; 427 ehci->watchdog.data = (unsigned long) ehci;
419 428
429 init_timer(&ehci->iaa_watchdog);
430 ehci->iaa_watchdog.function = ehci_iaa_watchdog;
431 ehci->iaa_watchdog.data = (unsigned long) ehci;
432
420 /* 433 /*
421 * hw default: 1K periodic list heads, one per frame. 434 * hw default: 1K periodic list heads, one per frame.
422 * periodic_size can shrink by USBCMD update if hcc_params allows. 435 * periodic_size can shrink by USBCMD update if hcc_params allows.
@@ -427,13 +440,12 @@ static int ehci_init(struct usb_hcd *hcd)
427 440
428 /* controllers may cache some of the periodic schedule ... */ 441 /* controllers may cache some of the periodic schedule ... */
429 hcc_params = readl(&ehci->caps->hcc_params); 442 hcc_params = readl(&ehci->caps->hcc_params);
430 if (HCC_ISOC_CACHE(hcc_params)) // full frame cache 443 if (HCC_ISOC_CACHE(hcc_params)) // full frame cache
431 ehci->i_thresh = 8; 444 ehci->i_thresh = 8;
432 else // N microframes cached 445 else // N microframes cached
433 ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); 446 ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params);
434 447
435 ehci->reclaim = NULL; 448 ehci->reclaim = NULL;
436 ehci->reclaim_ready = 0;
437 ehci->next_uframe = -1; 449 ehci->next_uframe = -1;
438 450
439 /* 451 /*
@@ -483,9 +495,6 @@ static int ehci_init(struct usb_hcd *hcd)
483 } 495 }
484 ehci->command = temp; 496 ehci->command = temp;
485 497
486 ehci->reboot_notifier.notifier_call = ehci_reboot;
487 register_reboot_notifier(&ehci->reboot_notifier);
488
489 return 0; 498 return 0;
490} 499}
491 500
@@ -499,7 +508,6 @@ static int ehci_run (struct usb_hcd *hcd)
499 508
500 /* EHCI spec section 4.1 */ 509 /* EHCI spec section 4.1 */
501 if ((retval = ehci_reset(ehci)) != 0) { 510 if ((retval = ehci_reset(ehci)) != 0) {
502 unregister_reboot_notifier(&ehci->reboot_notifier);
503 ehci_mem_cleanup(ehci); 511 ehci_mem_cleanup(ehci);
504 return retval; 512 return retval;
505 } 513 }
@@ -611,7 +619,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd, struct pt_regs *regs)
611 /* complete the unlinking of some qh [4.15.2.3] */ 619 /* complete the unlinking of some qh [4.15.2.3] */
612 if (status & STS_IAA) { 620 if (status & STS_IAA) {
613 COUNT (ehci->stats.reclaim); 621 COUNT (ehci->stats.reclaim);
614 ehci->reclaim_ready = 1; 622 end_unlink_async (ehci, regs);
615 bh = 1; 623 bh = 1;
616 } 624 }
617 625
@@ -715,10 +723,14 @@ static int ehci_urb_enqueue (
715 723
716static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) 724static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
717{ 725{
718 /* if we need to use IAA and it's busy, defer */ 726 // BUG_ON(qh->qh_state != QH_STATE_LINKED);
719 if (qh->qh_state == QH_STATE_LINKED 727
720 && ehci->reclaim 728 /* failfast */
721 && HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) { 729 if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state))
730 end_unlink_async (ehci, NULL);
731
732 /* defer till later if busy */
733 else if (ehci->reclaim) {
722 struct ehci_qh *last; 734 struct ehci_qh *last;
723 735
724 for (last = ehci->reclaim; 736 for (last = ehci->reclaim;
@@ -728,12 +740,8 @@ static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
728 qh->qh_state = QH_STATE_UNLINK_WAIT; 740 qh->qh_state = QH_STATE_UNLINK_WAIT;
729 last->reclaim = qh; 741 last->reclaim = qh;
730 742
731 /* bypass IAA if the hc can't care */ 743 /* start IAA cycle */
732 } else if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && ehci->reclaim) 744 } else
733 end_unlink_async (ehci, NULL);
734
735 /* something else might have unlinked the qh by now */
736 if (qh->qh_state == QH_STATE_LINKED)
737 start_unlink_async (ehci, qh); 745 start_unlink_async (ehci, qh);
738} 746}
739 747
@@ -755,7 +763,19 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
755 qh = (struct ehci_qh *) urb->hcpriv; 763 qh = (struct ehci_qh *) urb->hcpriv;
756 if (!qh) 764 if (!qh)
757 break; 765 break;
758 unlink_async (ehci, qh); 766 switch (qh->qh_state) {
767 case QH_STATE_LINKED:
768 case QH_STATE_COMPLETING:
769 unlink_async (ehci, qh);
770 break;
771 case QH_STATE_UNLINK:
772 case QH_STATE_UNLINK_WAIT:
773 /* already started */
774 break;
775 case QH_STATE_IDLE:
776 WARN_ON(1);
777 break;
778 }
759 break; 779 break;
760 780
761 case PIPE_INTERRUPT: 781 case PIPE_INTERRUPT:
@@ -847,6 +867,7 @@ rescan:
847 unlink_async (ehci, qh); 867 unlink_async (ehci, qh);
848 /* FALL THROUGH */ 868 /* FALL THROUGH */
849 case QH_STATE_UNLINK: /* wait for hw to finish? */ 869 case QH_STATE_UNLINK: /* wait for hw to finish? */
870 case QH_STATE_UNLINK_WAIT:
850idle_timeout: 871idle_timeout:
851 spin_unlock_irqrestore (&ehci->lock, flags); 872 spin_unlock_irqrestore (&ehci->lock, flags);
852 schedule_timeout_uninterruptible(1); 873 schedule_timeout_uninterruptible(1);