/*
- * Reserve a slot (or just one function) for a device. If
- * reserveEntireSlot is true, all functions for the slot are reserved,
- * otherwise only one. If fromConfig is true, the address being
- * requested came directly from the config and errors should be worded
- * appropriately. If fromConfig is false, the address was
+ * Reserve a function in a slot. If fromConfig is true, the address
+ * being requested came directly from the config and errors should be
+ * worded appropriately. If fromConfig is false, the address was
* automatically created by libvirt, so it is an internal error (not
* XML).
*/
virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs,
virPCIDeviceAddressPtr addr,
virDomainPCIConnectFlags flags,
- bool reserveEntireSlot,
bool fromConfig)
{
int ret = -1;
bus = &addrs->buses[addr->bus];
- if (reserveEntireSlot) {
- if (bus->slot[addr->slot].functions) {
- virReportError(errType,
- _("Attempted double use of PCI slot %s "
- "(may need \"multifunction='on'\" for "
- "device on function 0)"), addrStr);
- goto cleanup;
- }
- bus->slot[addr->slot].functions = 0xFF; /* reserve all functions of slot */
- VIR_DEBUG("Reserving PCI slot %s (multifunction='off')", addrStr);
- } else {
- if (bus->slot[addr->slot].functions & (1 << addr->function)) {
- if (addr->function == 0) {
- virReportError(errType,
- _("Attempted double use of PCI Address %s"),
- addrStr);
- } else {
- virReportError(errType,
- _("Attempted double use of PCI Address %s "
- "(may need \"multifunction='on'\" "
- "for device on function 0)"), addrStr);
- }
- goto cleanup;
- }
- bus->slot[addr->slot].functions |= (1 << addr->function);
- VIR_DEBUG("Reserving PCI address %s", addrStr);
+ if (bus->slot[addr->slot].functions & (1 << addr->function)) {
+ virReportError(errType,
+ _("Attempted double use of PCI Address %s"), addrStr);
+ goto cleanup;
}
+ bus->slot[addr->slot].functions |= (1 << addr->function);
+ VIR_DEBUG("Reserving PCI address %s", addrStr);
ret = 0;
cleanup:
virPCIDeviceAddressPtr addr,
virDomainPCIConnectFlags flags)
{
- return virDomainPCIAddressReserveAddr(addrs, addr, flags, true, false);
+ return virDomainPCIAddressReserveAddr(addrs, addr, flags, false);
}
int
addrStr, flags, true))
goto cleanup;
- ret = virDomainPCIAddressReserveAddr(addrs, &dev->addr.pci, flags,
- true, true);
+ ret = virDomainPCIAddressReserveAddr(addrs, &dev->addr.pci,
+ flags, true);
} else {
ret = virDomainPCIAddressReserveNextSlot(addrs, dev, flags);
}
static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
virDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs,
virPCIDeviceAddressPtr next_addr,
+ int function,
virDomainPCIConnectFlags flags)
{
/* default to starting the search for a free slot from
a.slot = addrs->buses[0].minSlot;
}
+ /* if the caller asks for "any function", give them function 0 */
+ if (function == -1)
+ a.function = 0;
+ else
+ a.function = function;
+
while (a.bus < addrs->nbuses) {
VIR_FREE(addrStr);
if (!(addrStr = virDomainPCIAddressAsString(&a)))
* @dev: virDomainDeviceInfo that should get the new address.
* @flags: CONNECT_TYPE flags for the device that needs an address.
* @function: which function on the slot to mark as reserved
- * (if @reserveEntireSlot is false)
- * @reserveEntireSlot: true to reserve all functions on the new slot,
- * false to reserve just @function
*
* Find the next *completely unreserved* slot with compatible
- * connection @flags, mark either one function or the entire
- * slot as in-use (according to @function and @reserveEntireSlot),
- * and set @dev->addr.pci with this newly reserved address.
+ * connection @flags, mark one function of the slot as in-use
+ * (according to @function), then set @dev->addr.pci with this newly
+ * reserved address. If @function is -1, then the lowest unused
+ * function of the slot will be reserved (and since we only look for
+ * completely unused slots, that means "0").
*
* returns 0 on success, or -1 on failure.
*/
virDomainPCIAddressReserveNextAddr(virDomainPCIAddressSetPtr addrs,
virDomainDeviceInfoPtr dev,
virDomainPCIConnectFlags flags,
- unsigned int function,
- bool reserveEntireSlot)
+ int function)
{
virPCIDeviceAddress addr;
- if (virDomainPCIAddressGetNextSlot(addrs, &addr, flags) < 0)
+ if (virDomainPCIAddressGetNextSlot(addrs, &addr, function, flags) < 0)
return -1;
- addr.function = reserveEntireSlot ? 0 : function;
-
- if (virDomainPCIAddressReserveAddr(addrs, &addr, flags, reserveEntireSlot, false) < 0)
+ if (virDomainPCIAddressReserveAddr(addrs, &addr, flags, false) < 0)
return -1;
addrs->lastaddr = addr;
virDomainDeviceInfoPtr dev,
virDomainPCIConnectFlags flags)
{
- return virDomainPCIAddressReserveNextAddr(addrs, dev, flags, 0, true);
+ return virDomainPCIAddressReserveNextAddr(addrs, dev, flags, 0);
}
static int
qemuDomainPCIAddressReserveNextAddr(virDomainPCIAddressSetPtr addrs,
virDomainDeviceInfoPtr dev,
- unsigned int function,
- bool reserveEntireSlot)
+ unsigned int function)
{
return virDomainPCIAddressReserveNextAddr(addrs, dev,
dev->pciConnectFlags,
- function, reserveEntireSlot);
+ function);
}
qemuDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs,
virDomainDeviceInfoPtr dev)
{
- return qemuDomainPCIAddressReserveNextAddr(addrs, dev, 0, true);
+ return qemuDomainPCIAddressReserveNextAddr(addrs, dev, 0);
}
virDomainPCIAddressSetPtr addrs = opaque;
int ret = -1;
virPCIDeviceAddressPtr addr = &info->addr.pci;
- bool entireSlot;
if (!virDeviceInfoPCIAddressPresent(info) ||
((device->type == VIR_DOMAIN_DEVICE_HOSTDEV) &&
}
}
- entireSlot = (addr->function == 0 &&
- addr->multi != VIR_TRISTATE_SWITCH_ON);
-
- if (virDomainPCIAddressReserveAddr(addrs, addr, info->pciConnectFlags,
- entireSlot, true) < 0)
+ if (virDomainPCIAddressReserveAddr(addrs, addr,
+ info->pciConnectFlags, true) < 0) {
goto cleanup;
+ }
ret = 0;
cleanup:
}
if (assign) {
if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr,
- flags, false, true) < 0)
+ flags, true) < 0)
goto cleanup;
cont->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
cont->info.addr.pci.domain = 0;
tmp_addr.slot = 0x1E;
if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) {
if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr,
- flags, true, false) < 0)
+ flags, false) < 0)
goto cleanup;
cont->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
cont->info.addr.pci.domain = 0;
tmp_addr.slot = 0x1F;
tmp_addr.function = 0;
tmp_addr.multi = VIR_TRISTATE_SWITCH_ON;
- if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
- false, false) < 0)
+ if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr,
+ flags, false) < 0)
goto cleanup;
tmp_addr.function = 3;
tmp_addr.multi = VIR_TRISTATE_SWITCH_ABSENT;
- if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags,
- false, false) < 0)
+ if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr,
+ flags, false) < 0)
goto cleanup;
}
/* Reserve this function on the slot we found */
if (virDomainPCIAddressReserveAddr(addrs, &addr,
cont->info.pciConnectFlags,
- false, true) < 0)
+ true) < 0)
goto error;
cont->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
/* This is the first part of the controller, so need
* to find a free slot & then reserve this function */
if (qemuDomainPCIAddressReserveNextAddr(addrs, &cont->info,
- addr.function,
- false) < 0) {
+ addr.function) < 0) {
goto error;
}