[libvirt] [PATCH 08/15] conf: utility function to convert PCI controller model into connect type

Laine Stump laine at laine.org
Thu Mar 24 19:25:43 UTC 2016


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




More information about the libvir-list mailing list