diff options
author | John Baldwin <jhb@FreeBSD.org> | 2023-06-19 16:15:48 +0000 |
---|---|---|
committer | Gordon Tetlow <gordon@FreeBSD.org> | 2023-09-06 16:57:02 +0000 |
commit | e80d2d894ff1afbdb932aac1f4ceb50922a779bb (patch) | |
tree | 25a9780778280c337f09a20a2c903fad77a9c60e | |
parent | 0b39d9de2e7170c214b39f1aca42c11d6f7c13e9 (diff) | |
download | src-e80d2d894ff1afbdb932aac1f4ceb50922a779bb.tar.gz src-e80d2d894ff1afbdb932aac1f4ceb50922a779bb.zip |
pcib: Allocate the memory BAR with the MSI-X table.
This is required for pci_alloc_msix() to work and to thus use
MSI-X interrupts for PCI-e hotplug.
Reported by: cperciva
Reviewed by: cperciva
Approved by: so
Security: FreeBSD-EN-23:10.pci
Differential Revision: https://reviews.freebsd.org/D40581
(cherry picked from commit e6b838363fb473b5e35a8ae6a1da5e15f5b52960)
(cherry picked from commit 12ce57e6d3e770db9ca83a8cbaa8f332515ce3d7)
-rw-r--r-- | sys/dev/pci/pci_pci.c | 23 | ||||
-rw-r--r-- | sys/dev/pci/pcib_private.h | 1 |
2 files changed, 19 insertions, 5 deletions
diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c index b735da657a6c..4284b1cbf567 100644 --- a/sys/dev/pci/pci_pci.c +++ b/sys/dev/pci/pci_pci.c @@ -1324,7 +1324,7 @@ static int pcib_alloc_pcie_irq(struct pcib_softc *sc) { device_t dev; - int count, error, rid; + int count, error, mem_rid, rid; rid = -1; dev = sc->dev; @@ -1336,9 +1336,17 @@ pcib_alloc_pcie_irq(struct pcib_softc *sc) */ count = pci_msix_count(dev); if (count == 1) { - error = pci_alloc_msix(dev, &count); - if (error == 0) - rid = 1; + mem_rid = pci_msix_table_bar(dev); + sc->pcie_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &mem_rid, RF_ACTIVE); + if (sc->pcie_mem == NULL) { + device_printf(dev, + "Failed to allocate BAR for MSI-X table\n"); + } else { + error = pci_alloc_msix(dev, &count); + if (error == 0) + rid = 1; + } } if (rid < 0 && pci_msi_count(dev) > 0) { @@ -1386,7 +1394,12 @@ pcib_release_pcie_irq(struct pcib_softc *sc) error = bus_free_resource(dev, SYS_RES_IRQ, sc->pcie_irq); if (error) return (error); - return (pci_release_msi(dev)); + error = pci_release_msi(dev); + if (error) + return (error); + if (sc->pcie_mem != NULL) + error = bus_free_resource(dev, SYS_RES_MEMORY, sc->pcie_mem); + return (error); } static void diff --git a/sys/dev/pci/pcib_private.h b/sys/dev/pci/pcib_private.h index af0b70a7add3..0dea325b6436 100644 --- a/sys/dev/pci/pcib_private.h +++ b/sys/dev/pci/pcib_private.h @@ -134,6 +134,7 @@ struct pcib_softc uint16_t pcie_link_sta; uint16_t pcie_slot_sta; uint32_t pcie_slot_cap; + struct resource *pcie_mem; struct resource *pcie_irq; void *pcie_ihand; struct task pcie_hp_task; |