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