diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 4408c4a7281722847339b322dfa27ed92e3fe20d..7ee893f675f08cbf112d29a988f2f99bf300f363 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 b5cb0eeb3c6604de886061a80f432259c26b8989..5b5de8a31ca78862f086f0f225a0331c0a15863b 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 abeba6c0fd22d58b2d306f6235a03ff33578dfaa..4ef51f04b0409a039d5d8253d0bcdffbd7089249 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 c6e694eba49e93ea7d2839b71f494c65876f2c7f..911bbef00ce2509812d3bd8524b731c8a268fb18 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)