From 9798935b4b81d153f59116707e7708e7a8988b05 Mon Sep 17 00:00:00 2001 Message-Id: <9798935b4b81d153f59116707e7708e7a8988b05@dist-git> From: =?UTF-8?q?J=C3=A1n=20Tomko?= Date: Thu, 21 Jul 2016 15:57:52 +0200 Subject: [PATCH] Add functions for adding USB hubs to addrs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. (cherry picked from commit 2f0813515e8a573a74c37850c4a90924cecebb90) Signed-off-by: Ján Tomko https://bugzilla.redhat.com/show_bug.cgi?id=1215968 --- src/conf/domain_addr.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index ea37a42..ad20fef 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -1432,6 +1432,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->ports[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->ports[targetPort]) { + virReportError(VIR_ERR_XML_ERROR, + _("Duplicate USB hub on bus %u port %s"), + hub->info.addr.usb.bus, portStr); + goto cleanup; + } + ignore_value(virBitmapSetBit(targetHub->portmap, targetPort)); + targetHub->ports[targetPort] = newHub; + newHub = NULL; + + ret = 0; + cleanup: + virDomainUSBAddressHubFree(newHub); + VIR_FREE(portStr); + return ret; +} + + int virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs, virDomainDefPtr def) @@ -1445,5 +1548,17 @@ 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 && + virDomainUSBAddressPortIsValid(hub->info.addr.usb.port)) { + /* 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.9.2