From 222d6dff27b81dd9cfd57b984538f3d481aae0f5 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 2 Nov 2010 11:47:29 +0100 Subject: usb: fix for USB_ST_STALLED status reporting in ehci_submit_async() 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 XactErr status bit. As a result clearing stall on an endpoint won't be done if this status bit was also set. Check for halted bit and report USB_ST_STALLED status if the host controller also indicates endpoit stall condition. Signed-off-by: Anatolij Gustschin --- drivers/usb/host/ehci-hcd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 982f96e8b..c7fba1048 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -491,6 +491,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); -- cgit v1.2.3 From 67333f76b683cb19762c60f180a4e9c592064fc1 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 26 Nov 2010 15:43:28 +0100 Subject: usb: Add WATCHDOG_RESET call to polling loop This watchdog reset call is needed here, otherwise the lwmon5 board (PPC440EPx based) will reset upon the "usb reset" command. Signed-off-by: Stefan Roese Cc: Remy Bohmer --- drivers/usb/host/ehci-hcd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index c7fba1048..c7de6f054 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "ehci.h" @@ -452,6 +453,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, token = hc32_to_cpu(vtd->qt_token); if (!(token & 0x80)) break; + WATCHDOG_RESET(); } while (get_timer(ts) < CONFIG_SYS_HZ); /* Disable async schedule. */ -- cgit v1.2.3 From 273d72044c383cc49ae7a8a70b2fc32c18b00a41 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 26 Nov 2010 15:44:00 +0100 Subject: usb: Clear CMD_RUN while issuing CMD_RESET in ehci_reset() This patch fixes a problem noticed on lwmon5 (PPC440EPx) using the common EHCI driver, when "usb reset" is issued multiple times. Upon the 2nd (and further) "usb reset" command, the command fails with the following messages: => usb reset (Re)start USB... USB: Register 1111 NbrPorts 1 USB EHCI 1.00 scanning bus for devices... 5 USB Device(s) found scanning bus for storage devices... 2 Storage Device(s) found => usb reset (Re)start USB... USB: EHCI fail to reset Error, couldn't init Lowlevel part This patch fixes this problem. Now "usb reset" can be called multiple times. Signed-off-by: Stefan Roese Cc: Remy Bohmer --- drivers/usb/host/ehci-hcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index c7de6f054..6eb38a413 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -230,7 +230,7 @@ static int ehci_reset(void) int ret = 0; cmd = ehci_readl(&hcor->or_usbcmd); - cmd |= CMD_RESET; + cmd = (cmd & ~CMD_RUN) | CMD_RESET; ehci_writel(&hcor->or_usbcmd, cmd); ret = handshake((uint32_t *)&hcor->or_usbcmd, CMD_RESET, 0, 250 * 1000); if (ret < 0) { -- cgit v1.2.3 From a42a9d71b58a789d3c4a1fbfbf400f65699a2689 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 26 Nov 2010 15:43:44 +0100 Subject: usb: Remove usb_dev_init() from ehci-ppc4xx.c Calling usb_dev_init() from within the EHCI host driver is wrong. The EHCI host driver should have no dependency/interconnection to the USB device driver. Signed-off-by: Stefan Roese Cc: Remy Bohmer --- drivers/usb/host/ehci-ppc4xx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/host/ehci-ppc4xx.c b/drivers/usb/host/ehci-ppc4xx.c index 946a0a07e..117991998 100644 --- a/drivers/usb/host/ehci-ppc4xx.c +++ b/drivers/usb/host/ehci-ppc4xx.c @@ -34,7 +34,6 @@ int ehci_hcd_init(void) hccr = (struct ehci_hccr *)(CONFIG_SYS_PPC4XX_USB_ADDR); hcor = (struct ehci_hcor *)((uint32_t) hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); - usb_dev_init(); return 0; } -- cgit v1.2.3