When keeping track of which functions of which slots are allocated, we
will need to have more information than just the current bitmap with a
bit for each function that is currently stored for each slot in a
virDomainPCIAddressBus. To prepare for adding more per-slot info, this
patch changes "int slots" into "virDomainPCIAddressSlot slot", which
currently has a single member named "functions" that serves the same
purpose previously served directly by "slots".
---
src/conf/domain_addr.c | 15 ++++++++-------
src/conf/domain_addr.h | 9 ++++++++-
src/qemu/qemu_domain_address.c | 2 +-
3 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
index 781050c..adc51f9 100644
--- a/src/conf/domain_addr.c
+++ b/src/conf/domain_addr.c
@@ -464,7 +464,7 @@ bool
virDomainPCIAddressSlotInUse(virDomainPCIAddressSetPtr addrs,
virPCIDeviceAddressPtr addr)
{
- return !!addrs->buses[addr->bus].slots[addr->slot];
+ return !!addrs->buses[addr->bus].slot[addr->slot].functions;
}
@@ -505,17 +505,17 @@ virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs,
bus = &addrs->buses[addr->bus];
if (reserveEntireSlot) {
- if (bus->slots[addr->slot]) {
+ 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->slots[addr->slot] = 0xFF; /* reserve all functions of slot */
+ bus->slot[addr->slot].functions = 0xFF; /* reserve all functions of slot
*/
VIR_DEBUG("Reserving PCI slot %s (multifunction='off')",
addrStr);
} else {
- if (bus->slots[addr->slot] & (1 << addr->function)) {
+ if (bus->slot[addr->slot].functions & (1 << addr->function))
{
if (addr->function == 0) {
virReportError(errType,
_("Attempted double use of PCI Address %s"),
@@ -528,7 +528,7 @@ virDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs,
}
goto cleanup;
}
- bus->slots[addr->slot] |= (1 << addr->function);
+ bus->slot[addr->slot].functions |= (1 << addr->function);
VIR_DEBUG("Reserving PCI address %s", addrStr);
}
@@ -595,7 +595,8 @@ int
virDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs,
virPCIDeviceAddressPtr addr)
{
- addrs->buses[addr->bus].slots[addr->slot] &= ~(1 <<
addr->function);
+ addrs->buses[addr->bus].slot[addr->slot].functions
+ &= ~(1 << addr->function);
return 0;
}
@@ -616,7 +617,7 @@ virDomainPCIAddressReleaseSlot(virDomainPCIAddressSetPtr addrs,
if (!virDomainPCIAddressValidate(addrs, addr, addrStr, flags, false))
goto cleanup;
- addrs->buses[addr->bus].slots[addr->slot] = 0;
+ addrs->buses[addr->bus].slot[addr->slot].functions = 0;
ret = 0;
cleanup:
VIR_FREE(addrStr);
diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h
index bcec2c7..7df0502 100644
--- a/src/conf/domain_addr.h
+++ b/src/conf/domain_addr.h
@@ -71,6 +71,13 @@ virDomainPCIConnectFlags
virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model);
typedef struct {
+ /* each function is represented by one it, set if that function is
+ * in use by a device, or clear if it isn't.
+ */
+ uint8_t functions;
+ } virDomainPCIAddressSlot;
+
+typedef struct {
virDomainControllerModelPCI model;
/* flags and min/max can be computed from model, but
* having them ready makes life easier.
@@ -80,7 +87,7 @@ typedef struct {
/* Each bit in a slot represents one function on that slot. If the
* bit is set, that function is in use by a device.
*/
- uint8_t slots[VIR_PCI_ADDRESS_SLOT_LAST + 1];
+ virDomainPCIAddressSlot slot[VIR_PCI_ADDRESS_SLOT_LAST + 1];
} virDomainPCIAddressBus;
typedef virDomainPCIAddressBus *virDomainPCIAddressBusPtr;
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
index 86984fb..a3dfd63 100644
--- a/src/qemu/qemu_domain_address.c
+++ b/src/qemu/qemu_domain_address.c
@@ -1462,7 +1462,7 @@ qemuDomainPCIBusFullyReserved(virDomainPCIAddressBusPtr bus)
size_t i;
for (i = bus->minSlot; i <= bus->maxSlot; i++)
- if (!bus->slots[i])
+ if (!bus->slot[i].functions)
return false;
return true;
--
2.7.4