Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F174184404
D59785.id187025.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D59785.id187025.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D59785: bhyve: usb: properly handle port init/deinit/power-on
Attached
Detach File
Event Timeline
Log In to Comment