31#include <sys/stdint.h>
32#include <sys/stddef.h>
37#include <sys/kernel.h>
39#include <sys/module.h>
42#include <sys/condvar.h>
43#include <sys/sysctl.h>
45#include <sys/unistd.h>
46#include <sys/callout.h>
47#include <sys/malloc.h>
65#define PCI_XHCI_VENDORID_AMD 0x1022
66#define PCI_XHCI_VENDORID_INTEL 0x8086
77 DEVMETHOD(device_suspend, bus_generic_suspend),
78 DEVMETHOD(device_resume, bus_generic_resume),
79 DEVMETHOD(device_shutdown, bus_generic_shutdown),
96 uint32_t device_id = pci_get_devid(self);
100 return (
"AMD KERNCZ USB 3.0 controller");
102 return (
"AMD Starship USB 3.0 controller");
104 return (
"AMD Matisse USB 3.0 controller");
106 return (
"AMD X399 USB 3.0 controller");
109 return (
"AMD 300 Series USB 3.0 controller");
113 return (
"AMD FCH USB 3.0 controller");
116 return (
"Hygon USB 3.0 controller");
119 return (
"NEC uPD720200 USB 3.0 controller");
121 return (
"NEC uPD720202 USB 3.0 controller");
124 return (
"Fresco Logic FL1000G USB 3.0 controller");
126 return (
"Fresco Logic FL1100 USB 3.0 controller");
129 return (
"ASMedia ASM1042 USB 3.0 controller");
131 return (
"ASMedia ASM1042A USB 3.0 controller");
133 return (
"ASMedia ASM1143 USB 3.1 controller");
135 return (
"ASMedia ASM3242 USB 3.2 controller");
138 return (
"Intel Goshen Ridge Thunderbolt 4 USB controller");
140 return (
"Intel BayTrail USB 3.0 controller");
142 return (
"Intel Maple Ridge Thunderbolt 4 USB controller");
146 return (
"Intel Alpine Ridge Thunderbolt 3 USB controller");
150 return (
"Intel Titan Ridge Thunderbolt 3 USB controller");
152 return (
"Intel Denverton USB 3.0 controller");
155 return (
"Intel Panther Point USB 3.0 controller");
157 return (
"Intel Braswell USB 3.0 controller");
159 return (
"Intel Gemini Lake USB 3.0 controller");
161 return (
"Intel Ice Lake-LP USB 3.1 controller");
163 return (
"Intel Tiger Lake-H USB 3.2 controller");
165 return (
"Intel Alder Lake-P Thunderbolt 4 USB controller");
167 return (
"Intel Alder Lake USB 3.2 controller");
169 return (
"Intel Apollo Lake USB 3.0 controller");
171 return (
"Intel Alder Lake USB 3.2 controller");
173 return (
"Intel Ice Lake Thunderbolt 3 USB controller");
175 return (
"Intel Lynx Point USB 3.0 controller");
177 return (
"Intel Wildcat Point USB 3.0 controller");
179 return (
"Intel Wellsburg USB 3.0 controller");
181 return (
"Intel Tiger Lake-LP Thunderbolt 4 USB controller");
183 return (
"Intel Tiger Lake-H Thunderbolt 4 USB controller");
185 return (
"Broadwell Integrated PCH-LP chipset USB 3.0 controller");
187 return (
"Intel Sunrise Point-LP USB 3.0 controller");
189 return (
"Intel Tiger Lake-LP USB 3.2 controller");
191 return (
"Intel Sunrise Point USB 3.0 controller");
193 return (
"Intel Lewisburg USB 3.0 controller");
195 return (
"Intel Union Point USB 3.0 controller");
197 return (
"Intel Cannon Lake USB 3.1 controller");
200 return (
"Cavium ThunderX USB 3.0 controller");
203 return (
"NVIDIA TU106 USB 3.1 controller");
212 return (
"XHCI (generic) USB 3.0 controller");
223 device_set_desc(self,
desc);
224 return (BUS_PROBE_DEFAULT);
265 device_printf(self,
"Port routing mask set to 0x%08x\n", temp);
273 struct xhci_softc *sc = device_get_softc(self);
276 uint8_t usedma32 = 0;
279 sc->
sc_io_res = bus_alloc_resource_any(self, SYS_RES_MEMORY, &
rid,
282 device_printf(self,
"Could not map memory\n");
289 switch (pci_get_devid(self)) {
322 device_printf(self,
"Could not initialize softc\n");
328 pci_enable_busmaster(self);
333 if (
xhci_use_msix && (msix_table = pci_msix_table_bar(self)) >= 0) {
338 SYS_RES_MEMORY, &msix_table, RF_ACTIVE);
342 "Unable to map MSI-X table\n");
347 if (pci_alloc_msix(self, &
count) == 0) {
349 device_printf(self,
"MSI-X enabled\n");
353 bus_release_resource(self,
363 if (pci_alloc_msi(self, &
count) == 0) {
365 device_printf(self,
"MSI enabled\n");
369 sc->
sc_irq_res = bus_alloc_resource_any(self, SYS_RES_IRQ, &
rid,
370 RF_ACTIVE | (
rid != 0 ? 0 : RF_SHAREABLE));
372 pci_release_msi(self);
373 device_printf(self,
"Could not allocate IRQ\n");
376 sc->
sc_bus.
bdev = device_add_child(self,
"usbus", -1);
378 device_printf(self,
"Could not add USB device\n");
383 switch (pci_get_vendor(self)) {
392 device_printf(self,
"(New XHCI DeviceId=0x%08x)\n",
393 pci_get_devid(self));
395 "(0x%04x)", pci_get_vendor(self));
400 err = bus_setup_intr(self, sc->
sc_irq_res, INTR_TYPE_BIO | INTR_MPSAFE,
403 bus_release_resource(self, SYS_RES_IRQ,
406 pci_release_msi(self);
407 device_printf(self,
"Could not setup IRQ, err=%d\n", err);
413 device_printf(self,
"Interrupt polling at %dHz\n", hz);
429 err = device_probe_and_attach(sc->
sc_bus.
bdev);
432 device_printf(self,
"XHCI halt/start/probe failed err=%d\n", err);
445 struct xhci_softc *sc = device_get_softc(self);
448 device_delete_children(self);
454 pci_disable_busmaster(self);
461 bus_release_resource(self, SYS_RES_IRQ,
464 pci_release_msi(self);
467 bus_release_resource(self, SYS_RES_MEMORY,
485 struct xhci_softc *sc = device_get_softc(self);
499 eec =
XREAD4(sc, capa, eecp);
503 bios_sem =
XREAD1(sc, capa, eecp +
507 device_printf(sc->
sc_bus.
bdev,
"waiting for BIOS "
508 "to give up control\n");
513 bios_sem =
XREAD1(sc, capa, eecp +
520 "timed out waiting for BIOS\n");
#define PCIP_SERIALBUS_USB_XHCI
#define PCIS_SERIALBUS_USB
bus_space_tag_t sc_io_tag
xhci_port_route_t * sc_port_route
struct resource * sc_io_res
uint8_t sc_no_deconfigure
bus_space_handle_t sc_io_hdl
struct usb_callout sc_callout
struct resource * sc_irq_res
struct resource * sc_msix_res
#define USB_BUS_UNLOCK(_b)
struct usb_endpoint_descriptor desc
void usb_pause_mtx(struct mtx *mtx, int timo)
#define usb_callout_init_mtx(c, m, f)
#define usb_callout_reset(c,...)
#define usb_callout_drain(c)
usb_error_t xhci_init(struct xhci_softc *sc, device_t self, uint8_t dma32)
usb_error_t xhci_reset_controller(struct xhci_softc *sc)
usb_error_t xhci_halt_controller(struct xhci_softc *sc)
uint8_t xhci_use_polling(void)
void xhci_uninit(struct xhci_softc *sc)
usb_error_t xhci_start_controller(struct xhci_softc *sc)
void xhci_interrupt(struct xhci_softc *sc)
static devclass_t xhci_devclass
DEFINE_CLASS_0(xhci, xhci_pci_driver, xhci_device_methods, sizeof(struct xhci_softc))
static void xhci_interrupt_poll(void *_sc)
#define PCI_XHCI_VENDORID_AMD
int xhci_pci_attach(device_t self)
static const char * xhci_pci_match(device_t self)
static device_probe_t xhci_pci_probe
TUNABLE_INT("hw.usb.xhci.msi", &xhci_use_msi)
static usb_take_controller_t xhci_pci_take_controller
#define PCI_XHCI_VENDORID_INTEL
MODULE_DEPEND(xhci, usb, 1, 1, 1)
static device_detach_t xhci_pci_detach
static int xhci_pci_port_route(device_t self, uint32_t set, uint32_t clear)
DRIVER_MODULE(xhci, pci, xhci_pci_driver, xhci_devclass, NULL, NULL)
static device_method_t xhci_device_methods[]
#define XREAD1(sc, what, a)
#define PCI_XHCI_INTEL_XUSB2PR
#define XHCI_XECP_NEXT(x)
#define XHCI_HCS0_XECP(x)
#define PCI_XHCI_INTEL_USB3PRM
#define XREAD4(sc, what, a)
#define XWRITE1(sc, what, a, x)
#define XHCI_IMOD_DEFAULT_LP
#define XHCI_ID_USB_LEGACY
#define PCI_XHCI_INTEL_USB3_PSSEN
#define PCI_XHCI_INTEL_USB2PRM
#define XHCI_XECP_BIOS_SEM