diff options
| author | Kyle Evans <kevans@FreeBSD.org> | 2024-12-29 03:57:03 +0000 |
|---|---|---|
| committer | Kyle Evans <kevans@FreeBSD.org> | 2024-12-29 03:57:03 +0000 |
| commit | b313229969cc56a057dfea28506784fd5468c6f3 (patch) | |
| tree | 151794ce836573edfb338f9ff703fe26250891e2 /sys/dev/pci | |
| parent | 14d370c9d72a8cd72dff2dbf2c1aa6ee6f5253aa (diff) | |
Diffstat (limited to 'sys/dev/pci')
| -rw-r--r-- | sys/dev/pci/pci_host_generic.c | 22 | ||||
| -rw-r--r-- | sys/dev/pci/pci_host_generic.h | 1 | ||||
| -rw-r--r-- | sys/dev/pci/pci_host_generic_acpi.c | 1 | ||||
| -rw-r--r-- | sys/dev/pci/pci_host_generic_fdt.c | 1 |
4 files changed, 20 insertions, 5 deletions
diff --git a/sys/dev/pci/pci_host_generic.c b/sys/dev/pci/pci_host_generic.c index 373a54a25a4d..884ab25548ce 100644 --- a/sys/dev/pci/pci_host_generic.c +++ b/sys/dev/pci/pci_host_generic.c @@ -59,6 +59,12 @@ #define PCI_RF_FLAGS 0 #endif +/* + * We allocate "ranges" specified mappings higher up in the rid space to avoid + * conflicts with various definitions in the wild that may have other registers + * attributed to the controller besides just the config space. + */ +#define RANGE_RID(idx) ((idx) + 100) /* Forward prototypes */ @@ -173,7 +179,7 @@ pci_host_generic_core_attach(device_t dev) phys_base = sc->ranges[tuple].phys_base; pci_base = sc->ranges[tuple].pci_base; size = sc->ranges[tuple].size; - rid = tuple + 1; + rid = RANGE_RID(tuple); if (size == 0) continue; /* empty range element */ switch (FLAG_TYPE(sc->ranges[tuple].flags)) { @@ -210,6 +216,7 @@ pci_host_generic_core_attach(device_t dev) error); continue; } + sc->ranges[tuple].rid = rid; sc->ranges[tuple].res = bus_alloc_resource_any(dev, type, &rid, RF_ACTIVE | RF_UNMAPPED | flags); if (sc->ranges[tuple].res == NULL) { @@ -246,7 +253,7 @@ int pci_host_generic_core_detach(device_t dev) { struct generic_pcie_core_softc *sc; - int error, tuple, type; + int error, rid, tuple, type; sc = device_get_softc(dev); @@ -255,8 +262,13 @@ pci_host_generic_core_detach(device_t dev) return (error); for (tuple = 0; tuple < MAX_RANGES_TUPLES; tuple++) { - if (sc->ranges[tuple].size == 0) + rid = sc->ranges[tuple].rid; + if (sc->ranges[tuple].size == 0) { + MPASS(sc->ranges[tuple].res == NULL); continue; /* empty range element */ + } + + MPASS(rid != -1); switch (FLAG_TYPE(sc->ranges[tuple].flags)) { case FLAG_TYPE_PMEM: case FLAG_TYPE_MEM: @@ -269,9 +281,9 @@ pci_host_generic_core_detach(device_t dev) continue; } if (sc->ranges[tuple].res != NULL) - bus_release_resource(dev, type, tuple + 1, + bus_release_resource(dev, type, rid, sc->ranges[tuple].res); - bus_delete_resource(dev, type, tuple + 1); + bus_delete_resource(dev, type, rid); } rman_fini(&sc->io_rman); rman_fini(&sc->mem_rman); diff --git a/sys/dev/pci/pci_host_generic.h b/sys/dev/pci/pci_host_generic.h index 7aa8852fd30a..6579cd0918c4 100644 --- a/sys/dev/pci/pci_host_generic.h +++ b/sys/dev/pci/pci_host_generic.h @@ -64,6 +64,7 @@ struct pcie_range { #define FLAG_TYPE_MEM 0x2 #define FLAG_TYPE_PMEM 0x3 struct resource *res; + int rid; }; struct generic_pcie_core_softc { diff --git a/sys/dev/pci/pci_host_generic_acpi.c b/sys/dev/pci/pci_host_generic_acpi.c index 1ff3a6bda707..f12632e7205b 100644 --- a/sys/dev/pci/pci_host_generic_acpi.c +++ b/sys/dev/pci/pci_host_generic_acpi.c @@ -182,6 +182,7 @@ pci_host_generic_acpi_parse_resource(ACPI_RESOURCE *res, void *arg) /* Save detected ranges */ if (res->Data.Address.ResourceType == ACPI_MEMORY_RANGE || res->Data.Address.ResourceType == ACPI_IO_RANGE) { + sc->base.ranges[r].rid = -1; sc->base.ranges[r].pci_base = min; sc->base.ranges[r].phys_base = min + off; sc->base.ranges[r].size = max - min + 1; diff --git a/sys/dev/pci/pci_host_generic_fdt.c b/sys/dev/pci/pci_host_generic_fdt.c index 4e933dec35db..73c6201dc14b 100644 --- a/sys/dev/pci/pci_host_generic_fdt.c +++ b/sys/dev/pci/pci_host_generic_fdt.c @@ -215,6 +215,7 @@ parse_pci_mem_ranges(device_t dev, struct generic_pcie_core_softc *sc) sc->ranges[i].flags |= FLAG_TYPE_MEM; } + sc->ranges[i].rid = -1; sc->ranges[i].pci_base = 0; for (k = 0; k < (pci_addr_cells - 1); k++) { sc->ranges[i].pci_base <<= 32; |
