From: Jamin Lin <jamin_lin@aspeedtech.com>
To: "kraxel@redhat.com" <kraxel@redhat.com>,
"marcandre.lureau@redhat.com" <marcandre.lureau@redhat.com>,
"junjie.cao@intel.com" <junjie.cao@intel.com>,
"junjie.cao@linux.dev" <junjie.cao@linux.dev>,
"Cédric Le Goater" <clg@kaod.org>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Kane Chen" <kane_chen@aspeedtech.com>,
"open list:ASPEED BMCs" <qemu-arm@nongnu.org>,
"open list:All patches CC here" <qemu-devel@nongnu.org>
Cc: Jamin Lin <jamin_lin@aspeedtech.com>, Troy Lee <troy_lee@aspeedtech.com>
Subject: [PATCH v7 1/8] hw/usb/bus: Let the controller ask for the automatic hub
Date: Wed, 28 Oct 2026 03:41:42 +0000 [thread overview]
Message-ID: <20261028034140.367393-2-jamin_lin@aspeedtech.com> (raw)
In-Reply-To: <20261028034140.367393-1-jamin_lin@aspeedtech.com>
usb_claim_port() plugs in a usb-hub when only one port is free, so that
more devices fit. Every bus gets that today. A controller with a single
root port then puts its only device behind a hub, and a transport that
carries one device cannot use that.
The hub speaks USB 1.1, so this belongs to UHCI and OHCI. Add auto_hub
and leave it off by default. UHCI and OHCI set it, both when they own
the bus and when they join one as a companion. dwc2 sets it too, so the
boards that use it keep working.
xHCI has up to 15 root ports, so it no longer grows a hub on its own. A
user who wants more ports there adds "-device usb-hub".
Suggested-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
include/hw/usb/usb.h | 1 +
hw/usb/bus.c | 6 +++++-
hw/usb/hcd-dwc2.c | 1 +
hw/usb/hcd-ohci.c | 1 +
hw/usb/hcd-uhci.c | 1 +
5 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/include/hw/usb/usb.h b/include/hw/usb/usb.h
index cbd4711933..cc1d6d74b1 100644
--- a/include/hw/usb/usb.h
+++ b/include/hw/usb/usb.h
@@ -484,6 +484,7 @@ struct USBBus {
int busnr;
int nfree;
int nused;
+ bool auto_hub;
QTAILQ_HEAD(, USBPort) free;
QTAILQ_HEAD(, USBPort) used;
QTAILQ_ENTRY(USBBus) next;
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 5cc5ffec33..d1ad22ac94 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -363,6 +363,9 @@ void usb_register_companion(const char *masterbus, USBPort *ports[],
return;
}
+ /* Only UHCI and OHCI come in as a companion, and both want the hub. */
+ bus->auto_hub = true;
+
for (i = 0; i < portcount; i++) {
usb_fill_port(ports[i], opaque, i, ops, speedmask);
}
@@ -413,7 +416,8 @@ void usb_claim_port(USBDevice *dev, Error **errp)
return;
}
} else {
- if (bus->nfree == 1 && strcmp(object_get_typename(OBJECT(dev)), "usb-hub") != 0) {
+ if (bus->nfree == 1 && bus->auto_hub &&
+ strcmp(object_get_typename(OBJECT(dev)), "usb-hub") != 0) {
/* Create a new hub and chain it on */
hub = USB_DEVICE(qdev_try_new("usb-hub"));
if (hub) {
diff --git a/hw/usb/hcd-dwc2.c b/hw/usb/hcd-dwc2.c
index cd3b61158d..104f493105 100644
--- a/hw/usb/hcd-dwc2.c
+++ b/hw/usb/hcd-dwc2.c
@@ -1354,6 +1354,7 @@ static void dwc2_realize(DeviceState *dev, Error **errp)
address_space_init(&s->dma_as, s->dma_mr, "dwc2");
usb_bus_new(&s->bus, sizeof(s->bus), &dwc2_bus_ops, dev);
+ s->bus.auto_hub = true;
usb_register_port(&s->bus, &s->uport, s, 0, &dwc2_port_ops,
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL |
(s->usb_version == 2 ? USB_SPEED_MASK_HIGH : 0));
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 5e5fe41f47..d6b1fc5b62 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1987,6 +1987,7 @@ void usb_ohci_init(OHCIState *ohci, DeviceState *dev, uint32_t num_ports,
}
} else {
usb_bus_new(&ohci->bus, sizeof(ohci->bus), &ohci_bus_ops, dev);
+ ohci->bus.auto_hub = true;
for (i = 0; i < num_ports; i++) {
usb_register_port(&ohci->bus, &ohci->rhport[i].port,
ohci, i, &ohci_port_ops,
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index a7b9fe1317..f11664bd55 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1213,6 +1213,7 @@ void usb_uhci_common_realize(PCIDevice *dev, Error **errp)
}
} else {
usb_bus_new(&s->bus, sizeof(s->bus), &uhci_bus_ops, DEVICE(dev));
+ s->bus.auto_hub = true;
for (i = 0; i < UHCI_PORTS; i++) {
usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops,
USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
--
2.53.0
next prev parent reply other threads:[~2026-10-28 3:42 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-28 3:41 [PATCH v7 0/8] hw/usb: Add a usbredir server transport Jamin Lin
2026-10-28 3:41 ` Jamin Lin [this message]
2026-10-29 10:09 ` [PATCH v7 1/8] hw/usb/bus: Let the controller ask for the automatic hub Junjie Cao
2026-10-29 11:33 ` Gerd Hoffmann
2026-10-29 14:49 ` Junjie Cao
2026-10-29 17:44 ` marcandre.lureau
2026-10-28 3:41 ` [PATCH v7 2/8] hw/usb/redirect-server: Add a usbredir server device Jamin Lin
2026-10-28 3:41 ` [PATCH v7 3/8] hw/usb/redirect-server: Connect usbredirparser to a chardev Jamin Lin
2026-10-28 3:41 ` [PATCH v7 4/8] hw/usb/redirect-server: Announce the exported device Jamin Lin
2026-10-29 10:09 ` Junjie Cao
2026-10-29 17:44 ` marcandre.lureau
2026-10-28 3:41 ` [PATCH v7 5/8] hw/usb/redirect-server: Implement control transfers Jamin Lin
2026-10-29 17:44 ` marcandre.lureau
2026-10-28 3:41 ` [PATCH v7 6/8] hw/usb/redirect-server: Implement bulk and interrupt transfers Jamin Lin
2026-10-29 10:09 ` Junjie Cao
2026-10-28 3:41 ` [PATCH v7 7/8] hw/usb/redirect-server: Stream interrupt IN endpoints Jamin Lin
2026-10-29 17:44 ` marcandre.lureau
2026-10-28 3:41 ` [PATCH v7 8/8] hw/arm/aspeed: Enable the usbredir server transport Jamin Lin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261028034140.367393-2-jamin_lin@aspeedtech.com \
--to=jamin_lin@aspeedtech.com \
--cc=clg@kaod.org \
--cc=junjie.cao@intel.com \
--cc=junjie.cao@linux.dev \
--cc=kane_chen@aspeedtech.com \
--cc=kraxel@redhat.com \
--cc=marcandre.lureau@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=troy_lee@aspeedtech.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.