mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-07 17:28:15 +00:00
Add functions for adding USB hubs to addrs
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.
This commit is contained in:
parent
6b3e4e2bea
commit
2f0813515e
@ -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
|
int
|
||||||
virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
|
virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
|
||||||
virDomainDefPtr def)
|
virDomainDefPtr def)
|
||||||
@ -1445,5 +1548,17 @@ virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs,
|
|||||||
return -1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user