From: Wolfgang Denk Date: Tue, 19 Oct 2010 14:13:15 +0000 (+0200) Subject: USB: sync Queue Element Transfer Descriptor against EHCI spec X-Git-Tag: v2010.12-rc1~70 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=3ed16071b006dbda65070a4143db74da469f6e30;p=u-boot USB: sync Queue Element Transfer Descriptor against EHCI spec 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 See http://permalink.gmane.org/gmane.comp.boot-loaders.u-boot/76942 Signed-off-by: Wolfgang Denk Cc: Remy Bohmer Cc: Dan Lykowski Cc: Stefano Babic Tested-by: Stefano Babic --- diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 37d056e005..f44fc4e3c4 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -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) diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 6fae8baf95..d3aa55b4a6 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -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 {