From a0616ee8a8436e3784c20313b93ddd8909834541 Mon Sep 17 00:00:00 2001 From: Laine Stump Date: Wed, 16 Mar 2016 14:20:52 -0400 Subject: [PATCH] conf: utility function to convert PCI controller model into connect type 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 | 48 +++++++++++++++++++++ src/conf/domain_addr.h | 3 ++ src/libvirt_private.syms | 1 + src/qemu/qemu_domain_address.c | 79 +++------------------------------- 4 files changed, 59 insertions(+), 72 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 4408c4a728..7ee893f675 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -32,6 +32,54 @@ VIR_LOG_INIT("conf.domain_addr"); +virDomainPCIConnectFlags +virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model) +{ + /* 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_LAST: + 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, "last" will never actually + * happen, it's just there so that all possible cases are + * covered in the switch (keeps the compiler happy). + */ + return 0; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: + /* pci-bridge is treated like a standard PCI endpoint device, */ + return VIR_PCI_CONNECT_TYPE_PCI_DEVICE; + + 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) + */ + return VIR_PCI_CONNECT_TYPE_PCIE_DEVICE; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: + return VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: + return VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT; + + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: + return VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_DOWNSTREAM_PORT; + + /* 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 b5cb0eeb3c..5b5de8a31c 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -59,6 +59,9 @@ typedef enum { # define VIR_PCI_CONNECT_TYPES_ENDPOINT \ (VIR_PCI_CONNECT_TYPE_PCI_DEVICE | VIR_PCI_CONNECT_TYPE_PCIE_DEVICE) +virDomainPCIConnectFlags +virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model); + 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 abeba6c0fd..4ef51f04b0 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 c6e694eba4..911bbef00c 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -446,39 +446,7 @@ 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; - } + flags = virDomainPCIControllerModelToConnectType(device->data.controller->model); break; case VIR_DOMAIN_CONTROLLER_TYPE_SATA: @@ -1058,51 +1026,18 @@ 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'")); - goto error; - } + flags = virDomainPCIControllerModelToConnectType(model); if (virDomainPCIAddressReserveNextSlot(addrs, &def->controllers[i]->info, flags) < 0) -- GitLab