summaryrefslogtreecommitdiff
path: root/usr/src/cmd/bhyve/pci_xhci.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd/bhyve/pci_xhci.c')
-rw-r--r--usr/src/cmd/bhyve/pci_xhci.c43
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,