Page 1 of 1

Need help for USB UHCI programming

Posted: Thu Sep 30, 2010 9:42 am
by muragavino
Hi there,

working on a ring0 singletask RTOS I have encountered an annoying problem regarding an USB UHCI controller. Testing board is an Intel Atom board D410PT with 1 EHCI and 4 UHCI companion controllers in the NM10 chipset.

I can send packets to a function, but responding IN packets from the function are ignored. The SETUP packet of the get_device_descriptor() arrives in the function which replies with the usual 18 bytes, but UHCI hardware sets the IN transfer descriptor as if nothing would have been sent back (C_ERR runs out and the CRC/Timeout bit is set in the status-field) . I tested by controling the function's source code (which was another project of mine) which works well with Windows, Mac and Linux. Also the EHCI on the board works fine!

After one week of searching this error I don't have any ideas left why this can happen!
Is anybody out there with experience in UHCI programming? On sucessfully solving my problem, I'm even willing and able to pay a little money, if this can help... (50 € is ok? #-o )

Hopefully,
Michael

Re: Need help for USB UHCI programming

Posted: Fri Oct 08, 2010 9:44 am
by muragavino
...and again it's me! More than 100 people have already viewed this post but none has replied - looks like lots of you have problems with UHCI and not much (none?) can help with it!

Well, here I'd like to give more details to my problem - hope it might help also someone else:

The Problem: transfers host-to-function (full-speed) work properly, but transfers function-to-host result in the host to show a CRC/timeout error, as if the function would have send nothing.

As USB-function I'm using a SiLabs C8051F320DK evaluation board, where I have programmed 2 LEDs to go ON when the GET_DEVICE_DESCRIPTOR has been received and the SET_ADDRESS control transfer has been accomplished. The function (a MIDI controller) has been tested and works fine with Windows, Linux and Mac.

Here the details:
When booting my Atom Board (D410PT), the BIOS enumerates the function (both LEDs go ON), thus the hardware on my board works perfectly.

(BIOS-version is MOPNV10N.86A.0178.2010.0331.0947)

The NM10 chipset of the board includes 1 EHCI with 4 UHCI companion controllers for full- and low-speed transfers.

After my kernel has started, the following is setup (in sequence) for the USB:

* - set the PCI bus master enable and memory space enable bits (if necessary)
* - get Host Control Capabilities Register address from PCI (that is EHCI at D29:F7 !)
* - check if the BIOS controls the EHCI and set control to OS. This regards bits 16 and 24 of the USB EHCI Legacy Support Extended register (offset 0x68). After this, the BIOS is not more able to access the USB-function.
* - get ehci mem space size, get Host Control Operational Register address and reset the EHCI.
* - Next I allocate memory for EHCI and UHCI queues and setup 3 framelists, 1 for EHCI use, and 2 for 2 UHCI controllers (there are 4, but only 2 will be used).
* - Register CONFIGFLAG is setup to route all ports to the EHCI first
* - The I/O addresses for the 4 UHCI controller are taken from PCI Baseaddress Register (D29:F0/F1/F2/F3) at offset 0x20
* - Every UHCI controller is now:

1. stopped and globally reset
2. clear all interrupt- and error-bits (register STS is ANDed with 0x1F)
3. clear legacy support and detach UHCI from BIOS by writing 0x8F00 to the PCI register USB_LEGKEY at offset 0xC0
4. start HCRESET (CMD |= 2) and wait till reset has finished
5. USB registers are cleared (CMD, STS, INTR, FRNUM and PORTSC[0/1] are 0, SOFMOD is 0x40)


At this point I start scanning the 8 ports for attached devices (to easy testing, only 1 device is attached!). If a high-speed device is found, everything runs fine, no problem!
If a full-speed device is found (EHCI port-reset leaves port disabled, ergo it must be full- or low-speed), the following is done:

* - release port ownership to a companion host controller by setting EHCI_PORTSC[port] |= (1<<13) and wait for the change to be accomplished
* - store the frame list base address to the UHCI FRBASEADD register and set FRNUM to 0
* - set bit PIRQ by writing 0x2000 to the PCI register USB_LEGKEY at offset 0xC0 (enable USB-PCI interrupt, BUT: All is still done by polling, no interrupts are enabled!)
* - send a resume signal on USB for 20 ms
* - reset the connected port
* - start the UHCI controller with max packet size to 64 bytes. (The last 3 items can be exchanged in any manner, the result is allways the same!)

Now I start enumeration by invoking the get_device_descriptor transaction. The 8 bytes of the SETUP token are sent and recived by the function (LED1 goes ON) which replies with the 18 requested bytes of the descriptor. The UHCI controller runs out of CERR and returns a CRC/timeout error.
Here the queue transfer definitions with the data before and after transfer:

1st Transfer: Setup: After Transfer:
Link pointer: 0xDEAD0001 0x1EFBFBF4
Control/Status: 0x18800000 0x18000007
Token: 0x00E0002D 0x00E0002D
buffer: 0x0009FB60 0x0009FB60

