Am Montag, 7. Januar 2008 schrieb David Brownell: > This has some bugfixes for the EHCI driver's ISO transfer scanning > logic. It was leaving ITDs and SITDs on the schedule too long, for > a few different reasons, which caused trouble. > > (a) Look at all microframes for high speed transfers, not just > the ones we expect to have finished. This way transfers > ending mid-frame will complete without needing another IRQ. > This also minimizes bogus scheduling underruns (e.g. EL2NSYNC). > > (b) When we encounter an ISO transfer (either speed, but this > hits mostly at full speed) that's not yet been completed, > immediately stop scanning; we've caught up to the hardware, > no matter what other indications might say. > > (c) Always clean up ITDs (for high speed transfers) when the HC > is no longer running. > > I'm not sure whether the last one has been observed before, but both > the others have been reported with "real world" audio and video code. > > Signed-off-by: David Brownell <[EMAIL PROTECTED]> > --- > Updated version ... primarily adding (b) to address another bug > in this same area. Against RC7.
This + not yet fully cooked patch at bottom on-top RC7 let snd-usb-us122l work :-) Still to fix: There are itds leaking, the printk() below executes every now and then. Likely caused by patch below. Karsten --- drivers/usb/host/ehci-sched.c.dave 2008-01-09 16:05:31.000000000 +0100 +++ drivers/usb/host/ehci-sched.c 2008-01-09 16:05:50.000000000 +0100 @@ -1180,12 +1180,17 @@ if (likely (!list_empty(&stream->free_list))) { itd = list_entry (stream->free_list.prev, struct ehci_itd, itd_list); - list_del (&itd->itd_list); - itd_dma = itd->itd_dma; + if (itd->frame == ehci->clock >> 3) { + itd = NULL; + } else { + list_del (&itd->itd_list); + itd_dma = itd->itd_dma; + } } else itd = NULL; if (!itd) { + printk(KERN_DEBUG"%s:%i\n", __FUNCTION__, __LINE__); spin_unlock_irqrestore (&ehci->lock, flags); itd = dma_pool_alloc (ehci->itd_pool, mem_flags, &itd_dma); @@ -2107,7 +2112,7 @@ static void scan_periodic (struct ehci_hcd *ehci) { - unsigned frame, clock, now_uframe, mod; + unsigned frame, now_uframe, mod; unsigned modified; mod = ehci->periodic_size << 3; @@ -2119,10 +2124,10 @@ */ now_uframe = ehci->next_uframe; if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) - clock = ehci_readl(ehci, &ehci->regs->frame_index); + ehci->clock = ehci_readl(ehci, &ehci->regs->frame_index); else - clock = now_uframe + mod - 1; - clock %= mod; + ehci->clock = now_uframe + mod - 1; + ehci->clock %= mod; for (;;) { union ehci_shadow q, *q_p; @@ -2253,7 +2258,7 @@ // FIXME: likewise assumes HC doesn't halt mid-scan - if (now_uframe == clock) { + if (now_uframe == ehci->clock) { unsigned now; if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) @@ -2264,7 +2269,7 @@ break; /* rescan the rest of this frame, then ... */ - clock = now; + ehci->clock = now; } else { now_uframe++; now_uframe %= mod; --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -86,6 +86,7 @@ struct ehci_hcd { /* one per controller */ union ehci_shadow *pshadow; /* mirror hw periodic table */ int next_uframe; /* scan periodic, start here */ + unsigned clock; unsigned periodic_sched; /* periodic activity count */ /* per root hub port */ - To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html