aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2014-07-18 16:25:36 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-07-18 19:30:45 -0400
commit95d9a01d727fdb6d2b667ac374341c48777cc41e (patch)
tree36f1c672f3dca5b67f510ecf9f3ea90574808673
parenta40178b2fa6ad87670fb1e5fa4024db00c149629 (diff)
USB: OHCI: revert the ZF Micro orphan-TD quirk
This patch reverts the important parts of commit 89a0fd18a96e (USB: OHCI handles more ZFMicro quirks), namely, the parts related to handling orphan TDs for interrupt endpoints. A later patch in this series will introduce a more general mechanism that applies to all endpoint types and all controllers. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/host/ohci-hcd.c134
-rw-r--r--drivers/usb/host/ohci-q.c25
-rw-r--r--drivers/usb/host/ohci.h6
3 files changed, 5 insertions, 160 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 7570098b1cfa..a8f0e1b00e7d 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -355,8 +355,6 @@ rescan:
355 if (ohci->rh_state != OHCI_RH_RUNNING) { 355 if (ohci->rh_state != OHCI_RH_RUNNING) {
356sanitize: 356sanitize:
357 ed->state = ED_IDLE; 357 ed->state = ED_IDLE;
358 if (quirk_zfmicro(ohci) && ed->type == PIPE_INTERRUPT)
359 ohci->eds_scheduled--;
360 finish_unlinks (ohci, 0); 358 finish_unlinks (ohci, 0);
361 } 359 }
362 360
@@ -365,11 +363,6 @@ sanitize:
365 /* major IRQ delivery trouble loses INTR_SF too... */ 363 /* major IRQ delivery trouble loses INTR_SF too... */
366 if (limit-- == 0) { 364 if (limit-- == 0) {
367 ohci_warn(ohci, "ED unlink timeout\n"); 365 ohci_warn(ohci, "ED unlink timeout\n");
368 if (quirk_zfmicro(ohci)) {
369 ohci_warn(ohci, "Attempting ZF TD recovery\n");
370 ohci->ed_to_check = ed;
371 ohci->zf_delay = 2;
372 }
373 goto sanitize; 366 goto sanitize;
374 } 367 }
375 spin_unlock_irqrestore (&ohci->lock, flags); 368 spin_unlock_irqrestore (&ohci->lock, flags);
@@ -431,93 +424,6 @@ ohci_shutdown (struct usb_hcd *hcd)
431 ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval); 424 ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval);
432} 425}
433 426
434static int check_ed(struct ohci_hcd *ohci, struct ed *ed)
435{
436 return (hc32_to_cpu(ohci, ed->hwINFO) & ED_IN) != 0
437 && (hc32_to_cpu(ohci, ed->hwHeadP) & TD_MASK)
438 == (hc32_to_cpu(ohci, ed->hwTailP) & TD_MASK)
439 && !list_empty(&ed->td_list);
440}
441
442/* ZF Micro watchdog timer callback. The ZF Micro chipset sometimes completes
443 * an interrupt TD but neglects to add it to the donelist. On systems with
444 * this chipset, we need to periodically check the state of the queues to look
445 * for such "lost" TDs.
446 */
447static void unlink_watchdog_func(unsigned long _ohci)
448{
449 unsigned long flags;
450 unsigned max;
451 unsigned seen_count = 0;
452 unsigned i;
453 struct ed **seen = NULL;
454 struct ohci_hcd *ohci = (struct ohci_hcd *) _ohci;
455
456 spin_lock_irqsave(&ohci->lock, flags);
457 max = ohci->eds_scheduled;
458 if (!max)
459 goto done;
460
461 if (ohci->ed_to_check)
462 goto out;
463
464 seen = kcalloc(max, sizeof *seen, GFP_ATOMIC);
465 if (!seen)
466 goto out;
467
468 for (i = 0; i < NUM_INTS; i++) {
469 struct ed *ed = ohci->periodic[i];
470
471 while (ed) {
472 unsigned temp;
473
474 /* scan this branch of the periodic schedule tree */
475 for (temp = 0; temp < seen_count; temp++) {
476 if (seen[temp] == ed) {
477 /* we've checked it and what's after */
478 ed = NULL;
479 break;
480 }
481 }
482 if (!ed)
483 break;
484 seen[seen_count++] = ed;
485 if (!check_ed(ohci, ed)) {
486 ed = ed->ed_next;
487 continue;
488 }
489
490 /* HC's TD list is empty, but HCD sees at least one
491 * TD that's not been sent through the donelist.
492 */
493 ohci->ed_to_check = ed;
494 ohci->zf_delay = 2;
495
496 /* The HC may wait until the next frame to report the
497 * TD as done through the donelist and INTR_WDH. (We
498 * just *assume* it's not a multi-TD interrupt URB;
499 * those could defer the IRQ more than one frame, using
500 * DI...) Check again after the next INTR_SF.
501 */
502 ohci_writel(ohci, OHCI_INTR_SF,
503 &ohci->regs->intrstatus);
504 ohci_writel(ohci, OHCI_INTR_SF,
505 &ohci->regs->intrenable);
506
507 /* flush those writes */
508 (void) ohci_readl(ohci, &ohci->regs->control);
509
510 goto out;
511 }
512 }
513out:
514 kfree(seen);
515 if (ohci->eds_scheduled)
516 mod_timer(&ohci->unlink_watchdog, round_jiffies(jiffies + HZ));
517done:
518 spin_unlock_irqrestore(&ohci->lock, flags);
519}
520
521/*-------------------------------------------------------------------------* 427/*-------------------------------------------------------------------------*
522 * HC functions 428 * HC functions
523 *-------------------------------------------------------------------------*/ 429 *-------------------------------------------------------------------------*/
@@ -761,15 +667,6 @@ retry:
761 // POTPGT delay is bits 24-31, in 2 ms units. 667 // POTPGT delay is bits 24-31, in 2 ms units.
762 mdelay ((val >> 23) & 0x1fe); 668 mdelay ((val >> 23) & 0x1fe);
763 669
764 if (quirk_zfmicro(ohci)) {
765 /* Create timer to watch for bad queue state on ZF Micro */
766 setup_timer(&ohci->unlink_watchdog, unlink_watchdog_func,
767 (unsigned long) ohci);
768
769 ohci->eds_scheduled = 0;
770 ohci->ed_to_check = NULL;
771 }
772
773 ohci_dump(ohci); 670 ohci_dump(ohci);
774 671
775 return 0; 672 return 0;
@@ -895,31 +792,6 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
895 spin_unlock (&ohci->lock); 792 spin_unlock (&ohci->lock);
896 } 793 }
897 794
898 if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) {
899 spin_lock(&ohci->lock);
900 if (ohci->ed_to_check) {
901 struct ed *ed = ohci->ed_to_check;
902
903 if (check_ed(ohci, ed)) {
904 /* HC thinks the TD list is empty; HCD knows
905 * at least one TD is outstanding
906 */
907 if (--ohci->zf_delay == 0) {
908 struct td *td = list_entry(
909 ed->td_list.next,
910 struct td, td_list);
911 ohci_warn(ohci,
912 "Reclaiming orphan TD %p\n",
913 td);
914 takeback_td(ohci, td);
915 ohci->ed_to_check = NULL;
916 }
917 } else
918 ohci->ed_to_check = NULL;
919 }
920 spin_unlock(&ohci->lock);
921 }
922
923 /* could track INTR_SO to reduce available PCI/... bandwidth */ 795 /* could track INTR_SO to reduce available PCI/... bandwidth */
924 796
925 /* handle any pending URB/ED unlinks, leaving INTR_SF enabled 797 /* handle any pending URB/ED unlinks, leaving INTR_SF enabled
@@ -928,9 +800,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd)
928 spin_lock (&ohci->lock); 800 spin_lock (&ohci->lock);
929 if (ohci->ed_rm_list) 801 if (ohci->ed_rm_list)
930 finish_unlinks (ohci, ohci_frame_no(ohci)); 802 finish_unlinks (ohci, ohci_frame_no(ohci));
931 if ((ints & OHCI_INTR_SF) != 0 803 if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list
932 && !ohci->ed_rm_list
933 && !ohci->ed_to_check
934 && ohci->rh_state == OHCI_RH_RUNNING) 804 && ohci->rh_state == OHCI_RH_RUNNING)
935 ohci_writel (ohci, OHCI_INTR_SF, &regs->intrdisable); 805 ohci_writel (ohci, OHCI_INTR_SF, &regs->intrdisable);
936 spin_unlock (&ohci->lock); 806 spin_unlock (&ohci->lock);
@@ -961,8 +831,6 @@ static void ohci_stop (struct usb_hcd *hcd)
961 free_irq(hcd->irq, hcd); 831 free_irq(hcd->irq, hcd);
962 hcd->irq = 0; 832 hcd->irq = 0;
963 833
964 if (quirk_zfmicro(ohci))
965 del_timer(&ohci->unlink_watchdog);
966 if (quirk_amdiso(ohci)) 834 if (quirk_amdiso(ohci))
967 usb_amd_dev_put(); 835 usb_amd_dev_put();
968 836
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index a6376f3e55cb..a9f4f04c3fad 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -187,10 +187,6 @@ static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed)
187 ed->ed_prev = NULL; 187 ed->ed_prev = NULL;
188 ed->ed_next = NULL; 188 ed->ed_next = NULL;
189 ed->hwNextED = 0; 189 ed->hwNextED = 0;
190 if (quirk_zfmicro(ohci)
191 && (ed->type == PIPE_INTERRUPT)
192 && !(ohci->eds_scheduled++))
193 mod_timer(&ohci->unlink_watchdog, round_jiffies(jiffies + HZ));
194 wmb (); 190 wmb ();
195 191
196 /* we care about rm_list when setting CLE/BLE in case the HC was at 192 /* we care about rm_list when setting CLE/BLE in case the HC was at
@@ -977,19 +973,13 @@ skip_ed:
977 TD_MASK; 973 TD_MASK;
978 974
979 /* INTR_WDH may need to clean up first */ 975 /* INTR_WDH may need to clean up first */
980 if (td->td_dma != head) { 976 if (td->td_dma != head)
981 if (ed == ohci->ed_to_check) 977 goto skip_ed;
982 ohci->ed_to_check = NULL;
983 else
984 goto skip_ed;
985 }
986 } 978 }
987 } 979 }
988 980
989 /* ED's now officially unlinked, hc doesn't see */ 981 /* ED's now officially unlinked, hc doesn't see */
990 ed->state = ED_IDLE; 982 ed->state = ED_IDLE;
991 if (quirk_zfmicro(ohci) && ed->type == PIPE_INTERRUPT)
992 ohci->eds_scheduled--;
993 ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_H); 983 ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_H);
994 ed->hwNextED = 0; 984 ed->hwNextED = 0;
995 wmb(); 985 wmb();
@@ -1122,12 +1112,7 @@ rescan_this:
1122 1112
1123/*-------------------------------------------------------------------------*/ 1113/*-------------------------------------------------------------------------*/
1124 1114
1125/* 1115/* Take back a TD from the host controller */
1126 * Used to take back a TD from the host controller. This would normally be
1127 * called from within dl_done_list, however it may be called directly if the
1128 * HC no longer sees the TD and it has not appeared on the donelist (after
1129 * two frames). This bug has been observed on ZF Micro systems.
1130 */
1131static void takeback_td(struct ohci_hcd *ohci, struct td *td) 1116static void takeback_td(struct ohci_hcd *ohci, struct td *td)
1132{ 1117{
1133 struct urb *urb = td->urb; 1118 struct urb *urb = td->urb;
@@ -1174,9 +1159,7 @@ static void takeback_td(struct ohci_hcd *ohci, struct td *td)
1174 * 1159 *
1175 * This is the main path for handing urbs back to drivers. The only other 1160 * This is the main path for handing urbs back to drivers. The only other
1176 * normal path is finish_unlinks(), which unlinks URBs using ed_rm_list, 1161 * normal path is finish_unlinks(), which unlinks URBs using ed_rm_list,
1177 * instead of scanning the (re-reversed) donelist as this does. There's 1162 * instead of scanning the (re-reversed) donelist as this does.
1178 * an abnormal path too, handling a quirk in some Compaq silicon: URBs
1179 * with TDs that appear to be orphaned are directly reclaimed.
1180 */ 1163 */
1181static void 1164static void
1182dl_done_list (struct ohci_hcd *ohci) 1165dl_done_list (struct ohci_hcd *ohci)
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index 05e02a709d4f..392932dd6318 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -411,12 +411,6 @@ struct ohci_hcd {
411 411
412 struct work_struct nec_work; /* Worker for NEC quirk */ 412 struct work_struct nec_work; /* Worker for NEC quirk */
413 413
414 /* Needed for ZF Micro quirk */
415 struct timer_list unlink_watchdog;
416 unsigned eds_scheduled;
417 struct ed *ed_to_check;
418 unsigned zf_delay;
419
420 struct dentry *debug_dir; 414 struct dentry *debug_dir;
421 struct dentry *debug_async; 415 struct dentry *debug_async;
422 struct dentry *debug_periodic; 416 struct dentry *debug_periodic;