2nd Transfer: Setup: After Transfer:
Link pointer: 0x1EFBFC14 0x1EFBFC14
Control/Status: 0x18800000 0x004507FF <--- the error!!!
Token: 0x02240069 0x02240069
buffer: 0x0009FB70 0x0009FB70

The 3rd Transfer is irrelevant - it has never been arrived up to here!

It took exactly 4 frames to arrive at the error (1 for the SETUP- and 3 for the IN-token).

HELP!!! I would be happy to hear any opinion and any ideas!

Re: Need help for USB UHCI programming

Posted: Fri Oct 08, 2010 10:27 am
by JamesM
Hi,

You're probably not getting any replies because you posted to the wrong subforum, so the people you're looking for probably aren't seeing this. I've moved the post to OS Development.

Also, the 100 views is probably people who click links (like me!) to remove the "unread" colour from them ;)

James

Re: Need help for USB UHCI programming

Posted: Fri Oct 08, 2010 11:32 am
by rdos
It could be the speed flag that is set incorrectly in the TD descriptor. UHCI has two different speeds.

Re: Need help for USB UHCI programming

Posted: Sat Oct 09, 2010 4:34 am
by ehenkes
http://www.lvr.com/forum/index.php?board=2.0
There you will find a usb forum

Re: Need help for USB UHCI programming

Posted: Sat Oct 09, 2010 8:10 am
by muragavino
JamesM wrote:Hi,

You're probably not getting any replies because you posted to the wrong subforum, so the people you're looking for probably aren't seeing this. I've moved the post to OS Development.

Also, the 100 views is probably people who click links (like me!) to remove the "unread" colour from them ;)

James
Thanks for moving my post! The already more than 200 views are from the Intel Embedded Forum from where I just copied the text over to here... UHCI seems to be sooo popular :shock:

Re: Need help for USB UHCI programming

Posted: Sat Oct 09, 2010 8:13 am
by muragavino
rdos wrote:It could be the speed flag that is set incorrectly in the TD descriptor. UHCI has two different speeds.
No, sorry, the flag is set correctly. I suppose the problem is lying somewhere in the setup/reseting of the UHCI...

Re: Need help for USB UHCI programming

Posted: Sat Oct 09, 2010 9:00 am
by muragavino
ehenkes wrote:http://www.lvr.com/forum/index.php?board=2.0
There you will find a usb forum
Thanks, that might be helpful! [-o<

Re: Need help for USB UHCI programming

Posted: Sun Oct 10, 2010 11:37 pm
by pcmattman
muragavino wrote:I can send packets to a function, but responding IN packets from the function are ignored. The SETUP packet of the get_device_descriptor() arrives in the function which replies with the usual 18 bytes, but UHCI hardware sets the IN transfer descriptor as if nothing would have been sent back (C_ERR runs out and the CRC/Timeout bit is set in the status-field) . I tested by controling the function's source code (which was another project of mine) which works well with Windows, Mac and Linux. Also the EHCI on the board works fine!
I'm dealing with pretty much the exact same problem (minus the unique hardware) at the moment. Similar to you, EHCI works without a problem on the same hardware (though for my UHCI tests I've completely disabled the EHCI controller).

If you make any progress I'd appreciate knowing what you did and how you did it (of course, I'll do the same if I make any progress!) :)

Re: Need help for USB UHCI programming

Posted: Fri Oct 15, 2010 11:49 am
by muragavino
pcmattman wrote:If you make any progress I'd appreciate knowing what you did and how you did it (of course, I'll do the same if I make any progress!) :)
Hi down under!
Up here I found out something weird: By putting intentionally the wrong toggle bit in the IN transfer-descriptor (toggel=0 instead of =1) and with the interrupts activated, I don't get an error, but simply nothing! That means an interrupt has captured the error. It must be an interrupt, not an event or break, since with disabled interrupts I can poll for the error normally.
I then re-vectored all protected mode ISRs to see where the interrupt comes from, just to see that still a real-mode ISR from the BIOS must be active! Since I have released EHCI from BIOS (in the LEG_EXT_CAP register) as prescribed, there must be still some other BIOS related register, I suppose.

Any ideas how to release the UHCIs definitely ???
Must there occure a reset and new setup of the PCI ???


I searched my chipset datasheet for "UHCI", but didn't find anything relevant.

Re: Need help for USB UHCI programming

Posted: Sat Oct 16, 2010 9:50 pm
by pcmattman
If you only write 0x8F00 to the PCI configuration space at 0xC0, you'll be zeroing the USBPIRQDEN bit and disabling IRQ generation altogether ;).

I've written 0x8F00 to clear all write to clear bits and then 0x2000 to enable IRQ generation. Devices do start up and accept addresses fairly regularly now, but still fail far too regularly for me to be happy with the code. It's always a stall during the handshake of the SET ADDRESS command - that specific behaviour never changes.