Hi Mark,
The scenario is very clear now, just one element is missing: whether the target image has Hcd_hsotg.DLL in it.
I was able to build two usable images from the iMX28-EVK BSP; I inspected BIB/REG files of both.
Both possible HOST-only selections are outlined below; it would be interesting to find out if OTG has any impact at all.
(1) USB HOST only build without OTG
One of the builds had just this selection from Freescale i.MX28 EVK: ARMV4I Catalog:
USB Devices
USB Host Device
[X] High Speed Host
It had just Hcd_hsh1.DLL in it, and the BIB/Registry files were set accordingly.
;------------------------------------------------------------------------------
; PURE HOST Registry
; @CESYSGEN IF CE_MODULES_USBHOST
; @CESYSGEN ENDIF CE_MODULES_USBHOST
; @CESYSGEN IF CE_MODULES_USBHOST
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\HCD_HSH1]
"Prefix"="HCD"
"Dll"="hcd_hsh1.dll"
"Order"=dword:15
"Class"=dword:0c
"SubClass"=dword:03
"ProgIF"=dword:20
"MemBase"=dword:80090000
"MemLen"=dword:00001000
"irq"=dword:5C
"HcdCapability"=dword:4 ;HCD_SUSPEND_ON_REQUEST
"OTGSupport"=dword:0
"OTGGroup"="01"
; @CESYSGEN ENDIF CE_MODULES_USBHOST
;
; END OF PURE HOST Registry
;------------------------------------------------------------------------------
(2) USB HOST build with pure host OTG
The other build had a radio button from the OTG group also checked in addition to the selection above:
USB Devices
USB High Speed OTG Device
( ) High Speed OTG Port Full OTG Function
( ) High Speed OTG Port Pure Client Function
(x) High Speed OTG Port Pure Host Function
It had both Hcd_hsotg.DLL and Hcd_hsh1.DLL in it, and the BIB/Registry files were set accordingly:
;------------------------------------------------------------------------------
; PURE HOST Registry
; @CESYSGEN IF CE_MODULES_USBHOST
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\HCD_HSOTG]
"Prefix"="HCD"
"Dll"="hcd_hsotg.dll"
"Order"=dword:15
"Class"=dword:0c
"SubClass"=dword:03
"ProgIF"=dword:20
"MemBase"=dword:80080000
"MemLen"=dword:00001000
"irq"=dword:5D
"HcdCapability"=dword:4 ;HCD_SUSPEND_ON_REQUEST
"OTGSupport"=dword:0
"OTGGroup"="01"
; @CESYSGEN ENDIF CE_MODULES_USBHOST
; @CESYSGEN IF CE_MODULES_USBHOST
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\HCD_HSH1]
"Prefix"="HCD"
"Dll"="hcd_hsh1.dll"
"Order"=dword:15
"Class"=dword:0c
"SubClass"=dword:03
"ProgIF"=dword:20
"MemBase"=dword:80090000
"MemLen"=dword:00001000
"irq"=dword:5C
"HcdCapability"=dword:4 ;HCD_SUSPEND_ON_REQUEST
"OTGSupport"=dword:0
"OTGGroup"="01"
; @CESYSGEN ENDIF CE_MODULES_USBHOST
;
; END OF PURE HOST Registry
;------------------------------------------------------------------------------
The suspicion of runaway qTD is very reasonable; however, time delay may be just workaround. Nothing like that has been ever implemented in MSFT or FSL USB port drivers.
Keep in mind that there are at least three threads (in order of low-to-high priority) which have access to queues & transfers:
USBD calling thread;
USBD event callback thread;
HC IRQ handler.
Each shared memory resource between these threads should be “volatile” qualified, to prevent optimizing compiler from caching a pointer or value on the local stack.
Another technique which might be applicable (albeit USB descriptors should always be allocated in non-cached memory) could be, CacheRangeFlush() call after release of queue descriptor.
= = = = =
All-in-all, I cannot imagine finding the root cause of the problem without debugging.
To confirm or deny the suspicion of time-related issue while freeing transfer descriptors, a debug session is a must.
My recommendation would be to focus on the function void CHub::AttachDevice() in <WEC7root>\Platform\CommonSRC\SoC\Common_FSL_V2\MS\USBH\usb2com folder.
Setting up ZONE_ATTACH and ATTACH_DETAIL to obtain traces during device attach process might also be helpful.
Needless to mention, USB Analyzer should be connected all the time and live results should be monitored wile attachment state machine is executing.
The state machine has only three stages before reaching DEVICE_DESCRIPTOR stages.
The stage immediately preceding DEVICE_CONFIG_STATUS_SCHEDULING_GET_DEVICE_DESCRIPTOR_TEST is no other but DEVICE_CONFIG_STATUS_RESET_AND_ENABLE_PORT.
Incomplete or improper reset of a port is very likely to have dire consequences, and this triage scenario may help:
- 1. Build RETAIL image with optimizations disabled for USB2COM files. Both KITL and DEBUGGER must be enabled for the image.
- 2. Set breakpoints
at line 1700, DEVICE_CONFIG_STATUS_OPENING_ENDPOINT_PIPE case; and
at line 1775, DEVICE_CONFIG_STATUS_GET_DEVICE_DECRIPTOR_TEST case;
then let run until the failure happens; that will confirm babble begins after few attempts in-between these two stages; - 3. Reboot target, disable breakpoint at line 1700 and set instead one
at line 1753, DEVICE_CONFIG_STATUS_RESET_AND_ENABLEPORT case;
pay specific attention to line 1765, BSPHostDisconnect(TRUE); even put breakpoint there too, just to see if it gets invoked and when. - 4. Let run and try to reproduce; see if babble start in-between the lastly set breakpoints.
If this happens, then the failure may only happen on a couple of code lines. - 5. Alternatively, step into and through the code of ResetAndEnablePort(port) function, and observe if this “slow-motion” effectively provides workaround.
There is exactly one pipe – the control pipe 0 – which is employed in the process; all its descriptor allocations may be observed while at breakpoint and any corruption of pointers/descriptors can be detected.
Before and after reset, a dump of HC port registers may also be useful for differential analysis.
Thanks,
Adeneo Engineering Team