There are two places in qemu_domain_address.c where we have a switch statement to convert PCI controller models (VIR_DOMAIN_CONTROLLER_MODEL_PCI*) into the connection type flag that is matched when looking for an upstream connection for that model of controller (VIR_PCI_CONNECT_TYPE_*). This patch makes a utility function in conf/domain_addr.c to do that, so that when a new PCI controller is added, we only need to add the new model-->connect-type in a single place. --- src/conf/domain_addr.c | 47 +++++++++++++++++++++++++ src/conf/domain_addr.h | 4 +++ src/libvirt_private.syms | 1 + src/qemu/qemu_domain_address.c | 80 +++++------------------------------------- 4 files changed, 61 insertions(+), 71 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 4408c4a..1bf2c9a 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -32,6 +32,53 @@ VIR_LOG_INIT("conf.domain_addr"); +int +virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model, + virDomainPCIConnectFlags *connectType) +{ + /* given a VIR_DOMAIN_CONTROLLER_MODEL_PCI*, set connectType to + * the equivalent VIR_PCI_CONNECT_TYPE_*. return 0 on success, -1 + * if the model wasn't recognized. + */ + switch (model) { + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + /* pci-root and pcie-root are implicit in the machine, + * and have no upstream connection + */ + *connectType = 0; + break; + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: + /* pci-bridge is treated like a standard PCI endpoint device, */ + *connectType = VIR_PCI_CONNECT_TYPE_PCI_DEVICE; + break; + case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: + /* dmi-to-pci-bridge is treated like a PCIe device + * (e.g. it can be plugged directly into pcie-root) + */ + *connectType = VIR_PCI_CONNECT_TYPE_PCIE_DEVICE; + break; + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: + *connectType = VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT; + break; + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: + *connectType = VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT; + break; + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: + *connectType = VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_DOWNSTREAM_PORT; + break; + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: + /* if this happens, there is an error in the code. A + * PCI controller should always have a proper model + * set + */ + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("PCI controller model incorrectly set to 'last'")); + return -1; + } + return 0; +} + bool virDomainPCIAddressFlagsCompatible(virDevicePCIAddressPtr addr, const char *addrStr, diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index b5cb0ee..eadfaf1 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -59,6 +59,10 @@ typedef enum { # define VIR_PCI_CONNECT_TYPES_ENDPOINT \ (VIR_PCI_CONNECT_TYPE_PCI_DEVICE | VIR_PCI_CONNECT_TYPE_PCIE_DEVICE) +int +virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model, + virDomainPCIConnectFlags *connectType); + typedef struct { virDomainControllerModelPCI model; /* flags and min/max can be computed from model, but diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index af133c5..6642f3a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -107,6 +107,7 @@ virDomainPCIAddressSetFree; virDomainPCIAddressSetGrow; virDomainPCIAddressSlotInUse; virDomainPCIAddressValidate; +virDomainPCIControllerModelToConnectType; virDomainVirtioSerialAddrAssign; virDomainVirtioSerialAddrAutoAssign; virDomainVirtioSerialAddrIsComplete; diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index c6e694e..7d3e441 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -446,39 +446,9 @@ qemuDomainCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED, case VIR_DOMAIN_DEVICE_CONTROLLER: switch (device->data.controller->type) { case VIR_DOMAIN_CONTROLLER_TYPE_PCI: - switch (device->data.controller->model) { - case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: - /* pci-bridge needs a PCI slot, but it isn't - * hot-pluggable, so it doesn't need a hot-pluggable slot. - */ - flags = VIR_PCI_CONNECT_TYPE_PCI_DEVICE; - 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 = VIR_PCI_CONNECT_TYPE_PCIE_DEVICE; - break; - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: - /* pcie-root-port isn't hot-pluggable, and - * is unique in what it can connect to, so - * it has its own flag. - */ - flags = VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT; - break; - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: - /* pcie-switch-upstream-port is also unique, and - * not hot-pluggable... - */ - flags = VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT; - break; - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: - /* ... same for pcie-switch-downstream-port */ - flags = VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_DOWNSTREAM_PORT; - break; - default: - break; - } + if (virDomainPCIControllerModelToConnectType(device->data.controller->model, + &flags) < 0) + return -1; break; case VIR_DOMAIN_CONTROLLER_TYPE_SATA: @@ -1058,51 +1028,19 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, /* PCI controllers */ for (i = 0; i < def->ncontrollers; i++) { if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) { - if (def->controllers[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + virDomainControllerModelPCI model = def->controllers[i]->model; + + if (def->controllers[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE || + model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT || + model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) continue; /* convert the type of controller into a "CONNECT_TYPE" * flag to use when searching for the proper * controller/bus to connect it to on the upstream side. */ - switch ((virDomainControllerModelPCI)def->controllers[i]->model) { - case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT: - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: - /* pci-root and pcie-root are implicit in the machine, - * and need no address */ - continue; - case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: - /* pci-bridge doesn't require hot-plug - * (although it does provide hot-plug in its slots) - */ - flags = VIR_PCI_CONNECT_TYPE_PCI_DEVICE; - break; - case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: - /* dmi-to-pci-bridge is treated like a - * non-hotplug-capable PCIe device (e.g. it can be - * plugged directly into pcie-root) - */ - flags = VIR_PCI_CONNECT_TYPE_PCIE_DEVICE; - break; - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: - flags = VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT; - break; - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: - flags = VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT; - break; - case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: - flags = VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_DOWNSTREAM_PORT; - break; - - case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: - /* if this happens, there is an error in the code. A - * PCI controller should always have a proper model - * set - */ - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("PCI controller model icorrectly set to 'last'")); + if (virDomainPCIControllerModelToConnectType(model, &flags) < 0) goto error; - } if (virDomainPCIAddressReserveNextSlot(addrs, &def->controllers[i]->info, flags) < 0) -- 2.5.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list