]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add functions for adding USB controllers to addrs
authorJán Tomko <jtomko@redhat.com>
Wed, 12 Aug 2015 14:52:16 +0000 (16:52 +0200)
committerJán Tomko <jtomko@redhat.com>
Thu, 21 Jul 2016 06:30:26 +0000 (08:30 +0200)
Walk through all the usb controllers in the domain definition
and create the corresponding structures in the virDomainUSBAddressSet.

src/conf/domain_addr.c
src/conf/domain_addr.h
src/libvirt_private.syms

index 658aad5b216716834e453502013e77b833a638e4..ea37a424733bfcb6794ecf8de99a61cc371600ad 100644 (file)
@@ -1326,3 +1326,124 @@ virDomainUSBAddressSetFree(virDomainUSBAddressSetPtr addrs)
     VIR_FREE(addrs->buses);
     VIR_FREE(addrs);
 }
+
+
+static size_t
+virDomainUSBAddressControllerModelToPorts(virDomainControllerDefPtr cont)
+{
+    int model = cont->model;
+
+    if (model == -1)
+        model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI;
+
+    switch ((virDomainControllerModelUSB) model) {
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI:
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX4_UHCI:
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_VT82C686B_UHCI:
+        return 2;
+
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_EHCI:
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1:
+        return 6;
+
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1:
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI2:
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI3:
+        /* These have two ports each and are used to provide USB1.1
+         * ports while ICH9_EHCI1 provides 6 USB2.0 ports.
+         * Ignore these since we will add the EHCI1 too. */
+        return 0;
+
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI:
+        return 3;
+
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI:
+        if (cont->opts.usbopts.ports != -1)
+            return cont->opts.usbopts.ports;
+        return 4;
+
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE:
+    case VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST:
+        break;
+    }
+    return 0;
+}
+
+
+static virDomainUSBAddressHubPtr
+virDomainUSBAddressHubNew(size_t nports)
+{
+    virDomainUSBAddressHubPtr hub = NULL, ret = NULL;
+
+    if (VIR_ALLOC(hub) < 0)
+        goto cleanup;
+
+    if (!(hub->portmap = virBitmapNew(nports)))
+        goto cleanup;
+
+    if (VIR_ALLOC_N(hub->ports, nports) < 0)
+        goto cleanup;
+    hub->nports = nports;
+
+    ret = hub;
+    hub = NULL;
+ cleanup:
+    virDomainUSBAddressHubFree(hub);
+    return ret;
+}
+
+
+static int
+virDomainUSBAddressSetAddController(virDomainUSBAddressSetPtr addrs,
+                                    virDomainControllerDefPtr cont)
+{
+    size_t nports = virDomainUSBAddressControllerModelToPorts(cont);
+    virDomainUSBAddressHubPtr hub = NULL;
+    int ret = -1;
+
+    VIR_DEBUG("Adding a USB controller model=%s with %zu ports",
+              virDomainControllerModelUSBTypeToString(cont->model),
+              nports);
+
+    /* Skip UHCI{1,2,3} companions; only add the EHCI1 */
+    if (nports == 0)
+        return 0;
+
+    if (addrs->nbuses <= cont->idx) {
+        if (VIR_EXPAND_N(addrs->buses, addrs->nbuses, cont->idx - addrs->nbuses + 1) < 0)
+            goto cleanup;
+    } else if (addrs->buses[cont->idx]) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("Duplicate USB controllers with index %u"),
+                       cont->idx);
+        goto cleanup;
+    }
+
+    if (!(hub = virDomainUSBAddressHubNew(nports)))
+        goto cleanup;
+
+    addrs->buses[cont->idx] = hub;
+    hub = NULL;
+
+    ret = 0;
+ cleanup:
+    virDomainUSBAddressHubFree(hub);
+    return ret;
+}
+
+
+int
+virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
+                                     virDomainDefPtr def)
+{
+    size_t i;
+
+    for (i = 0; i < def->ncontrollers; i++) {
+        virDomainControllerDefPtr cont = def->controllers[i];
+        if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) {
+            if (virDomainUSBAddressSetAddController(addrs, cont) < 0)
+                return -1;
+        }
+    }
+    return 0;
+}
index 168d3ed6f14196b42a8faf7605e174b518a952db..2bd4a0dfdc8ab32ec4dcad70bbf9b3046cc2b6ba 100644 (file)
@@ -269,6 +269,10 @@ typedef struct _virDomainUSBAddressSet virDomainUSBAddressSet;
 typedef virDomainUSBAddressSet *virDomainUSBAddressSetPtr;
 
 virDomainUSBAddressSetPtr virDomainUSBAddressSetCreate(void);
+
+int virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
+                                         virDomainDefPtr def)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 void virDomainUSBAddressSetFree(virDomainUSBAddressSetPtr addrs);
 
 #endif /* __DOMAIN_ADDR_H__ */
index c0bcff82436deb18bd7eca98758df4bf001bdadb..427ba5c332253cbfdf45937756863e83421d7376 100644 (file)
@@ -110,6 +110,7 @@ virDomainPCIControllerModelToConnectType;
 virDomainUSBAddressPortFormat;
 virDomainUSBAddressPortFormatBuf;
 virDomainUSBAddressPortIsValid;
+virDomainUSBAddressSetAddControllers;
 virDomainUSBAddressSetCreate;
 virDomainUSBAddressSetFree;
 virDomainVirtioSerialAddrAssign;