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.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index 39340ae00ac4..cd1e8bf5327e 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1565,13 +1565,27 @@ itd_patch(
1565static inline void 1565static inline void
1566itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) 1566itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd)
1567{ 1567{
1568 /* always prepend ITD/SITD ... only QH tree is order-sensitive */ 1568 union ehci_shadow *prev = &ehci->pshadow[frame];
1569 itd->itd_next = ehci->pshadow [frame]; 1569 __hc32 *hw_p = &ehci->periodic[frame];
1570 itd->hw_next = ehci->periodic [frame]; 1570 union ehci_shadow here = *prev;
1571 ehci->pshadow [frame].itd = itd; 1571 __hc32 type = 0;
1572
1573 /* skip any iso nodes which might belong to previous microframes */
1574 while (here.ptr) {
1575 type = Q_NEXT_TYPE(ehci, *hw_p);
1576 if (type == cpu_to_hc32(ehci, Q_TYPE_QH))
1577 break;
1578 prev = periodic_next_shadow(ehci, prev, type);
1579 hw_p = shadow_next_periodic(ehci, &here, type);
1580 here = *prev;
1581 }
1582
1583 itd->itd_next = here;
1584 itd->hw_next = *hw_p;
1585 prev->itd = itd;
1572 itd->frame = frame; 1586 itd->frame = frame;
1573 wmb (); 1587 wmb ();
1574 ehci->periodic[frame] = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); 1588 *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
1575} 1589}
1576 1590
1577/* fit urb's itds into the selected schedule slot; activate as needed */ 1591/* fit urb's itds into the selected schedule slot; activate as needed */