USB: sync Queue Element Transfer Descriptor against EHCI spec
authorWolfgang Denk <wd@denx.de>
Tue, 19 Oct 2010 14:13:15 +0000 (16:13 +0200)
committerWolfgang Denk <wd@denx.de>
Tue, 19 Oct 2010 22:23:57 +0000 (00:23 +0200)
Appendix B "EHCI 64-Bit Data Structures" of the "Enhanced Host
Controller Interface Specification for Universal Serial Bus" (Rev.
1.0, March 12, 2002) defines additional fields which were missing in
U-Boot's struct qTD; as these are also present in recent versions of
struct ehci_qtd in the Linux kernel, we add them here, too.

This fixes some nasty memory corruption problems.

Reported-by: Dan Lykowski <lykowdk@gmail.com>
See http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/76942

Signed-off-by: Wolfgang Denk <wd@denx.de>
Cc: Remy Bohmer <linux@bohmer.net>
Cc: Dan Lykowski <lykowdk@gmail.com>
Cc: Stefano Babic <sbabic@denx.de>
Tested-by: Stefano Babic <sbabic@denx.de>
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci.h

index 37d056e005793c2bcd5607503ae72fd2abde4c8d..f44fc4e3c4b693117979078adf55d692d83002be 100644 (file)
@@ -288,6 +288,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)
index 6fae8baf9505972e4403dc7bba46e53f78ac6592..d3aa55b4a6c70a40ff6f584b22ca8b482b4d7c4e 100644 (file)
@@ -166,12 +166,16 @@ struct usb_linux_config_descriptor {
 
 /* Queue Element Transfer Descriptor (qTD). */
 struct qTD {
-       uint32_t qt_next;
+       /* this part defined by EHCI spec */
+       uint32_t qt_next;               /* see EHCI 3.5.1 */
 #define        QT_NEXT_TERMINATE       1
-       uint32_t qt_altnext;
-       uint32_t qt_token;
-       uint32_t qt_buffer[5];
-};
+       uint32_t qt_altnext;            /* see EHCI 3.5.2 */
+       uint32_t qt_token;              /* see EHCI 3.5.3 */
+       uint32_t qt_buffer[5];          /* see EHCI 3.5.4 */
+       uint32_t qt_buffer_hi[5];       /* Appendix B */
+       /* pad struct for 32 byte alignment */
+       uint32_t unused[3];
+} __attribute__ ((aligned (32)));
 
 /* Queue Head (QH). */
 struct QH {