aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/pci_iov.c25
-rw-r--r--sys/dev/pci/pci_iov_private.h2
2 files changed, 23 insertions, 4 deletions
diff --git a/sys/dev/pci/pci_iov.c b/sys/dev/pci/pci_iov.c
index 1f72391fb6b4..0efcfeac9eff 100644
--- a/sys/dev/pci/pci_iov.c
+++ b/sys/dev/pci/pci_iov.c
@@ -734,11 +734,18 @@ pci_iov_config(struct cdev *cdev, struct pci_iov_arg *arg)
first_rid = pci_get_rid(dev) + rid_off;
last_rid = first_rid + (num_vfs - 1) * rid_stride;
- /* We don't yet support allocating extra bus numbers for VFs. */
if (pci_get_bus(dev) != PCI_RID2BUS(last_rid)) {
- device_printf(dev, "not enough PCIe bus numbers for VFs\n");
- error = ENOSPC;
- goto out;
+ int rid = 0;
+ uint16_t last_rid_bus = PCI_RID2BUS(last_rid);
+
+ iov->iov_bus_res = bus_alloc_resource(bus, PCI_RES_BUS, &rid,
+ last_rid_bus, last_rid_bus, 1, RF_ACTIVE);
+ if (iov->iov_bus_res == NULL) {
+ device_printf(dev,
+ "failed to allocate PCIe bus number for VFs\n");
+ error = ENOSPC;
+ goto out;
+ }
}
if (!ari_enabled && PCI_RID2SLOT(last_rid) != 0) {
@@ -786,6 +793,11 @@ out:
}
}
+ if (iov->iov_bus_res != NULL) {
+ bus_release_resource(bus, iov->iov_bus_res);
+ iov->iov_bus_res = NULL;
+ }
+
if (iov->iov_flags & IOV_RMAN_INITED) {
rman_fini(&iov->rman);
iov->iov_flags &= ~IOV_RMAN_INITED;
@@ -896,6 +908,11 @@ pci_iov_delete_iov_children(struct pci_devinfo *dinfo)
}
}
+ if (iov->iov_bus_res != NULL) {
+ bus_release_resource(bus, iov->iov_bus_res);
+ iov->iov_bus_res = NULL;
+ }
+
if (iov->iov_flags & IOV_RMAN_INITED) {
rman_fini(&iov->rman);
iov->iov_flags &= ~IOV_RMAN_INITED;
diff --git a/sys/dev/pci/pci_iov_private.h b/sys/dev/pci/pci_iov_private.h
index 7ae2219b936d..ecf0a9b21be5 100644
--- a/sys/dev/pci/pci_iov_private.h
+++ b/sys/dev/pci/pci_iov_private.h
@@ -39,6 +39,8 @@ struct pcicfg_iov {
struct cdev *iov_cdev;
nvlist_t *iov_schema;
+ struct resource *iov_bus_res;
+
struct pci_iov_bar iov_bar[PCIR_MAX_BAR_0 + 1];
struct rman rman;
char rman_name[64];