]> git.ipfire.org Git - people/ms/u-boot.git/blobdiff - drivers/usb/host/ehci-hcd.c
Merge branch 'master' of git://git.denx.de/u-boot-imx
[people/ms/u-boot.git] / drivers / usb / host / ehci-hcd.c
index 7784d92b6f6178281be7da45522134c69916ce9f..6eb38a4131f0ed83c905f21af4237b3bfbb2b5a8 100644 (file)
@@ -25,6 +25,7 @@
 #include <usb.h>
 #include <asm/io.h>
 #include <malloc.h>
+#include <watchdog.h>
 
 #include "ehci.h"
 
@@ -205,12 +206,12 @@ static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
        uint32_t result;
        do {
                result = ehci_readl(ptr);
+               udelay(5);
                if (result == ~(uint32_t)0)
                        return -1;
                result &= mask;
                if (result == done)
                        return 0;
-               udelay(1);
                usec--;
        } while (usec > 0);
        return -1;
@@ -229,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) {
@@ -275,7 +276,7 @@ static void *ehci_alloc(size_t sz, size_t align)
                return NULL;
        }
 
-       memset(p, sz, 0);
+       memset(p, 0, sz);
        return p;
 }
 
@@ -288,6 +289,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
        idx = 0;
        while (idx < 5) {
                td->qt_buffer[idx] = cpu_to_hc32(addr);
+               td->qt_buffer_hi[idx] = 0;
                next = (addr + 4096) & ~4095;
                delta = next - addr;
                if (delta >= sz)
@@ -350,7 +352,6 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
            (dev->parent->devnum << 16) | (0 << 8) | (0 << 0);
        qh->qh_endpt2 = cpu_to_hc32(endpt);
        qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
-       qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
 
        td = NULL;
        tdp = &qh->qh_overlay.qt_next;
@@ -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. */
@@ -491,6 +493,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);