aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShengYi Hung <aokblast@FreeBSD.org>2025-07-18 14:26:37 +0000
committerShengYi Hung <aokblast@FreeBSD.org>2025-07-23 15:50:59 +0000
commit48266828f5bb2cd9f0f7b69ce8eb5568e75a8b22 (patch)
treedaeb2171154e80fcb7faaf6266f4f6d92d04fea9
parent4b5ed4ef606b9dbf6189f3c445f32f36d26b8ecf (diff)
bhyve: use speed in hci to allow backend modify it.
The speed of a USB device may be determined dynamically by the backend. For example, USB device passthrough depends on the internal device reporting its speed accurately. To accommodate this, we now obtain the speed from the USB HCI rather than initializing it statically from the UE structure. If the backend does not provide a speed, we fall back to the value in the UE structure. Reviewed by: emaste Approved by: markj (mentor), lwhsu (mentor) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D51411
-rw-r--r--usr.sbin/bhyve/pci_xhci.c11
-rw-r--r--usr.sbin/bhyve/usb_emul.h1
2 files changed, 8 insertions, 4 deletions
diff --git a/usr.sbin/bhyve/pci_xhci.c b/usr.sbin/bhyve/pci_xhci.c
index 5b21361f2823..29001755cbbf 100644
--- a/usr.sbin/bhyve/pci_xhci.c
+++ b/usr.sbin/bhyve/pci_xhci.c
@@ -2588,7 +2588,7 @@ pci_xhci_reset_port(struct pci_xhci_softc *sc, int portn, int warm)
if (dev) {
port->portsc &= ~(XHCI_PS_PLS_MASK | XHCI_PS_PR | XHCI_PS_PRC);
port->portsc |= XHCI_PS_PED |
- XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed);
+ XHCI_PS_SPEED_SET(dev->hci.hci_speed);
if (warm && dev->dev_ue->ue_usbver == 3) {
port->portsc |= XHCI_PS_WRC;
@@ -2622,11 +2622,11 @@ pci_xhci_init_port(struct pci_xhci_softc *sc, int portn)
if (dev->dev_ue->ue_usbver == 2) {
port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_POLL) |
- XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed);
+ XHCI_PS_SPEED_SET(dev->hci.hci_speed);
} else {
port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_U0) |
- XHCI_PS_PED | /* enabled */
- XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed);
+ XHCI_PS_PED | /* enabled */
+ XHCI_PS_SPEED_SET(dev->hci.hci_speed);
}
DPRINTF(("Init port %d 0x%x", portn, port->portsc));
@@ -2833,6 +2833,7 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl)
dev->hci.hci_sc = dev;
dev->hci.hci_intr = pci_xhci_dev_intr;
dev->hci.hci_event = pci_xhci_dev_event;
+ dev->hci.hci_speed = USB_SPEED_MAX;
if (ue->ue_usbver == 2) {
if (usb2_port == sc->usb2_port_start +
@@ -2863,6 +2864,8 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl)
dev->dev_ue = ue;
dev->dev_sc = devsc;
+ if (dev->hci.hci_speed == USB_SPEED_MAX)
+ dev->hci.hci_speed = ue->ue_usbspeed;
XHCI_SLOTDEV_PTR(sc, slot) = dev;
ndevices++;
diff --git a/usr.sbin/bhyve/usb_emul.h b/usr.sbin/bhyve/usb_emul.h
index 8e0afcb2878b..85dedfeacd3b 100644
--- a/usr.sbin/bhyve/usb_emul.h
+++ b/usr.sbin/bhyve/usb_emul.h
@@ -85,6 +85,7 @@ struct usb_hci {
/* controller managed fields */
int hci_address;
int hci_port;
+ int hci_speed;
};
/*