Date: Thu, 13 Jan 2011 20:03:55 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r217374 - head/sys/dev/usb/controller Message-ID: <201101132003.p0DK3tbE061973@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: hselasky Date: Thu Jan 13 20:03:55 2011 New Revision: 217374 URL: http://svn.freebsd.org/changeset/base/217374 Log: - Add support for 64-byte contexts to XHCI driver. - Remove some dead code. - Fixed one instance of missing endian conversion. Approved by: thompsa (mentor) Modified: head/sys/dev/usb/controller/xhci.c head/sys/dev/usb/controller/xhci.h Modified: head/sys/dev/usb/controller/xhci.c ============================================================================== --- head/sys/dev/usb/controller/xhci.c Thu Jan 13 19:25:15 2011 (r217373) +++ head/sys/dev/usb/controller/xhci.c Thu Jan 13 20:03:55 2011 (r217374) @@ -133,6 +133,12 @@ static usb_error_t xhci_configure_mask(s 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); +#ifdef USB_DEBUG +static uint64_t xhci_ctx_get_le64(struct xhci_softc *sc, volatile uint64_t *ptr); +#endif extern struct usb_bus_methods xhci_bus_methods; @@ -147,26 +153,26 @@ xhci_dump_trb(struct xhci_trb *trb) } 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 @@ -188,6 +194,60 @@ xhci_iterate_hw_softc(struct usb_bus *bu } } +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 */ + /* all contexts are initially 32-bytes */ + offset = ((uintptr_t)ptr) & ((XHCI_PAGE_SIZE - 1) & ~(31U)); + 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 */ + /* all contexts are initially 32-bytes */ + offset = ((uintptr_t)ptr) & ((XHCI_PAGE_SIZE - 1) & ~(31U)); + 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 */ + /* all contexts are initially 32-bytes */ + offset = ((uintptr_t)ptr) & ((XHCI_PAGE_SIZE - 1) & ~(31U)); + 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 */ + /* all contexts are initially 32-bytes */ + offset = ((uintptr_t)ptr) & ((XHCI_PAGE_SIZE - 1) & ~(31U)); + ptr = (volatile uint64_t *)(((volatile uint8_t *)ptr) + offset); + } + return (le64toh(*ptr)); +} +#endif + usb_error_t xhci_start_controller(struct xhci_softc *sc) { @@ -221,9 +281,11 @@ xhci_start_controller(struct xhci_softc DPRINTF("HCS0 = 0x%08x\n", temp); if (XHCI_HCS0_CSZ(temp)) { - device_printf(sc->sc_bus.parent, "Driver does not " - "support 64-byte contexts."); - return (USB_ERR_IOERROR); + sc->sc_ctx_is_64_byte = 1; + device_printf(sc->sc_bus.parent, "64 byte context size.\n"); + } else { + sc->sc_ctx_is_64_byte = 0; + device_printf(sc->sc_bus.parent, "32 byte context size.\n"); } /* Reset controller */ @@ -1126,6 +1188,7 @@ xhci_set_address(struct usb_device *udev struct xhci_hw_dev *hdev; struct xhci_dev_ctx *pdev; struct xhci_endpoint_ext *pepext; + uint32_t temp; uint16_t mps; usb_error_t err; uint8_t index; @@ -1203,7 +1266,9 @@ xhci_set_address(struct usb_device *udev usbd_get_page(&hdev->device_pc, 0, &buf_dev); pdev = buf_dev.buffer; usb_pc_cpu_invalidate(&hdev->device_pc); - udev->address = XHCI_SCTX_3_DEV_ADDR_GET(pdev->ctx_slot.dwSctx3); + + temp = xhci_ctx_get_le32(sc, &pdev->ctx_slot.dwSctx3); + udev->address = XHCI_SCTX_3_DEV_ADDR_GET(temp); /* update device state to new value */ @@ -1963,11 +2028,11 @@ xhci_configure_mask(struct usb_device *u if (drop) { mask &= XHCI_INCTX_NON_CTRL_MASK; - pinp->ctx_input.dwInCtx0 = htole32(mask); - pinp->ctx_input.dwInCtx1 = 0; + xhci_ctx_set_le32(sc, &pinp->ctx_input.dwInCtx0, mask); + xhci_ctx_set_le32(sc, &pinp->ctx_input.dwInCtx1, 0); } else { - pinp->ctx_input.dwInCtx0 = 0; - pinp->ctx_input.dwInCtx1 = htole32(mask); + xhci_ctx_set_le32(sc, &pinp->ctx_input.dwInCtx0, 0); + xhci_ctx_set_le32(sc, &pinp->ctx_input.dwInCtx1, mask); } return (0); } @@ -2049,7 +2114,7 @@ xhci_configure_endpoint(struct usb_devic break; } - pinp->ctx_ep[epno - 1].dwEpCtx0 = htole32(temp); + xhci_ctx_set_le32(sc, &pinp->ctx_ep[epno - 1].dwEpCtx0, temp); temp = XHCI_EPCTX_1_HID_SET(0) | @@ -2080,11 +2145,11 @@ xhci_configure_endpoint(struct usb_devic if (epno & 1) temp |= XHCI_EPCTX_1_EPTYPE_SET(4); - pinp->ctx_ep[epno - 1].dwEpCtx1 = htole32(temp); + xhci_ctx_set_le32(sc, &pinp->ctx_ep[epno - 1].dwEpCtx1, temp); ring_addr |= XHCI_EPCTX_2_DCS_SET(1); - pinp->ctx_ep[epno - 1].qwEpCtx2 = htole64(ring_addr); + xhci_ctx_set_le64(sc, &pinp->ctx_ep[epno - 1].qwEpCtx2, ring_addr); switch (edesc->bmAttributes & UE_XFERTYPE) { case UE_INTERRUPT: @@ -2101,10 +2166,10 @@ xhci_configure_endpoint(struct usb_devic break; } - pinp->ctx_ep[epno - 1].dwEpCtx4 = htole32(temp); + xhci_ctx_set_le32(sc, &pinp->ctx_ep[epno - 1].dwEpCtx4, temp); #ifdef USB_DEBUG - xhci_dump_endpoint(&pinp->ctx_ep[epno - 1]); + xhci_dump_endpoint(sc, &pinp->ctx_ep[epno - 1]); #endif usb_pc_cpu_flush(&sc->sc_hw.devs[index].input_pc); @@ -2137,12 +2202,9 @@ static usb_error_t xhci_configure_device(struct usb_device *udev) { struct xhci_softc *sc = XHCI_BUS2SC(udev->bus); - struct usb_page_search buf_dev; struct usb_page_search buf_inp; - struct usb_page_cache *pcdev; struct usb_page_cache *pcinp; struct xhci_input_dev_ctx *pinp; - struct xhci_dev_ctx *pdev; struct usb_device *hubdev; uint32_t temp; uint32_t route; @@ -2154,13 +2216,10 @@ xhci_configure_device(struct usb_device DPRINTF("index=%u\n", index); - pcdev = &sc->sc_hw.devs[index].device_pc; pcinp = &sc->sc_hw.devs[index].input_pc; - usbd_get_page(pcdev, 0, &buf_dev); usbd_get_page(pcinp, 0, &buf_inp); - pdev = buf_dev.buffer; pinp = buf_inp.buffer; rh_port = 0; @@ -2231,7 +2290,7 @@ xhci_configure_device(struct usb_device #endif } - pinp->ctx_slot.dwSctx0 = htole32(temp); + xhci_ctx_set_le32(sc, &pinp->ctx_slot.dwSctx0, temp); temp = XHCI_SCTX_1_RH_PORT_SET(rh_port); @@ -2257,7 +2316,7 @@ xhci_configure_device(struct usb_device break; } - pinp->ctx_slot.dwSctx1 = htole32(temp); + xhci_ctx_set_le32(sc, &pinp->ctx_slot.dwSctx1, temp); temp = XHCI_SCTX_2_IRQ_TARGET_SET(0); @@ -2281,15 +2340,15 @@ xhci_configure_device(struct usb_device break; } - pinp->ctx_slot.dwSctx2 = htole32(temp); + xhci_ctx_set_le32(sc, &pinp->ctx_slot.dwSctx2, temp); temp = XHCI_SCTX_3_DEV_ADDR_SET(udev->address) | XHCI_SCTX_3_SLOT_STATE_SET(0); - pinp->ctx_slot.dwSctx3 = htole32(temp); + xhci_ctx_set_le32(sc, &pinp->ctx_slot.dwSctx3, temp); #ifdef USB_DEBUG - xhci_dump_device(&pinp->ctx_slot); + xhci_dump_device(sc, &pinp->ctx_slot); #endif usb_pc_cpu_flush(pcinp); @@ -2317,7 +2376,9 @@ xhci_alloc_device_ext(struct usb_device /* need to initialize the page cache */ pc->tag_parent = sc->sc_bus.dma_parent_tag; - if (usb_pc_alloc_mem(pc, pg, sizeof(struct xhci_dev_ctx), XHCI_PAGE_SIZE)) + if (usb_pc_alloc_mem(pc, pg, sc->sc_ctx_is_64_byte ? + (2 * sizeof(struct xhci_dev_ctx)) : + sizeof(struct xhci_dev_ctx), XHCI_PAGE_SIZE)) goto error; usbd_get_page(pc, 0, &buf_dev); @@ -2328,7 +2389,9 @@ xhci_alloc_device_ext(struct usb_device /* need to initialize the page cache */ pc->tag_parent = sc->sc_bus.dma_parent_tag; - if (usb_pc_alloc_mem(pc, pg, sizeof(struct xhci_input_dev_ctx), XHCI_PAGE_SIZE)) + if (usb_pc_alloc_mem(pc, pg, sc->sc_ctx_is_64_byte ? + (2 * sizeof(struct xhci_input_dev_ctx)) : + sizeof(struct xhci_input_dev_ctx), XHCI_PAGE_SIZE)) goto error; pc = &sc->sc_hw.devs[index].endpoint_pc; @@ -3347,13 +3410,10 @@ static usb_error_t xhci_configure_reset_endpoint(struct usb_xfer *xfer) { struct xhci_softc *sc = XHCI_BUS2SC(xfer->xroot->bus); - struct usb_page_search buf_dev; struct usb_page_search buf_inp; struct usb_device *udev; struct xhci_endpoint_ext *pepext; struct usb_endpoint_descriptor *edesc; - struct xhci_dev_ctx *pdctx; - struct usb_page_cache *pcdev; struct usb_page_cache *pcinp; usb_error_t err; uint8_t index; @@ -3365,14 +3425,10 @@ xhci_configure_reset_endpoint(struct usb udev = xfer->xroot->udev; index = udev->controller_slot_id; - pcdev = &sc->sc_hw.devs[index].device_pc; pcinp = &sc->sc_hw.devs[index].input_pc; - usbd_get_page(pcdev, 0, &buf_dev); usbd_get_page(pcinp, 0, &buf_inp); - pdctx = buf_dev.buffer; - edesc = xfer->endpoint->edesc; epno = edesc->bEndpointAddress; Modified: head/sys/dev/usb/controller/xhci.h ============================================================================== --- head/sys/dev/usb/controller/xhci.h Thu Jan 13 19:25:15 2011 (r217373) +++ head/sys/dev/usb/controller/xhci.h Thu Jan 13 20:03:55 2011 (r217374) @@ -477,6 +477,9 @@ struct xhci_softc { uint8_t sc_conf; uint8_t sc_hub_idata[2]; + /* size of context */ + uint8_t sc_ctx_is_64_byte; + /* vendor string for root HUB */ char sc_vendor[16]; };
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201101132003.p0DK3tbE061973>