
'usb start' command often fails with Toshiba USB stick 0x930/0x6545 connected to the SMSC USB 2.0 hub 0x424/0x2514. Debugging the issue showed that while bulk IN transfers with length of 13 or 18 the status field of the qTD token sometimes indicates trans- action error (XactErr) and sometimes additionally endpoint halted state. In the latter case resetting the USB device in error handling code works after clearing stall request on the endpoint. In the case where only XactErr bit was set the resetting doesn't work properly and device not ready status will be finally reported. This patch adds reporting endpoint stall status in case of trans- action errors for this hub/stick combination so that the error handling code can reset the device after clearing stall request to the endpoint.
However this fix is not enough to solve 'usb start' problem with hub/stick combination mentioned above. Running with lot of debug code in ehci_submit_async() I've never seen the problem with usb stick recognition. After removing this debug code the similar problem sometimes showed up again. Therefore the patch also adds delay in ehci_submit_async() for above-mentioned hub/stick combination. Even without this delay the fix is an improvement since it fixes the problem with board freezy after subsequent failed 'usb start/stop' cycles as it was observed on mpc5121ads board.
Signed-off-by: Anatolij Gustschin agust@denx.de --- drivers/usb/host/ehci-hcd.c | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index c7fba10..a001143 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -431,6 +431,12 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, usbsts = ehci_readl(&hcor->or_usbsts); ehci_writel(&hcor->or_usbsts, (usbsts & 0x3f));
+ if (dev->descriptor.idVendor == 0x930 && + dev->descriptor.idProduct == 0x6545 && + dev->parent->descriptor.idVendor == 0x424 && + dev->parent->descriptor.idProduct == 0x2514) + wait_ms(10); + /* Enable async. schedule. */ cmd = ehci_readl(&hcor->or_usbcmd); cmd |= CMD_ASE; @@ -493,6 +499,12 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, dev->status = USB_ST_CRC_ERR; if ((token & 0x40) == 0x40) dev->status |= USB_ST_STALLED; + + if (dev->descriptor.idVendor == 0x930 && + dev->descriptor.idProduct == 0x6545 && + dev->parent->descriptor.idVendor == 0x424 && + dev->parent->descriptor.idProduct == 0x2514) + dev->status |= USB_ST_STALLED; break; } dev->act_len = length - ((token >> 16) & 0x7fff);