6ae9ed
From 10bbdca5f7957403ea9baa4e007c8d5a18f23148 Mon Sep 17 00:00:00 2001
6ae9ed
Message-Id: <10bbdca5f7957403ea9baa4e007c8d5a18f23148@dist-git>
6ae9ed
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
6ae9ed
Date: Thu, 21 Jul 2016 15:57:51 +0200
6ae9ed
Subject: [PATCH] Add functions for adding USB controllers to addrs
6ae9ed
MIME-Version: 1.0
6ae9ed
Content-Type: text/plain; charset=UTF-8
6ae9ed
Content-Transfer-Encoding: 8bit
6ae9ed
6ae9ed
Walk through all the usb controllers in the domain definition
6ae9ed
and create the corresponding structures in the virDomainUSBAddressSet.
6ae9ed
6ae9ed
(cherry picked from commit 6b3e4e2bea91b1247485da0987f98ccbe30e0629)
6ae9ed
Signed-off-by: Ján Tomko <jtomko@redhat.com>
6ae9ed
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1215968
6ae9ed
---
6ae9ed
 src/conf/domain_addr.c   | 121 +++++++++++++++++++++++++++++++++++++++++++++++
6ae9ed
 src/conf/domain_addr.h   |   4 ++
6ae9ed
 src/libvirt_private.syms |   1 +
6ae9ed
 3 files changed, 126 insertions(+)
6ae9ed
6ae9ed
diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
6ae9ed
index 658aad5..ea37a42 100644
6ae9ed
--- a/src/conf/domain_addr.c
6ae9ed
+++ b/src/conf/domain_addr.c
6ae9ed
@@ -1326,3 +1326,124 @@ virDomainUSBAddressSetFree(virDomainUSBAddressSetPtr addrs)
6ae9ed
     VIR_FREE(addrs->buses);
6ae9ed
     VIR_FREE(addrs);
6ae9ed
 }
