Hello - Whenever I plug a device into my USB ports, my machine locks hard. I have the Intel Series 7 / C216 chip, so xhci attempts to route the port from ehci to xhci.
The following diff is from FreeBSD and makes my USB devices work again. https://github.com/freebsd/freebsd/blob/e79c62ff68fc74d88cb6f479859f6fae9baa5101/sys/dev/usb/controller/xhci_pci.c#L153-L176 Index: sys/dev/pci/xhci_pci.c =================================================================== RCS file: /cvs/src/sys/dev/pci/xhci_pci.c,v retrieving revision 1.6 diff -u -p -r1.6 xhci_pci.c --- sys/dev/pci/xhci_pci.c 22 Jun 2015 08:43:27 -0000 1.6 +++ sys/dev/pci/xhci_pci.c 19 Jul 2015 02:20:06 -0000 @@ -92,33 +92,45 @@ xhci_pci_match(struct device *parent, vo static int xhci_pci_port_route(struct xhci_pci_softc *psc) { - pcireg_t val; + pcireg_t val, usb2_mask, usb3_mask; - /* - * Check USB3 Port Routing Mask register that indicates the ports - * can be changed from OS, and turn on by USB3 Port SS Enable register. - */ - val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_USB3PRM); - DPRINTF(("%s: USB3PRM / USB3.0 configurable ports: 0x%08x\n", - psc->sc.sc_bus.bdev.dv_xname, val)); + /* + * Check USB3 Port Routing Mask register that indicates the ports + * can be changed from OS, and turn on by USB3 Port SS Enable register. + */ + usb3_mask = pci_conf_read(psc->sc_pc, psc->sc_tag, + PCI_XHCI_INTEL_USB3PRM); + DPRINTF(("%s: USB3PRM / USB3.0 configurable ports: 0x%08x\n", + psc->sc.sc_bus.bdev.dv_xname, usb3_mask)); + + /* + * Check USB2 Port Routing Mask register that indicates the USB2.0 + * ports to be controlled by xHCI HC, and switch them to xHCI HC. + */ + usb2_mask = pci_conf_read(psc->sc_pc, psc->sc_tag, + PCI_XHCI_INTEL_XUSB2PRM); + DPRINTF(("%s: XUSB2PRM / USB2.0 ports can switch from EHCI to xHCI:" + "0x%08x\n", psc->sc.sc_bus.bdev.dv_xname, val)); + + val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_USB3_PSSEN) | + pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_XUSB2PR); - pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_USB3_PSSEN, val); + + pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_USB3_PSSEN, + val & usb3_mask); +#ifdef XHCI_DEBUG val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_USB3_PSSEN); DPRINTF(("%s: USB3_PSSEN / Enabled USB3.0 ports under xHCI: 0x%08x\n", psc->sc.sc_bus.bdev.dv_xname, val)); +#endif - /* - * Check USB2 Port Routing Mask register that indicates the USB2.0 - * ports to be controlled by xHCI HC, and switch them to xHCI HC. - */ - val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_XUSB2PRM); - DPRINTF(("%s: XUSB2PRM / USB2.0 ports can switch from EHCI to xHCI:" - "0x%08x\n", psc->sc.sc_bus.bdev.dv_xname, val)); - - pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_XUSB2PR, val); + pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_XUSB2PR, + val & usb2_mask); +#ifdef XHCI_DEBUG val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_XUSB2PR); DPRINTF(("%s: XUSB2PR / USB2.0 ports under xHCI: 0x%08x\n", psc->sc.sc_bus.bdev.dv_xname, val)); +#endif return (0); }