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.c100
1 files changed, 76 insertions, 24 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index edd61ee90323..3ea05936851f 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -60,6 +60,20 @@ periodic_next_shadow(struct ehci_hcd *ehci, union ehci_shadow *periodic,
60 } 60 }
61} 61}
62 62
63static __hc32 *
64shadow_next_periodic(struct ehci_hcd *ehci, union ehci_shadow *periodic,
65 __hc32 tag)
66{
67 switch (hc32_to_cpu(ehci, tag)) {
68 /* our ehci_shadow.qh is actually software part */
69 case Q_TYPE_QH:
70 return &periodic->qh->hw->hw_next;
71 /* others are hw parts */
72 default:
73 return periodic->hw_next;
74 }
75}
76
63/* caller must hold ehci->lock */ 77/* caller must hold ehci->lock */
64static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr) 78static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
65{ 79{
@@ -71,7 +85,8 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
71 while (here.ptr && here.ptr != ptr) { 85 while (here.ptr && here.ptr != ptr) {
72 prev_p = periodic_next_shadow(ehci, prev_p, 86 prev_p = periodic_next_shadow(ehci, prev_p,
73 Q_NEXT_TYPE(ehci, *hw_p)); 87 Q_NEXT_TYPE(ehci, *hw_p));
74 hw_p = here.hw_next; 88 hw_p = shadow_next_periodic(ehci, &here,
89 Q_NEXT_TYPE(ehci, *hw_p));
75 here = *prev_p; 90 here = *prev_p;
76 } 91 }
77 /* an interrupt entry (at list end) could have been shared */ 92 /* an interrupt entry (at list end) could have been shared */
@@ -83,7 +98,7 @@ static void periodic_unlink (struct ehci_hcd *ehci, unsigned frame, void *ptr)
83 */ 98 */
84 *prev_p = *periodic_next_shadow(ehci, &here, 99 *prev_p = *periodic_next_shadow(ehci, &here,
85 Q_NEXT_TYPE(ehci, *hw_p)); 100 Q_NEXT_TYPE(ehci, *hw_p));
86 *hw_p = *here.hw_next; 101 *hw_p = *shadow_next_periodic(ehci, &here, Q_NEXT_TYPE(ehci, *hw_p));
87} 102}
88 103
89/* how many of the uframe's 125 usecs are allocated? */ 104/* how many of the uframe's 125 usecs are allocated? */
@@ -93,18 +108,20 @@ periodic_usecs (struct ehci_hcd *ehci, unsigned frame, unsigned uframe)
93 __hc32 *hw_p = &ehci->periodic [frame]; 108 __hc32 *hw_p = &ehci->periodic [frame];
94 union ehci_shadow *q = &ehci->pshadow [frame]; 109 union ehci_shadow *q = &ehci->pshadow [frame];
95 unsigned usecs = 0; 110 unsigned usecs = 0;
111 struct ehci_qh_hw *hw;
96 112
97 while (q->ptr) { 113 while (q->ptr) {
98 switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) { 114 switch (hc32_to_cpu(ehci, Q_NEXT_TYPE(ehci, *hw_p))) {
99 case Q_TYPE_QH: 115 case Q_TYPE_QH:
116 hw = q->qh->hw;
100 /* is it in the S-mask? */ 117 /* is it in the S-mask? */
101 if (q->qh->hw_info2 & cpu_to_hc32(ehci, 1 << uframe)) 118 if (hw->hw_info2 & cpu_to_hc32(ehci, 1 << uframe))
102 usecs += q->qh->usecs; 119 usecs += q->qh->usecs;
103 /* ... or C-mask? */ 120 /* ... or C-mask? */
104 if (q->qh->hw_info2 & cpu_to_hc32(ehci, 121 if (hw->hw_info2 & cpu_to_hc32(ehci,
105 1 << (8 + uframe))) 122 1 << (8 + uframe)))
106 usecs += q->qh->c_usecs; 123 usecs += q->qh->c_usecs;
107 hw_p = &q->qh->hw_next; 124 hw_p = &hw->hw_next;
108 q = &q->qh->qh_next; 125 q = &q->qh->qh_next;
109 break; 126 break;
110 // case Q_TYPE_FSTN: 127 // case Q_TYPE_FSTN:
@@ -237,10 +254,10 @@ periodic_tt_usecs (
237 continue; 254 continue;
238 case Q_TYPE_QH: 255 case Q_TYPE_QH:
239 if (same_tt(dev, q->qh->dev)) { 256 if (same_tt(dev, q->qh->dev)) {
240 uf = tt_start_uframe(ehci, q->qh->hw_info2); 257 uf = tt_start_uframe(ehci, q->qh->hw->hw_info2);
241 tt_usecs[uf] += q->qh->tt_usecs; 258 tt_usecs[uf] += q->qh->tt_usecs;
242 } 259 }
243 hw_p = &q->qh->hw_next; 260 hw_p = &q->qh->hw->hw_next;
244 q = &q->qh->qh_next; 261 q = &q->qh->qh_next;
245 continue; 262 continue;
246 case Q_TYPE_SITD: 263 case Q_TYPE_SITD:
@@ -375,6 +392,7 @@ static int tt_no_collision (
375 for (; frame < ehci->periodic_size; frame += period) { 392 for (; frame < ehci->periodic_size; frame += period) {
376 union ehci_shadow here; 393 union ehci_shadow here;
377 __hc32 type; 394 __hc32 type;
395 struct ehci_qh_hw *hw;
378 396
379 here = ehci->pshadow [frame]; 397 here = ehci->pshadow [frame];
380 type = Q_NEXT_TYPE(ehci, ehci->periodic [frame]); 398 type = Q_NEXT_TYPE(ehci, ehci->periodic [frame]);
@@ -385,17 +403,18 @@ static int tt_no_collision (
385 here = here.itd->itd_next; 403 here = here.itd->itd_next;
386 continue; 404 continue;
387 case Q_TYPE_QH: 405 case Q_TYPE_QH:
406 hw = here.qh->hw;
388 if (same_tt (dev, here.qh->dev)) { 407 if (same_tt (dev, here.qh->dev)) {
389 u32 mask; 408 u32 mask;
390 409
391 mask = hc32_to_cpu(ehci, 410 mask = hc32_to_cpu(ehci,
392 here.qh->hw_info2); 411 hw->hw_info2);
393 /* "knows" no gap is needed */ 412 /* "knows" no gap is needed */
394 mask |= mask >> 8; 413 mask |= mask >> 8;
395 if (mask & uf_mask) 414 if (mask & uf_mask)
396 break; 415 break;
397 } 416 }
398 type = Q_NEXT_TYPE(ehci, here.qh->hw_next); 417 type = Q_NEXT_TYPE(ehci, hw->hw_next);
399 here = here.qh->qh_next; 418 here = here.qh->qh_next;
400 continue; 419 continue;
401 case Q_TYPE_SITD: 420 case Q_TYPE_SITD:
@@ -498,7 +517,8 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
498 517
499 dev_dbg (&qh->dev->dev, 518 dev_dbg (&qh->dev->dev,
500 "link qh%d-%04x/%p start %d [%d/%d us]\n", 519 "link qh%d-%04x/%p start %d [%d/%d us]\n",
501 period, hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK), 520 period, hc32_to_cpup(ehci, &qh->hw->hw_info2)
521 & (QH_CMASK | QH_SMASK),
502 qh, qh->start, qh->usecs, qh->c_usecs); 522 qh, qh->start, qh->usecs, qh->c_usecs);
503 523
504 /* high bandwidth, or otherwise every microframe */ 524 /* high bandwidth, or otherwise every microframe */
@@ -517,7 +537,7 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
517 if (type == cpu_to_hc32(ehci, Q_TYPE_QH)) 537 if (type == cpu_to_hc32(ehci, Q_TYPE_QH))
518 break; 538 break;
519 prev = periodic_next_shadow(ehci, prev, type); 539 prev = periodic_next_shadow(ehci, prev, type);
520 hw_p = &here.qh->hw_next; 540 hw_p = shadow_next_periodic(ehci, &here, type);
521 here = *prev; 541 here = *prev;
522 } 542 }
523 543
@@ -528,14 +548,14 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
528 if (qh->period > here.qh->period) 548 if (qh->period > here.qh->period)
529 break; 549 break;
530 prev = &here.qh->qh_next; 550 prev = &here.qh->qh_next;
531 hw_p = &here.qh->hw_next; 551 hw_p = &here.qh->hw->hw_next;
532 here = *prev; 552 here = *prev;
533 } 553 }
534 /* link in this qh, unless some earlier pass did that */ 554 /* link in this qh, unless some earlier pass did that */
535 if (qh != here.qh) { 555 if (qh != here.qh) {
536 qh->qh_next = here; 556 qh->qh_next = here;
537 if (here.qh) 557 if (here.qh)
538 qh->hw_next = *hw_p; 558 qh->hw->hw_next = *hw_p;
539 wmb (); 559 wmb ();
540 prev->qh = qh; 560 prev->qh = qh;
541 *hw_p = QH_NEXT (ehci, qh->qh_dma); 561 *hw_p = QH_NEXT (ehci, qh->qh_dma);
@@ -581,7 +601,7 @@ static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
581 dev_dbg (&qh->dev->dev, 601 dev_dbg (&qh->dev->dev,
582 "unlink qh%d-%04x/%p start %d [%d/%d us]\n", 602 "unlink qh%d-%04x/%p start %d [%d/%d us]\n",
583 qh->period, 603 qh->period,
584 hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK), 604 hc32_to_cpup(ehci, &qh->hw->hw_info2) & (QH_CMASK | QH_SMASK),
585 qh, qh->start, qh->usecs, qh->c_usecs); 605 qh, qh->start, qh->usecs, qh->c_usecs);
586 606
587 /* qh->qh_next still "live" to HC */ 607 /* qh->qh_next still "live" to HC */
@@ -595,7 +615,19 @@ static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
595 615
596static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh) 616static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
597{ 617{
598 unsigned wait; 618 unsigned wait;
619 struct ehci_qh_hw *hw = qh->hw;
620 int rc;
621
622 /* If the QH isn't linked then there's nothing we can do
623 * unless we were called during a giveback, in which case
624 * qh_completions() has to deal with it.
625 */
626 if (qh->qh_state != QH_STATE_LINKED) {
627 if (qh->qh_state == QH_STATE_COMPLETING)
628 qh->needs_rescan = 1;
629 return;
630 }
599 631
600 qh_unlink_periodic (ehci, qh); 632 qh_unlink_periodic (ehci, qh);
601 633
@@ -606,15 +638,33 @@ static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
606 */ 638 */
607 if (list_empty (&qh->qtd_list) 639 if (list_empty (&qh->qtd_list)
608 || (cpu_to_hc32(ehci, QH_CMASK) 640 || (cpu_to_hc32(ehci, QH_CMASK)
609 & qh->hw_info2) != 0) 641 & hw->hw_info2) != 0)
610 wait = 2; 642 wait = 2;
611 else 643 else
612 wait = 55; /* worst case: 3 * 1024 */ 644 wait = 55; /* worst case: 3 * 1024 */
613 645
614 udelay (wait); 646 udelay (wait);
615 qh->qh_state = QH_STATE_IDLE; 647 qh->qh_state = QH_STATE_IDLE;
616 qh->hw_next = EHCI_LIST_END(ehci); 648 hw->hw_next = EHCI_LIST_END(ehci);
617 wmb (); 649 wmb ();
650
651 qh_completions(ehci, qh);
652
653 /* reschedule QH iff another request is queued */
654 if (!list_empty(&qh->qtd_list) &&
655 HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) {
656 rc = qh_schedule(ehci, qh);
657
658 /* An error here likely indicates handshake failure
659 * or no space left in the schedule. Neither fault
660 * should happen often ...
661 *
662 * FIXME kill the now-dysfunctional queued urbs
663 */
664 if (rc != 0)
665 ehci_err(ehci, "can't reschedule qh %p, err %d\n",
666 qh, rc);
667 }
618} 668}
619 669
620/*-------------------------------------------------------------------------*/ 670/*-------------------------------------------------------------------------*/
@@ -739,14 +789,15 @@ static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh)
739 unsigned uframe; 789 unsigned uframe;
740 __hc32 c_mask; 790 __hc32 c_mask;
741 unsigned frame; /* 0..(qh->period - 1), or NO_FRAME */ 791 unsigned frame; /* 0..(qh->period - 1), or NO_FRAME */
792 struct ehci_qh_hw *hw = qh->hw;
742 793
743 qh_refresh(ehci, qh); 794 qh_refresh(ehci, qh);
744 qh->hw_next = EHCI_LIST_END(ehci); 795 hw->hw_next = EHCI_LIST_END(ehci);
745 frame = qh->start; 796 frame = qh->start;
746 797
747 /* reuse the previous schedule slots, if we can */ 798 /* reuse the previous schedule slots, if we can */
748 if (frame < qh->period) { 799 if (frame < qh->period) {
749 uframe = ffs(hc32_to_cpup(ehci, &qh->hw_info2) & QH_SMASK); 800 uframe = ffs(hc32_to_cpup(ehci, &hw->hw_info2) & QH_SMASK);
750 status = check_intr_schedule (ehci, frame, --uframe, 801 status = check_intr_schedule (ehci, frame, --uframe,
751 qh, &c_mask); 802 qh, &c_mask);
752 } else { 803 } else {
@@ -784,11 +835,11 @@ static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh)
784 qh->start = frame; 835 qh->start = frame;
785 836
786 /* reset S-frame and (maybe) C-frame masks */ 837 /* reset S-frame and (maybe) C-frame masks */
787 qh->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK)); 838 hw->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK));
788 qh->hw_info2 |= qh->period 839 hw->hw_info2 |= qh->period
789 ? cpu_to_hc32(ehci, 1 << uframe) 840 ? cpu_to_hc32(ehci, 1 << uframe)
790 : cpu_to_hc32(ehci, QH_SMASK); 841 : cpu_to_hc32(ehci, QH_SMASK);
791 qh->hw_info2 |= c_mask; 842 hw->hw_info2 |= c_mask;
792 } else 843 } else
793 ehci_dbg (ehci, "reused qh %p schedule\n", qh); 844 ehci_dbg (ehci, "reused qh %p schedule\n", qh);
794 845
@@ -2188,10 +2239,11 @@ restart:
2188 case Q_TYPE_QH: 2239 case Q_TYPE_QH:
2189 /* handle any completions */ 2240 /* handle any completions */
2190 temp.qh = qh_get (q.qh); 2241 temp.qh = qh_get (q.qh);
2191 type = Q_NEXT_TYPE(ehci, q.qh->hw_next); 2242 type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next);
2192 q = q.qh->qh_next; 2243 q = q.qh->qh_next;
2193 modified = qh_completions (ehci, temp.qh); 2244 modified = qh_completions (ehci, temp.qh);
2194 if (unlikely (list_empty (&temp.qh->qtd_list))) 2245 if (unlikely(list_empty(&temp.qh->qtd_list) ||
2246 temp.qh->needs_rescan))
2195 intr_deschedule (ehci, temp.qh); 2247 intr_deschedule (ehci, temp.qh);
2196 qh_put (temp.qh); 2248 qh_put (temp.qh);
2197 break; 2249 break;