On Tuesday 18 July 2006 4:42 pm, Vivek Dharmadhikari wrote:
> Hello David
> 
> The Synopsys USB core that we are using the SOC has following bug which
> might cause the issue(host controller not issuing ping) that I have been
> dealing with. The workaround for the bug is also provided and I wanted
> to implement that in the driver. I guess the second workaround is easier
> to implement. Can you please provide comments on which workaround is
> easier to implement and most importantly how to implement it.

The first one is more in line with what the driver does today, so it's
easier.  The second one would cause a 4 msec (huge!!) burp in the queue
processing in the common "shrink the queue a bit" cases ... big slowdown.


I take it the following text is all provided by Synopsis?  It's more
descriptive than some errata, but I'm not entirely sure it would apply.

Do you have the full list of errata that Synopsis publicly acknowledges?
If so, another type of mechanism to look for is bugs in how the QH overlay
area is managed, especially as part of advancing a given queue.  Plus it's
of course possible you're zooming in on a "new" bug, or one of the ones
they've tried to sweep under the rug.  (All silicon vendors seem to do
that, especially for more complex bugs that don't have a big customer
forcing them to address the issue ... silicon fixes aren't cheap, and
they disrupt sales plans.)


> When software uses the Doorbell mechanism to remove queue heads, the
> host controller still has references to the removed queue head even
> after indicating an Interrupt on Async Advance. This happens if the last
> executed queue head's Next Link queue head is removed. 
> 
> Consequences of the defect:
> The Host controller fetches the removed queue head, using memory that
> would otherwise be deallocated.This results in incorrect transactions on
> both the USB and system memory. This may result in undefined behavior. 
> 
> Workarounds:
> 1) If no queue head is active (no Status field's Active bit is set)
> after removing the queue heads, the software can write one of the valid
> queue head addresses to the ASYNCLISTADDR register and deallocate the
> removed queue head's memory after 2 microframes. 

This case boils down to resetting ASYNCLISTADDR and waiting 250+ usec
before poisoning any QH as it's freed ... but it's unlikely that latter
would matter in the cases you've described, since your scenario (just
mass storage) isn't actually freed; it's just dequeued, to be reused soon.

Maybe the fix would be in end_unlink_async(), to read ASYNCLISTADDR
and compare it to qh->qh_dma ... and if it matches, then rewriting
that register.  (Stick a printk in to see if that code ever triggers.)
Or heck, maybe just _always_ rewrite it; fairness of queue processing
isn't usually a big deal.


> If one or more of the queue heads is active (the Active bit is set in
> the Status field) after removing the queue heads, the software can delay
> memory deallocation after time X, where X is the time required for the
> Host Controller to go through all the queue heads once. X varies with
> the number of queue heads and the time required to process periodic
> transactions: if more periodic transactions must be performed, the Host
> Controller has less time to process asynchronous transaction processing.

Or in short, wait for a _second_ IAA.  But again, this is unlikely to
change anything, since the QH isn't actually getting recycled.  If the
ASYNCLISTADDR update helps the case above, it should help here too..
 

> 2) Do not use the Doorbell mechanism to remove the queue heads. Disable
> the Asynchronous Schedule Enable bit instead.

As I noted above, this would be a major change to the driver, and would
slow things down significantly in typical cases.

- Dave


-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to