aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-hcd.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-10-17 16:57:18 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-10-17 16:57:18 -0400
commit64f89798da35f43c6ef6afda0541e25034513458 (patch)
tree419546d28bac423277b504b3a94ed7da333490ca /drivers/usb/host/ehci-hcd.c
parent4e4bc305e16440ab38060d61fbcb7d774881d2f1 (diff)
USB: revert EHCI VIA workaround patch
This reverts 26f953fd884ea4879585287917f855c63c6b2666 which caused resume problems on the mac mini. Cc: David Brownell <david-b@pacbell.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r--drivers/usb/host/ehci-hcd.c70
1 files changed, 21 insertions, 49 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index aac6ec5dd7cf..9030994aba98 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -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_MSECS 10 /* arbitrary */ 114#define EHCI_IAA_JIFFIES (HZ/100) /* arbitrary; ~10 msec */
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,7 +254,6 @@ static void ehci_quiesce (struct ehci_hcd *ehci)
254 254
255/*-------------------------------------------------------------------------*/ 255/*-------------------------------------------------------------------------*/
256 256
257static void end_unlink_async (struct ehci_hcd *ehci);
258static void ehci_work(struct ehci_hcd *ehci); 257static void ehci_work(struct ehci_hcd *ehci);
259 258
260#include "ehci-hub.c" 259#include "ehci-hub.c"
@@ -264,37 +263,25 @@ static void ehci_work(struct ehci_hcd *ehci);
264 263
265/*-------------------------------------------------------------------------*/ 264/*-------------------------------------------------------------------------*/
266 265
267static void ehci_iaa_watchdog (unsigned long param) 266static void ehci_watchdog (unsigned long param)
268{ 267{
269 struct ehci_hcd *ehci = (struct ehci_hcd *) param; 268 struct ehci_hcd *ehci = (struct ehci_hcd *) param;
270 unsigned long flags; 269 unsigned long flags;
271 u32 status;
272 270
273 spin_lock_irqsave (&ehci->lock, flags); 271 spin_lock_irqsave (&ehci->lock, flags);
274 WARN_ON(!ehci->reclaim);
275 272
276 /* lost IAA irqs wedge things badly; seen first with a vt8235 */ 273 /* lost IAA irqs wedge things badly; seen with a vt8235 */
277 if (ehci->reclaim) { 274 if (ehci->reclaim) {
278 status = readl (&ehci->regs->status); 275 u32 status = readl (&ehci->regs->status);
279 if (status & STS_IAA) { 276 if (status & STS_IAA) {
280 ehci_vdbg (ehci, "lost IAA\n"); 277 ehci_vdbg (ehci, "lost IAA\n");
281 COUNT (ehci->stats.lost_iaa); 278 COUNT (ehci->stats.lost_iaa);
282 writel (STS_IAA, &ehci->regs->status); 279 writel (STS_IAA, &ehci->regs->status);
283 end_unlink_async (ehci); 280 ehci->reclaim_ready = 1;
284 } 281 }
285 } 282 }
286 283
287 spin_unlock_irqrestore (&ehci->lock, flags); 284 /* stop async processing after it's idled a bit */
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 */
298 if (test_bit (TIMER_ASYNC_OFF, &ehci->actions)) 285 if (test_bit (TIMER_ASYNC_OFF, &ehci->actions))
299 start_unlink_async (ehci, ehci->async); 286 start_unlink_async (ehci, ehci->async);
300 287
@@ -345,6 +332,8 @@ static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
345static void ehci_work (struct ehci_hcd *ehci) 332static void ehci_work (struct ehci_hcd *ehci)
346{ 333{
347 timer_action_done (ehci, TIMER_IO_WATCHDOG); 334 timer_action_done (ehci, TIMER_IO_WATCHDOG);
335 if (ehci->reclaim_ready)
336 end_unlink_async (ehci);
348 337
349 /* another CPU may drop ehci->lock during a schedule scan while 338 /* another CPU may drop ehci->lock during a schedule scan while
350 * it reports urb completions. this flag guards against bogus 339 * it reports urb completions. this flag guards against bogus
@@ -379,7 +368,6 @@ static void ehci_stop (struct usb_hcd *hcd)
379 368
380 /* no more interrupts ... */ 369 /* no more interrupts ... */
381 del_timer_sync (&ehci->watchdog); 370 del_timer_sync (&ehci->watchdog);
382 del_timer_sync (&ehci->iaa_watchdog);
383 371
384 spin_lock_irq(&ehci->lock); 372 spin_lock_irq(&ehci->lock);
385 if (HC_IS_RUNNING (hcd->state)) 373 if (HC_IS_RUNNING (hcd->state))
@@ -426,10 +414,6 @@ static int ehci_init(struct usb_hcd *hcd)
426 ehci->watchdog.function = ehci_watchdog; 414 ehci->watchdog.function = ehci_watchdog;
427 ehci->watchdog.data = (unsigned long) ehci; 415 ehci->watchdog.data = (unsigned long) ehci;
428 416
429 init_timer(&ehci->iaa_watchdog);
430 ehci->iaa_watchdog.function = ehci_iaa_watchdog;
431 ehci->iaa_watchdog.data = (unsigned long) ehci;
432
433 /* 417 /*
434 * hw default: 1K periodic list heads, one per frame. 418 * hw default: 1K periodic list heads, one per frame.
435 * periodic_size can shrink by USBCMD update if hcc_params allows. 419 * periodic_size can shrink by USBCMD update if hcc_params allows.
@@ -446,6 +430,7 @@ static int ehci_init(struct usb_hcd *hcd)
446 ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params); 430 ehci->i_thresh = 2 + HCC_ISOC_THRES(hcc_params);
447 431
448 ehci->reclaim = NULL; 432 ehci->reclaim = NULL;
433 ehci->reclaim_ready = 0;
449 ehci->next_uframe = -1; 434 ehci->next_uframe = -1;
450 435
451 /* 436 /*
@@ -619,7 +604,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
619 /* complete the unlinking of some qh [4.15.2.3] */ 604 /* complete the unlinking of some qh [4.15.2.3] */
620 if (status & STS_IAA) { 605 if (status & STS_IAA) {
621 COUNT (ehci->stats.reclaim); 606 COUNT (ehci->stats.reclaim);
622 end_unlink_async (ehci); 607 ehci->reclaim_ready = 1;
623 bh = 1; 608 bh = 1;
624 } 609 }
625 610
@@ -723,14 +708,10 @@ static int ehci_urb_enqueue (
723 708
724static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) 709static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
725{ 710{
726 // BUG_ON(qh->qh_state != QH_STATE_LINKED); 711 /* if we need to use IAA and it's busy, defer */
727 712 if (qh->qh_state == QH_STATE_LINKED
728 /* failfast */ 713 && ehci->reclaim
729 if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) 714 && HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) {
730 end_unlink_async (ehci);
731
732 /* defer till later if busy */
733 else if (ehci->reclaim) {
734 struct ehci_qh *last; 715 struct ehci_qh *last;
735 716
736 for (last = ehci->reclaim; 717 for (last = ehci->reclaim;
@@ -740,8 +721,12 @@ static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
740 qh->qh_state = QH_STATE_UNLINK_WAIT; 721 qh->qh_state = QH_STATE_UNLINK_WAIT;
741 last->reclaim = qh; 722 last->reclaim = qh;
742 723
743 /* start IAA cycle */ 724 /* bypass IAA if the hc can't care */
744 } else 725 } else if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state) && ehci->reclaim)
726 end_unlink_async (ehci);
727
728 /* something else might have unlinked the qh by now */
729 if (qh->qh_state == QH_STATE_LINKED)
745 start_unlink_async (ehci, qh); 730 start_unlink_async (ehci, qh);
746} 731}
747 732
@@ -763,19 +748,7 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
763 qh = (struct ehci_qh *) urb->hcpriv; 748 qh = (struct ehci_qh *) urb->hcpriv;
764 if (!qh) 749 if (!qh)
765 break; 750 break;
766 switch (qh->qh_state) { 751 unlink_async (ehci, qh);
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 }
779 break; 752 break;
780 753
781 case PIPE_INTERRUPT: 754 case PIPE_INTERRUPT:
@@ -867,7 +840,6 @@ rescan:
867 unlink_async (ehci, qh); 840 unlink_async (ehci, qh);
868 /* FALL THROUGH */ 841 /* FALL THROUGH */
869 case QH_STATE_UNLINK: /* wait for hw to finish? */ 842 case QH_STATE_UNLINK: /* wait for hw to finish? */
870 case QH_STATE_UNLINK_WAIT:
871idle_timeout: 843idle_timeout:
872 spin_unlock_irqrestore (&ehci->lock, flags); 844 spin_unlock_irqrestore (&ehci->lock, flags);
873 schedule_timeout_uninterruptible(1); 845 schedule_timeout_uninterruptible(1);