aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-sched.c
diff options
context:
space:
mode:
authorAlek Du <alek.du@intel.com>2009-07-13 19:23:29 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 09:46:29 -0400
commit3807e26d69b9ad3864fe03224ebebc9610d5802e (patch)
tree3c85a5cb0686a7e72255c523b963942bbfc60b7f /drivers/usb/host/ehci-sched.c
parent403dbd36739e344d2d25f56ebbe342248487bd48 (diff)
USB: EHCI: split ehci_qh into hw and sw parts
The ehci_qh structure merged hw and sw together which is not good: 1. More and more items are being added into ehci_qh, the ehci_qh software part are unnecessary to be allocated in DMA qh_pool. 2. If HCD has local SRAM, the sw part will consume it too, and it won't bring any benefit. 3. For non-cache-coherence system, the entire ehci_qh is uncachable, actually we only need the hw part to be uncacheable. Spliting them will let the sw part to be cacheable. Signed-off-by: Alek Du <alek.du@intel.com> Cc: David Brownell <dbrownell@users.sourceforge.net> CC: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ehci-sched.c')
-rw-r--r--drivers/usb/host/ehci-sched.c66
1 files changed, 44 insertions, 22 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index edd61ee90323..327437af2122 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 */
@@ -596,6 +616,7 @@ static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
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;
599 620
600 qh_unlink_periodic (ehci, qh); 621 qh_unlink_periodic (ehci, qh);
601 622
@@ -606,14 +627,14 @@ static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
606 */ 627 */
607 if (list_empty (&qh->qtd_list) 628 if (list_empty (&qh->qtd_list)
608 || (cpu_to_hc32(ehci, QH_CMASK) 629 || (cpu_to_hc32(ehci, QH_CMASK)
609 & qh->hw_info2) != 0) 630 & hw->hw_info2) != 0)
610 wait = 2; 631 wait = 2;
611 else 632 else
612 wait = 55; /* worst case: 3 * 1024 */ 633 wait = 55; /* worst case: 3 * 1024 */
613 634
614 udelay (wait); 635 udelay (wait);
615 qh->qh_state = QH_STATE_IDLE; 636 qh->qh_state = QH_STATE_IDLE;
616 qh->hw_next = EHCI_LIST_END(ehci); 637 hw->hw_next = EHCI_LIST_END(ehci);
617 wmb (); 638 wmb ();
618} 639}
619 640
@@ -739,14 +760,15 @@ static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh)
739 unsigned uframe; 760 unsigned uframe;
740 __hc32 c_mask; 761 __hc32 c_mask;
741 unsigned frame; /* 0..(qh->period - 1), or NO_FRAME */ 762 unsigned frame; /* 0..(qh->period - 1), or NO_FRAME */
763 struct ehci_qh_hw *hw = qh->hw;
742 764
743 qh_refresh(ehci, qh); 765 qh_refresh(ehci, qh);
744 qh->hw_next = EHCI_LIST_END(ehci); 766 hw->hw_next = EHCI_LIST_END(ehci);
745 frame = qh->start; 767 frame = qh->start;
746 768
747 /* reuse the previous schedule slots, if we can */ 769 /* reuse the previous schedule slots, if we can */
748 if (frame < qh->period) { 770 if (frame < qh->period) {
749 uframe = ffs(hc32_to_cpup(ehci, &qh->hw_info2) & QH_SMASK); 771 uframe = ffs(hc32_to_cpup(ehci, &hw->hw_info2) & QH_SMASK);
750 status = check_intr_schedule (ehci, frame, --uframe, 772 status = check_intr_schedule (ehci, frame, --uframe,
751 qh, &c_mask); 773 qh, &c_mask);
752 } else { 774 } else {
@@ -784,11 +806,11 @@ static int qh_schedule(struct ehci_hcd *ehci, struct ehci_qh *qh)
784 qh->start = frame; 806 qh->start = frame;
785 807
786 /* reset S-frame and (maybe) C-frame masks */ 808 /* reset S-frame and (maybe) C-frame masks */
787 qh->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK)); 809 hw->hw_info2 &= cpu_to_hc32(ehci, ~(QH_CMASK | QH_SMASK));
788 qh->hw_info2 |= qh->period 810 hw->hw_info2 |= qh->period
789 ? cpu_to_hc32(ehci, 1 << uframe) 811 ? cpu_to_hc32(ehci, 1 << uframe)
790 : cpu_to_hc32(ehci, QH_SMASK); 812 : cpu_to_hc32(ehci, QH_SMASK);
791 qh->hw_info2 |= c_mask; 813 hw->hw_info2 |= c_mask;
792 } else 814 } else
793 ehci_dbg (ehci, "reused qh %p schedule\n", qh); 815 ehci_dbg (ehci, "reused qh %p schedule\n", qh);
794 816
@@ -2188,7 +2210,7 @@ restart:
2188 case Q_TYPE_QH: 2210 case Q_TYPE_QH:
2189 /* handle any completions */ 2211 /* handle any completions */
2190 temp.qh = qh_get (q.qh); 2212 temp.qh = qh_get (q.qh);
2191 type = Q_NEXT_TYPE(ehci, q.qh->hw_next); 2213 type = Q_NEXT_TYPE(ehci, q.qh->hw->hw_next);
2192 q = q.qh->qh_next; 2214 q = q.qh->qh_next;
2193 modified = qh_completions (ehci, temp.qh); 2215 modified = qh_completions (ehci, temp.qh);
2194 if (unlikely (list_empty (&temp.qh->qtd_list))) 2216 if (unlikely (list_empty (&temp.qh->qtd_list)))