aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/ehci-hcd.c7
-rw-r--r--drivers/usb/host/ehci-q.c3
-rw-r--r--drivers/usb/host/ehci-sched.c96
-rw-r--r--drivers/usb/host/ehci-timer.c7
-rw-r--r--drivers/usb/host/ehci.h8
5 files changed, 71 insertions, 50 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index f6cf1d178107..c13dad8a8503 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -410,8 +410,10 @@ static void ehci_work (struct ehci_hcd *ehci)
410 ehci->need_rescan = false; 410 ehci->need_rescan = false;
411 if (ehci->async_count) 411 if (ehci->async_count)
412 scan_async(ehci); 412 scan_async(ehci);
413 if (ehci->next_uframe != -1) 413 if (ehci->intr_count > 0)
414 scan_periodic (ehci); 414 scan_intr(ehci);
415 if (ehci->isoc_count > 0)
416 scan_isoc(ehci);
415 if (ehci->need_rescan) 417 if (ehci->need_rescan)
416 goto rescan; 418 goto rescan;
417 ehci->scanning = false; 419 ehci->scanning = false;
@@ -509,6 +511,7 @@ static int ehci_init(struct usb_hcd *hcd)
509 * periodic_size can shrink by USBCMD update if hcc_params allows. 511 * periodic_size can shrink by USBCMD update if hcc_params allows.
510 */ 512 */
511 ehci->periodic_size = DEFAULT_I_TDPS; 513 ehci->periodic_size = DEFAULT_I_TDPS;
514 INIT_LIST_HEAD(&ehci->intr_qh_list);
512 INIT_LIST_HEAD(&ehci->cached_itd_list); 515 INIT_LIST_HEAD(&ehci->cached_itd_list);
513 INIT_LIST_HEAD(&ehci->cached_sitd_list); 516 INIT_LIST_HEAD(&ehci->cached_sitd_list);
514 517
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index bae931767825..c9c7f7b3b7db 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -322,7 +322,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh)
322 * 322 *
323 * It's a bug for qh->qh_state to be anything other than 323 * It's a bug for qh->qh_state to be anything other than
324 * QH_STATE_IDLE, unless our caller is scan_async() or 324 * QH_STATE_IDLE, unless our caller is scan_async() or
325 * scan_periodic(). 325 * scan_intr().
326 */ 326 */
327 state = qh->qh_state; 327 state = qh->qh_state;
328 qh->qh_state = QH_STATE_COMPLETING; 328 qh->qh_state = QH_STATE_COMPLETING;
@@ -832,7 +832,6 @@ qh_make (
832 is_input, 0, 832 is_input, 0,
833 hb_mult(maxp) * max_packet(maxp))); 833 hb_mult(maxp) * max_packet(maxp)));
834 qh->start = NO_FRAME; 834 qh->start = NO_FRAME;
835 qh->stamp = ehci->periodic_stamp;
836 835
837 if (urb->dev->speed == USB_SPEED_HIGH) { 836 if (urb->dev->speed == USB_SPEED_HIGH) {
838 qh->c_usecs = 0; 837 qh->c_usecs = 0;
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 11b2f21d7ac1..263b542985c0 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -569,7 +569,10 @@ static void qh_link_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
569 ? ((qh->usecs + qh->c_usecs) / qh->period) 569 ? ((qh->usecs + qh->c_usecs) / qh->period)
570 : (qh->usecs * 8); 570 : (qh->usecs * 8);
571 571
572 list_add(&qh->intr_node, &ehci->intr_qh_list);
573
572 /* maybe enable periodic schedule processing */ 574 /* maybe enable periodic schedule processing */
575 ++ehci->intr_count;
573 enable_periodic(ehci); 576 enable_periodic(ehci);
574} 577}
575 578
@@ -614,6 +617,11 @@ static void qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
614 /* qh->qh_next still "live" to HC */ 617 /* qh->qh_next still "live" to HC */
615 qh->qh_state = QH_STATE_UNLINK; 618 qh->qh_state = QH_STATE_UNLINK;
616 qh->qh_next.ptr = NULL; 619 qh->qh_next.ptr = NULL;
620
621 if (ehci->qh_scan_next == qh)
622 ehci->qh_scan_next = list_entry(qh->intr_node.next,
623 struct ehci_qh, intr_node);
624 list_del(&qh->intr_node);
617} 625}
618 626
619static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh) 627static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
@@ -683,6 +691,7 @@ static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh)
683 } 691 }
684 692
685 /* maybe turn off periodic schedule */ 693 /* maybe turn off periodic schedule */
694 --ehci->intr_count;
686 disable_periodic(ehci); 695 disable_periodic(ehci);
687} 696}
688 697
@@ -920,6 +929,35 @@ done_not_linked:
920 return status; 929 return status;
921} 930}
922 931
932static void scan_intr(struct ehci_hcd *ehci)
933{
934 struct ehci_qh *qh;
935
936 list_for_each_entry_safe(qh, ehci->qh_scan_next, &ehci->intr_qh_list,
937 intr_node) {
938 rescan:
939 /* clean any finished work for this qh */
940 if (!list_empty(&qh->qtd_list)) {
941 int temp;
942
943 /*
944 * Unlinks could happen here; completion reporting
945 * drops the lock. That's why ehci->qh_scan_next
946 * always holds the next qh to scan; if the next qh
947 * gets unlinked then ehci->qh_scan_next is adjusted
948 * in qh_unlink_periodic().
949 */
950 temp = qh_completions(ehci, qh);
951 if (unlikely(qh->needs_rescan ||
952 (list_empty(&qh->qtd_list) &&
953 qh->qh_state == QH_STATE_LINKED)))
954 start_unlink_intr(ehci, qh);
955 else if (temp != 0)
956 goto rescan;
957 }
958 }
959}
960
923/*-------------------------------------------------------------------------*/ 961/*-------------------------------------------------------------------------*/
924 962
925/* ehci_iso_stream ops work with both ITD and SITD */ 963/* ehci_iso_stream ops work with both ITD and SITD */
@@ -1450,6 +1488,10 @@ iso_stream_schedule (
1450 urb->start_frame = stream->next_uframe; 1488 urb->start_frame = stream->next_uframe;
1451 if (!stream->highspeed) 1489 if (!stream->highspeed)
1452 urb->start_frame >>= 3; 1490 urb->start_frame >>= 3;
1491
1492 /* Make sure scan_isoc() sees these */
1493 if (ehci->isoc_count == 0)
1494 ehci->next_uframe = now;
1453 return 0; 1495 return 0;
1454 1496
1455 fail: 1497 fail:
@@ -1608,6 +1650,7 @@ static void itd_link_urb(
1608 urb->hcpriv = NULL; 1650 urb->hcpriv = NULL;
1609 1651
1610 timer_action (ehci, TIMER_IO_WATCHDOG); 1652 timer_action (ehci, TIMER_IO_WATCHDOG);
1653 ++ehci->isoc_count;
1611 enable_periodic(ehci); 1654 enable_periodic(ehci);
1612} 1655}
1613 1656
@@ -1688,9 +1731,11 @@ itd_complete (
1688 ehci_urb_done(ehci, urb, 0); 1731 ehci_urb_done(ehci, urb, 0);
1689 retval = true; 1732 retval = true;
1690 urb = NULL; 1733 urb = NULL;
1734
1735 --ehci->isoc_count;
1691 disable_periodic(ehci); 1736 disable_periodic(ehci);
1692 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
1693 1737
1738 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
1694 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { 1739 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
1695 if (ehci->amd_pll_fix == 1) 1740 if (ehci->amd_pll_fix == 1)
1696 usb_amd_quirk_pll_enable(); 1741 usb_amd_quirk_pll_enable();
@@ -2008,6 +2053,7 @@ static void sitd_link_urb(
2008 urb->hcpriv = NULL; 2053 urb->hcpriv = NULL;
2009 2054
2010 timer_action (ehci, TIMER_IO_WATCHDOG); 2055 timer_action (ehci, TIMER_IO_WATCHDOG);
2056 ++ehci->isoc_count;
2011 enable_periodic(ehci); 2057 enable_periodic(ehci);
2012} 2058}
2013 2059
@@ -2074,9 +2120,11 @@ sitd_complete (
2074 ehci_urb_done(ehci, urb, 0); 2120 ehci_urb_done(ehci, urb, 0);
2075 retval = true; 2121 retval = true;
2076 urb = NULL; 2122 urb = NULL;
2123
2124 --ehci->isoc_count;
2077 disable_periodic(ehci); 2125 disable_periodic(ehci);
2078 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
2079 2126
2127 ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
2080 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) { 2128 if (ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs == 0) {
2081 if (ehci->amd_pll_fix == 1) 2129 if (ehci->amd_pll_fix == 1)
2082 usb_amd_quirk_pll_enable(); 2130 usb_amd_quirk_pll_enable();
@@ -2165,8 +2213,7 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb,
2165 2213
2166/*-------------------------------------------------------------------------*/ 2214/*-------------------------------------------------------------------------*/
2167 2215
2168static void 2216static void scan_isoc(struct ehci_hcd *ehci)
2169scan_periodic (struct ehci_hcd *ehci)
2170{ 2217{
2171 unsigned now_uframe, frame, clock, clock_frame, mod; 2218 unsigned now_uframe, frame, clock, clock_frame, mod;
2172 unsigned modified; 2219 unsigned modified;
@@ -2189,7 +2236,6 @@ scan_periodic (struct ehci_hcd *ehci)
2189 ehci->clock_frame = clock_frame; 2236 ehci->clock_frame = clock_frame;
2190 clock &= mod - 1; 2237 clock &= mod - 1;
2191 clock_frame = clock >> 3; 2238 clock_frame = clock >> 3;
2192 ++ehci->periodic_stamp;
2193 2239
2194 for (;;) { 2240 for (;;) {
2195 union ehci_shadow q, *q_p; 2241 union ehci_shadow q, *q_p;
@@ -2208,36 +2254,10 @@ restart:
2208 2254
2209 while (q.ptr != NULL) { 2255 while (q.ptr != NULL) {
2210 unsigned uf; 2256 unsigned uf;
2211 union ehci_shadow temp;
2212 int live; 2257 int live;
2213 2258
2214 live = (ehci->rh_state >= EHCI_RH_RUNNING); 2259 live = (ehci->rh_state >= EHCI_RH_RUNNING);
2215 switch (hc32_to_cpu(ehci, type)) { 2260 switch (hc32_to_cpu(ehci, type)) {
2216 case Q_TYPE_QH:
2217 /* handle any completions */
2218 temp.qh = q.qh;
2219 type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next);
2220 q = q.qh->qh_next;
2221 if (temp.qh->stamp != ehci->periodic_stamp) {
2222 modified = qh_completions(ehci, temp.qh);
2223 if (!modified)
2224 temp.qh->stamp = ehci->periodic_stamp;
2225 if (unlikely(list_empty(&temp.qh->qtd_list) ||
2226 temp.qh->needs_rescan))
2227 start_unlink_intr(ehci, temp.qh);
2228 }
2229 break;
2230 case Q_TYPE_FSTN:
2231 /* for "save place" FSTNs, look at QH entries
2232 * in the previous frame for completions.
2233 */
2234 if (q.fstn->hw_prev != EHCI_LIST_END(ehci)) {
2235 ehci_dbg(ehci,
2236 "ignoring completions from FSTNs\n");
2237 }
2238 type = Q_NEXT_TYPE(ehci, q.fstn->hw_next);
2239 q = q.fstn->fstn_next;
2240 break;
2241 case Q_TYPE_ITD: 2261 case Q_TYPE_ITD:
2242 /* If this ITD is still active, leave it for 2262 /* If this ITD is still active, leave it for
2243 * later processing ... check the next entry. 2263 * later processing ... check the next entry.
@@ -2319,12 +2339,17 @@ restart:
2319 ehci_dbg(ehci, "corrupt type %d frame %d shadow %p\n", 2339 ehci_dbg(ehci, "corrupt type %d frame %d shadow %p\n",
2320 type, frame, q.ptr); 2340 type, frame, q.ptr);
2321 // BUG (); 2341 // BUG ();
2342 /* FALL THROUGH */
2343 case Q_TYPE_QH:
2344 case Q_TYPE_FSTN:
2345 /* End of the iTDs and siTDs */
2322 q.ptr = NULL; 2346 q.ptr = NULL;
2347 break;
2323 } 2348 }
2324 2349
2325 /* assume completion callbacks modify the queue */ 2350 /* assume completion callbacks modify the queue */
2326 if (unlikely (modified)) { 2351 if (unlikely (modified)) {
2327 if (likely(ehci->periodic_count > 0)) 2352 if (likely(ehci->isoc_count > 0))
2328 goto restart; 2353 goto restart;
2329 /* short-circuit this scan */ 2354 /* short-circuit this scan */
2330 now_uframe = clock; 2355 now_uframe = clock;
@@ -2353,7 +2378,7 @@ restart:
2353 unsigned now; 2378 unsigned now;
2354 2379
2355 if (ehci->rh_state < EHCI_RH_RUNNING 2380 if (ehci->rh_state < EHCI_RH_RUNNING
2356 || ehci->periodic_count == 0) 2381 || ehci->isoc_count == 0)
2357 break; 2382 break;
2358 ehci->next_uframe = now_uframe; 2383 ehci->next_uframe = now_uframe;
2359 now = ehci_read_frame_index(ehci) & (mod - 1); 2384 now = ehci_read_frame_index(ehci) & (mod - 1);
@@ -2363,10 +2388,7 @@ restart:
2363 /* rescan the rest of this frame, then ... */ 2388 /* rescan the rest of this frame, then ... */
2364 clock = now; 2389 clock = now;
2365 clock_frame = clock >> 3; 2390 clock_frame = clock >> 3;
2366 if (ehci->clock_frame != clock_frame) { 2391 ehci->clock_frame = clock_frame;
2367 ehci->clock_frame = clock_frame;
2368 ++ehci->periodic_stamp;
2369 }
2370 } else { 2392 } else {
2371 now_uframe++; 2393 now_uframe++;
2372 now_uframe &= mod - 1; 2394 now_uframe &= mod - 1;
diff --git a/drivers/usb/host/ehci-timer.c b/drivers/usb/host/ehci-timer.c
index a823290b5139..0e28bae78d18 100644
--- a/drivers/usb/host/ehci-timer.c
+++ b/drivers/usb/host/ehci-timer.c
@@ -168,13 +168,8 @@ static void ehci_poll_PSS(struct ehci_hcd *ehci)
168 168
169 /* The status is up-to-date; restart or stop the schedule as needed */ 169 /* The status is up-to-date; restart or stop the schedule as needed */
170 if (want == 0) { /* Stopped */ 170 if (want == 0) { /* Stopped */
171 if (ehci->periodic_count > 0) { 171 if (ehci->periodic_count > 0)
172
173 /* make sure ehci_work scans these */
174 ehci->next_uframe = ehci_read_frame_index(ehci)
175 & ((ehci->periodic_size << 3) - 1);
176 ehci_set_command_bit(ehci, CMD_PSE); 172 ehci_set_command_bit(ehci, CMD_PSE);
177 }
178 173
179 } else { /* Running */ 174 } else { /* Running */
180 if (ehci->periodic_count == 0) { 175 if (ehci->periodic_count == 0) {
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index c462d52ac575..08637183aad0 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -117,6 +117,7 @@ struct ehci_hcd { /* one per controller */
117 bool need_rescan:1; 117 bool need_rescan:1;
118 bool intr_unlinking:1; 118 bool intr_unlinking:1;
119 bool async_unlinking:1; 119 bool async_unlinking:1;
120 struct ehci_qh *qh_scan_next;
120 121
121 /* async schedule support */ 122 /* async schedule support */
122 struct ehci_qh *async; 123 struct ehci_qh *async;
@@ -124,7 +125,6 @@ struct ehci_hcd { /* one per controller */
124 struct ehci_qh *async_unlink; 125 struct ehci_qh *async_unlink;
125 struct ehci_qh *async_unlink_last; 126 struct ehci_qh *async_unlink_last;
126 struct ehci_qh *async_iaa; 127 struct ehci_qh *async_iaa;
127 struct ehci_qh *qh_scan_next;
128 unsigned async_unlink_cycle; 128 unsigned async_unlink_cycle;
129 unsigned async_count; /* async activity count */ 129 unsigned async_count; /* async activity count */
130 130
@@ -133,6 +133,7 @@ struct ehci_hcd { /* one per controller */
133 unsigned periodic_size; 133 unsigned periodic_size;
134 __hc32 *periodic; /* hw periodic table */ 134 __hc32 *periodic; /* hw periodic table */
135 dma_addr_t periodic_dma; 135 dma_addr_t periodic_dma;
136 struct list_head intr_qh_list;
136 unsigned i_thresh; /* uframes HC might cache */ 137 unsigned i_thresh; /* uframes HC might cache */
137 138
138 union ehci_shadow *pshadow; /* mirror hw periodic table */ 139 union ehci_shadow *pshadow; /* mirror hw periodic table */
@@ -140,6 +141,8 @@ struct ehci_hcd { /* one per controller */
140 struct ehci_qh *intr_unlink_last; 141 struct ehci_qh *intr_unlink_last;
141 unsigned intr_unlink_cycle; 142 unsigned intr_unlink_cycle;
142 int next_uframe; /* scan periodic, start here */ 143 int next_uframe; /* scan periodic, start here */
144 unsigned intr_count; /* intr activity count */
145 unsigned isoc_count; /* isoc activity count */
143 unsigned periodic_count; /* periodic activity count */ 146 unsigned periodic_count; /* periodic activity count */
144 unsigned uframe_periodic_max; /* max periodic time per uframe */ 147 unsigned uframe_periodic_max; /* max periodic time per uframe */
145 148
@@ -176,7 +179,6 @@ struct ehci_hcd { /* one per controller */
176 179
177 struct timer_list watchdog; 180 struct timer_list watchdog;
178 unsigned long actions; 181 unsigned long actions;
179 unsigned periodic_stamp;
180 unsigned random_frame; 182 unsigned random_frame;
181 unsigned long next_statechange; 183 unsigned long next_statechange;
182 ktime_t last_periodic_enable; 184 ktime_t last_periodic_enable;
@@ -381,11 +383,11 @@ struct ehci_qh {
381 dma_addr_t qh_dma; /* address of qh */ 383 dma_addr_t qh_dma; /* address of qh */
382 union ehci_shadow qh_next; /* ptr to qh; or periodic */ 384 union ehci_shadow qh_next; /* ptr to qh; or periodic */
383 struct list_head qtd_list; /* sw qtd list */ 385 struct list_head qtd_list; /* sw qtd list */
386 struct list_head intr_node; /* list of intr QHs */
384 struct ehci_qtd *dummy; 387 struct ehci_qtd *dummy;
385 struct ehci_qh *unlink_next; /* next on unlink list */ 388 struct ehci_qh *unlink_next; /* next on unlink list */
386 389
387 unsigned unlink_cycle; 390 unsigned unlink_cycle;
388 unsigned stamp;
389 391
390 u8 needs_rescan; /* Dequeue during giveback */ 392 u8 needs_rescan; /* Dequeue during giveback */
391 u8 qh_state; 393 u8 qh_state;