Extract PCI handling related structs that could be shared
with other drivers.
List of structs moved to virpci.h and new names:
qemuDomainPCIAddressBus -> virDomainPCIAddressBus
qemuDomainPCIAddressBusPtr -> virDomainPCIAddressBusPtr
_qemuDomainPCIAddressSet -> virDomainPCIAddressSet
qemuDomainPCIAddressSetPtr -> virDomainPCIAddressSetPtr
qemuDomainPCIConnectFlags -> virDomainPCIConnectFlags
Also, extract qemuDomainPCIAddressAsString function and rename
it into virPCIDeviceAddressAsString.
---
src/Makefile.am | 2 +-
src/libvirt_private.syms | 1 +
src/qemu/qemu_command.c | 201 +++++++++++++++++++----------------------------
src/qemu/qemu_command.h | 40 +++-------
src/qemu/qemu_domain.h | 5 +-
src/util/virpci.c | 14 ++++
src/util/virpci.h | 48 +++++++++++
tools/Makefile.am | 1 +
8 files changed, 158 insertions(+), 154 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index e9dc9e0..8f95d02 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -979,7 +979,7 @@ libvirt_util_la_LIBADD = $(CAPNG_LIBS) $(YAJL_LIBS) $(LIBNL_LIBS) \
noinst_LTLIBRARIES += libvirt_conf.la
libvirt_la_BUILT_LIBADD += libvirt_conf.la
libvirt_conf_la_SOURCES = $(CONF_SOURCES)
-libvirt_conf_la_CFLAGS = $(AM_CFLAGS)
+libvirt_conf_la_CFLAGS = -I$(top_srcdir)/src/conf $(AM_CFLAGS)
libvirt_conf_la_LDFLAGS = $(AM_LDFLAGS)
noinst_LTLIBRARIES += libvirt_cpu.la
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index cc3ae2c..657ca22 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1661,6 +1661,7 @@ virObjectUnref;
# util/virpci.h
+virPCIDeviceAddressAsString;
virPCIDeviceAddressGetIOMMUGroupAddresses;
virPCIDeviceAddressGetIOMMUGroupNum;
virPCIDeviceAddressGetSysfsFile;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 96072cf..a9c6a9a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1443,47 +1443,20 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
return ret;
}
-#define QEMU_PCI_ADDRESS_SLOT_LAST 31
-#define QEMU_PCI_ADDRESS_FUNCTION_LAST 7
-
-typedef struct {
- virDomainControllerModelPCI model;
- /* flags an min/max can be computed from model, but
- * having them ready makes life easier.
- */
- qemuDomainPCIConnectFlags flags;
- size_t minSlot, maxSlot; /* usually 0,0 or 1,31 */
- /* 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[QEMU_PCI_ADDRESS_SLOT_LAST + 1];
-} qemuDomainPCIAddressBus;
-typedef qemuDomainPCIAddressBus *qemuDomainPCIAddressBusPtr;
-
-struct _qemuDomainPCIAddressSet {
- qemuDomainPCIAddressBus *buses;
- size_t nbuses;
- virDevicePCIAddress lastaddr;
- qemuDomainPCIConnectFlags lastFlags;
- bool dryRun; /* on a dry run, new buses are auto-added
- and addresses aren't saved in device infos */
-};
-
-
static bool
qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
const char *addrStr,
- qemuDomainPCIConnectFlags busFlags,
- qemuDomainPCIConnectFlags devFlags,
+ virDomainPCIConnectFlags busFlags,
+ virDomainPCIConnectFlags devFlags,
bool reportError,
bool fromConfig)
{
virErrorNumber errType = (fromConfig
? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
- qemuDomainPCIConnectFlags flagsMatchMask = QEMU_PCI_CONNECT_TYPES_MASK;
+ virDomainPCIConnectFlags flagsMatchMask = QEMU_PCI_CONNECT_TYPES_MASK;
if (fromConfig)
- flagsMatchMask |= QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG;
+ flagsMatchMask |= VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG;
/* If this bus doesn't allow the type of connection (PCI
* vs. PCIe) required by the device, or if the device requires
@@ -1491,13 +1464,13 @@ qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
*/
if (!(devFlags & busFlags & flagsMatchMask)) {
if (reportError) {
- if (devFlags & QEMU_PCI_CONNECT_TYPE_PCI) {
+ if (devFlags & VIR_PCI_CONNECT_TYPE_PCI) {
virReportError(errType,
_("PCI bus is not compatible with the device "
"at %s. Device requires a standard PCI slot,
"
"which is not provided by bus %.4x:%.2x"),
addrStr, addr->domain, addr->bus);
- } else if (devFlags & QEMU_PCI_CONNECT_TYPE_PCIE) {
+ } else if (devFlags & VIR_PCI_CONNECT_TYPE_PCIE) {
virReportError(errType,
_("PCI bus is not compatible with the device "
"at %s. Device requires a PCI Express slot, "
@@ -1514,8 +1487,8 @@ qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
}
return false;
}
- if ((devFlags & QEMU_PCI_CONNECT_HOTPLUGGABLE) &&
- !(busFlags & QEMU_PCI_CONNECT_HOTPLUGGABLE)) {
+ if ((devFlags & VIR_PCI_CONNECT_HOTPLUGGABLE) &&
+ !(busFlags & VIR_PCI_CONNECT_HOTPLUGGABLE)) {
if (reportError) {
virReportError(errType,
_("PCI bus is not compatible with the device "
@@ -1534,13 +1507,13 @@ qemuDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr,
* comparing the flags).
*/
static bool
-qemuDomainPCIAddressValidate(qemuDomainPCIAddressSetPtr addrs,
+qemuDomainPCIAddressValidate(virDomainPCIAddressSetPtr addrs,
virDevicePCIAddressPtr addr,
const char *addrStr,
- qemuDomainPCIConnectFlags flags,
+ virDomainPCIConnectFlags flags,
bool fromConfig)
{
- qemuDomainPCIAddressBusPtr bus;
+ virDomainPCIAddressBusPtr bus;
virErrorNumber errType = (fromConfig
? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
@@ -1585,10 +1558,10 @@ qemuDomainPCIAddressValidate(qemuDomainPCIAddressSetPtr addrs,
addrStr, bus->maxSlot);
return false;
}
- if (addr->function > QEMU_PCI_ADDRESS_FUNCTION_LAST) {
+ if (addr->function > VIR_PCI_ADDRESS_FUNCTION_LAST) {
virReportError(errType,
_("Invalid PCI address %s. function must be <= %u"),
- addrStr, QEMU_PCI_ADDRESS_FUNCTION_LAST);
+ addrStr, VIR_PCI_ADDRESS_FUNCTION_LAST);
return false;
}
return true;
@@ -1596,33 +1569,33 @@ qemuDomainPCIAddressValidate(qemuDomainPCIAddressSetPtr addrs,
static int
-qemuDomainPCIAddressBusSetModel(qemuDomainPCIAddressBusPtr bus,
+qemuDomainPCIAddressBusSetModel(virDomainPCIAddressBusPtr bus,
virDomainControllerModelPCI model)
{
switch (model) {
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
- bus->flags = (QEMU_PCI_CONNECT_HOTPLUGGABLE |
- QEMU_PCI_CONNECT_TYPE_PCI);
+ bus->flags = (VIR_PCI_CONNECT_HOTPLUGGABLE |
+ VIR_PCI_CONNECT_TYPE_PCI);
bus->minSlot = 1;
- bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST;
+ bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
break;
case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
/* slots 1 - 31, no hotplug, PCIe only unless the address was
* specified in user config *and* the particular device being
* attached also allows it
*/
- bus->flags = (QEMU_PCI_CONNECT_TYPE_PCIE |
- QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG);
+ bus->flags = (VIR_PCI_CONNECT_TYPE_PCIE |
+ VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG);
bus->minSlot = 1;
- bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST;
+ bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
break;
case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
/* slots 1 - 31, standard PCI slots,
* but *not* hot-pluggable */
- bus->flags = QEMU_PCI_CONNECT_TYPE_PCI;
+ bus->flags = VIR_PCI_CONNECT_TYPE_PCI;
bus->minSlot = 1;
- bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST;
+ bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST;
break;
default:
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -1646,9 +1619,9 @@ qemuDomainPCIAddressBusSetModel(qemuDomainPCIAddressBusPtr bus,
* >0 = number of buses added
*/
static int
-qemuDomainPCIAddressSetGrow(qemuDomainPCIAddressSetPtr addrs,
+qemuDomainPCIAddressSetGrow(virDomainPCIAddressSetPtr addrs,
virDevicePCIAddressPtr addr,
- qemuDomainPCIConnectFlags flags)
+ virDomainPCIConnectFlags flags)
{
int add;
size_t i;
@@ -1659,7 +1632,7 @@ qemuDomainPCIAddressSetGrow(qemuDomainPCIAddressSetPtr addrs,
return 0;
/* auto-grow only works when we're adding plain PCI devices */
- if (!(flags & QEMU_PCI_CONNECT_TYPE_PCI)) {
+ 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."));
@@ -1682,33 +1655,19 @@ qemuDomainPCIAddressSetGrow(qemuDomainPCIAddressSetPtr addrs,
}
-static char *
-qemuDomainPCIAddressAsString(virDevicePCIAddressPtr addr)
-{
- char *str;
-
- ignore_value(virAsprintf(&str, "%.4x:%.2x:%.2x.%.1x",
- addr->domain,
- addr->bus,
- addr->slot,
- addr->function));
- return str;
-}
-
-
static int
qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
virDomainDeviceDefPtr device,
virDomainDeviceInfoPtr info,
void *opaque)
{
- qemuDomainPCIAddressSetPtr addrs = opaque;
+ virDomainPCIAddressSetPtr addrs = opaque;
int ret = -1;
virDevicePCIAddressPtr addr = &info->addr.pci;
bool entireSlot;
/* flags may be changed from default below */
- qemuDomainPCIConnectFlags flags = (QEMU_PCI_CONNECT_HOTPLUGGABLE |
- QEMU_PCI_CONNECT_TYPE_PCI);
+ virDomainPCIConnectFlags flags = (VIR_PCI_CONNECT_HOTPLUGGABLE |
+ VIR_PCI_CONNECT_TYPE_PCI);
if ((info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
|| ((device->type == VIR_DOMAIN_DEVICE_HOSTDEV) &&
@@ -1732,13 +1691,13 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
/* pci-bridge needs a PCI slot, but it isn't
* hot-pluggable, so it doesn't need a hot-pluggable slot.
*/
- flags = QEMU_PCI_CONNECT_TYPE_PCI;
+ flags = VIR_PCI_CONNECT_TYPE_PCI;
break;
case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
/* pci-bridge needs a PCIe slot, but it isn't
* hot-pluggable, so it doesn't need a hot-pluggable slot.
*/
- flags = QEMU_PCI_CONNECT_TYPE_PCIE;
+ flags = VIR_PCI_CONNECT_TYPE_PCIE;
break;
default:
break;
@@ -1749,7 +1708,7 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
/* SATA controllers aren't hot-plugged, and can be put in
* either a PCI or PCIe slot
*/
- flags = QEMU_PCI_CONNECT_TYPE_PCI | QEMU_PCI_CONNECT_TYPE_PCIE;
+ flags = VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE;
break;
case VIR_DOMAIN_CONTROLLER_TYPE_USB:
@@ -1763,14 +1722,14 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI2:
case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI3:
case VIR_DOMAIN_CONTROLLER_MODEL_USB_VT82C686B_UHCI:
- flags = (QEMU_PCI_CONNECT_TYPE_PCI |
- QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG);
+ flags = (VIR_PCI_CONNECT_TYPE_PCI |
+ VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG);
break;
case VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI:
/* should this be PCIE-only? Or do we need to allow PCI
* for backward compatibility?
*/
- flags = QEMU_PCI_CONNECT_TYPE_PCI | QEMU_PCI_CONNECT_TYPE_PCIE;
+ flags = VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE;
break;
case VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI:
case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI:
@@ -1785,8 +1744,8 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
switch (device->data.sound->model) {
case VIR_DOMAIN_SOUND_MODEL_ICH6:
case VIR_DOMAIN_SOUND_MODEL_ICH9:
- flags = (QEMU_PCI_CONNECT_TYPE_PCI |
- QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG);
+ flags = (VIR_PCI_CONNECT_TYPE_PCI |
+ VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG);
break;
}
break;
@@ -1795,7 +1754,7 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
/* video cards aren't hot-plugged, and can be put in either a
* PCI or PCIe slot
*/
- flags = QEMU_PCI_CONNECT_TYPE_PCI | QEMU_PCI_CONNECT_TYPE_PCIE;
+ flags = VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE;
break;
}
@@ -1827,7 +1786,7 @@ qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
* commandline, but that don't really care if a PCI bus
* actually exists. */
if (addrs->nbuses > 0 &&
- !(addrs->buses[0].flags & QEMU_PCI_CONNECT_TYPE_PCI)) {
+ !(addrs->buses[0].flags & VIR_PCI_CONNECT_TYPE_PCI)) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Bus 0 must be PCI for integrated PIIX3 "
"USB or IDE controllers"));
@@ -1868,7 +1827,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
virDomainObjPtr obj)
{
int ret = -1;
- qemuDomainPCIAddressSetPtr addrs = NULL;
+ virDomainPCIAddressSetPtr addrs = NULL;
qemuDomainObjPrivatePtr priv = NULL;
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
@@ -1876,7 +1835,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
int nbuses = 0;
size_t i;
int rv;
- qemuDomainPCIConnectFlags flags = QEMU_PCI_CONNECT_TYPE_PCI;
+ virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCI;
for (i = 0; i < def->ncontrollers; i++) {
if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) {
@@ -1901,7 +1860,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
goto cleanup;
for (i = 1; i < addrs->nbuses; i++) {
- qemuDomainPCIAddressBusPtr bus = &addrs->buses[i];
+ virDomainPCIAddressBusPtr bus = &addrs->buses[i];
if ((rv = virDomainDefMaybeAddController(
def, VIR_DOMAIN_CONTROLLER_TYPE_PCI,
@@ -1975,12 +1934,12 @@ int qemuDomainAssignAddresses(virDomainDefPtr def,
}
-qemuDomainPCIAddressSetPtr
+virDomainPCIAddressSetPtr
qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
unsigned int nbuses,
bool dryRun)
{
- qemuDomainPCIAddressSetPtr addrs;
+ virDomainPCIAddressSetPtr addrs;
size_t i;
if (VIR_ALLOC(addrs) < 0)
@@ -2038,7 +1997,7 @@ qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
/*
* Check if the PCI slot is used by another device.
*/
-static bool qemuDomainPCIAddressSlotInUse(qemuDomainPCIAddressSetPtr addrs,
+static bool qemuDomainPCIAddressSlotInUse(virDomainPCIAddressSetPtr addrs,
virDevicePCIAddressPtr addr)
{
return !!addrs->buses[addr->bus].slots[addr->slot];
@@ -2055,19 +2014,19 @@ static bool
qemuDomainPCIAddressSlotInUse(qemuDomainPCIAddressSetPtr addrs,
* XML).
*/
int
-qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
+qemuDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs,
virDevicePCIAddressPtr addr,
- qemuDomainPCIConnectFlags flags,
+ virDomainPCIConnectFlags flags,
bool reserveEntireSlot,
bool fromConfig)
{
int ret = -1;
char *addrStr = NULL;
- qemuDomainPCIAddressBusPtr bus;
+ virDomainPCIAddressBusPtr bus;
virErrorNumber errType = (fromConfig
? VIR_ERR_XML_ERROR : VIR_ERR_INTERNAL_ERROR);
- if (!(addrStr = qemuDomainPCIAddressAsString(addr)))
+ if (!(addrStr = virPCIDeviceAddressAsString(addr)))
goto cleanup;
/* Add an extra bus if necessary */
@@ -2117,14 +2076,14 @@ qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
int
-qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
+qemuDomainPCIAddressReserveSlot(virDomainPCIAddressSetPtr addrs,
virDevicePCIAddressPtr addr,
- qemuDomainPCIConnectFlags flags)
+ virDomainPCIConnectFlags flags)
{
return qemuDomainPCIAddressReserveAddr(addrs, addr, flags, true, false);
}
-int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
+int qemuDomainPCIAddressEnsureAddr(virDomainPCIAddressSetPtr addrs,
virDomainDeviceInfoPtr dev)
{
int ret = -1;
@@ -2134,10 +2093,10 @@ int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr
addrs,
* function is only used for hot-plug, though, and hot-plug is
* only supported for standard PCI devices, so we can safely use
* the setting below */
- qemuDomainPCIConnectFlags flags = (QEMU_PCI_CONNECT_HOTPLUGGABLE |
- QEMU_PCI_CONNECT_TYPE_PCI);
+ virDomainPCIConnectFlags flags = (VIR_PCI_CONNECT_HOTPLUGGABLE |
+ VIR_PCI_CONNECT_TYPE_PCI);
- if (!(addrStr = qemuDomainPCIAddressAsString(&dev->addr.pci)))
+ if (!(addrStr = virPCIDeviceAddressAsString(&dev->addr.pci)))
goto cleanup;
if (dev->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
@@ -2166,7 +2125,7 @@ int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr
addrs,
}
-int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs,
+int qemuDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs,
virDevicePCIAddressPtr addr)
{
addrs->buses[addr->bus].slots[addr->slot] &= ~(1 <<
addr->function);
@@ -2174,17 +2133,17 @@ int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr
addrs,
}
static int
-qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs,
+qemuDomainPCIAddressReleaseSlot(virDomainPCIAddressSetPtr addrs,
virDevicePCIAddressPtr addr)
{
/* permit any kind of connection type in validation, since we
* already had it, and are giving it back.
*/
- qemuDomainPCIConnectFlags flags = QEMU_PCI_CONNECT_TYPES_MASK;
+ virDomainPCIConnectFlags flags = QEMU_PCI_CONNECT_TYPES_MASK;
int ret = -1;
char *addrStr = NULL;
- if (!(addrStr = qemuDomainPCIAddressAsString(addr)))
+ if (!(addrStr = virPCIDeviceAddressAsString(addr)))
goto cleanup;
if (!qemuDomainPCIAddressValidate(addrs, addr, addrStr, flags, false))
@@ -2197,7 +2156,7 @@ qemuDomainPCIAddressReleaseSlot(qemuDomainPCIAddressSetPtr addrs,
return ret;
}
-void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs)
+void qemuDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs)
{
if (!addrs)
return;
@@ -2208,9 +2167,9 @@ void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs)
static int
-qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs,
+qemuDomainPCIAddressGetNextSlot(virDomainPCIAddressSetPtr addrs,
virDevicePCIAddressPtr next_addr,
- qemuDomainPCIConnectFlags flags)
+ virDomainPCIConnectFlags flags)
{
/* default to starting the search for a free slot from
* 0000:00:00.0
@@ -2231,7 +2190,7 @@ qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs,
/* Start the search at the last used bus and slot */
for (a.slot++; a.bus < addrs->nbuses; a.bus++) {
- if (!(addrStr = qemuDomainPCIAddressAsString(&a)))
+ if (!(addrStr = virPCIDeviceAddressAsString(&a)))
goto error;
if (!qemuDomainPCIAddressFlagsCompatible(&a, addrStr,
addrs->buses[a.bus].flags,
@@ -2241,7 +2200,7 @@ qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs,
a.domain, a.bus);
continue;
}
- for (; a.slot <= QEMU_PCI_ADDRESS_SLOT_LAST; a.slot++) {
+ for (; a.slot <= VIR_PCI_ADDRESS_SLOT_LAST; a.slot++) {
if (!qemuDomainPCIAddressSlotInUse(addrs, &a))
goto success;
@@ -2262,7 +2221,7 @@ qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs,
/* Check the buses from 0 up to the last used one */
for (a.bus = 0; a.bus <= addrs->lastaddr.bus; a.bus++) {
addrStr = NULL;
- if (!(addrStr = qemuDomainPCIAddressAsString(&a)))
+ if (!(addrStr = virPCIDeviceAddressAsString(&a)))
goto error;
if (!qemuDomainPCIAddressFlagsCompatible(&a, addrStr,
addrs->buses[a.bus].flags,
@@ -2271,7 +2230,7 @@ qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs,
a.domain, a.bus);
continue;
}
- for (a.slot = 1; a.slot <= QEMU_PCI_ADDRESS_SLOT_LAST; a.slot++) {
+ for (a.slot = 1; a.slot <= VIR_PCI_ADDRESS_SLOT_LAST; a.slot++) {
if (!qemuDomainPCIAddressSlotInUse(addrs, &a))
goto success;
@@ -2296,9 +2255,9 @@ qemuDomainPCIAddressGetNextSlot(qemuDomainPCIAddressSetPtr addrs,
}
int
-qemuDomainPCIAddressReserveNextSlot(qemuDomainPCIAddressSetPtr addrs,
+qemuDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs,
virDomainDeviceInfoPtr dev,
- qemuDomainPCIConnectFlags flags)
+ virDomainPCIConnectFlags flags)
{
virDevicePCIAddress addr;
if (qemuDomainPCIAddressGetNextSlot(addrs, &addr, flags) < 0)
@@ -2354,14 +2313,14 @@ qemuDomainReleaseDeviceAddress(virDomainObjPtr vm,
static int
qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
virQEMUCapsPtr qemuCaps,
- qemuDomainPCIAddressSetPtr addrs)
+ virDomainPCIAddressSetPtr addrs)
{
int ret = -1;
size_t i;
virDevicePCIAddress tmp_addr;
bool qemuDeviceVideoUsable = virQEMUCapsGet(qemuCaps,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
char *addrStr = NULL;
- qemuDomainPCIConnectFlags flags = QEMU_PCI_CONNECT_HOTPLUGGABLE |
QEMU_PCI_CONNECT_TYPE_PCI;
+ virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_HOTPLUGGABLE |
VIR_PCI_CONNECT_TYPE_PCI;
/* Verify that first IDE and USB controllers (if any) is on the PIIX3, fn 1 */
for (i = 0; i < def->ncontrollers; i++) {
@@ -2429,7 +2388,7 @@ qemuValidateDevicePCISlotsPIIX3(virDomainDefPtr def,
memset(&tmp_addr, 0, sizeof(tmp_addr));
tmp_addr.slot = 2;
- if (!(addrStr = qemuDomainPCIAddressAsString(&tmp_addr)))
+ if (!(addrStr = virPCIDeviceAddressAsString(&tmp_addr)))
goto cleanup;
if (!qemuDomainPCIAddressValidate(addrs, &tmp_addr,
addrStr, flags, false))
@@ -2507,14 +2466,14 @@ qemuDomainMachineIsI440FX(virDomainDefPtr def)
static int
qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
virQEMUCapsPtr qemuCaps,
- qemuDomainPCIAddressSetPtr addrs)
+ virDomainPCIAddressSetPtr addrs)
{
int ret = -1;
size_t i;
virDevicePCIAddress tmp_addr;
bool qemuDeviceVideoUsable = virQEMUCapsGet(qemuCaps,
QEMU_CAPS_DEVICE_VIDEO_PRIMARY);
char *addrStr = NULL;
- qemuDomainPCIConnectFlags flags = QEMU_PCI_CONNECT_TYPE_PCIE;
+ virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCIE;
for (i = 0; i < def->ncontrollers; i++) {
switch (def->controllers[i]->type) {
@@ -2599,7 +2558,7 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
memset(&tmp_addr, 0, sizeof(tmp_addr));
tmp_addr.slot = 1;
- if (!(addrStr = qemuDomainPCIAddressAsString(&tmp_addr)))
+ if (!(addrStr = virPCIDeviceAddressAsString(&tmp_addr)))
goto cleanup;
if (!qemuDomainPCIAddressValidate(addrs, &tmp_addr,
addrStr, flags, false))
@@ -2690,10 +2649,10 @@ qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def,
int
qemuAssignDevicePCISlots(virDomainDefPtr def,
virQEMUCapsPtr qemuCaps,
- qemuDomainPCIAddressSetPtr addrs)
+ virDomainPCIAddressSetPtr addrs)
{
size_t i, j;
- qemuDomainPCIConnectFlags flags;
+ virDomainPCIConnectFlags flags;
virDevicePCIAddress tmp_addr;
if ((STRPREFIX(def->os.machine, "pc-0.") ||
@@ -2725,16 +2684,16 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
/* pci-bridge doesn't require hot-plug
* (although it does provide hot-plug in its slots)
*/
- flags = QEMU_PCI_CONNECT_TYPE_PCI;
+ flags = VIR_PCI_CONNECT_TYPE_PCI;
break;
case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
/* dmi-to-pci-bridge requires a non-hotplug PCIe
* slot
*/
- flags = QEMU_PCI_CONNECT_TYPE_PCIE;
+ flags = VIR_PCI_CONNECT_TYPE_PCIE;
break;
default:
- flags = QEMU_PCI_CONNECT_HOTPLUGGABLE | QEMU_PCI_CONNECT_TYPE_PCI;
+ flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI;
break;
}
if (qemuDomainPCIAddressReserveNextSlot(addrs,
@@ -2744,7 +2703,7 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
}
}
- flags = QEMU_PCI_CONNECT_HOTPLUGGABLE | QEMU_PCI_CONNECT_TYPE_PCI;
+ flags = VIR_PCI_CONNECT_HOTPLUGGABLE | VIR_PCI_CONNECT_TYPE_PCI;
for (i = 0; i < def->nfss; i++) {
if (def->fss[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
@@ -3001,7 +2960,7 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
const char *contAlias = NULL;
size_t i;
- if (!(devStr = qemuDomainPCIAddressAsString(&info->addr.pci)))
+ if (!(devStr = virPCIDeviceAddressAsString(&info->addr.pci)))
goto cleanup;
for (i = 0; i < domainDef->ncontrollers; i++) {
virDomainControllerDefPtr cont = domainDef->controllers[i];
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 0866c6b..9ed7fc4 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -233,55 +233,39 @@ void qemuDomainReleaseDeviceAddress(virDomainObjPtr vm,
virDomainDeviceInfoPtr info,
const char *devstr);
-typedef enum {
- QEMU_PCI_CONNECT_HOTPLUGGABLE = 1 << 0,
- /* This bus supports hot-plug */
- QEMU_PCI_CONNECT_SINGLESLOT = 1 << 1,
- /* This "bus" has only a single downstream slot/port */
-
- QEMU_PCI_CONNECT_TYPE_PCI = 1 << 2,
- /* PCI devices can connect to this bus */
- QEMU_PCI_CONNECT_TYPE_PCIE = 1 << 3,
- /* PCI Express devices can connect to this bus */
- QEMU_PCI_CONNECT_TYPE_EITHER_IF_CONFIG = 1 << 4,
- /* PCI *and* PCIe devices allowed, if the address
- * was specified in the config by the user
- */
-} qemuDomainPCIConnectFlags;
-
/* a combination of all bit that describe the type of connections
* allowed, e.g. PCI, PCIe, switch
*/
# define QEMU_PCI_CONNECT_TYPES_MASK \
- (QEMU_PCI_CONNECT_TYPE_PCI | QEMU_PCI_CONNECT_TYPE_PCIE)
+ (VIR_PCI_CONNECT_TYPE_PCI | VIR_PCI_CONNECT_TYPE_PCIE)
int qemuDomainAssignPCIAddresses(virDomainDefPtr def,
virQEMUCapsPtr qemuCaps,
virDomainObjPtr obj);
-qemuDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
+virDomainPCIAddressSetPtr qemuDomainPCIAddressSetCreate(virDomainDefPtr def,
unsigned int nbuses,
bool dryRun);
-int qemuDomainPCIAddressReserveSlot(qemuDomainPCIAddressSetPtr addrs,
+int qemuDomainPCIAddressReserveSlot(virDomainPCIAddressSetPtr addrs,
virDevicePCIAddressPtr addr,
- qemuDomainPCIConnectFlags flags);
-int qemuDomainPCIAddressReserveAddr(qemuDomainPCIAddressSetPtr addrs,
+ virDomainPCIConnectFlags flags);
+int qemuDomainPCIAddressReserveAddr(virDomainPCIAddressSetPtr addrs,
virDevicePCIAddressPtr addr,
- qemuDomainPCIConnectFlags flags,
+ virDomainPCIConnectFlags flags,
bool reserveEntireSlot,
bool fromConfig);
-int qemuDomainPCIAddressReserveNextSlot(qemuDomainPCIAddressSetPtr addrs,
+int qemuDomainPCIAddressReserveNextSlot(virDomainPCIAddressSetPtr addrs,
virDomainDeviceInfoPtr dev,
- qemuDomainPCIConnectFlags flags);
-int qemuDomainPCIAddressEnsureAddr(qemuDomainPCIAddressSetPtr addrs,
+ virDomainPCIConnectFlags flags);
+int qemuDomainPCIAddressEnsureAddr(virDomainPCIAddressSetPtr addrs,
virDomainDeviceInfoPtr dev);
-int qemuDomainPCIAddressReleaseAddr(qemuDomainPCIAddressSetPtr addrs,
+int qemuDomainPCIAddressReleaseAddr(virDomainPCIAddressSetPtr addrs,
virDevicePCIAddressPtr addr);
-void qemuDomainPCIAddressSetFree(qemuDomainPCIAddressSetPtr addrs);
+void qemuDomainPCIAddressSetFree(virDomainPCIAddressSetPtr addrs);
int qemuAssignDevicePCISlots(virDomainDefPtr def,
virQEMUCapsPtr qemuCaps,
- qemuDomainPCIAddressSetPtr addrs);
+ virDomainPCIAddressSetPtr addrs);
int qemuDomainCCWAddressAssign(virDomainDeviceInfoPtr dev, qemuDomainCCWAddressSetPtr
addrs,
bool autoassign);
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 31611b5..d18a5b2 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -116,9 +116,6 @@ struct qemuDomainJobObj {
bool asyncAbort; /* abort of async job requested */
};
-typedef struct _qemuDomainPCIAddressSet qemuDomainPCIAddressSet;
-typedef qemuDomainPCIAddressSet *qemuDomainPCIAddressSetPtr;
-
typedef void (*qemuDomainCleanupCallback)(virQEMUDriverPtr driver,
virDomainObjPtr vm);
typedef struct _qemuDomainCCWAddressSet qemuDomainCCWAddressSet;
@@ -146,7 +143,7 @@ struct _qemuDomainObjPrivate {
int nvcpupids;
int *vcpupids;
- qemuDomainPCIAddressSetPtr pciaddrs;
+ virDomainPCIAddressSetPtr pciaddrs;
qemuDomainCCWAddressSetPtr ccwaddrs;
int persistentAddrs;
diff --git a/src/util/virpci.c b/src/util/virpci.c
index e0f2344..847122c 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -2378,6 +2378,20 @@ virPCIDeviceAddressParse(char *address,
return ret;
}
+char *
+virPCIDeviceAddressAsString(virDevicePCIAddressPtr addr)
+{
+ char *str;
+
+ ignore_value(virAsprintf(&str, "%.4x:%.2x:%.2x.%.1x",
+ addr->domain,
+ addr->bus,
+ addr->slot,
+ addr->function));
+ return str;
+}
+
+
#ifdef __linux__
/*
diff --git a/src/util/virpci.h b/src/util/virpci.h
index 20ffe54..21fe261 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -26,6 +26,7 @@
# include "internal.h"
# include "virobject.h"
+# include "domain_conf.h"
typedef struct _virPCIDevice virPCIDevice;
typedef virPCIDevice *virPCIDevicePtr;
@@ -41,6 +42,53 @@ struct _virPCIDeviceAddress {
unsigned int function;
};
+typedef enum {
+ VIR_PCI_CONNECT_HOTPLUGGABLE = 1 << 0,
+ /* This bus supports hot-plug */
+ VIR_PCI_CONNECT_SINGLESLOT = 1 << 1,
+ /* This "bus" has only a single downstream slot/port */
+
+ VIR_PCI_CONNECT_TYPE_PCI = 1 << 2,
+ /* PCI devices can connect to this bus */
+ VIR_PCI_CONNECT_TYPE_PCIE = 1 << 3,
+ /* PCI Express devices can connect to this bus */
+ VIR_PCI_CONNECT_TYPE_EITHER_IF_CONFIG = 1 << 4,
+ /* PCI *and* PCIe devices allowed, if the address
+ * was specified in the config by the user
+ */
+} virDomainPCIConnectFlags;
+
+# define VIR_PCI_ADDRESS_SLOT_LAST 31
+# define VIR_PCI_ADDRESS_FUNCTION_LAST 7
+
+typedef struct {
+ virDomainControllerModelPCI model;
+ /* flags an min/max can be computed from model, but
+ * having them ready makes life easier.
+ */
+ virDomainPCIConnectFlags flags;
+ size_t minSlot, maxSlot; /* usually 0,0 or 1,31 */
+ /* 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];
+} virDomainPCIAddressBus;
+typedef virDomainPCIAddressBus *virDomainPCIAddressBusPtr;
+
+
+typedef struct {
+ virDomainPCIAddressBus *buses;
+ size_t nbuses;
+ virDevicePCIAddress lastaddr;
+ virDomainPCIConnectFlags lastFlags;
+ bool dryRun; /* on a dry run, new buses are auto-added
+ and addresses aren't saved in device infos */
+} virDomainPCIAddressSet;
+typedef virDomainPCIAddressSet *virDomainPCIAddressSetPtr;
+
+char *virPCIDeviceAddressAsString(virDevicePCIAddressPtr addr)
+ ATTRIBUTE_NONNULL(1);
+
virPCIDevicePtr virPCIDeviceNew(unsigned int domain,
unsigned int bus,
unsigned int slot,
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 93d642d..e9eb434 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -18,6 +18,7 @@ INCLUDES = \
-I$(top_builddir)/include -I$(top_srcdir)/include \
-I$(top_builddir)/gnulib/lib -I$(top_srcdir)/gnulib/lib \
-I$(top_builddir)/src -I$(top_srcdir)/src \
+ -I$(top_srcdir)/src/conf \
-I$(top_srcdir)/src/util \
-I$(top_srcdir) \
$(GETTEXT_CPPFLAGS)
--
1.9.0