#define QEMU_PCI_ADDRESS_SLOT_LAST 32
#define QEMU_PCI_ADDRESS_FUNCTION_LAST 8
-/*
- * Each bit represents a function
- * Each byte represents a slot
- */
-typedef uint8_t qemuDomainPCIAddressBus[QEMU_PCI_ADDRESS_SLOT_LAST];
+typedef struct {
+ /* Each bit in a slot represents one function on that slot */
+ uint8_t slots[QEMU_PCI_ADDRESS_SLOT_LAST];
+} qemuDomainPCIAddressBus;
+typedef qemuDomainPCIAddressBus *qemuDomainPCIAddressBusPtr;
+
struct _qemuDomainPCIAddressSet {
- qemuDomainPCIAddressBus *used;
+ qemuDomainPCIAddressBus *buses;
+ size_t nbuses;
virDevicePCIAddress lastaddr;
- size_t nbuses; /* allocation of 'used' */
bool dryRun; /* on a dry run, new buses are auto-added
and addresses aren't saved in device infos */
};
i = addrs->nbuses;
if (add <= 0)
return 0;
- if (VIR_EXPAND_N(addrs->used, addrs->nbuses, add) < 0)
+ if (VIR_EXPAND_N(addrs->buses, addrs->nbuses, add) < 0)
return -1;
/* reserve slot 0 on the new buses */
for (; i < addrs->nbuses; i++)
- addrs->used[i][0] = 0xFF;
+ addrs->buses[i].slots[0] = 0xFF;
return add;
}
if (!(str = qemuPCIAddressAsString(addr)))
goto cleanup;
- if (addrs->used[addr->bus][addr->slot] & (1 << addr->function)) {
+ if (addrs->buses[addr->bus].slots[addr->slot] & (1 << addr->function)) {
if (info->addr.pci.function != 0) {
virReportError(VIR_ERR_XML_ERROR,
_("Attempted double use of PCI Address '%s' "
if ((info->addr.pci.function == 0) &&
(info->addr.pci.multi != VIR_DEVICE_ADDRESS_PCI_MULTI_ON)) {
/* a function 0 w/o multifunction=on must reserve the entire slot */
- if (addrs->used[addr->bus][addr->slot]) {
+ if (addrs->buses[addr->bus].slots[addr->slot]) {
virReportError(VIR_ERR_XML_ERROR,
_("Attempted double use of PCI Address on slot '%s' "
"(need \"multifunction='off'\" for device "
str);
goto cleanup;
}
- addrs->used[addr->bus][addr->slot] = 0xFF;
+ addrs->buses[addr->bus].slots[addr->slot] = 0xFF;
VIR_DEBUG("Remembering PCI slot: %s (multifunction=off)", str);
} else {
VIR_DEBUG("Remembering PCI addr: %s", str);
- addrs->used[addr->bus][addr->slot] |= 1 << addr->function;
+ addrs->buses[addr->bus].slots[addr->slot] |= 1 << addr->function;
}
ret = 0;
cleanup:
if (VIR_ALLOC(addrs) < 0)
goto error;
- if (VIR_ALLOC_N(addrs->used, nbuses) < 0)
+ if (VIR_ALLOC_N(addrs->buses, nbuses) < 0)
goto error;
addrs->nbuses = nbuses;
/* reserve slot 0 in every bus - it's used by the host bridge on bus 0
* and unusable on PCI bridges */
for (i = 0; i < nbuses; i++)
- addrs->used[i][0] = 0xFF;
+ addrs->buses[i].slots[0] = 0xFF;
if (virDomainDeviceInfoIterate(def, qemuCollectPCIAddress, addrs) < 0)
goto error;
static bool qemuDomainPCIAddressSlotInUse(qemuDomainPCIAddressSetPtr addrs,
virDevicePCIAddressPtr addr)
{
- return !!addrs->used[addr->bus][addr->slot];
+ return !!addrs->buses[addr->bus].slots[addr->slot];
}
int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
VIR_DEBUG("Reserving PCI addr %s", str);
- if (addrs->used[addr->bus][addr->slot] & (1 << addr->function)) {
+ if (addrs->buses[addr->bus].slots[addr->slot] & (1 << addr->function)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unable to reserve PCI address %s"), str);
VIR_FREE(str);
addrs->lastaddr = *addr;
addrs->lastaddr.function = 0;
addrs->lastaddr.multi = 0;
- addrs->used[addr->bus][addr->slot] |= 1 << addr->function;
+ addrs->buses[addr->bus].slots[addr->slot] |= 1 << addr->function;
return 0;
}
VIR_DEBUG("Reserving PCI slot %s", str);
- if (addrs->used[addr->bus][addr->slot]) {
+ if (addrs->buses[addr->bus].slots[addr->slot]) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unable to reserve PCI slot %s"), str);
VIR_FREE(str);
}
VIR_FREE(str);
- addrs->used[addr->bus][addr->slot] = 0xFF;
+ addrs->buses[addr->bus].slots[addr->slot] = 0xFF;
return 0;
}
int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs,
virDevicePCIAddressPtr addr)
{
- addrs->used[addr->bus][addr->slot] &= ~(1 << addr->function);
+ addrs->buses[addr->bus].slots[addr->slot] &= ~(1 << addr->function);
return 0;
}
if (!qemuPCIAddressValidate(addrs, addr))
return -1;
- addrs->used[addr->bus][addr->slot] = 0;
+ addrs->buses[addr->bus].slots[addr->slot] = 0;
return 0;
}
if (!addrs)
return;
- VIR_FREE(addrs->used);
+ VIR_FREE(addrs->buses);
VIR_FREE(addrs);
}