I count seven (7) TDs for your Get Descriptor transaction. Why seven? If you have one for the SETUP at the beginning, and one OUT at then end, that leaves five IN packets. Five times eight is 40 bytes. A standard Device Descriptor has a max length of 18 bytes. Somewhere along the lines, one of your TD's (the third IN packet) will SPD. At the SPD, you must move directly to the OUT packet or the remaining IN packets will STALL.
You must create your schedule so that on a SPD, the controller stops execution in the vertical direction and moves to the Horizontal pointer of the Queue Head, which should contain the ending zero length OUT packet. This way, none of the "extra" IN packets get executed.
Code: Select all
[QH:HORZ] ----> [Ending zero length OUT packet. AKA: Status packet]
[QH:VERT] \----------------------\
| |
v |
[TD0] --> [TD1] --> [TD2] --> [TD3] --> [TD4]--> [TDn]
(SETUP) (IN) (IN) (IN) (IN) ... (OUT)
In the (crude) example above, the controller will start with the VERT pointer, execute TD0 (setup), TD1 (eight bytes), TD2 (eight bytes), TD3 (two bytes and SPD), stop execution in the Vertical direction and move back to the Horizontal pointer, which now points to the ending OUT packet. TD3 through TDn never get executed. This is the whole design of the UHCI stack.
Does that make any sense?
With your current code, after the 7th TD of the Get Descriptor call, the "stack" is in the STALL state. As soon as you get to the SET_ADDRESS call, the SETUP packet will clear the stall. This is a good thing, however, at the same time, the device is still expecting the OUT packet from the previous call. Therefore, a SET_ADDRESS command might fail, in your case it most likely is.
It is good practice, as far as the UHCI is concerned, to always request 255 bytes for every Control request, allowing the controller to SPD (Short Packet Detect) and move to the Horizontal pointer and the ending IN or OUT packet, AKA the STATUS packet.
Your interrupt routine should process the URB (URB = USB Request Block = All of the TDs from SETUP to STATUS) and return the count of bytes actually transferred, while removing this queue from the schedule.
Hope all of this makes sense.
My book explains this in great detail. It also explains that after a reset, you should only request the first 8 bytes of the Device Descriptor, do another reset, then request all 18 bytes, all *before* trying to set the address of the device. Even though the design specifies that all 18 are available, there are devices that will only return the first 8 after a (first) reset.
At first, dealing with the USB, whether it be UHCI or xHCI, it can be quite frustrating. However, after you get a good working knowledge of the hardware, it actually becomes addicting, which I won't admit at all that I am addicted. Nope, won't do it :-)
Hope this helps,
Ben