|
@@ -1565,13 +1565,27 @@ itd_patch(
|
|
|
static inline void
|
|
|
itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd)
|
|
|
{
|
|
|
- /* always prepend ITD/SITD ... only QH tree is order-sensitive */
|
|
|
- itd->itd_next = ehci->pshadow [frame];
|
|
|
- itd->hw_next = ehci->periodic [frame];
|
|
|
- ehci->pshadow [frame].itd = itd;
|
|
|
+ union ehci_shadow *prev = &ehci->pshadow[frame];
|
|
|
+ __hc32 *hw_p = &ehci->periodic[frame];
|
|
|
+ union ehci_shadow here = *prev;
|
|
|
+ __hc32 type = 0;
|
|
|
+
|
|
|
+ /* skip any iso nodes which might belong to previous microframes */
|
|
|
+ while (here.ptr) {
|
|
|
+ type = Q_NEXT_TYPE(ehci, *hw_p);
|
|
|
+ if (type == cpu_to_hc32(ehci, Q_TYPE_QH))
|
|
|
+ break;
|
|
|
+ prev = periodic_next_shadow(ehci, prev, type);
|
|
|
+ hw_p = shadow_next_periodic(ehci, &here, type);
|
|
|
+ here = *prev;
|
|
|
+ }
|
|
|
+
|
|
|
+ itd->itd_next = here;
|
|
|
+ itd->hw_next = *hw_p;
|
|
|
+ prev->itd = itd;
|
|
|
itd->frame = frame;
|
|
|
wmb ();
|
|
|
- ehci->periodic[frame] = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
|
|
|
+ *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD);
|
|
|
}
|
|
|
|
|
|
/* fit urb's itds into the selected schedule slot; activate as needed */
|