diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/host/ohci-hcd.c | 166 | ||||
-rw-r--r-- | drivers/usb/host/ohci-mem.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/ohci-pci.c | 22 | ||||
-rw-r--r-- | drivers/usb/host/ohci-q.c | 113 | ||||
-rw-r--r-- | drivers/usb/host/ohci.h | 26 |
5 files changed, 253 insertions, 75 deletions
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 6edf4097d2d2..d673cb9c36b1 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -81,7 +81,6 @@ static void ohci_dump (struct ohci_hcd *ohci, int verbose); | |||
81 | static int ohci_init (struct ohci_hcd *ohci); | 81 | static int ohci_init (struct ohci_hcd *ohci); |
82 | static void ohci_stop (struct usb_hcd *hcd); | 82 | static void ohci_stop (struct usb_hcd *hcd); |
83 | static int ohci_restart (struct ohci_hcd *ohci); | 83 | static int ohci_restart (struct ohci_hcd *ohci); |
84 | static void ohci_quirk_nec_worker (struct work_struct *work); | ||
85 | 84 | ||
86 | #include "ohci-hub.c" | 85 | #include "ohci-hub.c" |
87 | #include "ohci-dbg.c" | 86 | #include "ohci-dbg.c" |
@@ -314,6 +313,8 @@ rescan: | |||
314 | if (!HC_IS_RUNNING (hcd->state)) { | 313 | if (!HC_IS_RUNNING (hcd->state)) { |
315 | sanitize: | 314 | sanitize: |
316 | ed->state = ED_IDLE; | 315 | ed->state = ED_IDLE; |
316 | if (quirk_zfmicro(ohci) && ed->type == PIPE_INTERRUPT) | ||
317 | ohci->eds_scheduled--; | ||
317 | finish_unlinks (ohci, 0); | 318 | finish_unlinks (ohci, 0); |
318 | } | 319 | } |
319 | 320 | ||
@@ -321,7 +322,12 @@ sanitize: | |||
321 | case ED_UNLINK: /* wait for hw to finish? */ | 322 | case ED_UNLINK: /* wait for hw to finish? */ |
322 | /* major IRQ delivery trouble loses INTR_SF too... */ | 323 | /* major IRQ delivery trouble loses INTR_SF too... */ |
323 | if (limit-- == 0) { | 324 | if (limit-- == 0) { |
324 | ohci_warn (ohci, "IRQ INTR_SF lossage\n"); | 325 | ohci_warn(ohci, "ED unlink timeout\n"); |
326 | if (quirk_zfmicro(ohci)) { | ||
327 | ohci_warn(ohci, "Attempting ZF TD recovery\n"); | ||
328 | ohci->ed_to_check = ed; | ||
329 | ohci->zf_delay = 2; | ||
330 | } | ||
325 | goto sanitize; | 331 | goto sanitize; |
326 | } | 332 | } |
327 | spin_unlock_irqrestore (&ohci->lock, flags); | 333 | spin_unlock_irqrestore (&ohci->lock, flags); |
@@ -379,6 +385,93 @@ ohci_shutdown (struct usb_hcd *hcd) | |||
379 | (void) ohci_readl (ohci, &ohci->regs->control); | 385 | (void) ohci_readl (ohci, &ohci->regs->control); |
380 | } | 386 | } |
381 | 387 | ||
388 | static int check_ed(struct ohci_hcd *ohci, struct ed *ed) | ||
389 | { | ||
390 | return (hc32_to_cpu(ohci, ed->hwINFO) & ED_IN) != 0 | ||
391 | && (hc32_to_cpu(ohci, ed->hwHeadP) & TD_MASK) | ||
392 | == (hc32_to_cpu(ohci, ed->hwTailP) & TD_MASK) | ||
393 | && !list_empty(&ed->td_list); | ||
394 | } | ||
395 | |||
396 | /* ZF Micro watchdog timer callback. The ZF Micro chipset sometimes completes | ||
397 | * an interrupt TD but neglects to add it to the donelist. On systems with | ||
398 | * this chipset, we need to periodically check the state of the queues to look | ||
399 | * for such "lost" TDs. | ||
400 | */ | ||
401 | static void unlink_watchdog_func(unsigned long _ohci) | ||
402 | { | ||
403 | long flags; | ||
404 | unsigned max; | ||
405 | unsigned seen_count = 0; | ||
406 | unsigned i; | ||
407 | struct ed **seen = NULL; | ||
408 | struct ohci_hcd *ohci = (struct ohci_hcd *) _ohci; | ||
409 | |||
410 | spin_lock_irqsave(&ohci->lock, flags); | ||
411 | max = ohci->eds_scheduled; | ||
412 | if (!max) | ||
413 | goto done; | ||
414 | |||
415 | if (ohci->ed_to_check) | ||
416 | goto out; | ||
417 | |||
418 | seen = kcalloc(max, sizeof *seen, GFP_ATOMIC); | ||
419 | if (!seen) | ||
420 | goto out; | ||
421 | |||
422 | for (i = 0; i < NUM_INTS; i++) { | ||
423 | struct ed *ed = ohci->periodic[i]; | ||
424 | |||
425 | while (ed) { | ||
426 | unsigned temp; | ||
427 | |||
428 | /* scan this branch of the periodic schedule tree */ | ||
429 | for (temp = 0; temp < seen_count; temp++) { | ||
430 | if (seen[temp] == ed) { | ||
431 | /* we've checked it and what's after */ | ||
432 | ed = NULL; | ||
433 | break; | ||
434 | } | ||
435 | } | ||
436 | if (!ed) | ||
437 | break; | ||
438 | seen[seen_count++] = ed; | ||
439 | if (!check_ed(ohci, ed)) { | ||
440 | ed = ed->ed_next; | ||
441 | continue; | ||
442 | } | ||
443 | |||
444 | /* HC's TD list is empty, but HCD sees at least one | ||
445 | * TD that's not been sent through the donelist. | ||
446 | */ | ||
447 | ohci->ed_to_check = ed; | ||
448 | ohci->zf_delay = 2; | ||
449 | |||
450 | /* The HC may wait until the next frame to report the | ||
451 | * TD as done through the donelist and INTR_WDH. (We | ||
452 | * just *assume* it's not a multi-TD interrupt URB; | ||
453 | * those could defer the IRQ more than one frame, using | ||
454 | * DI...) Check again after the next INTR_SF. | ||
455 | */ | ||
456 | ohci_writel(ohci, OHCI_INTR_SF, | ||
457 | &ohci->regs->intrstatus); | ||
458 | ohci_writel(ohci, OHCI_INTR_SF, | ||
459 | &ohci->regs->intrenable); | ||
460 | |||
461 | /* flush those writes */ | ||
462 | (void) ohci_readl(ohci, &ohci->regs->control); | ||
463 | |||
464 | goto out; | ||
465 | } | ||
466 | } | ||
467 | out: | ||
468 | kfree(seen); | ||
469 | if (ohci->eds_scheduled) | ||
470 | mod_timer(&ohci->unlink_watchdog, round_jiffies_relative(HZ)); | ||
471 | done: | ||
472 | spin_unlock_irqrestore(&ohci->lock, flags); | ||
473 | } | ||
474 | |||
382 | /*-------------------------------------------------------------------------* | 475 | /*-------------------------------------------------------------------------* |
383 | * HC functions | 476 | * HC functions |
384 | *-------------------------------------------------------------------------*/ | 477 | *-------------------------------------------------------------------------*/ |
@@ -616,6 +709,15 @@ retry: | |||
616 | mdelay ((temp >> 23) & 0x1fe); | 709 | mdelay ((temp >> 23) & 0x1fe); |
617 | hcd->state = HC_STATE_RUNNING; | 710 | hcd->state = HC_STATE_RUNNING; |
618 | 711 | ||
712 | if (quirk_zfmicro(ohci)) { | ||
713 | /* Create timer to watch for bad queue state on ZF Micro */ | ||
714 | setup_timer(&ohci->unlink_watchdog, unlink_watchdog_func, | ||
715 | (unsigned long) ohci); | ||
716 | |||
717 | ohci->eds_scheduled = 0; | ||
718 | ohci->ed_to_check = NULL; | ||
719 | } | ||
720 | |||
619 | ohci_dump (ohci, 1); | 721 | ohci_dump (ohci, 1); |
620 | 722 | ||
621 | return 0; | 723 | return 0; |
@@ -629,10 +731,11 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
629 | { | 731 | { |
630 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 732 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
631 | struct ohci_regs __iomem *regs = ohci->regs; | 733 | struct ohci_regs __iomem *regs = ohci->regs; |
632 | int ints; | 734 | int ints; |
633 | 735 | ||
634 | /* we can eliminate a (slow) ohci_readl() | 736 | /* we can eliminate a (slow) ohci_readl() |
635 | if _only_ WDH caused this irq */ | 737 | * if _only_ WDH caused this irq |
738 | */ | ||
636 | if ((ohci->hcca->done_head != 0) | 739 | if ((ohci->hcca->done_head != 0) |
637 | && ! (hc32_to_cpup (ohci, &ohci->hcca->done_head) | 740 | && ! (hc32_to_cpup (ohci, &ohci->hcca->done_head) |
638 | & 0x01)) { | 741 | & 0x01)) { |
@@ -651,7 +754,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
651 | 754 | ||
652 | if (ints & OHCI_INTR_UE) { | 755 | if (ints & OHCI_INTR_UE) { |
653 | // e.g. due to PCI Master/Target Abort | 756 | // e.g. due to PCI Master/Target Abort |
654 | if (ohci->flags & OHCI_QUIRK_NEC) { | 757 | if (quirk_nec(ohci)) { |
655 | /* Workaround for a silicon bug in some NEC chips used | 758 | /* Workaround for a silicon bug in some NEC chips used |
656 | * in Apple's PowerBooks. Adapted from Darwin code. | 759 | * in Apple's PowerBooks. Adapted from Darwin code. |
657 | */ | 760 | */ |
@@ -713,6 +816,31 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
713 | ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrenable); | 816 | ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrenable); |
714 | } | 817 | } |
715 | 818 | ||
819 | if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) { | ||
820 | spin_lock(&ohci->lock); | ||
821 | if (ohci->ed_to_check) { | ||
822 | struct ed *ed = ohci->ed_to_check; | ||
823 | |||
824 | if (check_ed(ohci, ed)) { | ||
825 | /* HC thinks the TD list is empty; HCD knows | ||
826 | * at least one TD is outstanding | ||
827 | */ | ||
828 | if (--ohci->zf_delay == 0) { | ||
829 | struct td *td = list_entry( | ||
830 | ed->td_list.next, | ||
831 | struct td, td_list); | ||
832 | ohci_warn(ohci, | ||
833 | "Reclaiming orphan TD %p\n", | ||
834 | td); | ||
835 | takeback_td(ohci, td); | ||
836 | ohci->ed_to_check = NULL; | ||
837 | } | ||
838 | } else | ||
839 | ohci->ed_to_check = NULL; | ||
840 | } | ||
841 | spin_unlock(&ohci->lock); | ||
842 | } | ||
843 | |||
716 | /* could track INTR_SO to reduce available PCI/... bandwidth */ | 844 | /* could track INTR_SO to reduce available PCI/... bandwidth */ |
717 | 845 | ||
718 | /* handle any pending URB/ED unlinks, leaving INTR_SF enabled | 846 | /* handle any pending URB/ED unlinks, leaving INTR_SF enabled |
@@ -721,7 +849,9 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
721 | spin_lock (&ohci->lock); | 849 | spin_lock (&ohci->lock); |
722 | if (ohci->ed_rm_list) | 850 | if (ohci->ed_rm_list) |
723 | finish_unlinks (ohci, ohci_frame_no(ohci)); | 851 | finish_unlinks (ohci, ohci_frame_no(ohci)); |
724 | if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list | 852 | if ((ints & OHCI_INTR_SF) != 0 |
853 | && !ohci->ed_rm_list | ||
854 | && !ohci->ed_to_check | ||
725 | && HC_IS_RUNNING(hcd->state)) | 855 | && HC_IS_RUNNING(hcd->state)) |
726 | ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); | 856 | ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); |
727 | spin_unlock (&ohci->lock); | 857 | spin_unlock (&ohci->lock); |
@@ -751,6 +881,9 @@ static void ohci_stop (struct usb_hcd *hcd) | |||
751 | free_irq(hcd->irq, hcd); | 881 | free_irq(hcd->irq, hcd); |
752 | hcd->irq = -1; | 882 | hcd->irq = -1; |
753 | 883 | ||
884 | if (quirk_zfmicro(ohci)) | ||
885 | del_timer(&ohci->unlink_watchdog); | ||
886 | |||
754 | remove_debug_files (ohci); | 887 | remove_debug_files (ohci); |
755 | ohci_mem_cleanup (ohci); | 888 | ohci_mem_cleanup (ohci); |
756 | if (ohci->hcca) { | 889 | if (ohci->hcca) { |
@@ -828,27 +961,6 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
828 | 961 | ||
829 | /*-------------------------------------------------------------------------*/ | 962 | /*-------------------------------------------------------------------------*/ |
830 | 963 | ||
831 | /* NEC workaround */ | ||
832 | static void ohci_quirk_nec_worker(struct work_struct *work) | ||
833 | { | ||
834 | struct ohci_hcd *ohci = container_of(work, struct ohci_hcd, nec_work); | ||
835 | int status; | ||
836 | |||
837 | status = ohci_init(ohci); | ||
838 | if (status != 0) { | ||
839 | ohci_err(ohci, "Restarting NEC controller failed " | ||
840 | "in ohci_init, %d\n", status); | ||
841 | return; | ||
842 | } | ||
843 | |||
844 | status = ohci_restart(ohci); | ||
845 | if (status != 0) | ||
846 | ohci_err(ohci, "Restarting NEC controller failed " | ||
847 | "in ohci_restart, %d\n", status); | ||
848 | } | ||
849 | |||
850 | /*-------------------------------------------------------------------------*/ | ||
851 | |||
852 | #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC | 964 | #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC |
853 | 965 | ||
854 | MODULE_AUTHOR (DRIVER_AUTHOR); | 966 | MODULE_AUTHOR (DRIVER_AUTHOR); |
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index 450c7b460c5a..2f20d3dc895b 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c | |||
@@ -28,7 +28,6 @@ static void ohci_hcd_init (struct ohci_hcd *ohci) | |||
28 | ohci->next_statechange = jiffies; | 28 | ohci->next_statechange = jiffies; |
29 | spin_lock_init (&ohci->lock); | 29 | spin_lock_init (&ohci->lock); |
30 | INIT_LIST_HEAD (&ohci->pending); | 30 | INIT_LIST_HEAD (&ohci->pending); |
31 | INIT_WORK (&ohci->nec_work, ohci_quirk_nec_worker); | ||
32 | } | 31 | } |
33 | 32 | ||
34 | /*-------------------------------------------------------------------------*/ | 33 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index a5e2eb85d073..d0360f65ebd9 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -84,7 +84,7 @@ static int ohci_quirk_zfmicro(struct usb_hcd *hcd) | |||
84 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 84 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
85 | 85 | ||
86 | ohci->flags |= OHCI_QUIRK_ZFMICRO; | 86 | ohci->flags |= OHCI_QUIRK_ZFMICRO; |
87 | ohci_dbg (ohci, "enabled Compaq ZFMicro chipset quirk\n"); | 87 | ohci_dbg(ohci, "enabled Compaq ZFMicro chipset quirks\n"); |
88 | 88 | ||
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
@@ -113,11 +113,31 @@ static int ohci_quirk_toshiba_scc(struct usb_hcd *hcd) | |||
113 | 113 | ||
114 | /* Check for NEC chip and apply quirk for allegedly lost interrupts. | 114 | /* Check for NEC chip and apply quirk for allegedly lost interrupts. |
115 | */ | 115 | */ |
116 | |||
117 | static void ohci_quirk_nec_worker(struct work_struct *work) | ||
118 | { | ||
119 | struct ohci_hcd *ohci = container_of(work, struct ohci_hcd, nec_work); | ||
120 | int status; | ||
121 | |||
122 | status = ohci_init(ohci); | ||
123 | if (status != 0) { | ||
124 | ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n", | ||
125 | "ohci_init", status); | ||
126 | return; | ||
127 | } | ||
128 | |||
129 | status = ohci_restart(ohci); | ||
130 | if (status != 0) | ||
131 | ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n", | ||
132 | "ohci_restart", status); | ||
133 | } | ||
134 | |||
116 | static int ohci_quirk_nec(struct usb_hcd *hcd) | 135 | static int ohci_quirk_nec(struct usb_hcd *hcd) |
117 | { | 136 | { |
118 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 137 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
119 | 138 | ||
120 | ohci->flags |= OHCI_QUIRK_NEC; | 139 | ohci->flags |= OHCI_QUIRK_NEC; |
140 | INIT_WORK(&ohci->nec_work, ohci_quirk_nec_worker); | ||
121 | ohci_dbg (ohci, "enabled NEC chipset lost interrupt quirk\n"); | 141 | ohci_dbg (ohci, "enabled NEC chipset lost interrupt quirk\n"); |
122 | 142 | ||
123 | return 0; | 143 | return 0; |
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 830a3fe8615e..547d39be3eb9 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
@@ -179,6 +179,10 @@ static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed) | |||
179 | ed->ed_prev = NULL; | 179 | ed->ed_prev = NULL; |
180 | ed->ed_next = NULL; | 180 | ed->ed_next = NULL; |
181 | ed->hwNextED = 0; | 181 | ed->hwNextED = 0; |
182 | if (quirk_zfmicro(ohci) | ||
183 | && (ed->type == PIPE_INTERRUPT) | ||
184 | && !(ohci->eds_scheduled++)) | ||
185 | mod_timer(&ohci->unlink_watchdog, round_jiffies_relative(HZ)); | ||
182 | wmb (); | 186 | wmb (); |
183 | 187 | ||
184 | /* we care about rm_list when setting CLE/BLE in case the HC was at | 188 | /* we care about rm_list when setting CLE/BLE in case the HC was at |
@@ -940,8 +944,12 @@ skip_ed: | |||
940 | TD_MASK; | 944 | TD_MASK; |
941 | 945 | ||
942 | /* INTR_WDH may need to clean up first */ | 946 | /* INTR_WDH may need to clean up first */ |
943 | if (td->td_dma != head) | 947 | if (td->td_dma != head) { |
944 | goto skip_ed; | 948 | if (ed == ohci->ed_to_check) |
949 | ohci->ed_to_check = NULL; | ||
950 | else | ||
951 | goto skip_ed; | ||
952 | } | ||
945 | } | 953 | } |
946 | } | 954 | } |
947 | 955 | ||
@@ -998,6 +1006,8 @@ rescan_this: | |||
998 | 1006 | ||
999 | /* ED's now officially unlinked, hc doesn't see */ | 1007 | /* ED's now officially unlinked, hc doesn't see */ |
1000 | ed->state = ED_IDLE; | 1008 | ed->state = ED_IDLE; |
1009 | if (quirk_zfmicro(ohci) && ed->type == PIPE_INTERRUPT) | ||
1010 | ohci->eds_scheduled--; | ||
1001 | ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_H); | 1011 | ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_H); |
1002 | ed->hwNextED = 0; | 1012 | ed->hwNextED = 0; |
1003 | wmb (); | 1013 | wmb (); |
@@ -1021,7 +1031,7 @@ rescan_this: | |||
1021 | 1031 | ||
1022 | if (ohci->ed_controltail) { | 1032 | if (ohci->ed_controltail) { |
1023 | command |= OHCI_CLF; | 1033 | command |= OHCI_CLF; |
1024 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1034 | if (quirk_zfmicro(ohci)) |
1025 | mdelay(1); | 1035 | mdelay(1); |
1026 | if (!(ohci->hc_control & OHCI_CTRL_CLE)) { | 1036 | if (!(ohci->hc_control & OHCI_CTRL_CLE)) { |
1027 | control |= OHCI_CTRL_CLE; | 1037 | control |= OHCI_CTRL_CLE; |
@@ -1031,7 +1041,7 @@ rescan_this: | |||
1031 | } | 1041 | } |
1032 | if (ohci->ed_bulktail) { | 1042 | if (ohci->ed_bulktail) { |
1033 | command |= OHCI_BLF; | 1043 | command |= OHCI_BLF; |
1034 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1044 | if (quirk_zfmicro(ohci)) |
1035 | mdelay(1); | 1045 | mdelay(1); |
1036 | if (!(ohci->hc_control & OHCI_CTRL_BLE)) { | 1046 | if (!(ohci->hc_control & OHCI_CTRL_BLE)) { |
1037 | control |= OHCI_CTRL_BLE; | 1047 | control |= OHCI_CTRL_BLE; |
@@ -1043,13 +1053,13 @@ rescan_this: | |||
1043 | /* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */ | 1053 | /* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */ |
1044 | if (control) { | 1054 | if (control) { |
1045 | ohci->hc_control |= control; | 1055 | ohci->hc_control |= control; |
1046 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1056 | if (quirk_zfmicro(ohci)) |
1047 | mdelay(1); | 1057 | mdelay(1); |
1048 | ohci_writel (ohci, ohci->hc_control, | 1058 | ohci_writel (ohci, ohci->hc_control, |
1049 | &ohci->regs->control); | 1059 | &ohci->regs->control); |
1050 | } | 1060 | } |
1051 | if (command) { | 1061 | if (command) { |
1052 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1062 | if (quirk_zfmicro(ohci)) |
1053 | mdelay(1); | 1063 | mdelay(1); |
1054 | ohci_writel (ohci, command, &ohci->regs->cmdstatus); | 1064 | ohci_writel (ohci, command, &ohci->regs->cmdstatus); |
1055 | } | 1065 | } |
@@ -1061,11 +1071,59 @@ rescan_this: | |||
1061 | /*-------------------------------------------------------------------------*/ | 1071 | /*-------------------------------------------------------------------------*/ |
1062 | 1072 | ||
1063 | /* | 1073 | /* |
1074 | * Used to take back a TD from the host controller. This would normally be | ||
1075 | * called from within dl_done_list, however it may be called directly if the | ||
1076 | * HC no longer sees the TD and it has not appeared on the donelist (after | ||
1077 | * two frames). This bug has been observed on ZF Micro systems. | ||
1078 | */ | ||
1079 | static void takeback_td(struct ohci_hcd *ohci, struct td *td) | ||
1080 | { | ||
1081 | struct urb *urb = td->urb; | ||
1082 | urb_priv_t *urb_priv = urb->hcpriv; | ||
1083 | struct ed *ed = td->ed; | ||
1084 | |||
1085 | /* update URB's length and status from TD */ | ||
1086 | td_done(ohci, urb, td); | ||
1087 | urb_priv->td_cnt++; | ||
1088 | |||
1089 | /* If all this urb's TDs are done, call complete() */ | ||
1090 | if (urb_priv->td_cnt == urb_priv->length) | ||
1091 | finish_urb(ohci, urb); | ||
1092 | |||
1093 | /* clean schedule: unlink EDs that are no longer busy */ | ||
1094 | if (list_empty(&ed->td_list)) { | ||
1095 | if (ed->state == ED_OPER) | ||
1096 | start_ed_unlink(ohci, ed); | ||
1097 | |||
1098 | /* ... reenabling halted EDs only after fault cleanup */ | ||
1099 | } else if ((ed->hwINFO & cpu_to_hc32(ohci, ED_SKIP | ED_DEQUEUE)) | ||
1100 | == cpu_to_hc32(ohci, ED_SKIP)) { | ||
1101 | td = list_entry(ed->td_list.next, struct td, td_list); | ||
1102 | if (!(td->hwINFO & cpu_to_hc32(ohci, TD_DONE))) { | ||
1103 | ed->hwINFO &= ~cpu_to_hc32(ohci, ED_SKIP); | ||
1104 | /* ... hc may need waking-up */ | ||
1105 | switch (ed->type) { | ||
1106 | case PIPE_CONTROL: | ||
1107 | ohci_writel(ohci, OHCI_CLF, | ||
1108 | &ohci->regs->cmdstatus); | ||
1109 | break; | ||
1110 | case PIPE_BULK: | ||
1111 | ohci_writel(ohci, OHCI_BLF, | ||
1112 | &ohci->regs->cmdstatus); | ||
1113 | break; | ||
1114 | } | ||
1115 | } | ||
1116 | } | ||
1117 | } | ||
1118 | |||
1119 | /* | ||
1064 | * Process normal completions (error or success) and clean the schedules. | 1120 | * Process normal completions (error or success) and clean the schedules. |
1065 | * | 1121 | * |
1066 | * This is the main path for handing urbs back to drivers. The only other | 1122 | * This is the main path for handing urbs back to drivers. The only other |
1067 | * path is finish_unlinks(), which unlinks URBs using ed_rm_list, instead of | 1123 | * normal path is finish_unlinks(), which unlinks URBs using ed_rm_list, |
1068 | * scanning the (re-reversed) donelist as this does. | 1124 | * instead of scanning the (re-reversed) donelist as this does. There's |
1125 | * an abnormal path too, handling a quirk in some Compaq silicon: URBs | ||
1126 | * with TDs that appear to be orphaned are directly reclaimed. | ||
1069 | */ | 1127 | */ |
1070 | static void | 1128 | static void |
1071 | dl_done_list (struct ohci_hcd *ohci) | 1129 | dl_done_list (struct ohci_hcd *ohci) |
@@ -1074,44 +1132,7 @@ dl_done_list (struct ohci_hcd *ohci) | |||
1074 | 1132 | ||
1075 | while (td) { | 1133 | while (td) { |
1076 | struct td *td_next = td->next_dl_td; | 1134 | struct td *td_next = td->next_dl_td; |
1077 | struct urb *urb = td->urb; | 1135 | takeback_td(ohci, td); |
1078 | urb_priv_t *urb_priv = urb->hcpriv; | ||
1079 | struct ed *ed = td->ed; | ||
1080 | |||
1081 | /* update URB's length and status from TD */ | ||
1082 | td_done (ohci, urb, td); | ||
1083 | urb_priv->td_cnt++; | ||
1084 | |||
1085 | /* If all this urb's TDs are done, call complete() */ | ||
1086 | if (urb_priv->td_cnt == urb_priv->length) | ||
1087 | finish_urb (ohci, urb); | ||
1088 | |||
1089 | /* clean schedule: unlink EDs that are no longer busy */ | ||
1090 | if (list_empty (&ed->td_list)) { | ||
1091 | if (ed->state == ED_OPER) | ||
1092 | start_ed_unlink (ohci, ed); | ||
1093 | |||
1094 | /* ... reenabling halted EDs only after fault cleanup */ | ||
1095 | } else if ((ed->hwINFO & cpu_to_hc32 (ohci, | ||
1096 | ED_SKIP | ED_DEQUEUE)) | ||
1097 | == cpu_to_hc32 (ohci, ED_SKIP)) { | ||
1098 | td = list_entry (ed->td_list.next, struct td, td_list); | ||
1099 | if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) { | ||
1100 | ed->hwINFO &= ~cpu_to_hc32 (ohci, ED_SKIP); | ||
1101 | /* ... hc may need waking-up */ | ||
1102 | switch (ed->type) { | ||
1103 | case PIPE_CONTROL: | ||
1104 | ohci_writel (ohci, OHCI_CLF, | ||
1105 | &ohci->regs->cmdstatus); | ||
1106 | break; | ||
1107 | case PIPE_BULK: | ||
1108 | ohci_writel (ohci, OHCI_BLF, | ||
1109 | &ohci->regs->cmdstatus); | ||
1110 | break; | ||
1111 | } | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1115 | td = td_next; | 1136 | td = td_next; |
1116 | } | 1137 | } |
1117 | } | 1138 | } |
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 4ada43cf1387..dd4d5b4dcb6c 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -401,8 +401,34 @@ struct ohci_hcd { | |||
401 | // there are also chip quirks/bugs in init logic | 401 | // there are also chip quirks/bugs in init logic |
402 | 402 | ||
403 | struct work_struct nec_work; /* Worker for NEC quirk */ | 403 | struct work_struct nec_work; /* Worker for NEC quirk */ |
404 | |||
405 | /* Needed for ZF Micro quirk */ | ||
406 | struct timer_list unlink_watchdog; | ||
407 | unsigned eds_scheduled; | ||
408 | struct ed *ed_to_check; | ||
409 | unsigned zf_delay; | ||
404 | }; | 410 | }; |
405 | 411 | ||
412 | #ifdef CONFIG_PCI | ||
413 | static inline int quirk_nec(struct ohci_hcd *ohci) | ||
414 | { | ||
415 | return ohci->flags & OHCI_QUIRK_NEC; | ||
416 | } | ||
417 | static inline int quirk_zfmicro(struct ohci_hcd *ohci) | ||
418 | { | ||
419 | return ohci->flags & OHCI_QUIRK_ZFMICRO; | ||
420 | } | ||
421 | #else | ||
422 | static inline int quirk_nec(struct ohci_hcd *ohci) | ||
423 | { | ||
424 | return 0; | ||
425 | } | ||
426 | static inline int quirk_zfmicro(struct ohci_hcd *ohci) | ||
427 | { | ||
428 | return 0; | ||
429 | } | ||
430 | #endif | ||
431 | |||
406 | /* convert between an hcd pointer and the corresponding ohci_hcd */ | 432 | /* convert between an hcd pointer and the corresponding ohci_hcd */ |
407 | static inline struct ohci_hcd *hcd_to_ohci (struct usb_hcd *hcd) | 433 | static inline struct ohci_hcd *hcd_to_ohci (struct usb_hcd *hcd) |
408 | { | 434 | { |