|
|
6ae9ed |
From 9798935b4b81d153f59116707e7708e7a8988b05 Mon Sep 17 00:00:00 2001
|
|
|
6ae9ed |
Message-Id: <9798935b4b81d153f59116707e7708e7a8988b05@dist-git>
|
|
|
6ae9ed |
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
|
|
|
6ae9ed |
Date: Thu, 21 Jul 2016 15:57:52 +0200
|
|
|
6ae9ed |
Subject: [PATCH] Add functions for adding USB hubs 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 hubs in the domain definition
|
|
|
6ae9ed |
that have a USB address specified, create the
|
|
|
6ae9ed |
corresponding structures in the virDomainUSBAddressSet
|
|
|
6ae9ed |
and mark the port it occupies as used.
|
|
|
6ae9ed |
|
|
|
6ae9ed |
(cherry picked from commit 2f0813515e8a573a74c37850c4a90924cecebb90)
|
|
|
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 | 115 +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
6ae9ed |
1 file changed, 115 insertions(+)
|
|
|
6ae9ed |
|
|
|
6ae9ed |
diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
|
|
|
6ae9ed |
index ea37a42..ad20fef 100644
|
|
|
6ae9ed |
--- a/src/conf/domain_addr.c
|
|
|
6ae9ed |
+++ b/src/conf/domain_addr.c
|
|
|
6ae9ed |
@@ -1432,6 +1432,109 @@ virDomainUSBAddressSetAddController(virDomainUSBAddressSetPtr addrs,
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+static ssize_t
|
|
|
6ae9ed |
+virDomainUSBAddressGetLastIdx(virDomainDeviceInfoPtr info)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ ssize_t i;
|
|
|
6ae9ed |
+ for (i = VIR_DOMAIN_DEVICE_USB_MAX_PORT_DEPTH - 1; i > 0; i--) {
|
|
|
6ae9ed |
+ if (info->addr.usb.port[i] != 0)
|
|
|
6ae9ed |
+ break;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ return i;
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+/* Find the USBAddressHub structure representing the hub/controller
|
|
|
6ae9ed |
+ * that corresponds to the bus/port path specified by info.
|
|
|
6ae9ed |
+ * Returns the index of the requested port in targetIdx.
|
|
|
6ae9ed |
+ */
|
|
|
6ae9ed |
+static virDomainUSBAddressHubPtr
|
|
|
6ae9ed |
+virDomainUSBAddressFindPort(virDomainUSBAddressSetPtr addrs,
|
|
|
6ae9ed |
+ virDomainDeviceInfoPtr info,
|
|
|
6ae9ed |
+ int *targetIdx,
|
|
|
6ae9ed |
+ const char *portStr)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ virDomainUSBAddressHubPtr hub = NULL;
|
|
|
6ae9ed |
+ ssize_t i, lastIdx;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (info->addr.usb.bus >= addrs->nbuses ||
|
|
|
6ae9ed |
+ !addrs->buses[info->addr.usb.bus]) {
|
|
|
6ae9ed |
+ virReportError(VIR_ERR_XML_ERROR, _("Missing USB bus %u"),
|
|
|
6ae9ed |
+ info->addr.usb.bus);
|
|
|
6ae9ed |
+ return NULL;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ hub = addrs->buses[info->addr.usb.bus];
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ lastIdx = virDomainUSBAddressGetLastIdx(info);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ for (i = 0; i < lastIdx; i++) {
|
|
|
6ae9ed |
+ /* ports are numbered from 1 */
|
|
|
6ae9ed |
+ int portIdx = info->addr.usb.port[i] - 1;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (hub->nports <= portIdx) {
|
|
|
6ae9ed |
+ virReportError(VIR_ERR_XML_ERROR,
|
|
|
6ae9ed |
+ _("port %u out of range in USB address bus: %u port: %s"),
|
|
|
6ae9ed |
+ info->addr.usb.port[i],
|
|
|
6ae9ed |
+ info->addr.usb.bus,
|
|
|
6ae9ed |
+ portStr);
|
|
|
6ae9ed |
+ return NULL;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ hub = hub->ports[portIdx];
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ *targetIdx = info->addr.usb.port[lastIdx] - 1;
|
|
|
6ae9ed |
+ return hub;
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+#define VIR_DOMAIN_USB_HUB_PORTS 8
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+static int
|
|
|
6ae9ed |
+virDomainUSBAddressSetAddHub(virDomainUSBAddressSetPtr addrs,
|
|
|
6ae9ed |
+ virDomainHubDefPtr hub)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ virDomainUSBAddressHubPtr targetHub = NULL, newHub = NULL;
|
|
|
6ae9ed |
+ int ret = -1;
|
|
|
6ae9ed |
+ int targetPort;
|
|
|
6ae9ed |
+ char *portStr = NULL;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (hub->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
|
|
|
6ae9ed |
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
|
6ae9ed |
+ _("Wrong address type for USB hub"));
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (!(portStr = virDomainUSBAddressPortFormat(hub->info.addr.usb.port)))
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ VIR_DEBUG("Adding a USB hub with 8 ports on bus=%u port=%s",
|
|
|
6ae9ed |
+ hub->info.addr.usb.bus, portStr);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (!(newHub = virDomainUSBAddressHubNew(VIR_DOMAIN_USB_HUB_PORTS)))
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (!(targetHub = virDomainUSBAddressFindPort(addrs, &(hub->info), &targetPort,
|
|
|
6ae9ed |
+ portStr)))
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (targetHub->ports[targetPort]) {
|
|
|
6ae9ed |
+ virReportError(VIR_ERR_XML_ERROR,
|
|
|
6ae9ed |
+ _("Duplicate USB hub on bus %u port %s"),
|
|
|
6ae9ed |
+ hub->info.addr.usb.bus, portStr);
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ ignore_value(virBitmapSetBit(targetHub->portmap, targetPort));
|
|
|
6ae9ed |
+ targetHub->ports[targetPort] = newHub;
|
|
|
6ae9ed |
+ newHub = NULL;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ ret = 0;
|
|
|
6ae9ed |
+ cleanup:
|
|
|
6ae9ed |
+ virDomainUSBAddressHubFree(newHub);
|
|
|
6ae9ed |
+ VIR_FREE(portStr);
|
|
|
6ae9ed |
+ return ret;
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
int
|
|
|
6ae9ed |
virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
|
|
|
6ae9ed |
virDomainDefPtr def)
|
|
|
6ae9ed |
@@ -1445,5 +1548,17 @@ virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
|
|
|
6ae9ed |
return -1;
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ for (i = 0; i < def->nhubs; i++) {
|
|
|
6ae9ed |
+ virDomainHubDefPtr hub = def->hubs[i];
|
|
|
6ae9ed |
+ if (hub->type == VIR_DOMAIN_HUB_TYPE_USB &&
|
|
|
6ae9ed |
+ hub->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB &&
|
|
|
6ae9ed |
+ virDomainUSBAddressPortIsValid(hub->info.addr.usb.port)) {
|
|
|
6ae9ed |
+ /* USB hubs that do not yet have an USB address have to be
|
|
|
6ae9ed |
+ * dealt with later */
|
|
|
6ae9ed |
+ if (virDomainUSBAddressSetAddHub(addrs, hub) < 0)
|
|
|
6ae9ed |
+ return -1;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
return 0;
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
--
|
|
|
6ae9ed |
2.9.2
|
|
|
6ae9ed |
|