/* Ensure addr fits in the address set, by expanding it if needed. * This will only grow if the flags say that we need a normal * hot-pluggable PCI slot. If we need a different type of slot, it * will fail. * * Return value: * -1 = OOM * 0 = no action performed * >0 = number of buses added */ int virDomainPCIAddressSetGrow(virDomainPCIAddressSetPtr addrs, virDevicePCIAddressPtr addr, virDomainPCIConnectFlags flags) { int add; size_t i; add = addr->bus - addrs->nbuses + 1; i = addrs->nbuses; if (add <= 0) return 0; /* auto-grow only works when we're adding plain PCI devices */ if (!(flags & VIR_PCI_CONNECT_TYPE_PCI)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Cannot automatically add a new PCI bus for a " "device requiring a slot other than standard PCI.")); return -1; } if (VIR_EXPAND_N(addrs->buses, addrs->nbuses, add) < 0) return -1; for (; i < addrs->nbuses; i++) { /* Any time we auto-add a bus, we will want a multi-slot * bus. Currently the only type of bus we will auto-add is a * pci-bridge, which is hot-pluggable and provides standard * PCI slots. */ virDomainPCIAddressBusSetModel(&addrs->buses[i], VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE); } return add; }
virDomainPCIAddressSetPtr bhyveDomainPCIAddressSetCreate(virDomainDefPtr def, unsigned int nbuses) { virDomainPCIAddressSetPtr addrs; if ((addrs = virDomainPCIAddressSetAlloc(nbuses)) == NULL) return NULL; if (virDomainPCIAddressBusSetModel(&addrs->buses[0], VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) < 0) goto error; if (virDomainDeviceInfoIterate(def, bhyveCollectPCIAddress, addrs) < 0) goto error; return addrs; error: virDomainPCIAddressSetFree(addrs); return NULL; }