Page MenuHomeFreeBSD

D59785.id187025.diff
No OneTemporary

D59785.id187025.diff

diff --git a/usr.sbin/bhyve/pci_xhci.c b/usr.sbin/bhyve/pci_xhci.c
--- a/usr.sbin/bhyve/pci_xhci.c
+++ b/usr.sbin/bhyve/pci_xhci.c
@@ -359,6 +359,7 @@
static void pci_xhci_assert_interrupt(struct pci_xhci_softc *sc);
static void pci_xhci_reset_slot(struct pci_xhci_softc *sc, int slot);
static void pci_xhci_reset_port(struct pci_xhci_softc *sc, int portn, int warm);
+static void pci_xhci_init_port(struct pci_xhci_softc *sc, int portn);
static void pci_xhci_update_ep_ring(struct pci_xhci_softc *sc,
struct pci_xhci_dev_emu *dev, struct pci_xhci_dev_ep *devep,
struct xhci_endp_ctx *ep_ctx, uint32_t streamid,
@@ -500,8 +501,18 @@
}
if ((p->portsc & XHCI_PS_PP) == 0) {
- WPRINTF(("pci_xhci: portregs_write to unpowered "
- "port %d", port));
+ if (value & XHCI_PS_PP) {
+ pci_xhci_init_port(sc, port);
+ p->portsc |= XHCI_PS_CSC;
+ pci_xhci_set_evtrb(&evtrb, port,
+ XHCI_TRB_ERROR_SUCCESS,
+ XHCI_TRB_EVENT_PORT_STS_CHANGE);
+
+ pci_xhci_insert_event(sc, &evtrb, 1);
+ } else {
+ WPRINTF(("pci_xhci: portregs_write to unpowered "
+ "port %d", port));
+ }
break;
}
@@ -2708,6 +2719,34 @@
}
}
+static void
+pci_xhci_deinit_port(struct pci_xhci_softc *sc, int portn)
+{
+ struct pci_xhci_portregs *port;
+ struct pci_xhci_dev_emu *dev;
+
+ port = XHCI_PORTREG_PTR(sc, portn);
+ dev = XHCI_DEVINST_PTR(sc, portn);
+ if (dev) {
+ port->portsc &= ~(XHCI_PS_CCS | /* connected */
+ XHCI_PS_PP); /* port power */
+
+ 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 {
+ port->portsc &= ~(XHCI_PS_PLS_SET(UPS_PORT_LS_U0) |
+ XHCI_PS_PED | /* enabled */
+ XHCI_PS_SPEED_SET(dev->hci.hci_speed));
+ }
+
+ DPRINTF(("Deinit port %d 0x%x", portn, port->portsc));
+ } else {
+ port->portsc = XHCI_PS_PLS_SET(UPS_PORT_LS_RX_DET) | XHCI_PS_PP;
+ DPRINTF(("Deinit empty port %d 0x%x", portn, port->portsc));
+ }
+}
+
static int
pci_xhci_dev_intr(struct usb_hci *hci, int epctx)
{
@@ -2773,10 +2812,44 @@
}
static int
-pci_xhci_dev_event(struct usb_hci *hci, enum hci_usbev evid __unused,
+pci_xhci_dev_event(struct usb_hci *hci, enum hci_usbev evid,
void *param __unused)
{
+ struct xhci_trb evtrb;
+ struct pci_xhci_dev_emu *dev = hci->hci_sc;
+ struct pci_xhci_softc *xsc = dev->xsc;
+ struct pci_xhci_portregs *port;
+ int err;
+
+ port = XHCI_PORTREG_PTR(xsc, hci->hci_port);
DPRINTF(("xhci device event port %d", hci->hci_port));
+
+ switch (evid) {
+ case USBDEV_ATTACH:
+ pci_xhci_init_port(xsc, hci->hci_port);
+ port->portsc |= XHCI_PS_CSC;
+ pci_xhci_set_evtrb(&evtrb, hci->hci_port,
+ XHCI_TRB_ERROR_SUCCESS, XHCI_TRB_EVENT_PORT_STS_CHANGE);
+ if ((err = pci_xhci_insert_event(xsc, &evtrb, 1)) !=
+ XHCI_TRB_ERROR_SUCCESS)
+ return (err);
+ pci_xhci_assert_interrupt(xsc);
+ xsc->opregs.usbsts |= XHCI_STS_PCD;
+ return (0);
+ case USBDEV_REMOVE:
+ pci_xhci_deinit_port(xsc, hci->hci_port);
+ port->portsc |= XHCI_PS_CSC;
+ pci_xhci_set_evtrb(&evtrb, hci->hci_port,
+ XHCI_TRB_ERROR_SUCCESS, XHCI_TRB_EVENT_PORT_STS_CHANGE);
+ if ((err = pci_xhci_insert_event(xsc, &evtrb, 1)) !=
+ XHCI_TRB_ERROR_SUCCESS)
+ return (err);
+ xsc->opregs.usbsts |= XHCI_STS_PCD;
+ pci_xhci_assert_interrupt(xsc);
+ return (0);
+ default:
+ break;
+ }
return (0);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Oct 2, 5:22 AM (8 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39190589
Default Alt Text
D59785.id187025.diff (3 KB)

Event Timeline