diff options
Diffstat (limited to 'drivers/usb/host/ehci-sched.c')
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 39340ae00ac4..a0aaaaff2560 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -1123,8 +1123,8 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb) | |||
1123 | urb->interval); | 1123 | urb->interval); |
1124 | } | 1124 | } |
1125 | 1125 | ||
1126 | /* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */ | 1126 | /* if dev->ep [epnum] is a QH, hw is set */ |
1127 | } else if (unlikely (stream->hw_info1 != 0)) { | 1127 | } else if (unlikely (stream->hw != NULL)) { |
1128 | ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n", | 1128 | ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n", |
1129 | urb->dev->devpath, epnum, | 1129 | urb->dev->devpath, epnum, |
1130 | usb_pipein(urb->pipe) ? "in" : "out"); | 1130 | usb_pipein(urb->pipe) ? "in" : "out"); |
@@ -1565,13 +1565,27 @@ itd_patch( | |||
1565 | static inline void | 1565 | static inline void |
1566 | itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) | 1566 | itd_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 */ |