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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.