Re: Lost IAA and EHCI reclaim problems
David Brownell <[email protected]>
| Newsgroups | gmane.linux.usb.devel |
|---|---|
| Message-ID | <[email protected]> |
On Sunday 19 August 2007, Alan Stern wrote: > Dave: > > I just read through your old iaa_watchdog patch, and there are several > things about it (maybe about the pre-patch code too) that seem strange. > > Management of the reclaim list is wrong. Every qh that was added > before the IAA doorbell bit was set should get unlinked when > end_unlink_async() runs, whereas qhs added after the IAAD bit should > cause another IAA cycle. However end_unlink_async() never changes > more than one qh's state to QH_STATE_IDLE. The pessimistic assumption is that only one QH will be removed per doorbell. I don't see how that would be "wrong"... > The iaa_watchdog routine seems to assume that STS_IAA gets set properly > and the interrupt is never delivered. That is, assumes that the hardware behaves correctly. > Isn't it likely that some controllers may fail to set STS_IAA at all? I wouldn't think so; but of course if you *knew* of such a controller it wouldn't be likely ... it'd be a certainty! > Shouldn't the watchdog > routine take a more careful approach? For example, it could disable > the async schedule, wait until the schedule really was off, then clear > CMD_IAAD and handle all the pending unlinks. That would be an alternate strategy to follow. Appropriate for use with controllers that don't implement the doorbell correctly. Maybe that would even be a "better" strategy than expecting the watchdog could never fire before IAA should have happened. (I can imagine how a huge async ring and a really busy PCI could break that expectation.) > Here's a somewhat unrelated question that came up earlier: When an > async transfer stops because of an error the endpoint queue has to be > restarted, presumably by setting qh->hw_current to point to the first > qtd in the next URB. But the driver never does this. How does a > stopped queue get restarted? Does it go through an unlink cycle first? It's been a long time since I touched that code, so details are fuzzy... But the basic notion is that there's only one routine scanning a QH and removing TDs from it -- qh_completions() is its name. This ensures that there are no little races of the type ISTR the original OHCI code suffered from, with one routine fighting another. A comment at the top of qh_completions() says that it leaves HALT (error) status set until the queue is completely scrubbed. A QH that's halted like that, or else is in QH_STATE_IDLE, can safely be scanned and modified even after the hardware's view of the queue head. Otherwise the TD queue only get modified by removing completed TDs (before the head) or by adding new ones (after the tail). A QH that's getting that "scrub everything" treatment should always get reactivated using qh_refresh(), and thence qh_update(). And if it's in that mode, the qh_completions() loop doesn't stop when it gets to an active TD ... it keeps scanning to the end of the list, processing pending unlinks (in queue order, once). Now, I seem to recall that there were two refresh modes. One was where the QH overlay was partially completed ... e.g. TD at list head was for 8 packets, and 3 of them were processed already, but an URB after this one got unlinked. In that case the important part is clearing the overlay bits that said "be a NOP for now". The other mode was where that overlay was no longer valid, in which case it invalidates the overlay so that the next QTD is read. Both require careful attention to the text in 4.10 regarding operation of queue heads. Now, in the error case you asked about, the overlay became invalid. So 4.10.2 needs to come into play ... it ignores hw_current when both ACTIVE and HALT bits are cleared. That's ensured by qh_update(); at the very end it scrubs those bits. Which makes the HC fetch from the qh->hw_next field, and then normally process that QTD and update the overlay. Tadaa! - Dave > > Alan Stern > ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/ _______________________________________________ [email protected] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel