aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-sched.c')
-rw-r--r--drivers/usb/host/ehci-sched.c68
1 files changed, 56 insertions, 12 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index a92526d6e5ae..6c9fbe352f73 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -98,7 +98,14 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
98 */ 98 */
99 *prev_p = *periodic_next_shadow(ehci, &here, 99 *prev_p = *periodic_next_shadow(ehci, &here,
100 Q_NEXT_TYPE(ehci, *hw_p)); 100 Q_NEXT_TYPE(ehci, *hw_p));
101 *hw_p = *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p)); 101
102 if (!ehci->use_dummy_qh ||
103 *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p))
104 != EHCI_LIST_END(ehci))
105 *hw_p = *shadow_next_periodic(ehci, &here,
106 Q_NEXT_TYPE(ehci, *hw_p));
107 else
108 *hw_p = ehci->dummy->qh_dma;
102} 109}
103 110
104/* how many of the uframe's 125 usecs are allocated? */ 111/* how many of the uframe's 125 usecs are allocated? */
@@ -464,8 +471,10 @@ static int enable_periodic (struct ehci_hcd *ehci)
464 */ 471 */
465 status = handshake_on_error_set_halt(ehci, &ehci->regs->status, 472 status = handshake_on_error_set_halt(ehci, &ehci->regs->status,
466 STS_PSS, 0, 9 * 125); 473 STS_PSS, 0, 9 * 125);
467 if (status) 474 if (status) {
475 usb_hc_died(ehci_to_hcd(ehci));
468 return status; 476 return status;
477 }
469 478
470 cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE; 479 cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE;
471 ehci_writel(ehci, cmd, &ehci->regs->command); 480 ehci_writel(ehci, cmd, &ehci->regs->command);
@@ -503,8 +512,10 @@ static int disable_periodic (struct ehci_hcd *ehci)
503 */ 512 */
504 status = handshake_on_error_set_halt(ehci, &ehci->regs->status, 513 status = handshake_on_error_set_halt(ehci, &ehci->regs->status,
505 STS_PSS, STS_PSS, 9 * 125); 514 STS_PSS, STS_PSS, 9 * 125);
506 if (status) 515 if (status) {
516 usb_hc_died(ehci_to_hcd(ehci));
507 return status; 517 return status;
518 }
508 519
509 cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE; 520 cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE;
510 ehci_writel(ehci, cmd, &ehci->regs->command); 521 ehci_writel(ehci, cmd, &ehci->regs->command);
@@ -1041,8 +1052,6 @@ iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream)
1041 * not like a QH -- no persistent state (toggle, halt) 1052 * not like a QH -- no persistent state (toggle, halt)
1042 */ 1053 */
1043 if (stream->refcount == 1) { 1054 if (stream->refcount == 1) {
1044 int is_in;
1045
1046 // BUG_ON (!list_empty(&stream->td_list)); 1055 // BUG_ON (!list_empty(&stream->td_list));
1047 1056
1048 while (!list_empty (&stream->free_list)) { 1057 while (!list_empty (&stream->free_list)) {
@@ -1069,7 +1078,6 @@ iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream)
1069 } 1078 }
1070 } 1079 }
1071 1080
1072 is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0;
1073 stream->bEndpointAddress &= 0x0f; 1081 stream->bEndpointAddress &= 0x0f;
1074 if (stream->ep) 1082 if (stream->ep)
1075 stream->ep->hcpriv = NULL; 1083 stream->ep->hcpriv = NULL;
@@ -1609,6 +1617,12 @@ itd_link_urb (
1609 urb->interval, 1617 urb->interval,
1610 next_uframe >> 3, next_uframe & 0x7); 1618 next_uframe >> 3, next_uframe & 0x7);
1611 } 1619 }
1620
1621 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
1622 if (ehci->amd_pll_fix == 1)
1623 usb_amd_quirk_pll_disable();
1624 }
1625
1612 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; 1626 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
1613 1627
1614 /* fill iTDs uframe by uframe */ 1628 /* fill iTDs uframe by uframe */
@@ -1733,6 +1747,11 @@ itd_complete (
1733 (void) disable_periodic(ehci); 1747 (void) disable_periodic(ehci);
1734 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; 1748 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
1735 1749
1750 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
1751 if (ehci->amd_pll_fix == 1)
1752 usb_amd_quirk_pll_enable();
1753 }
1754
1736 if (unlikely(list_is_singular(&stream->td_list))) { 1755 if (unlikely(list_is_singular(&stream->td_list))) {
1737 ehci_to_hcd(ehci)->self.bandwidth_allocated 1756 ehci_to_hcd(ehci)->self.bandwidth_allocated
1738 -= stream->bandwidth; 1757 -= stream->bandwidth;
@@ -2018,6 +2037,12 @@ sitd_link_urb (
2018 (next_uframe >> 3) & (ehci->periodic_size - 1), 2037 (next_uframe >> 3) & (ehci->periodic_size - 1),
2019 stream->interval, hc32_to_cpu(ehci, stream->splits)); 2038 stream->interval, hc32_to_cpu(ehci, stream->splits));
2020 } 2039 }
2040
2041 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
2042 if (ehci->amd_pll_fix == 1)
2043 usb_amd_quirk_pll_disable();
2044 }
2045
2021 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++; 2046 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs++;
2022 2047
2023 /* fill sITDs frame by frame */ 2048 /* fill sITDs frame by frame */
@@ -2118,6 +2143,11 @@ sitd_complete (
2118 (void) disable_periodic(ehci); 2143 (void) disable_periodic(ehci);
2119 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; 2144 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
2120 2145
2146 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
2147 if (ehci->amd_pll_fix == 1)
2148 usb_amd_quirk_pll_enable();
2149 }
2150
2121 if (list_is_singular(&stream->td_list)) { 2151 if (list_is_singular(&stream->td_list)) {
2122 ehci_to_hcd(ehci)->self.bandwidth_allocated 2152 ehci_to_hcd(ehci)->self.bandwidth_allocated
2123 -= stream->bandwidth; 2153 -= stream->bandwidth;
@@ -2261,6 +2291,7 @@ scan_periodic (struct ehci_hcd *ehci)
2261 } 2291 }
2262 clock &= mod - 1; 2292 clock &= mod - 1;
2263 clock_frame = clock >> 3; 2293 clock_frame = clock >> 3;
2294 ++ehci->periodic_stamp;
2264 2295
2265 for (;;) { 2296 for (;;) {
2266 union ehci_shadow q, *q_p; 2297 union ehci_shadow q, *q_p;
@@ -2289,10 +2320,14 @@ restart:
2289 temp.qh = qh_get (q.qh); 2320 temp.qh = qh_get (q.qh);
2290 type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next); 2321 type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next);
2291 q = q.qh->qh_next; 2322 q = q.qh->qh_next;
2292 modified = qh_completions (ehci, temp.qh); 2323 if (temp.qh->stamp != ehci->periodic_stamp) {
2293 if (unlikely(list_empty(&temp.qh->qtd_list) || 2324 modified = qh_completions(ehci, temp.qh);
2294 temp.qh->needs_rescan)) 2325 if (!modified)
2295 intr_deschedule (ehci, temp.qh); 2326 temp.qh->stamp = ehci->periodic_stamp;
2327 if (unlikely(list_empty(&temp.qh->qtd_list) ||
2328 temp.qh->needs_rescan))
2329 intr_deschedule(ehci, temp.qh);
2330 }
2296 qh_put (temp.qh); 2331 qh_put (temp.qh);
2297 break; 2332 break;
2298 case Q_TYPE_FSTN: 2333 case Q_TYPE_FSTN:
@@ -2335,7 +2370,11 @@ restart:
2335 * pointer for much longer, if at all. 2370 * pointer for much longer, if at all.
2336 */ 2371 */
2337 *q_p = q.itd->itd_next; 2372 *q_p = q.itd->itd_next;
2338 *hw_p = q.itd->hw_next; 2373 if (!ehci->use_dummy_qh ||
2374 q.itd->hw_next != EHCI_LIST_END(ehci))
2375 *hw_p = q.itd->hw_next;
2376 else
2377 *hw_p = ehci->dummy->qh_dma;
2339 type = Q_NEXT_TYPE(ehci, q.itd->hw_next); 2378 type = Q_NEXT_TYPE(ehci, q.itd->hw_next);
2340 wmb(); 2379 wmb();
2341 modified = itd_complete (ehci, q.itd); 2380 modified = itd_complete (ehci, q.itd);
@@ -2368,7 +2407,11 @@ restart:
2368 * URB completion. 2407 * URB completion.
2369 */ 2408 */
2370 *q_p = q.sitd->sitd_next; 2409 *q_p = q.sitd->sitd_next;
2371 *hw_p = q.sitd->hw_next; 2410 if (!ehci->use_dummy_qh ||
2411 q.sitd->hw_next != EHCI_LIST_END(ehci))
2412 *hw_p = q.sitd->hw_next;
2413 else
2414 *hw_p = ehci->dummy->qh_dma;
2372 type = Q_NEXT_TYPE(ehci, q.sitd->hw_next); 2415 type = Q_NEXT_TYPE(ehci, q.sitd->hw_next);
2373 wmb(); 2416 wmb();
2374 modified = sitd_complete (ehci, q.sitd); 2417 modified = sitd_complete (ehci, q.sitd);
@@ -2426,6 +2469,7 @@ restart:
2426 if (ehci->clock_frame != clock_frame) { 2469 if (ehci->clock_frame != clock_frame) {
2427 free_cached_lists(ehci); 2470 free_cached_lists(ehci);
2428 ehci->clock_frame = clock_frame; 2471 ehci->clock_frame = clock_frame;
2472 ++ehci->periodic_stamp;
2429 } 2473 }
2430 } else { 2474 } else {
2431 now_uframe++; 2475 now_uframe++;