From 3d65fce90bbcd131288011c7d6014de6be88ecce Mon Sep 17 00:00:00 2001 From: mpi Date: Fri, 8 Aug 2014 14:28:02 +0000 Subject: [PATCH] Improve the logic to determine the maximum endpoint service interface time payload. Super speed companion descriptor are still not used but at least we can properly initialize super speed interrupt pipes. --- sys/dev/usb/xhci.c | 45 +++++++++++++++++++++++++++++-------------- sys/dev/usb/xhcireg.h | 23 ++++++++-------------- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index 7a3afac5f6f..2437d6039e2 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xhci.c,v 1.18 2014/08/08 14:22:45 mpi Exp $ */ +/* $OpenBSD: xhci.c,v 1.19 2014/08/08 14:28:02 mpi Exp $ */ /* * Copyright (c) 2014 Martin Pieuchot @@ -932,23 +932,40 @@ xhci_pipe_open(struct usbd_pipe *pipe) return (USBD_NORMAL_COMPLETION); } +/* + * Set the maximum Endpoint Service Interface Time (ESIT) payload and + * the average TRB buffer length for an endpoint. + */ static inline uint32_t -xhci_endpoint_txinfo(struct xhci_softc *sc, usb_endpoint_descriptor_t *ed) +xhci_get_txinfo(struct xhci_softc *sc, struct usbd_pipe *pipe) { + usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc; + uint32_t mep, atl, mps = UGETW(ed->wMaxPacketSize); + switch (ed->bmAttributes & UE_XFERTYPE) { case UE_CONTROL: - return (XHCI_EPCTX_AVG_TRB_LEN(8)); - case UE_BULK: - return (0); + mep = 0; + atl = 8; + break; case UE_INTERRUPT: case UE_ISOCHRONOUS: - default: + if (pipe->device->speed == USB_SPEED_SUPER) { + /* XXX Read the companion descriptor */ + } + + mep = (UE_GET_TRANS(mps) | 0x1) * UE_GET_SIZE(mps); + atl = min(sc->sc_pagesize, mep); break; + case UE_BULK: + default: + mep = 0; + atl = 0; } - DPRINTF(("%s: partial stub\n", __func__)); + DPRINTF(("%s: max ESIT payload = %u, average TRB length = %u\n", + DEVNAME(sc), mep, atl)); - return (XHCI_EPCTX_MAX_ESIT_PAYLOAD(0) | XHCI_EPCTX_AVG_TRB_LEN(0)); + return (XHCI_EPCTX_MAX_ESIT_PAYLOAD(mep) | XHCI_EPCTX_AVG_TRB_LEN(atl)); } int @@ -1031,7 +1048,7 @@ xhci_pipe_init(struct xhci_softc *sc, struct usbd_pipe *pipe, uint32_t port) } /* XXX Until we fix wMaxPacketSize for ctrl ep depending on the speed */ - mps = max(mps, UGETW(ed->wMaxPacketSize)); + mps = max(mps, UE_GET_SIZE(UGETW(ed->wMaxPacketSize))); if (pipe->interval != USBD_DEFAULT_INTERVAL) ival = min(ival, pipe->interval); @@ -1054,7 +1071,7 @@ xhci_pipe_init(struct xhci_softc *sc, struct usbd_pipe *pipe, uint32_t port) XHCI_EPCTX_SET_MPS(mps) | XHCI_EPCTX_SET_EPTYPE(xfertype) | XHCI_EPCTX_SET_CERR(cerr) | XHCI_EPCTX_SET_MAXB(0) ); - sdev->ep_ctx[xp->dci-1]->txinfo = htole32(xhci_endpoint_txinfo(sc, ed)); + sdev->ep_ctx[xp->dci-1]->txinfo = htole32(xhci_get_txinfo(sc, pipe)); sdev->ep_ctx[xp->dci-1]->deqp = htole64( DMAADDR(&xp->ring.dma, 0) | XHCI_EPCTX_DCS ); @@ -1064,14 +1081,14 @@ xhci_pipe_init(struct xhci_softc *sc, struct usbd_pipe *pipe, uint32_t port) sdev->input_ctx->add_flags = htole32(XHCI_INCTX_MASK_DCI(xp->dci)); /* Setup the slot context */ - sdev->slot_ctx->info_lo = htole32(XHCI_SCTX_SET_DCI(xp->dci)); + sdev->slot_ctx->info_lo = htole32(XHCI_SCTX_DCI(xp->dci)); sdev->slot_ctx->info_hi = 0; sdev->slot_ctx->tt = 0; sdev->slot_ctx->state = 0; if (UE_GET_XFERTYPE(ed->bmAttributes) == UE_CONTROL) { - sdev->slot_ctx->info_lo |= htole32(XHCI_SCTX_SET_SPEED(speed)); - sdev->slot_ctx->info_hi |= htole32(XHCI_SCTX_SET_RHPORT(port)); + sdev->slot_ctx->info_lo |= htole32(XHCI_SCTX_SPEED(speed)); + sdev->slot_ctx->info_hi |= htole32(XHCI_SCTX_RHPORT(port)); } usb_syncmem(&sdev->ictx_dma, 0, sc->sc_pagesize, BUS_DMASYNC_PREWRITE); @@ -1118,7 +1135,7 @@ xhci_pipe_close(struct usbd_pipe *pipe) if (lxp != NULL && lxp != xp) break; } - sdev->slot_ctx->info_lo = htole32(XHCI_SCTX_SET_DCI(lxp->dci)); + sdev->slot_ctx->info_lo = htole32(XHCI_SCTX_DCI(lxp->dci)); /* Clear the Endpoint Context */ memset(&sdev->ep_ctx[xp->dci - 1], 0, sizeof(struct xhci_epctx)); diff --git a/sys/dev/usb/xhcireg.h b/sys/dev/usb/xhcireg.h index 6ea860468a0..2c3987031e4 100644 --- a/sys/dev/usb/xhcireg.h +++ b/sys/dev/usb/xhcireg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: xhcireg.h,v 1.2 2014/07/12 17:38:51 yuo Exp $ */ +/* $OpenBSD: xhcireg.h,v 1.3 2014/08/08 14:28:02 mpi Exp $ */ /*- * Copyright (c) 2014 Martin Pieuchot. All rights reserved. @@ -245,22 +245,15 @@ struct xhci_erseg { struct xhci_sctx { uint32_t info_lo; #define XHCI_SCTX_ROUTE(x) ((x) & 0xfffff) -#define XHCI_SCTX_SET_SPEED(x) (((x) & 0xf) << 20) -#define XHCI_SCTX_GET_SPEED(x) (((x) >> 20) & 0xf) -#define XHCI_SCTX_SET_MTT(x) (((x) & 0x1) << 25) -#define XHCI_SCTX_GET_MTT(x) (((x) >> 25) & 0x1) -#define XHCI_SCTX_SET_HUB(x) (((x) & 0x1) << 26) -#define XHCI_SCTX_GET_HUB(x) (((x) >> 26) & 0x1) -#define XHCI_SCTX_SET_DCI(x) (((x) & 0x1f) << 27) -#define XHCI_SCTX_GET_DCI(x) (((x) >> 27) & 0x1f) +#define XHCI_SCTX_SPEED(x) (((x) & 0xf) << 20) +#define XHCI_SCTX_MTT(x) (((x) & 0x1) << 25) +#define XHCI_SCTX_HUB(x) (((x) & 0x1) << 26) +#define XHCI_SCTX_DCI(x) (((x) & 0x1f) << 27) uint32_t info_hi; -#define XHCI_SCTX_SET_MAX_EL(x) ((x) & 0xffff) -#define XHCI_SCTX_GET_MAX_EL(x) ((x) & 0xffff) -#define XHCI_SCTX_SET_RHPORT(x) (((x) & 0xff) << 16) -#define XHCI_SCTX_GET_RHPORT(x) (((x) >> 16) & 0xff) -#define XHCI_SCTX_SET_NPORTS(x) (((x) & 0xff) << 24) -#define XHCI_SCTX_GET_NPORTS(x) (((x) >> 24) & 0xff) +#define XHCI_SCTX_MAX_EL(x) ((x) & 0xffff) +#define XHCI_SCTX_RHPORT(x) (((x) & 0xff) << 16) +#define XHCI_SCTX_NPORTS(x) (((x) & 0xff) << 24) uint32_t tt; #define XHCI_SCTX_TT_HUB_SID(x) ((x) & 0xff) -- 2.20.1