Index: sys/dev/usb/controller/xhci.c =================================================================== --- sys/dev/usb/controller/xhci.c (revision 315483) +++ sys/dev/usb/controller/xhci.c (working copy) @@ -96,6 +96,7 @@ SYSCTL_INT(_hw_usb_xhci, OID_AUTO, streams, CTLFLA #ifdef USB_DEBUG static int xhcidebug; static int xhciroute; +static int xhcipssen; static int xhcipolling; static int xhcidma32; @@ -103,6 +104,9 @@ SYSCTL_INT(_hw_usb_xhci, OID_AUTO, debug, CTLFLAG_ &xhcidebug, 0, "Debug level"); SYSCTL_INT(_hw_usb_xhci, OID_AUTO, xhci_port_route, CTLFLAG_RWTUN, &xhciroute, 0, "Routing bitmap for switching EHCI ports to the XHCI controller"); +SYSCTL_INT(_hw_usb_xhci, OID_AUTO, xhci_port_pssen, CTLFLAG_RWTUN, + &xhcipssen, 0, "Port bitmap to force enable in the Port SuperSpeed Enable" \ + "Register for the XHCI controller"); SYSCTL_INT(_hw_usb_xhci, OID_AUTO, use_polling, CTLFLAG_RWTUN, &xhcipolling, 0, "Set to enable software interrupt polling for the XHCI controller"); SYSCTL_INT(_hw_usb_xhci, OID_AUTO, dma32, CTLFLAG_RWTUN, @@ -206,6 +210,12 @@ xhci_use_polling(void) #endif } +int32_t +xhci_port_pssen(void) +{ + return (xhcipssen); +} + static void xhci_iterate_hw_softc(struct usb_bus *bus, usb_bus_mem_sub_cb_t *cb) { Index: sys/dev/usb/controller/xhci.h =================================================================== --- sys/dev/usb/controller/xhci.h (revision 315483) +++ sys/dev/usb/controller/xhci.h (working copy) @@ -524,6 +524,7 @@ struct xhci_softc { /* prototypes */ uint8_t xhci_use_polling(void); +int32_t xhci_port_pssen(void); usb_error_t xhci_halt_controller(struct xhci_softc *); usb_error_t xhci_reset_controller(struct xhci_softc *); usb_error_t xhci_init(struct xhci_softc *, device_t, uint8_t); Index: sys/dev/usb/controller/xhci_pci.c =================================================================== --- sys/dev/usb/controller/xhci_pci.c (revision 315483) +++ sys/dev/usb/controller/xhci_pci.c (working copy) @@ -176,13 +176,21 @@ static int xhci_pci_port_route(device_t self, uint32_t set, uint32_t clear) { uint32_t temp; + uint32_t temp_pssen, temp_xusb2pr; uint32_t usb3_mask; uint32_t usb2_mask; - temp = pci_read_config(self, PCI_XHCI_INTEL_USB3_PSSEN, 4) | - pci_read_config(self, PCI_XHCI_INTEL_XUSB2PR, 4); + temp_pssen = pci_read_config(self, PCI_XHCI_INTEL_USB3_PSSEN, 4); + temp_xusb2pr = pci_read_config(self, PCI_XHCI_INTEL_XUSB2PR, 4); - temp |= set; +#ifdef USB_DEBUG + device_printf(self, "USB Ports w/ enabled SuperSpeed: 0x%08x\n", + temp_pssen); + device_printf(self, "USB 2.0 Ports handed over to xHCI: 0x%08x\n", + temp_xusb2pr); +#endif + + temp = temp_pssen | temp_xusb2pr | set; temp &= ~clear; /* Don't set bits which the hardware doesn't support */ @@ -189,11 +197,24 @@ xhci_pci_port_route(device_t self, uint32_t set, u usb3_mask = pci_read_config(self, PCI_XHCI_INTEL_USB3PRM, 4); usb2_mask = pci_read_config(self, PCI_XHCI_INTEL_USB2PRM, 4); - pci_write_config(self, PCI_XHCI_INTEL_USB3_PSSEN, temp & usb3_mask, 4); - pci_write_config(self, PCI_XHCI_INTEL_XUSB2PR, temp & usb2_mask, 4); +#ifdef USB_DEBUG + device_printf(self, "Ports to enable SuperSpeed: 0x%08x\n", usb3_mask); + device_printf(self, "Ports to hand over to xHCI: 0x%08x\n", usb2_mask); +#endif - device_printf(self, "Port routing mask set to 0x%08x\n", temp); + pci_write_config(self, PCI_XHCI_INTEL_USB3_PSSEN, temp & (usb3_mask | + temp_pssen), 4); + pci_write_config(self, PCI_XHCI_INTEL_XUSB2PR, temp & (usb2_mask | + temp_xusb2pr), 4); + usb3_mask = pci_read_config(self, PCI_XHCI_INTEL_USB3_PSSEN, 4); + usb2_mask = pci_read_config(self, PCI_XHCI_INTEL_XUSB2PR, 4); + + device_printf(self, "USB 3.0 ports that are now enabled under xHCI:" + "0x%08x\n", usb3_mask); + device_printf(self, "USB 2.0 ports that are now switched over to xHCI:" + "0x%08x\n", usb2_mask); + return (0); }