diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 001b2c389be2..8a8e08a51ba3 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -2123,17 +2123,9 @@ scan_periodic (struct ehci_hcd *ehci) | |||
2123 | for (;;) { | 2123 | for (;;) { |
2124 | union ehci_shadow q, *q_p; | 2124 | union ehci_shadow q, *q_p; |
2125 | __hc32 type, *hw_p; | 2125 | __hc32 type, *hw_p; |
2126 | unsigned uframes; | 2126 | unsigned incomplete = false; |
2127 | 2127 | ||
2128 | /* don't scan past the live uframe */ | ||
2129 | frame = now_uframe >> 3; | 2128 | frame = now_uframe >> 3; |
2130 | if (frame == (clock >> 3)) | ||
2131 | uframes = now_uframe & 0x07; | ||
2132 | else { | ||
2133 | /* safe to scan the whole frame at once */ | ||
2134 | now_uframe |= 0x07; | ||
2135 | uframes = 8; | ||
2136 | } | ||
2137 | 2129 | ||
2138 | restart: | 2130 | restart: |
2139 | /* scan each element in frame's queue for completions */ | 2131 | /* scan each element in frame's queue for completions */ |
@@ -2171,12 +2163,15 @@ restart: | |||
2171 | q = q.fstn->fstn_next; | 2163 | q = q.fstn->fstn_next; |
2172 | break; | 2164 | break; |
2173 | case Q_TYPE_ITD: | 2165 | case Q_TYPE_ITD: |
2174 | /* skip itds for later in the frame */ | 2166 | /* If this ITD is still active, leave it for |
2167 | * later processing ... check the next entry. | ||
2168 | */ | ||
2175 | rmb (); | 2169 | rmb (); |
2176 | for (uf = live ? uframes : 8; uf < 8; uf++) { | 2170 | for (uf = 0; uf < 8 && live; uf++) { |
2177 | if (0 == (q.itd->hw_transaction [uf] | 2171 | if (0 == (q.itd->hw_transaction [uf] |
2178 | & ITD_ACTIVE(ehci))) | 2172 | & ITD_ACTIVE(ehci))) |
2179 | continue; | 2173 | continue; |
2174 | incomplete = true; | ||
2180 | q_p = &q.itd->itd_next; | 2175 | q_p = &q.itd->itd_next; |
2181 | hw_p = &q.itd->hw_next; | 2176 | hw_p = &q.itd->hw_next; |
2182 | type = Q_NEXT_TYPE(ehci, | 2177 | type = Q_NEXT_TYPE(ehci, |
@@ -2184,10 +2179,12 @@ restart: | |||
2184 | q = *q_p; | 2179 | q = *q_p; |
2185 | break; | 2180 | break; |
2186 | } | 2181 | } |
2187 | if (uf != 8) | 2182 | if (uf < 8 && live) |
2188 | break; | 2183 | break; |
2189 | 2184 | ||
2190 | /* this one's ready ... HC won't cache the | 2185 | /* Take finished ITDs out of the schedule |
2186 | * and process them: recycle, maybe report | ||
2187 | * URB completion. HC won't cache the | ||
2191 | * pointer for much longer, if at all. | 2188 | * pointer for much longer, if at all. |
2192 | */ | 2189 | */ |
2193 | *q_p = q.itd->itd_next; | 2190 | *q_p = q.itd->itd_next; |
@@ -2198,8 +2195,12 @@ restart: | |||
2198 | q = *q_p; | 2195 | q = *q_p; |
2199 | break; | 2196 | break; |
2200 | case Q_TYPE_SITD: | 2197 | case Q_TYPE_SITD: |
2198 | /* If this SITD is still active, leave it for | ||
2199 | * later processing ... check the next entry. | ||
2200 | */ | ||
2201 | if ((q.sitd->hw_results & SITD_ACTIVE(ehci)) | 2201 | if ((q.sitd->hw_results & SITD_ACTIVE(ehci)) |
2202 | && live) { | 2202 | && live) { |
2203 | incomplete = true; | ||
2203 | q_p = &q.sitd->sitd_next; | 2204 | q_p = &q.sitd->sitd_next; |
2204 | hw_p = &q.sitd->hw_next; | 2205 | hw_p = &q.sitd->hw_next; |
2205 | type = Q_NEXT_TYPE(ehci, | 2206 | type = Q_NEXT_TYPE(ehci, |
@@ -2207,6 +2208,11 @@ restart: | |||
2207 | q = *q_p; | 2208 | q = *q_p; |
2208 | break; | 2209 | break; |
2209 | } | 2210 | } |
2211 | |||
2212 | /* Take finished SITDs out of the schedule | ||
2213 | * and process them: recycle, maybe report | ||
2214 | * URB completion. | ||
2215 | */ | ||
2210 | *q_p = q.sitd->sitd_next; | 2216 | *q_p = q.sitd->sitd_next; |
2211 | *hw_p = q.sitd->hw_next; | 2217 | *hw_p = q.sitd->hw_next; |
2212 | type = Q_NEXT_TYPE(ehci, q.sitd->hw_next); | 2218 | type = Q_NEXT_TYPE(ehci, q.sitd->hw_next); |
@@ -2232,7 +2238,14 @@ restart: | |||
2232 | } | 2238 | } |
2233 | } | 2239 | } |
2234 | 2240 | ||
2235 | /* stop when we catch up to the HC */ | 2241 | /* If we can tell we caught up to the hardware, stop now. |
2242 | * We can't advance our scan without collecting the ISO | ||
2243 | * transfers that are still pending in this frame. | ||
2244 | */ | ||
2245 | if (incomplete && HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { | ||
2246 | ehci->next_uframe = now_uframe; | ||
2247 | break; | ||
2248 | } | ||
2236 | 2249 | ||
2237 | // FIXME: this assumes we won't get lapped when | 2250 | // FIXME: this assumes we won't get lapped when |
2238 | // latencies climb; that should be rare, but... | 2251 | // latencies climb; that should be rare, but... |