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.
This commit is contained in:
Laine Stump 2016-03-16 14:20:52 -04:00
parent d1cc4605d7
commit a0616ee8a8
4 changed files with 59 additions and 72 deletions

View File

@ -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,

View File

@ -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

View File

@ -107,6 +107,7 @@ virDomainPCIAddressSetFree;
virDomainPCIAddressSetGrow;
virDomainPCIAddressSlotInUse;
virDomainPCIAddressValidate;
virDomainPCIControllerModelToConnectType;
virDomainVirtioSerialAddrAssign;
virDomainVirtioSerialAddrAutoAssign;
virDomainVirtioSerialAddrIsComplete;

View File

@ -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)