diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2014-10-21 12:29:33 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2014-10-28 11:38:18 +0100 |
commit | 2aa6bfcb663c43775600a95719ef0c6b849188d0 (patch) | |
tree | c13086040ce45918d132493a8dbb44c59afdb07f | |
parent | 81b49e8f892a977f3821f3416ea51aa641d63ac4 (diff) |
xhci: add property to turn on/off streams support
streams support in usb-redir and usb-host works only with recent enough
versions of the support libraries (libusbredir and libusbx). Failure
mode is rather unelegant: Any stream usb transfers will throw stall
errors. Turning off support for streams in the xhci host controller
will work better as the guest can figure beforehand that streams are
not going to work.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r-- | hw/usb/hcd-xhci.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index a27c9d37fa..2930b72c1d 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -459,6 +459,7 @@ struct XHCIState { uint32_t numintrs; uint32_t numslots; uint32_t flags; + uint32_t max_pstreams_mask; /* Operational Registers */ uint32_t usbcmd; @@ -500,6 +501,7 @@ enum xhci_flags { XHCI_FLAG_USE_MSI_X, XHCI_FLAG_SS_FIRST, XHCI_FLAG_FORCE_PCIE_ENDCAP, + XHCI_FLAG_ENABLE_STREAMS, }; static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, @@ -1384,7 +1386,7 @@ static void xhci_init_epctx(XHCIEPContext *epctx, epctx->pctx = pctx; epctx->max_psize = ctx[1]>>16; epctx->max_psize *= 1+((ctx[1]>>8)&0xff); - epctx->max_pstreams = (ctx[0] >> 10) & 0xf; + epctx->max_pstreams = (ctx[0] >> 10) & epctx->xhci->max_pstreams_mask; epctx->lsa = (ctx[0] >> 15) & 1; if (epctx->max_pstreams) { xhci_alloc_streams(epctx, dequeue); @@ -2956,9 +2958,9 @@ static uint64_t xhci_cap_read(void *ptr, hwaddr reg, unsigned size) break; case 0x10: /* HCCPARAMS */ if (sizeof(dma_addr_t) == 4) { - ret = 0x00087000; + ret = 0x00080000 | (xhci->max_pstreams_mask << 12); } else { - ret = 0x00087001; + ret = 0x00080001 | (xhci->max_pstreams_mask << 12); } break; case 0x14: /* DBOFF */ @@ -3590,6 +3592,11 @@ static int usb_xhci_initfn(struct PCIDevice *dev) if (xhci->numslots < 1) { xhci->numslots = 1; } + if (xhci_get_flag(xhci, XHCI_FLAG_ENABLE_STREAMS)) { + xhci->max_pstreams_mask = 7; /* == 256 primary streams */ + } else { + xhci->max_pstreams_mask = 0; + } xhci->mfwrap_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, xhci_mfwrap_timer, xhci); @@ -3853,6 +3860,8 @@ static Property xhci_properties[] = { XHCIState, flags, XHCI_FLAG_SS_FIRST, true), DEFINE_PROP_BIT("force-pcie-endcap", XHCIState, flags, XHCI_FLAG_FORCE_PCIE_ENDCAP, false), + DEFINE_PROP_BIT("streams", XHCIState, flags, + XHCI_FLAG_ENABLE_STREAMS, true), DEFINE_PROP_UINT32("intrs", XHCIState, numintrs, MAXINTRS), DEFINE_PROP_UINT32("slots", XHCIState, numslots, MAXSLOTS), DEFINE_PROP_UINT32("p2", XHCIState, numports_2, 4), |