6ae9ed
+
6ae9ed
+
6ae9ed
+static size_t
6ae9ed
+virDomainUSBAddressControllerModelToPorts(virDomainControllerDefPtr cont)
6ae9ed
+{
6ae9ed
+    int model = cont->model;
6ae9ed
+
6ae9ed
+    if (model == -1)
6ae9ed
+        model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI;
6ae9ed
+
6ae9ed
+    switch ((virDomainControllerModelUSB) model) {
6ae9ed
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI:
6ae9ed
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX4_UHCI:
6ae9ed
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_VT82C686B_UHCI:
6ae9ed
+        return 2;
6ae9ed
+
6ae9ed
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_EHCI:
6ae9ed
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1:
6ae9ed
+        return 6;
6ae9ed
+
6ae9ed
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1:
6ae9ed
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI2:
6ae9ed
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI3:
6ae9ed
+        /* These have two ports each and are used to provide USB1.1
6ae9ed
+         * ports while ICH9_EHCI1 provides 6 USB2.0 ports.
6ae9ed
+         * Ignore these since we will add the EHCI1 too. */
6ae9ed
+        return 0;
6ae9ed
+
6ae9ed
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI:
6ae9ed
+        return 3;
6ae9ed
+
6ae9ed
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI:
6ae9ed
+        if (cont->opts.usbopts.ports != -1)
6ae9ed
+            return cont->opts.usbopts.ports;
6ae9ed
+        return 4;
6ae9ed
+
6ae9ed
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE:
6ae9ed
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST:
6ae9ed
+        break;
6ae9ed
+    }
6ae9ed
+    return 0;
6ae9ed
+}
6ae9ed
+
6ae9ed
+
6ae9ed
+static virDomainUSBAddressHubPtr
6ae9ed
+virDomainUSBAddressHubNew(size_t nports)
6ae9ed
+{
6ae9ed
+    virDomainUSBAddressHubPtr hub = NULL, ret = NULL;
6ae9ed
+
6ae9ed
+    if (VIR_ALLOC(hub) < 0)
6ae9ed
+        goto cleanup;
6ae9ed
+
6ae9ed
+    if (!(hub->portmap = virBitmapNew(nports)))
6ae9ed
+        goto cleanup;
6ae9ed
+
6ae9ed
+    if (VIR_ALLOC_N(hub->ports, nports) < 0)
6ae9ed
+        goto cleanup;
6ae9ed
+    hub->nports = nports;
6ae9ed
+
6ae9ed
+    ret = hub;
6ae9ed
+    hub = NULL;
6ae9ed
+ cleanup:
6ae9ed
+    virDomainUSBAddressHubFree(hub);
6ae9ed
+    return ret;
6ae9ed
+}
6ae9ed
+
6ae9ed
+
6ae9ed
+static int
6ae9ed
+virDomainUSBAddressSetAddController(virDomainUSBAddressSetPtr addrs,
6ae9ed
+                                    virDomainControllerDefPtr cont)
6ae9ed
+{
6ae9ed
+    size_t nports = virDomainUSBAddressControllerModelToPorts(cont);
6ae9ed
+    virDomainUSBAddressHubPtr hub = NULL;
6ae9ed
+    int ret = -1;
6ae9ed
+
6ae9ed
+    VIR_DEBUG("Adding a USB controller model=%s with %zu ports",
6ae9ed
+              virDomainControllerModelUSBTypeToString(cont->model),
6ae9ed
+              nports);
6ae9ed
+
6ae9ed
+    /* Skip UHCI{1,2,3} companions; only add the EHCI1 */
6ae9ed
+    if (nports == 0)
6ae9ed
+        return 0;
6ae9ed
+
6ae9ed
+    if (addrs->nbuses <= cont->idx) {
6ae9ed
+        if (VIR_EXPAND_N(addrs->buses, addrs->nbuses, cont->idx - addrs->nbuses + 1) < 0)
6ae9ed
+            goto cleanup;
6ae9ed
+    } else if (addrs->buses[cont->idx]) {
6ae9ed
+        virReportError(VIR_ERR_XML_ERROR,
6ae9ed
+                       _("Duplicate USB controllers with index %u"),
6ae9ed
+                       cont->idx);
6ae9ed
+        goto cleanup;
6ae9ed
+    }
6ae9ed
+
6ae9ed
+    if (!(hub = virDomainUSBAddressHubNew(nports)))
6ae9ed
+        goto cleanup;
6ae9ed
+
6ae9ed
+    addrs->buses[cont->idx] = hub;
6ae9ed
+    hub = NULL;
6ae9ed
+
6ae9ed
+    ret = 0;
6ae9ed
+ cleanup:
6ae9ed
+    virDomainUSBAddressHubFree(hub);
6ae9ed
+    return ret;
6ae9ed
+}
6ae9ed
+
6ae9ed
+
6ae9ed
+int
6ae9ed
+virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
6ae9ed
+                                     virDomainDefPtr def)
6ae9ed
+{
6ae9ed
+    size_t i;
6ae9ed
+
6ae9ed
+    for (i = 0; i < def->ncontrollers; i++) {
6ae9ed
+        virDomainControllerDefPtr cont = def->controllers[i];
6ae9ed
+        if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) {
6ae9ed
+            if (virDomainUSBAddressSetAddController(addrs, cont) < 0)
6ae9ed
+                return -1;
6ae9ed
+        }
6ae9ed
+    }
6ae9ed
+    return 0;
6ae9ed
+}
6ae9ed
diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h
6ae9ed
index 168d3ed..2bd4a0d 100644
6ae9ed
--- a/src/conf/domain_addr.h
6ae9ed
+++ b/src/conf/domain_addr.h
6ae9ed
@@ -269,6 +269,10 @@ typedef struct _virDomainUSBAddressSet virDomainUSBAddressSet;
6ae9ed
 typedef virDomainUSBAddressSet *virDomainUSBAddressSetPtr;
6ae9ed
 
6ae9ed
 virDomainUSBAddressSetPtr virDomainUSBAddressSetCreate(void);
6ae9ed
+
6ae9ed
+int virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
6ae9ed
+                                         virDomainDefPtr def)
6ae9ed
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
6ae9ed
 void virDomainUSBAddressSetFree(virDomainUSBAddressSetPtr addrs);
6ae9ed
 
6ae9ed
 #endif /* __DOMAIN_ADDR_H__ */
6ae9ed
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
6ae9ed
index 49f8d6c..f0fed8e 100644
6ae9ed
--- a/src/libvirt_private.syms
6ae9ed
+++ b/src/libvirt_private.syms
6ae9ed
@@ -110,6 +110,7 @@ virDomainPCIControllerModelToConnectType;
6ae9ed
 virDomainUSBAddressPortFormat;
6ae9ed
 virDomainUSBAddressPortFormatBuf;
6ae9ed
 virDomainUSBAddressPortIsValid;
6ae9ed
+virDomainUSBAddressSetAddControllers;
6ae9ed
 virDomainUSBAddressSetCreate;
6ae9ed
 virDomainUSBAddressSetFree;
6ae9ed
 virDomainVirtioSerialAddrAssign;
6ae9ed
-- 
6ae9ed
2.9.2
6ae9ed