[PATCHv3 06/10] Add functions for adding USB hubs to addrs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Walk through all the usb hubs in the domain definition
that have a USB address specified, create the
corresponding structures in the virDomainUSBAddressSet
and mark the port it occupies as used.
---
 src/conf/domain_addr.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
index 9ae9570..343ae0c 100644
--- a/src/conf/domain_addr.c
+++ b/src/conf/domain_addr.c
@@ -1430,6 +1430,109 @@ virDomainUSBAddressSetAddController(virDomainUSBAddressSetPtr addrs,
 }
 
 
+static ssize_t
+virDomainUSBAddressGetLastIdx(virDomainDeviceInfoPtr info)
+{
+    ssize_t i;
+    for (i = VIR_DOMAIN_DEVICE_USB_MAX_PORT_DEPTH - 1; i > 0; i--) {
+        if (info->addr.usb.port[i] != 0)
+            break;
+    }
+    return i;
+}
+
+
+/* Find the USBAddressHub structure representing the hub/controller
+ * that corresponds to the bus/port path specified by info.
+ * Returns the index of the requested port in targetIdx.
+ */
+static virDomainUSBAddressHubPtr
+virDomainUSBAddressFindPort(virDomainUSBAddressSetPtr addrs,
+                            virDomainDeviceInfoPtr info,
+                            int *targetIdx,
+                            const char *portStr)
+{
+    virDomainUSBAddressHubPtr hub = NULL;
+    ssize_t i, lastIdx;
+
+    if (info->addr.usb.bus >= addrs->nbuses ||
+        !addrs->buses[info->addr.usb.bus]) {
+        virReportError(VIR_ERR_XML_ERROR, _("Missing USB bus %u"),
+                       info->addr.usb.bus);
+        return NULL;
+    }
+    hub = addrs->buses[info->addr.usb.bus];
+
+    lastIdx = virDomainUSBAddressGetLastIdx(info);
+
+    for (i = 0; i < lastIdx; i++) {
+        /* ports are numbered from 1 */
+        int portIdx = info->addr.usb.port[i] - 1;
+
+        if (hub->nports <= portIdx) {
+            virReportError(VIR_ERR_XML_ERROR,
+                           _("port %u out of range in USB address bus: %u port: %s"),
+                           info->addr.usb.port[i],
+                           info->addr.usb.bus,
+                           portStr);
+            return NULL;
+        }
+        hub = hub->hubs[portIdx];
+    }
+
+    *targetIdx = info->addr.usb.port[lastIdx] - 1;
+    return hub;
+}
+
+
+#define VIR_DOMAIN_USB_HUB_PORTS 8
+
+static int
+virDomainUSBAddressSetAddHub(virDomainUSBAddressSetPtr addrs,
+                             virDomainHubDefPtr hub)
+{
+    virDomainUSBAddressHubPtr targetHub = NULL, newHub = NULL;
+    int ret = -1;
+    int targetPort;
+    char *portStr = NULL;
+
+    if (hub->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("Wrong address type for USB hub"));
+        goto cleanup;
+    }
+
+    if (!(portStr = virDomainUSBAddressPortFormat(hub->info.addr.usb.port)))
+        goto cleanup;
+
+    VIR_DEBUG("Adding a USB hub with 8 ports on bus=%u port=%s",
+              hub->info.addr.usb.bus, portStr);
+
+    if (!(newHub = virDomainUSBAddressHubNew(VIR_DOMAIN_USB_HUB_PORTS)))
+        goto cleanup;
+
+    if (!(targetHub = virDomainUSBAddressFindPort(addrs, &(hub->info), &targetPort,
+                                                  portStr)))
+        goto cleanup;
+
+    if (targetHub->hubs[targetPort]) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("Dupicate USB hub on bus %u port %s"),
+                       hub->info.addr.usb.bus, portStr);
+        goto cleanup;
+    }
+    ignore_value(virBitmapSetBit(targetHub->ports, targetPort));
+    targetHub->hubs[targetPort] = newHub;
+    newHub = NULL;
+
+    ret = 0;
+ cleanup:
+    virDomainUSBAddressHubFree(newHub);
+    VIR_FREE(portStr);
+    return ret;
+}
+
+
 int virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
                                          virDomainDefPtr def)
 {
@@ -1442,5 +1545,16 @@ int virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
                 return -1;
         }
     }
+
+    for (i = 0; i < def->nhubs; i++) {
+        virDomainHubDefPtr hub = def->hubs[i];
+        if (hub->type == VIR_DOMAIN_HUB_TYPE_USB &&
+            hub->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
+            /* USB hubs that do not yet have an USB address have to be
+             * dealt with later */
+            if (virDomainUSBAddressSetAddHub(addrs, hub) < 0)
+                return -1;
+        }
+    }
     return 0;
 }
-- 
2.7.3

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]