Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/pci/pci.c
Show First 20 Lines • Show All 397 Lines • ▼ Show 20 Lines | SYSCTL_INT(_hw_pci, OID_AUTO, usb_early_takeover, CTLFLAG_RDTUN, | ||||
"Enable early takeover of USB controllers. Disable this if you depend on" | "Enable early takeover of USB controllers. Disable this if you depend on" | ||||
" BIOS emulation of USB devices, that is you use USB devices (like" | " BIOS emulation of USB devices, that is you use USB devices (like" | ||||
" keyboard or mouse) but do not load USB drivers"); | " keyboard or mouse) but do not load USB drivers"); | ||||
static int pci_clear_bars; | static int pci_clear_bars; | ||||
SYSCTL_INT(_hw_pci, OID_AUTO, clear_bars, CTLFLAG_RDTUN, &pci_clear_bars, 0, | SYSCTL_INT(_hw_pci, OID_AUTO, clear_bars, CTLFLAG_RDTUN, &pci_clear_bars, 0, | ||||
"Ignore firmware-assigned resources for BARs."); | "Ignore firmware-assigned resources for BARs."); | ||||
#if defined(PCI_RES_BUS) | |||||
static int pci_clear_buses; | static int pci_clear_buses; | ||||
SYSCTL_INT(_hw_pci, OID_AUTO, clear_buses, CTLFLAG_RDTUN, &pci_clear_buses, 0, | SYSCTL_INT(_hw_pci, OID_AUTO, clear_buses, CTLFLAG_RDTUN, &pci_clear_buses, 0, | ||||
"Ignore firmware-assigned bus numbers."); | "Ignore firmware-assigned bus numbers."); | ||||
#endif | |||||
static int pci_enable_ari = 1; | static int pci_enable_ari = 1; | ||||
SYSCTL_INT(_hw_pci, OID_AUTO, enable_ari, CTLFLAG_RDTUN, &pci_enable_ari, | SYSCTL_INT(_hw_pci, OID_AUTO, enable_ari, CTLFLAG_RDTUN, &pci_enable_ari, | ||||
0, "Enable support for PCIe Alternative RID Interpretation"); | 0, "Enable support for PCIe Alternative RID Interpretation"); | ||||
int pci_enable_aspm = 1; | int pci_enable_aspm = 1; | ||||
SYSCTL_INT(_hw_pci, OID_AUTO, enable_aspm, CTLFLAG_RDTUN, &pci_enable_aspm, | SYSCTL_INT(_hw_pci, OID_AUTO, enable_aspm, CTLFLAG_RDTUN, &pci_enable_aspm, | ||||
0, "Enable support for PCIe Active State Power Management"); | 0, "Enable support for PCIe Active State Power Management"); | ||||
▲ Show 20 Lines • Show All 3,251 Lines • ▼ Show 20 Lines | for (eecp = XHCI_HCS0_XECP(cparams) << 2; eecp != 0 && XHCI_XECP_NEXT(eec); | ||||
/* Disable interrupts */ | /* Disable interrupts */ | ||||
offs = bus_read_1(res, XHCI_CAPLENGTH); | offs = bus_read_1(res, XHCI_CAPLENGTH); | ||||
bus_write_4(res, offs + XHCI_USBCMD, 0); | bus_write_4(res, offs + XHCI_USBCMD, 0); | ||||
bus_read_4(res, offs + XHCI_USBSTS); | bus_read_4(res, offs + XHCI_USBSTS); | ||||
} | } | ||||
bus_release_resource(self, SYS_RES_MEMORY, rid, res); | bus_release_resource(self, SYS_RES_MEMORY, rid, res); | ||||
} | } | ||||
#if defined(PCI_RES_BUS) | |||||
static void | static void | ||||
pci_reserve_secbus(device_t bus, device_t dev, pcicfgregs *cfg, | pci_reserve_secbus(device_t bus, device_t dev, pcicfgregs *cfg, | ||||
struct resource_list *rl) | struct resource_list *rl) | ||||
{ | { | ||||
struct resource *res; | struct resource *res; | ||||
char *cp; | char *cp; | ||||
rman_res_t start, end, count; | rman_res_t start, end, count; | ||||
int rid, sec_bus, sec_reg, sub_bus, sub_reg, sup_bus; | int rid, sec_bus, sec_reg, sub_bus, sub_reg, sup_bus; | ||||
▲ Show 20 Lines • Show All 139 Lines • ▼ Show 20 Lines | if (bootverbose) | ||||
"Lazy allocation of %ju bus%s at %ju\n", count, | "Lazy allocation of %ju bus%s at %ju\n", count, | ||||
count == 1 ? "" : "es", rman_get_start(res)); | count == 1 ? "" : "es", rman_get_start(res)); | ||||
PCI_WRITE_CONFIG(dev, child, sec_reg, rman_get_start(res), 1); | PCI_WRITE_CONFIG(dev, child, sec_reg, rman_get_start(res), 1); | ||||
PCI_WRITE_CONFIG(dev, child, sub_reg, rman_get_end(res), 1); | PCI_WRITE_CONFIG(dev, child, sub_reg, rman_get_end(res), 1); | ||||
} | } | ||||
return (resource_list_alloc(rl, dev, child, PCI_RES_BUS, rid, start, | return (resource_list_alloc(rl, dev, child, PCI_RES_BUS, rid, start, | ||||
end, count, flags)); | end, count, flags)); | ||||
} | } | ||||
#endif | |||||
static int | static int | ||||
pci_ea_bei_to_rid(device_t dev, int bei) | pci_ea_bei_to_rid(device_t dev, int bei) | ||||
{ | { | ||||
#ifdef PCI_IOV | #ifdef PCI_IOV | ||||
struct pci_devinfo *dinfo; | struct pci_devinfo *dinfo; | ||||
int iov_pos; | int iov_pos; | ||||
struct pcicfg_iov *iov; | struct pcicfg_iov *iov; | ||||
▲ Show 20 Lines • Show All 239 Lines • ▼ Show 20 Lines | if (pci_usb_takeover && pci_get_class(dev) == PCIC_SERIALBUS && | ||||
else if (pci_get_progif(dev) == PCIP_SERIALBUS_USB_EHCI) | else if (pci_get_progif(dev) == PCIP_SERIALBUS_USB_EHCI) | ||||
ehci_early_takeover(dev); | ehci_early_takeover(dev); | ||||
else if (pci_get_progif(dev) == PCIP_SERIALBUS_USB_OHCI) | else if (pci_get_progif(dev) == PCIP_SERIALBUS_USB_OHCI) | ||||
ohci_early_takeover(dev); | ohci_early_takeover(dev); | ||||
else if (pci_get_progif(dev) == PCIP_SERIALBUS_USB_UHCI) | else if (pci_get_progif(dev) == PCIP_SERIALBUS_USB_UHCI) | ||||
uhci_early_takeover(dev); | uhci_early_takeover(dev); | ||||
} | } | ||||
#if defined(PCI_RES_BUS) | |||||
/* | /* | ||||
* Reserve resources for secondary bus ranges behind bridge | * Reserve resources for secondary bus ranges behind bridge | ||||
* devices. | * devices. | ||||
*/ | */ | ||||
pci_reserve_secbus(bus, dev, cfg, rl); | pci_reserve_secbus(bus, dev, cfg, rl); | ||||
#endif | |||||
} | } | ||||
static struct pci_devinfo * | static struct pci_devinfo * | ||||
pci_identify_function(device_t pcib, device_t dev, int domain, int busno, | pci_identify_function(device_t pcib, device_t dev, int domain, int busno, | ||||
int slot, int func) | int slot, int func) | ||||
{ | { | ||||
struct pci_devinfo *dinfo; | struct pci_devinfo *dinfo; | ||||
▲ Show 20 Lines • Show All 324 Lines • ▼ Show 20 Lines | pci_probe(device_t dev) | ||||
return (BUS_PROBE_GENERIC); | return (BUS_PROBE_GENERIC); | ||||
} | } | ||||
int | int | ||||
pci_attach_common(device_t dev) | pci_attach_common(device_t dev) | ||||
{ | { | ||||
struct pci_softc *sc; | struct pci_softc *sc; | ||||
int busno, domain; | int busno, domain; | ||||
#ifdef PCI_RES_BUS | |||||
int rid; | int rid; | ||||
#endif | |||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
domain = pcib_get_domain(dev); | domain = pcib_get_domain(dev); | ||||
busno = pcib_get_bus(dev); | busno = pcib_get_bus(dev); | ||||
#ifdef PCI_RES_BUS | |||||
rid = 0; | rid = 0; | ||||
sc->sc_bus = bus_alloc_resource(dev, PCI_RES_BUS, &rid, busno, busno, | sc->sc_bus = bus_alloc_resource(dev, PCI_RES_BUS, &rid, busno, busno, | ||||
1, 0); | 1, 0); | ||||
if (sc->sc_bus == NULL) { | if (sc->sc_bus == NULL) { | ||||
device_printf(dev, "failed to allocate bus number\n"); | device_printf(dev, "failed to allocate bus number\n"); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
#endif | |||||
if (bootverbose) | if (bootverbose) | ||||
device_printf(dev, "domain=%d, physical bus=%d\n", | device_printf(dev, "domain=%d, physical bus=%d\n", | ||||
domain, busno); | domain, busno); | ||||
sc->sc_dma_tag = bus_get_dma_tag(dev); | sc->sc_dma_tag = bus_get_dma_tag(dev); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
Show All 15 Lines | pci_attach(device_t dev) | ||||
busno = pcib_get_bus(dev); | busno = pcib_get_bus(dev); | ||||
pci_add_children(dev, domain, busno); | pci_add_children(dev, domain, busno); | ||||
return (bus_generic_attach(dev)); | return (bus_generic_attach(dev)); | ||||
} | } | ||||
int | int | ||||
pci_detach(device_t dev) | pci_detach(device_t dev) | ||||
{ | { | ||||
#ifdef PCI_RES_BUS | |||||
struct pci_softc *sc; | struct pci_softc *sc; | ||||
#endif | |||||
int error; | int error; | ||||
error = bus_generic_detach(dev); | error = bus_generic_detach(dev); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
#ifdef PCI_RES_BUS | |||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
error = bus_release_resource(dev, PCI_RES_BUS, 0, sc->sc_bus); | error = bus_release_resource(dev, PCI_RES_BUS, 0, sc->sc_bus); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
#endif | |||||
return (device_delete_children(dev)); | return (device_delete_children(dev)); | ||||
} | } | ||||
static void | static void | ||||
pci_hint_device_unit(device_t dev, device_t child, const char *name, int *unitp) | pci_hint_device_unit(device_t dev, device_t child, const char *name, int *unitp) | ||||
{ | { | ||||
int line, unit; | int line, unit; | ||||
const char *at; | const char *at; | ||||
▲ Show 20 Lines • Show All 556 Lines • ▼ Show 20 Lines | else | ||||
pci_printf(&dinfo->cfg, "Device leaked %d MSI-X " | pci_printf(&dinfo->cfg, "Device leaked %d MSI-X " | ||||
"vectors\n", dinfo->cfg.msix.msix_alloc); | "vectors\n", dinfo->cfg.msix.msix_alloc); | ||||
(void)pci_release_msi(child); | (void)pci_release_msi(child); | ||||
} | } | ||||
if (resource_list_release_active(rl, dev, child, SYS_RES_MEMORY) != 0) | if (resource_list_release_active(rl, dev, child, SYS_RES_MEMORY) != 0) | ||||
pci_printf(&dinfo->cfg, "Device leaked memory resources\n"); | pci_printf(&dinfo->cfg, "Device leaked memory resources\n"); | ||||
if (resource_list_release_active(rl, dev, child, SYS_RES_IOPORT) != 0) | if (resource_list_release_active(rl, dev, child, SYS_RES_IOPORT) != 0) | ||||
pci_printf(&dinfo->cfg, "Device leaked I/O resources\n"); | pci_printf(&dinfo->cfg, "Device leaked I/O resources\n"); | ||||
#ifdef PCI_RES_BUS | |||||
if (resource_list_release_active(rl, dev, child, PCI_RES_BUS) != 0) | if (resource_list_release_active(rl, dev, child, PCI_RES_BUS) != 0) | ||||
pci_printf(&dinfo->cfg, "Device leaked PCI bus numbers\n"); | pci_printf(&dinfo->cfg, "Device leaked PCI bus numbers\n"); | ||||
#endif | |||||
pci_cfg_save(child, dinfo, 1); | pci_cfg_save(child, dinfo, 1); | ||||
} | } | ||||
/* | /* | ||||
* Parse the PCI device database, if loaded, and return a pointer to a | * Parse the PCI device database, if loaded, and return a pointer to a | ||||
* description of the device. | * description of the device. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 420 Lines • ▼ Show 20 Lines | pci_alloc_multi_resource(device_t dev, device_t child, int type, int *rid, | ||||
/* | /* | ||||
* Perform lazy resource allocation | * Perform lazy resource allocation | ||||
*/ | */ | ||||
dinfo = device_get_ivars(child); | dinfo = device_get_ivars(child); | ||||
rl = &dinfo->resources; | rl = &dinfo->resources; | ||||
cfg = &dinfo->cfg; | cfg = &dinfo->cfg; | ||||
switch (type) { | switch (type) { | ||||
#if defined(PCI_RES_BUS) | |||||
case PCI_RES_BUS: | case PCI_RES_BUS: | ||||
return (pci_alloc_secbus(dev, child, rid, start, end, count, | return (pci_alloc_secbus(dev, child, rid, start, end, count, | ||||
flags)); | flags)); | ||||
#endif | |||||
case SYS_RES_IRQ: | case SYS_RES_IRQ: | ||||
/* | /* | ||||
* Can't alloc legacy interrupt once MSI messages have | * Can't alloc legacy interrupt once MSI messages have | ||||
* been allocated. | * been allocated. | ||||
*/ | */ | ||||
if (*rid == 0 && (cfg->msi.msi_alloc > 0 || | if (*rid == 0 && (cfg->msi.msi_alloc > 0 || | ||||
cfg->msix.msix_alloc > 0)) | cfg->msix.msix_alloc > 0)) | ||||
return (NULL); | return (NULL); | ||||
▲ Show 20 Lines • Show All 1,254 Lines • Show Last 20 Lines |