In addition to the code in qemuDomainControllerDefPostParse(),
which we have just factored into its own function, we also have
some code in qemuDomainDefAddDefaultDevices() that deals with
choosing the USB controller model for a couple of specific
machine types.

Once again, extract the logic to a dedicated helper. The
behavior is unchanged.

Signed-off-by: Andrea Bolognani <abolo...@redhat.com>
---
 src/qemu/qemu_domain.c    | 57 +++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_domain.h    |  2 ++
 src/qemu/qemu_postparse.c | 27 +++++++------------
 3 files changed, 69 insertions(+), 17 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index f03624eda8..639506d22a 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4376,6 +4376,63 @@ qemuDomainDefaultUSBControllerModel(const virDomainDef 
*def,
 }
 
 
+/**
+ * qemuDomainDefaultUSBControllerModelAutoAdded:
+ * @def: domain definition
+ * @qemuCaps: QEMU capabilities, or NULL
+ *
+ * Choose a reasonable model to use for a USB controller that is
+ * being automatically added to a domain.
+ *
+ * The choice is based on a number of factors, including the guest's
+ * architecture and machine type. @qemuCaps, if provided, might be
+ * taken into consideration too.
+ *
+ * The return value can be a specific controller model, or
+ * VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT; the latter indicates that
+ * no suitable model could be identified. How to behave in that
+ * scenario is entirely up to the caller.
+ *
+ * Additionally, VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE can be returned
+ * to indicate that the caller should not auto-add the USB controller
+ * after all.
+ *
+ * Returns: the model
+ */
+virDomainControllerModelUSB
+qemuDomainDefaultUSBControllerModelAutoAdded(const virDomainDef *def,
+                                             virQEMUCaps *qemuCaps)
+{
+    virDomainControllerModelUSB model = 
VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT;
+
+    if (ARCH_IS_X86(def->os.arch)) {
+        if (qemuDomainIsQ35(def)) {
+            /* Prefer adding a USB3 controller if supported, fall back
+             * to USB2 if there is no USB3 available, and if that's
+             * unavailable don't add anything.
+             */
+            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI))
+                model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
+            else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
+                model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
+            else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_USB_EHCI1))
+                model = VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1;
+            else
+                model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE;
+        }
+    }
+
+    if (ARCH_IS_ARM(def->os.arch)) {
+        if (STREQ(def->os.machine, "versatilepb") ||
+            STRPREFIX(def->os.machine, "realview-eb"))
+            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_OHCI))
+                model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI;
+    }
+
+    return model;
+}
+
+
 /**
  * qemuDomainDefNumaCPUsRectify:
  * @numa: pointer to numa definition
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index bdcfcc6e86..5ccd3b2dbb 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -845,6 +845,8 @@ virDomainControllerModelSCSI 
qemuDomainDefaultSCSIControllerModel(const virDomai
 virDomainControllerModelUSB qemuDomainDefaultUSBControllerModel(const 
virDomainDef *def,
                                                                 virQEMUCaps 
*qemuCaps,
                                                                 unsigned int 
parseFlags);
+virDomainControllerModelUSB qemuDomainDefaultUSBControllerModelAutoAdded(const 
virDomainDef *def,
+                                                                         
virQEMUCaps *qemuCaps);
 
 int qemuDomainDefAddDefaultAudioBackend(virQEMUDriver *driver,
                                         virDomainDef *def);
diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c
index 46ba12cd4a..3befd4a775 100644
--- a/src/qemu/qemu_postparse.c
+++ b/src/qemu/qemu_postparse.c
@@ -1189,7 +1189,7 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
                                virQEMUCaps *qemuCaps)
 {
     bool addDefaultUSB = false;
-    int usbModel = -1; /* "default for machinetype" */
+    virDomainControllerModelUSB usbModel = 
VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT;
     int pciRoot;       /* index within def->controllers */
     bool addImplicitSATA = false;
     bool addPCIRoot = false;
@@ -1223,20 +1223,6 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
             if (virDomainDefGetVcpusMax(def) > QEMU_MAX_VCPUS_WITHOUT_EIM) {
                 addIOMMU = true;
             }
-
-            /* Prefer adding a USB3 controller if supported, fall back
-             * to USB2 if there is no USB3 available, and if that's
-             * unavailable don't add anything.
-             */
-            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI))
-                usbModel = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
-            else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
-                usbModel = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
-            else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_USB_EHCI1))
-                usbModel = VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1;
-            else
-                addDefaultUSB = false;
-            break;
         }
         if (qemuDomainIsI440FX(def))
             addPCIRoot = true;
@@ -1252,8 +1238,6 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
             STRPREFIX(def->os.machine, "realview-eb")) {
             addPCIRoot = true;
             addDefaultUSB = true;
-            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_OHCI))
-                usbModel = VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI;
         }
 
         if (qemuDomainIsARMVirt(def))
@@ -1374,6 +1358,15 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
         return -1;
     }
 
+    if (addDefaultUSB && usbModel == VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT) {
+        usbModel = qemuDomainDefaultUSBControllerModelAutoAdded(def, qemuCaps);
+
+        /* If no reasonable model can be figured out, we should
+         * simply not add the default USB controller */
+        if (usbModel == VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE)
+            addDefaultUSB = false;
+    }
+
     if (addDefaultUSB && virDomainControllerFind(def, 
VIR_DOMAIN_CONTROLLER_TYPE_USB, 0) < 0)
         virDomainDefAddUSBController(def, 0, usbModel);
 
-- 
2.50.1

Reply via email to