xHCI has up to 15 root ports and does not need a hub to fit more devices. Add auto-hub and leave it off. hw_compat_11_1 turns it on, so an older machine type keeps the hub it has today and a guest saved by an older QEMU still loads.
Suggested-by: Gerd Hoffmann <[email protected]> Reported-by: Junjie Cao <[email protected]> Signed-off-by: Jamin Lin <[email protected]> --- hw/usb/hcd-xhci.h | 1 + hw/core/machine.c | 1 + hw/usb/hcd-xhci.c | 2 ++ 3 files changed, 4 insertions(+) diff --git a/hw/usb/hcd-xhci.h b/hw/usb/hcd-xhci.h index 5cb9e06d1d..a3eaf2ebb6 100644 --- a/hw/usb/hcd-xhci.h +++ b/hw/usb/hcd-xhci.h @@ -191,6 +191,7 @@ typedef struct XHCIState { uint32_t numslots; uint32_t flags; uint32_t max_pstreams_mask; + bool auto_hub; void (*intr_update)(XHCIState *s, int n, bool enable); bool (*intr_raise)(XHCIState *s, int n, bool level); /* diff --git a/hw/core/machine.c b/hw/core/machine.c index d9ac4b419a..f8f5b01117 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -43,6 +43,7 @@ GlobalProperty hw_compat_11_1[] = { { "sysbus-ehci-usb", "x-migrate-fetch-addr-64bit", "off" }, { "pci-ehci-usb", "x-migrate-fetch-addr-64bit", "off" }, + { "base-xhci", "auto-hub", "on" }, }; const size_t hw_compat_11_1_len = G_N_ELEMENTS(hw_compat_11_1); diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 376bc00264..1e42c851b4 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -3377,6 +3377,7 @@ static void usb_xhci_init(XHCIState *xhci) xhci->numports = xhci->numports_2 + xhci->numports_3; usb_bus_new(&xhci->bus, sizeof(xhci->bus), &xhci_bus_ops, xhci->hostOpaque); + xhci->bus.auto_hub = xhci->auto_hub; for (i = 0; i < usbports; i++) { speedmask = 0; @@ -3660,6 +3661,7 @@ static const Property xhci_properties[] = { DEFINE_PROP_UINT32("p3", XHCIState, numports_3, 4), DEFINE_PROP_LINK("host", XHCIState, hostOpaque, TYPE_DEVICE, DeviceState *), + DEFINE_PROP_BOOL("auto-hub", XHCIState, auto_hub, false), }; static void xhci_class_init(ObjectClass *klass, const void *data) -- 2.43.0
