I'm sending this in for discussion. It fixes a real bug in ehci-hcd (the sched->span value is not getting converted from frames to microframes). The effect of the bug is that some Isochronous URB submissions are accepted when they should not be, messing up the periodic schedule. I'm not submitting this patch right now because it is certain to cause new failures. It's hard to say whether it will cause any regressions; the things that would fail might not be working correctly now anyway. There's a good chance some regressions will occur. The problem is that with some types of hardware, ehci-hcd uses a scheduling horizon of only 256 ms. It won't accept Isochronous URBs that go farther than that into the future. However the usbaudio driver is known to submit URBs for timing synchronization that will overrun this limit. (The current version of ehci-hcd accepts these URBs even though it shouldn't; that's the bug.) The default scheduling horizon is 1024 ms but ehci-hcd uses the smaller value if the hardware supports it, in order to reduce the amount of processing needed when updating the schedule. I can see two possible approaches. One is for ehci-hcd always to use 1024 ms and not worry about the extra processing costs. The other is to change the drivers that want to schedule URBs too far into the future. The difficulty here is that I'm not aware of all the drivers that might need changes; there may be others in addition to usbaudio. Suggestions? Alan Stern Index: usb-2.6/drivers/usb/host/ehci-sched.c =================================================================== --- usb-2.6.orig/drivers/usb/host/ehci-sched.c +++ usb-2.6/drivers/usb/host/ehci-sched.c @@ -1396,29 +1396,32 @@ iso_stream_schedule ( struct ehci_iso_stream *stream ) { - u32 now, next, start, period; + u32 now, next, start, period, span; int status; unsigned mod = ehci->periodic_size << 3; struct ehci_iso_sched *sched = urb->hcpriv; struct pci_dev *pdev; - if (sched->span > (mod - SCHEDULE_SLOP)) { + period = urb->interval; + span = sched->span; + if (!stream->highspeed) { + period <<= 3; + span <<= 3; + } + + if (span > mod - SCHEDULE_SLOP) { ehci_dbg (ehci, "iso request %p too long\n", urb); status = -EFBIG; goto fail; } - if ((stream->depth + sched->span) > mod) { + if (stream->depth + span > mod) { ehci_dbg (ehci, "request %p would overflow (%d+%d>%d)\n", - urb, stream->depth, sched->span, mod); + urb, stream->depth, span, mod); status = -EFBIG; goto fail; } - period = urb->interval; - if (!stream->highspeed) - period <<= 3; - now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; /* Typical case: reuse current schedule, stream is still active. @@ -1448,7 +1451,7 @@ iso_stream_schedule ( period); /* Tried to schedule too far into the future? */ - if (unlikely(((start - now) & (mod - 1)) + sched->span + if (unlikely(((start - now) & (mod - 1)) + span >= mod - 2 * SCHEDULE_SLOP)) { status = -EFBIG; goto fail; -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html