Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Dec 2004 23:15:58 -0800
From:      Julian Elischer <julian@elischer.org>
To:        hselasky@c2i.net
Cc:        freebsd-usb@freebsd.org
Subject:   Re: USB vendore designations..
Message-ID:  <41CFB6AE.1080705@elischer.org>
In-Reply-To: <200412261747.36555.hselasky@c2i.net>
References:  <41CB38A7.5020700@vicor.com> <41CB4BCB.1080708@elischer.org> <20041224124346.GG45586@cicely12.cicely.de> <200412261747.36555.hselasky@c2i.net>

next in thread | previous in thread | raw e-mail | index | archive | help
Hans Petter Selasky wrote:
> On Friday 24 December 2004 13:43, Bernd Walter wrote:
> 
>>On Thu, Dec 23, 2004 at 02:50:51PM -0800, Julian Elischer wrote:
>>
>>>EHCI is almost ok.. except for where it REALLY SUCKS!
>>
> 
> The EHCI manual says that QH's can be removed without stopping the HC. QH 
> removal is done like this: set the previous QH to point to the next QH, and 
> then set the DOORBELL bit in the EHCI command register and wait for it to 
> clear. This is the same whether the QH is finished or cancelled, though if it 
> is finished one might get around with a short DELAY(), hence the HC should 
> already be skipping the QH? Currently, no driver is checking cancelled QH's,  
> to see if they were finished after all. If the drivers did, then no 
> information as to whether the transfers on it were completed or not, would be 
> lost. 
> 
> As long as there are not so many transfers the EHCI is not that inefficient.

yes I read the spec.

here's the problem:

If you have  a QH with many qTDs hanging off it, you can tell whether
a TD has been comleted by whether it is still active.
if it is no longer active, you need to look at the error bits
to see if the transfer was successful or not.


Now, when you do the "doobell trick" as descibed in the spec,
there is one little part of it.. that is the catch.

The spec says:
"Software should first deactivate all active qTDs, wait for the
queue head to go inactive, then remove the queue head from
the asynchronous list."

Note the word "all"

Ok, so since we want to remove only SOME of the qTDs from the queue
(those corresponding to the aborting command), and we need to read
the status word to see which has been completed by whether the
active bit is set, and since we are in a race with the hardware
to clear the active bit, which of the qTDs, not in the list of
qTDs we want to remove, was completed?

Remember that the "current qTD" pointer could have been changed
by the hardware the very next bus cycle after we read it, so
we can not trust that at all on an active queue. We can only tell where it has 
gotten past before we started fiddling, but we don't really know where it got
to WHILE we were fiddling. (at least by my reading).
It is possible that we might be able to turn a qTD and check the
"current qTD" in some combined manner that would allow you to deduce
the exact state, but my head hurts when I try work it out.
Add to that that you need to be sure that you have a memory barrier in teh right
place and be absolutly sure that the cache has been updated for the locations
accessed by the PCI bus when you read them, etc.etc.

The OHCI driver actually hands you the completed TDs by linking them
onto a separate queue.
There is NO ambiguity there.

They could have even solved it by making the "completed" status bit be a 
different bit in a different memory word from the "This is not active"
bit used by the software.

One gets a little hope from reading the state diagrams at the back of the
spec. but it's a lot to get one's head around.

> 
> Yours
> --HPS
> _______________________________________________
> freebsd-usb@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-usb
> To unsubscribe, send any mail to "freebsd-usb-unsubscribe@freebsd.org"



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?41CFB6AE.1080705>