diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/usb/host/ehci-sched.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'drivers/usb/host/ehci-sched.c')
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 68 |
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++; |