Page 1 of 1

EHCI - Data Toggle/Bytes To Transfer [ SOLVED ]

Posted: Sun Apr 04, 2010 9:48 pm
by prajwal
Hello Friends,

I recently am able to get EHCI Async schedule work with few control transfers to get device desc, set address, get config value etc...

Before I proceed, I am very much confused with the way EHCI Data Toggling works and also how Total Bytes to Transfer is interpreted by controller and device.

I have read the EHCI doc but not able to understand or get clarifications about this.

Question 1: Can anybody please explain how Data Toggle works (DTC and DT) ?
In UHCI, it was straight fwd as I just need to toggle the data toggle bit for every control transaction starting at "0"
If I do the same with EHCI, it doesn't work properly for all control transfers !

Question 2: What should be the value of Length field in qTD token and also in USB Device Request structure (wLength) for a SETUP transaction of 8 bytes
and for an IN transaction of 18 bytes ?

In UHCI, it is very clear. Length field in USB Device Request (URB) is exactly equal to Length of bytes to transfer. It will be zero for zero length transfer
Length field in TD Token will be always 1 less than the number of bytes to transfer. For Zero Length transaction it should be 0x7FF

In EHCI, While doing GetDeviceDesc control transaction, it works if the Length Field in URB is (Len + 1) and the length field in qTD Token = Len !!
If I have Length field in URB = Len and length field in qTD Token = (Len - 1), it works but it transfers only (Len - 1) bytes
If I have Length field in URB = Len and length field in qTD Token also = Len, Transaction fails.
This issue is compounded with Data Toggle issue as I am not sure when to toggle the bits ?
I am thinking that every new control transaction will start with Data Toggle value of "0" like the way it works in UHCI
i.e,
for SetAddress it will be SETUP (0), IN ACK(1)
for GetDeviceDesc it will be SETUP(0), IN Desc(1), OUT ACK(0)

Thanks very much in advance for helping on this

Best Regards,
- MosMan

Re: EHCI - Data Toggle/Bytes To Transfer

Posted: Tue Apr 06, 2010 11:44 am
by TomT
Hi MosMan,

I have the following suggestions which you should of course take with a grain of salt and investigate tatOS because my memory is short.

For ehci data toggle I use the same code as uhci. In the 2nd dword of your ehci QH you can instruct the controller to take the toggle bit from your TD just like uhci.

Some rules I follow for the data toggle bit:

1) each endpoint maintains its own toggle which alternates between 0 and 1 with each TD

2) on reset host and device set there toggles to 0

3) control transfers have rigid rules for toggle:
* command transport = first TD uses DATA0 then alternates
* data transport = first TD uses DATA1 then alternates
* status transport = first TD uses DATA1 then alternates

4) for bulk transfers you must use a global dataIN and dataOUT variable and alternate
this even across transactions and phases.
i.e. if the previous status transport was an IN=1 then
the next data transport if IN must be 0

5) if NAK do not toggle, instead retry with same

tatOS is actually quite dump about the toggle. If a transaction gets messed up I just reset the controller and port and start over. I usually dont need to do this.

To your second question about transaction length I would just suggest looking at the comments in tatOS/usb/prepareTD.s


See also tatOS/usb/controller.s and /usb/prepareTD.s and /usb/info-TD

Good luck,
TomT
http://code.google.com/p/tatos/

Re: EHCI - Data Toggle/Bytes To Transfer

Posted: Fri Apr 09, 2010 5:42 am
by prajwal
Thanks for extending your help.

I am able to solve this issue almost... It was not related to DT and Length field actually.

EHCI controller advances (adds) the bytes read into the BufferPointer address in TD. Now, this is something which I didn't realize and
was trying to read data from TD->BufferPointer0 which now points to "Initial TD->BufferPointer0" + Bytes Transfered !

The Data Toggle works same as how it works for UHCI
Bytes to Transfer is little different in that for EHCI it is = "The actual bytes to transfer" but for UHCI it is = "One less than actual bytes to transfer"

With that, I am able to cleanly enumerate a Flash drive but I am stuck at doing IN/OUT bulk transaction with the flash disk device...
Hoping to resolve this over the weekend

Let me know if there are any "special" things that I have to be aware of while doing IN/OUT bulk transaction
Basically my IN bulk transaction does not process at all... No errros in the status field it just does not get processed !

Thanks,
- MosMan

Re: EHCI - Data Toggle/Bytes To Transfer

Posted: Sun Apr 11, 2010 6:17 pm
by osdnlo
The only time I have seen this behavior was when the controller was misconfigured, the address was bunk, the controller was off, or the port was disabled. If your device enumeration process was OK, then we might rule out misconfiguration, I would then concentrate on my address and the state of the controller/port. HTH :)

Re: EHCI - Data Toggle/Bytes To Transfer

Posted: Mon Apr 12, 2010 2:25 am
by prajwal
All resolved.

Just that I did not care about bit 0 of TD Status of OUT transaction which indicates PING state

I went over USB 2.0 and EHCI doc on the purpose of this bit. Nothing that I need to do additional in my EHCI driver, just that I was considering this as an error which is not !

Now, the data toggle for IN/OUT also starts from 0 and not 1

All works fine. I am now able to enumerate and load the driver for usb flash drive and use it

Re: EHCI - Data Toggle/Bytes To Transfer [ SOLVED ]

Posted: Mon Apr 12, 2010 3:44 am
by osdnlo
OIC. When you said, they weren't processing at all, I assumed just that. At any rate, good work. Glad you got it working.