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);
 }

Reply via email to