diff options
Diffstat (limited to 'usr/src/cmd/bhyve/pci_xhci.c')
-rw-r--r-- | usr/src/cmd/bhyve/pci_xhci.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/usr/src/cmd/bhyve/pci_xhci.c b/usr/src/cmd/bhyve/pci_xhci.c index 0b9fde3208..4caa32e981 100644 --- a/usr/src/cmd/bhyve/pci_xhci.c +++ b/usr/src/cmd/bhyve/pci_xhci.c @@ -167,6 +167,13 @@ struct pci_xhci_dev_ep { #define ep_tr _ep_trbsctx._epu_tr #define ep_sctx _ep_trbsctx._epu_sctx + /* + * Caches the value of MaxPStreams from the endpoint context + * when an endpoint is initialized and is used to validate the + * use of ep_ringaddr vs ep_sctx_trbs[] as well as the length + * of ep_sctx_trbs[]. + */ + uint32_t ep_MaxPStreams; union { struct pci_xhci_trb_ring _epu_trb; struct pci_xhci_trb_ring *_epu_sctx_trbs; @@ -565,7 +572,7 @@ pci_xhci_portregs_write(struct pci_xhci_softc *sc, uint64_t offset, } } -struct xhci_dev_ctx * +static struct xhci_dev_ctx * pci_xhci_get_dev_ctx(struct pci_xhci_softc *sc, uint32_t slot) { uint64_t devctx_addr; @@ -589,7 +596,7 @@ pci_xhci_get_dev_ctx(struct pci_xhci_softc *sc, uint32_t slot) return (devctx); } -struct xhci_trb * +static struct xhci_trb * pci_xhci_trb_next(struct pci_xhci_softc *sc, struct xhci_trb *curtrb, uint64_t *guestaddr) { @@ -674,6 +681,7 @@ pci_xhci_init_ep(struct pci_xhci_dev_emu *dev, int epid) devep->ep_tr = XHCI_GADDR(dev->xsc, devep->ep_ringaddr); DPRINTF(("init_ep tr DCS %x", devep->ep_ccs)); } + devep->ep_MaxPStreams = pstreams; if (devep->ep_xfer == NULL) { devep->ep_xfer = malloc(sizeof(struct usb_data_xfer)); @@ -695,9 +703,8 @@ pci_xhci_disable_ep(struct pci_xhci_dev_emu *dev, int epid) ep_ctx->dwEpCtx0 = (ep_ctx->dwEpCtx0 & ~0x7) | XHCI_ST_EPCTX_DISABLED; devep = &dev->eps[epid]; - if (XHCI_EPCTX_0_MAXP_STREAMS_GET(ep_ctx->dwEpCtx0) > 0 && - devep->ep_sctx_trbs != NULL) - free(devep->ep_sctx_trbs); + if (devep->ep_MaxPStreams > 0) + free(devep->ep_sctx_trbs); if (devep->ep_xfer != NULL) { free(devep->ep_xfer); @@ -1157,7 +1164,7 @@ pci_xhci_cmd_reset_ep(struct pci_xhci_softc *sc, uint32_t slot, ep_ctx->dwEpCtx0 = (ep_ctx->dwEpCtx0 & ~0x7) | XHCI_ST_EPCTX_STOPPED; - if (XHCI_EPCTX_0_MAXP_STREAMS_GET(ep_ctx->dwEpCtx0) == 0) + if (devep->ep_MaxPStreams == 0) ep_ctx->qwEpCtx2 = devep->ep_ringaddr | devep->ep_ccs; DPRINTF(("pci_xhci: reset ep[%u] %08x %08x %016lx %08x", @@ -1178,16 +1185,15 @@ done: static uint32_t pci_xhci_find_stream(struct pci_xhci_softc *sc, struct xhci_endp_ctx *ep, - uint32_t streamid, struct xhci_stream_ctx **osctx) + struct pci_xhci_dev_ep *devep, uint32_t streamid, + struct xhci_stream_ctx **osctx) { struct xhci_stream_ctx *sctx; - uint32_t maxpstreams; - maxpstreams = XHCI_EPCTX_0_MAXP_STREAMS_GET(ep->dwEpCtx0); - if (maxpstreams == 0) + if (devep->ep_MaxPStreams == 0) return (XHCI_TRB_ERROR_TRB); - if (maxpstreams > XHCI_STREAMS_MAX) + if (devep->ep_MaxPStreams > XHCI_STREAMS_MAX) return (XHCI_TRB_ERROR_INVALID_SID); if (XHCI_EPCTX_0_LSA_GET(ep->dwEpCtx0) == 0) { @@ -1196,7 +1202,7 @@ pci_xhci_find_stream(struct pci_xhci_softc *sc, struct xhci_endp_ctx *ep, } /* only support primary stream */ - if (streamid > maxpstreams) + if (streamid > devep->ep_MaxPStreams) return (XHCI_TRB_ERROR_STREAM_TYPE); sctx = XHCI_GADDR(sc, ep->qwEpCtx2 & ~0xFUL) + streamid; @@ -1258,11 +1264,12 @@ pci_xhci_cmd_set_tr(struct pci_xhci_softc *sc, uint32_t slot, } streamid = XHCI_TRB_2_STREAM_GET(trb->dwTrb2); - if (XHCI_EPCTX_0_MAXP_STREAMS_GET(ep_ctx->dwEpCtx0) > 0) { + if (devep->ep_MaxPStreams > 0) { struct xhci_stream_ctx *sctx; sctx = NULL; - cmderr = pci_xhci_find_stream(sc, ep_ctx, streamid, &sctx); + cmderr = pci_xhci_find_stream(sc, ep_ctx, devep, streamid, + &sctx); if (sctx != NULL) { assert(devep->ep_sctx != NULL); @@ -1632,7 +1639,7 @@ pci_xhci_update_ep_ring(struct pci_xhci_softc *sc, struct pci_xhci_dev_emu *dev, uint32_t streamid, uint64_t ringaddr, int ccs) { - if (XHCI_EPCTX_0_MAXP_STREAMS_GET(ep_ctx->dwEpCtx0) != 0) { + if (devep->ep_MaxPStreams != 0) { devep->ep_sctx[streamid].qwSctx0 = (ringaddr & ~0xFUL) | (ccs & 0x1); @@ -1959,7 +1966,7 @@ pci_xhci_device_doorbell(struct pci_xhci_softc *sc, uint32_t slot, } /* get next trb work item */ - if (XHCI_EPCTX_0_MAXP_STREAMS_GET(ep_ctx->dwEpCtx0) != 0) { + if (devep->ep_MaxPStreams != 0) { struct xhci_stream_ctx *sctx; /* @@ -1972,7 +1979,7 @@ pci_xhci_device_doorbell(struct pci_xhci_softc *sc, uint32_t slot, } sctx = NULL; - pci_xhci_find_stream(sc, ep_ctx, streamid, &sctx); + pci_xhci_find_stream(sc, ep_ctx, devep, streamid, &sctx); if (sctx == NULL) { DPRINTF(("pci_xhci: invalid stream %u", streamid)); return; @@ -2950,7 +2957,7 @@ done: return (error); } -struct pci_devemu pci_de_xhci = { +static const struct pci_devemu pci_de_xhci = { .pe_emu = "xhci", .pe_init = pci_xhci_init, .pe_legacy_config = pci_xhci_legacy_config, |