aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2023-06-19 16:15:48 +0000
committerGordon Tetlow <gordon@FreeBSD.org>2023-09-06 16:57:02 +0000
commite80d2d894ff1afbdb932aac1f4ceb50922a779bb (patch)
tree25a9780778280c337f09a20a2c903fad77a9c60e
parent0b39d9de2e7170c214b39f1aca42c11d6f7c13e9 (diff)
downloadsrc-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.c23
-rw-r--r--sys/dev/pci/pcib_private.h1
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;