Friday, 11 July 2008

Windows CE: USB: Considerations when using EHCI and OHCI in the same image

If your device has a USB host controller with both EHCI (USB 2.0 host controller) and OHCI (USB 1.1 host controller) components (e.g. NEC 720101), communication always starts with EHCI and is handed over to OHCI if an OHCI device is detected.

Since the standard EHCI and the OHCI drivers both have the same load order in the registry, either one of them can load first. Both, EHCI and OHCI drivers have their own HubStatusChangeThread, which is responsible for detecting insertion and removal of USB devices. Normally, every attach (or detach) is handled by the EHCI driver. If the EHCI driver detects that the attached device is an OHCI device it hands it over to the OHCI driver to handle the attach.

A problem occurs when the OHCI driver loads before the EHCI driver. In that case the OHCI HubStatusChangeThread will also start first. If a device is attached to the USB host controller port before the EHCI HubStatusChangeThread is loaded, the OHCI driver will handle the attach. This behavior results in a slower boot time of the device or even a crash or freeze of the device while booting depending on whether the EHCI HubStatusChangeThread is loaded during the OHCI attach or after.

One approach to solve this dilemma is to stall the start of the OHCI HubStatusChangeThread until the EHCI HubStatusChangeThread is loaded. This can be done using a named event:

1. In the OHCI CHub::HubStatusChangeThreadStub create a named, non-signaled event and wait for that event with WaitForSingleObject right before the
return ((CHub*)context)->HubStatusChangeThread(); statement.
2. In the EHCI CHub::HubStatusChangeThreadStub create the same named, non-signaled event and signal the event with SetEvent right before the
return ((CHub*)context)->HubStatusChangeThread(); statement.

Have fun!

No comments: