--- src/conf/domain_addr.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_addr.h | 4 +++ src/libvirt_private.syms | 1 + 3 files changed, 93 insertions(+) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 3962357..024d47b 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -1239,3 +1239,91 @@ void virDomainUSBAddressSetFree(virDomainUSBAddressSetPtr addrs) VIR_FREE(addrs->buses); VIR_FREE(addrs); } + + +static int virDomainUSBAddressSetAddController(virDomainUSBAddressSetPtr addrs, + virDomainControllerDefPtr cont) +{ + virDomainUSBAddressHubPtr hub = NULL; + size_t ports = 0; + int ret = -1; + int model = cont->model; + + VIR_DEBUG("addrs=%p controller type=%d model=%d", + addrs, cont->type, cont->model); + + if (VIR_ALLOC(hub) < 0) + goto cleanup; + + if (model == -1) + model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI; + + switch ((virDomainControllerModelUSB)model) { + case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI: + case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX4_UHCI: + case VIR_DOMAIN_CONTROLLER_MODEL_USB_VT82C686B_UHCI: + ports = 2; + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_USB_EHCI: + case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1: + ports = 6; + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1: + case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI2: + case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI3: + return 0; + /* FIXME * check the companions? */ + ports = 2; + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI: + ports = 3; + break; + + case VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI: + ports = 15; + + case VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE: + case VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST: + ret = 0; + goto cleanup; + } + + if (cont->idx >= addrs->nbuses) { + if (VIR_EXPAND_N(addrs->buses, addrs->nbuses, cont->idx - addrs->nbuses + 1) < 0) + goto cleanup; + } + + if (VIR_ALLOC_N(hub->ports, ports + 1) < 0) + goto cleanup; + hub->nports = ports + 1; + + VIR_DEBUG("Added %zu ports on hub %p", hub->nports - 1, hub); + + /* FIXME: is there a bus already? */ + addrs->buses[cont->idx] = hub; + hub = NULL; + + ret = 0; + cleanup: + VIR_FREE(hub); + return ret; +} + + +int virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs, + virDomainDefPtr def) +{ + size_t i; + + for (i = 0; i < def->ncontrollers; i++) { + virDomainControllerDefPtr cont = def->controllers[i]; + if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) { + if (virDomainUSBAddressSetAddController(addrs, cont) < 0) + return -1; + } + } + return 0; +} diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index dcf86d4..64d35e9 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -263,6 +263,10 @@ typedef struct _virDomainUSBAddressSet virDomainUSBAddressSet; typedef virDomainUSBAddressSet *virDomainUSBAddressSetPtr; virDomainUSBAddressSetPtr virDomainUSBAddressSetCreate(void); + +int virDomainUSBAddressSetAddControllers(virDomainUSBAddressSetPtr addrs, + virDomainDefPtr def) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); void virDomainUSBAddressSetFree(virDomainUSBAddressSetPtr addrs); #endif /* __DOMAIN_ADDR_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a628d00..7db4839 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -108,6 +108,7 @@ virDomainPCIAddressSlotInUse; virDomainPCIAddressValidate; virDomainUSBAddressGetPortBuf; virDomainUSBAddressGetPortString; +virDomainUSBAddressSetAddControllers; virDomainUSBAddressSetCreate; virDomainUSBAddressSetFree; virDomainVirtioSerialAddrAssign; -- 2.4.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list