mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
bhyve: Populate the device version from the backend
The pci_xhci driver requires the USB device version to be known before allocating a hub port. To support this, we split the original xHCI initialization into two phases: 1. Probe: Parse the nvlist and determine the device version. 2. Init: Complete initialization and set up the softc details. This change ensures proper hub port allocation based on accurate device version. Approved by: markj (mentor) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D51478
This commit is contained in:
1 parent
bc59895909
commit
ec99803ad7
3 files changed
+39
-13
No files matched your search
+25
-10
@@ -406,7 +406,7 @@ pci_xhci_usbcmd_write(struct pci_xhci_softc *sc, uint32_t cmd)
|
||||
* XHCI 4.19.3 USB2 RxDetect->Polling,
|
||||
* USB3 Polling->U0
|
||||
*/
|
||||
if (dev->dev_ue->ue_usbver == 2)
|
||||
if (dev->hci.hci_usbver == 2)
|
||||
port->portsc |=
|
||||
XHCI_PS_PLS_SET(UPS_PORT_LS_POLL);
|
||||
else
|
||||
@@ -2590,7 +2590,7 @@ pci_xhci_reset_port(struct pci_xhci_softc *sc, int portn, int warm)
|
||||
port->portsc |= XHCI_PS_PED |
|
||||
XHCI_PS_SPEED_SET(dev->hci.hci_speed);
|
||||
|
||||
if (warm && dev->dev_ue->ue_usbver == 3) {
|
||||
if (warm && dev->hci.hci_usbver == 3) {
|
||||
port->portsc |= XHCI_PS_WRC;
|
||||
}
|
||||
|
||||
@@ -2620,7 +2620,7 @@ pci_xhci_init_port(struct pci_xhci_softc *sc, int portn)
|
||||
port->portsc = XHCI_PS_CCS | /* connected */
|
||||
XHCI_PS_PP; /* port power */
|
||||
|
||||
if (dev->dev_ue->ue_usbver == 2) {
|
||||
if (dev->hci.hci_usbver == 2) {
|
||||
port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_POLL) |
|
||||
XHCI_PS_SPEED_SET(dev->hci.hci_speed);
|
||||
} else {
|
||||
@@ -2785,8 +2785,8 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl)
|
||||
|
||||
cookie = NULL;
|
||||
while ((name = nvlist_next(slots_nvl, &type, &cookie)) != NULL) {
|
||||
if (usb2_port == ((sc->usb2_port_start) + XHCI_MAX_DEVS/2) ||
|
||||
usb3_port == ((sc->usb3_port_start) + XHCI_MAX_DEVS/2)) {
|
||||
if (usb2_port == ((sc->usb2_port_start) + XHCI_MAX_DEVS / 2) ||
|
||||
usb3_port == ((sc->usb3_port_start) + XHCI_MAX_DEVS / 2)) {
|
||||
WPRINTF(("pci_xhci max number of USB 2 or 3 "
|
||||
"devices reached, max %d", XHCI_MAX_DEVS/2));
|
||||
goto bad;
|
||||
@@ -2834,12 +2834,25 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl)
|
||||
dev->hci.hci_intr = pci_xhci_dev_intr;
|
||||
dev->hci.hci_event = pci_xhci_dev_event;
|
||||
dev->hci.hci_speed = USB_SPEED_MAX;
|
||||
dev->hci.hci_usbver = -1;
|
||||
|
||||
if (ue->ue_usbver == 2) {
|
||||
devsc = ue->ue_probe(&dev->hci, nvl);
|
||||
if (devsc == NULL) {
|
||||
free(dev);
|
||||
goto bad;
|
||||
}
|
||||
dev->dev_sc = devsc;
|
||||
|
||||
if (dev->hci.hci_usbver == -1)
|
||||
dev->hci.hci_usbver = ue->ue_usbver;
|
||||
|
||||
if (dev->hci.hci_usbver == 2) {
|
||||
if (usb2_port == sc->usb2_port_start +
|
||||
XHCI_MAX_DEVS / 2) {
|
||||
WPRINTF(("pci_xhci max number of USB 2 devices "
|
||||
"reached, max %d", XHCI_MAX_DEVS / 2));
|
||||
free(dev->dev_sc);
|
||||
free(dev);
|
||||
goto bad;
|
||||
}
|
||||
dev->hci.hci_port = usb2_port;
|
||||
@@ -2849,6 +2862,8 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl)
|
||||
XHCI_MAX_DEVS / 2) {
|
||||
WPRINTF(("pci_xhci max number of USB 3 devices "
|
||||
"reached, max %d", XHCI_MAX_DEVS / 2));
|
||||
free(dev->dev_sc);
|
||||
free(dev);
|
||||
goto bad;
|
||||
}
|
||||
dev->hci.hci_port = usb3_port;
|
||||
@@ -2857,13 +2872,10 @@ pci_xhci_parse_devices(struct pci_xhci_softc *sc, nvlist_t *nvl)
|
||||
XHCI_DEVINST_PTR(sc, dev->hci.hci_port) = dev;
|
||||
|
||||
dev->hci.hci_address = 0;
|
||||
devsc = ue->ue_init(&dev->hci, nvl);
|
||||
if (devsc == NULL) {
|
||||
if (ue->ue_init(dev->dev_sc))
|
||||
goto bad;
|
||||
}
|
||||
|
||||
dev->dev_ue = ue;
|
||||
dev->dev_sc = devsc;
|
||||
if (dev->hci.hci_speed == USB_SPEED_MAX)
|
||||
dev->hci.hci_speed = ue->ue_usbspeed;
|
||||
|
||||
@@ -2885,6 +2897,8 @@ portsfinal:
|
||||
|
||||
bad:
|
||||
for (i = 1; i <= XHCI_MAX_DEVS; i++) {
|
||||
if (XHCI_DEVINST_PTR(sc, i) != NULL)
|
||||
free(XHCI_DEVINST_PTR(sc, i)->dev_sc);
|
||||
free(XHCI_DEVINST_PTR(sc, i));
|
||||
}
|
||||
|
||||
@@ -3232,6 +3246,7 @@ pci_xhci_snapshot(struct vm_snapshot_meta *meta)
|
||||
SNAPSHOT_VAR_OR_LEAVE(dev->hci.hci_address, meta, ret, done);
|
||||
SNAPSHOT_VAR_OR_LEAVE(dev->hci.hci_port, meta, ret, done);
|
||||
SNAPSHOT_VAR_OR_LEAVE(dev->hci.hci_speed, meta, ret, done);
|
||||
SNAPSHOT_VAR_OR_LEAVE(dev->hci.hci_usbver, meta, ret, done);
|
||||
}
|
||||
|
||||
SNAPSHOT_VAR_OR_LEAVE(sc->usb2_port_start, meta, ret, done);
|
||||
|
||||
@@ -52,7 +52,8 @@ struct usb_devemu {
|
||||
int ue_usbspeed; /* usb device speed */
|
||||
|
||||
/* instance creation */
|
||||
void *(*ue_init)(struct usb_hci *hci, nvlist_t *nvl);
|
||||
void *(*ue_probe)(struct usb_hci *hci, nvlist_t *nvl);
|
||||
int (*ue_init)(void *sc);
|
||||
|
||||
/* handlers */
|
||||
int (*ue_request)(void *sc, struct usb_data_xfer *xfer);
|
||||
@@ -86,6 +87,7 @@ struct usb_hci {
|
||||
int hci_address;
|
||||
int hci_port;
|
||||
int hci_speed;
|
||||
int hci_usbver;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -295,20 +295,28 @@ umouse_event(uint8_t button, int x, int y, void *arg)
|
||||
}
|
||||
|
||||
static void *
|
||||
umouse_init(struct usb_hci *hci, nvlist_t *nvl __unused)
|
||||
umouse_probe(struct usb_hci *hci, nvlist_t *nvl __unused)
|
||||
{
|
||||
struct umouse_softc *sc;
|
||||
|
||||
sc = calloc(1, sizeof(struct umouse_softc));
|
||||
sc->hci = hci;
|
||||
|
||||
return (sc);
|
||||
}
|
||||
|
||||
static int
|
||||
umouse_init(void *scarg)
|
||||
{
|
||||
struct umouse_softc *sc = (struct umouse_softc *)scarg;
|
||||
|
||||
sc->hid.protocol = 1; /* REPORT protocol */
|
||||
pthread_mutex_init(&sc->mtx, NULL);
|
||||
pthread_mutex_init(&sc->ev_mtx, NULL);
|
||||
|
||||
console_ptr_register(umouse_event, sc, 10);
|
||||
|
||||
return (sc);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#define UREQ(x,y) ((x) | ((y) << 8))
|
||||
@@ -811,6 +819,7 @@ static struct usb_devemu ue_mouse = {
|
||||
.ue_emu = "tablet",
|
||||
.ue_usbver = 3,
|
||||
.ue_usbspeed = USB_SPEED_HIGH,
|
||||
.ue_probe = umouse_probe,
|
||||
.ue_init = umouse_init,
|
||||
.ue_request = umouse_request,
|
||||
.ue_data = umouse_data_handler,
|
||||
|
||||
Reference in new issue
Block a user