Walk through all the usb hubs in the domain definition and create the corresponding structures in the virDomainUSBAddressSet. --- src/conf/domain_addr.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 58159ef..50d23b4 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -1428,6 +1428,97 @@ 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) +{ + 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"), + info->addr.usb.port[i]); + 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 portIdx; + + VIR_DEBUG("Adding a USB hub with 8 ports"); + + if (!(newHub = virDomainUSBAddressHubNew(VIR_DOMAIN_USB_HUB_PORTS))) + goto cleanup; + + 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 (!(targetHub = virDomainUSBAddressFindPort(addrs, &(hub->info), &portIdx))) + goto cleanup; + + if (targetHub->hubs[portIdx]) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Dupicate USB hub")); + goto cleanup; + } + targetHub->hubs[portIdx] = newHub; + newHub = NULL; + + ret = 0; + cleanup: + virDomainUSBAddressHubFree(newHub); + return ret; +} + + int virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs, virDomainDefPtr def) { @@ -1440,5 +1531,13 @@ 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) { + 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