Hi,
On Saturday 11 December 2010 02:08:37 Dwight Schauer wrote:
I'm with Texas Instruments and I'm trying to get our USB3 host
controller working with FreeBSD 8.2-BETA1
However, nothing happens when I attach a mass storage device to the
Texas Instruments USB3 host controller.
Any advice is welcome.
The mode your XHCI controller is using is currently not supported.
Please try the attached patch and report back.
--HPS
Patch xhci_context.patch level 1
Source: [No source]
Target: ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f:/head/sys/dev/usb/controller:215649 [mirrored] [updated]
(svn+ssh://hsela...@svn.freebsd.org/base)
Log:
- Add support for 64-byte contexts to XHCI driver.
- Remove some dead code.
- Fixed one instance of missing endian conversion.
MFC after: 3 days
Approved by: thompsa (mentor)
=== xhci.c
==
--- xhci.c (revision 215649)
+++ xhci.c (patch xhci_context.patch level 1)
@@ -134,6 +134,10 @@
static usb_error_t xhci_cmd_evaluate_ctx(struct xhci_softc *,
uint64_t, uint8_t);
static void xhci_endpoint_doorbell(struct usb_xfer *);
+static void xhci_ctx_set_le32(struct xhci_softc *sc, volatile uint32_t *ptr, uint32_t val);
+static uint32_t xhci_ctx_get_le32(struct xhci_softc *sc, volatile uint32_t *ptr);
+static void xhci_ctx_set_le64(struct xhci_softc *sc, volatile uint64_t *ptr, uint64_t val);
+static uint64_t xhci_ctx_get_le64(struct xhci_softc *sc, volatile uint64_t *ptr);
extern struct usb_bus_methods xhci_bus_methods;
@@ -148,26 +152,26 @@
}
static void
-xhci_dump_endpoint(struct xhci_endp_ctx *pep)
+xhci_dump_endpoint(struct xhci_softc *sc, struct xhci_endp_ctx *pep)
{
DPRINTFN(5, pep = %p\n, pep);
- DPRINTFN(5, dwEpCtx0=0x%08x\n, pep-dwEpCtx0);
- DPRINTFN(5, dwEpCtx1=0x%08x\n, pep-dwEpCtx1);
- DPRINTFN(5, qwEpCtx2=0x%016llx\n, (long long)pep-qwEpCtx2);
- DPRINTFN(5, dwEpCtx4=0x%08x\n, pep-dwEpCtx4);
- DPRINTFN(5, dwEpCtx5=0x%08x\n, pep-dwEpCtx5);
- DPRINTFN(5, dwEpCtx6=0x%08x\n, pep-dwEpCtx6);
- DPRINTFN(5, dwEpCtx7=0x%08x\n, pep-dwEpCtx7);
+ DPRINTFN(5, dwEpCtx0=0x%08x\n, xhci_ctx_get_le32(sc, pep-dwEpCtx0));
+ DPRINTFN(5, dwEpCtx1=0x%08x\n, xhci_ctx_get_le32(sc, pep-dwEpCtx1));
+ DPRINTFN(5, qwEpCtx2=0x%016llx\n, (long long)xhci_ctx_get_le64(sc, pep-qwEpCtx2));
+ DPRINTFN(5, dwEpCtx4=0x%08x\n, xhci_ctx_get_le32(sc, pep-dwEpCtx4));
+ DPRINTFN(5, dwEpCtx5=0x%08x\n, xhci_ctx_get_le32(sc, pep-dwEpCtx5));
+ DPRINTFN(5, dwEpCtx6=0x%08x\n, xhci_ctx_get_le32(sc, pep-dwEpCtx6));
+ DPRINTFN(5, dwEpCtx7=0x%08x\n, xhci_ctx_get_le32(sc, pep-dwEpCtx7));
}
static void
-xhci_dump_device(struct xhci_slot_ctx *psl)
+xhci_dump_device(struct xhci_softc *sc, struct xhci_slot_ctx *psl)
{
DPRINTFN(5, psl = %p\n, psl);
- DPRINTFN(5, dwSctx0=0x%08x\n, psl-dwSctx0);
- DPRINTFN(5, dwSctx1=0x%08x\n, psl-dwSctx1);
- DPRINTFN(5, dwSctx2=0x%08x\n, psl-dwSctx2);
- DPRINTFN(5, dwSctx3=0x%08x\n, psl-dwSctx3);
+ DPRINTFN(5, dwSctx0=0x%08x\n, xhci_ctx_get_le32(sc, psl-dwSctx0));
+ DPRINTFN(5, dwSctx1=0x%08x\n, xhci_ctx_get_le32(sc, psl-dwSctx1));
+ DPRINTFN(5, dwSctx2=0x%08x\n, xhci_ctx_get_le32(sc, psl-dwSctx2));
+ DPRINTFN(5, dwSctx3=0x%08x\n, xhci_ctx_get_le32(sc, psl-dwSctx3));
}
#endif
@@ -189,6 +193,60 @@
}
}
+static void
+xhci_ctx_set_le32(struct xhci_softc *sc, volatile uint32_t *ptr, uint32_t val)
+{
+ if (sc-sc_ctx_is_64_byte) {
+ uint32_t offset;
+ /* exploit the fact that our structures are XHCI_PAGE_SIZE aligned */
+ offset = ((uintptr_t)ptr) (XHCI_PAGE_SIZE - 1);
+ offset = ~31U; /* all contexts are initially 32-bytes */
+ ptr = (volatile uint32_t *)(((volatile uint8_t *)ptr) + offset);
+ }
+ *ptr = htole32(val);
+}
+
+static uint32_t
+xhci_ctx_get_le32(struct xhci_softc *sc, volatile uint32_t *ptr)
+{
+ if (sc-sc_ctx_is_64_byte) {
+ uint32_t offset;
+ /* exploit the fact that our structures are XHCI_PAGE_SIZE aligned */
+ offset = ((uintptr_t)ptr) (XHCI_PAGE_SIZE - 1);
+ offset = ~31U; /* all contexts are initially 32-bytes */
+ ptr = (volatile uint32_t *)(((volatile uint8_t *)ptr) + offset);
+ }
+ return (le32toh(*ptr));
+}
+
+static void
+xhci_ctx_set_le64(struct xhci_softc *sc, volatile uint64_t *ptr, uint64_t val)
+{
+ if (sc-sc_ctx_is_64_byte) {
+ uint32_t offset;
+ /* exploit the fact that our structures are XHCI_PAGE_SIZE aligned */
+ offset = ((uintptr_t)ptr) (XHCI_PAGE_SIZE - 1);
+ offset = ~31U; /* all contexts are initially 32-bytes */
+ ptr = (volatile uint64_t *)(((volatile uint8_t *)ptr) + offset);
+ }
+ *ptr = htole64(val);
+}
+
+#ifdef USB_DEBUG
+static uint64_t
+xhci_ctx_get_le64(struct xhci_softc *sc, volatile uint64_t *ptr)
+{
+ if (sc-sc_ctx_is_64_byte) {
+ uint32_t offset;
+ /* exploit the fact that our structures are XHCI_PAGE_SIZE aligned */
+ offset = ((uintptr_t)ptr) (XHCI_PAGE_SIZE - 1);
+ offset = ~31U; /* all contexts are initially 32-bytes */
+ ptr = (volatile uint64_t *)(((volatile uint8_t *)ptr) + offset);
+ }
+ return