[U-Boot] [PATCH] usb: fix usb start problem with SMSC USB hub and Toshiba USB stick

Roland Kletzing
2010-09-20T20:46:20Z

Hello,

i`m searching for a solution for a while, so i`m trying my luck here. I`m
using Seagate Dockstar (ARM926EJ-S based) NAS device and installed Debian
ARM on that as documented at http://jeff.doozan.com/debian/

While it`s running fine with a sandisk flash usb stick and a sd-card in a
usb cardreader, i`m not able to get the thingie boot with 2 different real
2.5" ide disks attached to two different kinds of ide2usb converter cables.

The pogoplug linux (which runs on dockstar by default) detects the disks
very fine and debian installation from there runs fine too, but booting from
that always fails like this:

U-Boot 2010.06-00695-gbd23130-dirty (Aug 30 2010 - 23:04:56)
Marvell-Dockstar/Pogoplug by Jeff Doozan
Hit any key to stop autoboot: 0
(Re)start USB...
USB: Register 10011 NbrPorts 1
USB EHCI 1.00
scanning bus for devices... 3 USB Device(s) found
scanning bus for storage devices... 1 Storage Device(s) found
** Bad partition 1 **
** Bad partition 1 **
Wrong Image Format for bootm command
ERROR: can't get kernel image!
stopping USB..

I found a LOT of references on the net where people report similar problems
for sheevaplug, pogoplug, dockstar - even with flash based media and just
came across this posting on u-boot list. looks related to me!?

i assume there is something which needs be fixed in u-boot and this is not
storage-device specific but must be specific to the usb chipset or platform.

the problem is that i don`t know how to unbrick dockstar yet, but i`d like
to let you know that a lot of people will be happy if this gets fixed. i
will read deeper into how to build uboot and safely replace it on my device,
if there is anything more i can do to provide input or do testing please let
me know. i think i can dig out tons of reports of similar issues. as my "i
replace my homeserver with a dockstar"-projects depends on this, maybe i can
even donate a dockstar for the person willing or be able to fix this issue.

from another post:
>Is this problem only valid for the EHCI code? I can imagine that the
>other host controllers (like UHCI and OHCI and so on) code suffer the
>same problem and need similar fixes...
>(At least I know that I have here a couple of USB sticks that show
>similar problems with OHCI ;-) )

If this helps - this is some info from a successful linux boot on that
dockstar platform. usb runs perfectly when in linux, but it seems that there
are problems only in u-boot.

[ 1.180000] ehci_marvell ehci_marvell.70059: Marvell Orion EHCI
[ 1.190000] ehci_marvell ehci_marvell.70059: new USB bus registered,
assigned bus number 1
[ 1.230000] ehci_marvell ehci_marvell.70059: irq 19, io base 0xf1050100
[ 1.250000] ehci_marvell ehci_marvell.70059: USB 2.0 started, EHCI 1.00,
driver 10 Dec 2004
[ 1.250000] usb usb1: configuration #1 chosen from 1 choice
[ 1.260000] hub 1-0:1.0: USB hub found
[ 1.260000] hub 1-0:1.0: 1 port detected
[ 1.380000] ohci_hcd: 2006 August 04 USB 1.1 'Open' Host Controller
(OHCI) Driver
[ 1.380000] USB Universal Host Controller Interface driver v3.0
[ 1.660000] usb 1-1: new high speed USB device using ehci_marvell and
address 2
[ 1.810000] usb 1-1: configuration #1 chosen from 1 choice
[ 1.810000] hub 1-1:1.0: USB hub found
[ 1.820000] hub 1-1:1.0: 4 ports detected
[ 2.170000] usb 1-1.3: new high speed USB device using ehci_marvell and
address 3
[ 2.270000] usb 1-1.3: configuration #1 chosen from 1 choice

regards
roland

ps:
i found the following line in common/usb_storage.c - so maybe we cannot
expect the usb code to work with real disks at all !?
/*
* New Note:
* Support for USB Mass Storage Devices (BBB) has been added. It has
* only been tested with USB memory sticks.
*/

quote:
[U-Boot] [PATCH] usb: fix usb start problem with SMSC USB hub and Toshiba
USB stick
Anatolij Gustschin agust at denx.de
Tue Aug 31 20:45:14 CEST 2010
Previous message: [U-Boot] [PATCH] zlib: Add further watchdog reset calls
Next message: [U-Boot] [PATCH] [v2] mpc8610: refactor DIU initialization
code to use existing bitmap and logo features
Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

Checking the status field of the qTD token in the current code
do not take into acount cases where endpoint stall (halted) bit
is set together with some other status bits. As a result clearing
stall on an endpoint won't be done if other status bits were set.

E.g. 'usb start' 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
recovery code fails as no clear stall request on the endpoint
will be done. The patch fixes status field checking code to
properly handle endpoint halted state.

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>
---
common/usb_storage.c | 5 +++--
drivers/usb/host/ehci-hcd.c | 8 ++++++++
2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/common/usb_storage.c b/common/usb_storage.c
index 76949b8..5ca92c3 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -680,7 +680,8 @@ int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
result = usb_bulk_msg(us->pusb_dev, pipe, srb->pdata, srb->datalen,
&data_actlen, USB_CNTL_TIMEOUT * 5);
/* special handling of STALL in DATA phase */
- if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) {
+ if ((result < 0) &&
+ (us->pusb_dev->status & (USB_ST_STALLED | USB_ST_CRC_ERR))) {
USB_STOR_PRINTF("DATA:stall\n");
/* clear the STALL on the endpoint */
result = usb_stor_BBB_clear_endpt_stall(us,
@@ -710,7 +711,7 @@ again:

/* special handling of STALL in STATUS phase */
if ((result < 0) && (retry < 1) &&
- (us->pusb_dev->status & USB_ST_STALLED)) {
+ (us->pusb_dev->status & (USB_ST_STALLED | USB_ST_CRC_ERR))) {
USB_STOR_PRINTF("STATUS:stall\n");
/* clear the STALL on the endpoint */
result = usb_stor_BBB_clear_endpt_stall(us, us->ep_in);
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 37d056e..7463a75 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -430,6 +430,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;
@@ -490,6 +496,8 @@ ehci_submit_async(struct usb_device *dev, unsigned long
pipe, void *buffer,
break;
default:
dev->status = USB_ST_CRC_ERR;
+ if ((token & 0x40) == 0x40)
+ dev->status |= USB_ST_STALLED;
break;
}
dev->act_len = length - ((token >> 16) & 0x7fff);
--
1.7.0.4