On Wednesday 16 February 2005 3:37 am, Steve Hosgood wrote: > Basically, David, your suggestion of "try small URBs" works! I am now > seeing 40 fps from my camera with URBs of 4K, 8K and 16K. > > So I'd say that your first hypothesis below pans out nicely: > ... > > Now while that's normally a fine thing, it's also a mode > > that doesn't usually kick in ... AND it's one where some > > shenanigans have to be used to patch up short reads. AND > > you're seeing problems after some short reads. > > > > Specifically, when the first TD (len=20480) triggers any > > kind of short read, it enters a special patch-up mode > > (flagged by the '#') where instead of going to the next > > TD, it goes to a magic "alternate" dummy that just stops > > the whole queue ... and the queue scanning logic has to > > detect that magic dummy, and restart it. > > > > ==> HYPOTHESIS: there's a bug in how the queue scanning > > handles that special case. It's very rare; QED. > > > > ==> PLEASE TEST BY: trying buffers of no more than 5[pages] > > in your bulk-IN urbs. This will completely avoid > > those special cases.
OK, then this looks wierd. Can you see if this patch helps at all? It shouldn't matter, but this test is more direct and so it should catch cases where the hardware isn't quite acting as expected. (Some chips have misbehaved in related areas...) - Dave
Try a more direct test for the condition that detects the funky short read case where an URB requires two or more transfer descriptors (transfer buffer is more than about 20KB, or maybe less depending on alignment) and the device provides a short packet somewhere before the last descriptor. This relies on knowing that the QTD's hw_alt_next is only ever initialized to one of two values, and ignores the QH entirely on the knowledge that some hardware doesn't manage the QH overlay according to the EHCI spec. --- 1.78/drivers/usb/host/ehci-q.c 2005-03-02 09:25:54 -08:00 +++ edited/drivers/usb/host/ehci-q.c 2005-03-02 10:08:35 -08:00 @@ -340,8 +340,7 @@ /* magic dummy for some short reads; qh won't advance */ } else if (IS_SHORT_READ (token) - && (qh->hw_alt_next & QTD_MASK) - == ehci->async->hw_alt_next) { + && !(qtd->hw_alt_next & EHCI_LIST_END)) { stopped = 1; goto halt; }