@@ -731,14 +731,8 @@ static void pci_config_free(PCIDevice *pci_dev)
g_free(pci_dev->used);
}
-/* -1 for devfn means auto assign */
-static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
- const char *name, int devfn,
- const PCIDeviceInfo *info)
+static int pci_assign_devfn(PCIBus *bus, int devfn, const char *name)
{
- PCIConfigReadFunc *config_read = info->config_read;
- PCIConfigWriteFunc *config_write = info->config_write;
-
if (devfn < 0) {
for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
devfn += PCI_FUNC_MAX) {
@@ -746,13 +740,30 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
goto found;
}
error_report("PCI: no slot/function available for %s, all in use", name);
- return NULL;
+ return -1;
found: ;
} else if (bus->devices[devfn]) {
error_report("PCI: slot %d function %d not available for %s, in use by %s",
PCI_SLOT(devfn), PCI_FUNC(devfn), name, bus->devices[devfn]->name);
+ return -1;
+ }
+
+ return devfn;
+}
+
+/* -1 for devfn means auto assign */
+static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
+ const char *name, int devfn,
+ const PCIDeviceInfo *info)
+{
+ PCIConfigReadFunc *config_read = info->config_read;
+ PCIConfigWriteFunc *config_write = info->config_write;
+
+ devfn = pci_assign_devfn(bus, devfn, name);
+ if (devfn == -1) {
return NULL;
}
+
pci_dev->bus = bus;
pci_dev->devfn = devfn;
pstrcpy(pci_dev->name, sizeof(pci_dev->name), name);
@@ -1723,7 +1734,10 @@ PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction,
{
DeviceState *dev;
+ devfn = pci_assign_devfn(bus, devfn, name);
+
dev = qdev_create(&bus->qbus, name, NULL);
+
qdev_prop_set_uint32(dev, "addr", devfn);
qdev_prop_set_bit(dev, "multifunction", multifunction);
return DO_UPCAST(PCIDevice, qdev, dev);
We need devfn to be allocated before the device is initialized in order to derive the name from the devfn. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> --- hw/pci.c | 30 ++++++++++++++++++++++-------- 1 files changed, 22 insertions(+), 8 deletions(-)