Currently, libvirt could not tell what usb specification a certain USB device is running on or what kind of usb spec a USB controller supports. For example, USB controller: piix3-usb-uhci, piix4-usb-uhci, ohci only support USB 1.1 usb-ehci and ich9-usb-ehci1 only support USB 2.0 ich9-usb-ehci1 + ich9-usb-uhci{1|2|3} supports both USB 1.1 and USB 2.0 nec-usb-xhci supports USB 1.1, 2.0, 3.0 USB device: Most of them only support USB 1.1 usb-tablet Supports USB 1.1 and 2.0(in qemu 1.3 & older 1.1 only) usb-uas is USB 2.0 or above device. usb-storage supports USB1.1, 2.0 and 3.0 The usb spec may change over time for USB device, for USB constrollers it is fixed(From Gerd Hoffmann). So this patch tries to record usb spec infomation and port number supported by usb constrollers. Based on these info, we can simply check whether a usb device goes with right controller. --- src/conf/domain_conf.c | 32 ++++++++++++++++---------------- src/conf/domain_conf.h | 24 +++++++++++++++++++++++- src/qemu/qemu_command.c | 8 ++++---- 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 6feded4..646baab 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4507,30 +4507,30 @@ virDomainControllerDefParseXML(xmlNodePtr node, char *ports = virXMLPropString(node, "ports"); if (ports) { int r = virStrToLong_i(ports, NULL, 10, - &def->opts.vioserial.ports); - if (r != 0 || def->opts.vioserial.ports < 0) { + &def->data.vioserial.ports); + if (r != 0 || def->data.vioserial.ports < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid ports: %s"), ports); VIR_FREE(ports); goto error; } } else { - def->opts.vioserial.ports = -1; + def->data.vioserial.ports = -1; } VIR_FREE(ports); char *vectors = virXMLPropString(node, "vectors"); if (vectors) { int r = virStrToLong_i(vectors, NULL, 10, - &def->opts.vioserial.vectors); - if (r != 0 || def->opts.vioserial.vectors < 0) { + &def->data.vioserial.vectors); + if (r != 0 || def->data.vioserial.vectors < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid vectors: %s"), vectors); VIR_FREE(vectors); goto error; } } else { - def->opts.vioserial.vectors = -1; + def->data.vioserial.vectors = -1; } VIR_FREE(vectors); break; @@ -8818,8 +8818,8 @@ static int virDomainDefMaybeAddController(virDomainDefPtr def, cont->model = -1; if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL) { - cont->opts.vioserial.ports = -1; - cont->opts.vioserial.vectors = -1; + cont->data.vioserial.ports = -1; + cont->data.vioserial.vectors = -1; } @@ -10895,17 +10895,17 @@ static bool virDomainControllerDefCheckABIStability(virDomainControllerDefPtr sr } if (src->type == VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL) { - if (src->opts.vioserial.ports != dst->opts.vioserial.ports) { + if (src->data.vioserial.ports != dst->data.vioserial.ports) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target controller ports %d does not match source %d"), - dst->opts.vioserial.ports, src->opts.vioserial.ports); + dst->data.vioserial.ports, src->data.vioserial.ports); goto cleanup; } - if (src->opts.vioserial.vectors != dst->opts.vioserial.vectors) { + if (src->data.vioserial.vectors != dst->data.vioserial.vectors) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target controller vectors %d does not match source %d"), - dst->opts.vioserial.vectors, src->opts.vioserial.vectors); + dst->data.vioserial.vectors, src->data.vioserial.vectors); goto cleanup; } } @@ -12497,13 +12497,13 @@ virDomainControllerDefFormat(virBufferPtr buf, switch (def->type) { case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: - if (def->opts.vioserial.ports != -1) { + if (def->data.vioserial.ports != -1) { virBufferAsprintf(buf, " ports='%d'", - def->opts.vioserial.ports); + def->data.vioserial.ports); } - if (def->opts.vioserial.vectors != -1) { + if (def->data.vioserial.vectors != -1) { virBufferAsprintf(buf, " vectors='%d'", - def->opts.vioserial.vectors); + def->data.vioserial.vectors); } break; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 2ac338c..67143a5 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -701,6 +701,27 @@ struct _virDomainVirtioSerialOpts { int vectors; /* -1 == undef */ }; +enum virDomainUSBSpec { + VIR_DOMAIN_USB_SPEC_NONE = 0, + VIR_DOMAIN_USB_SEPC_1_1 = 1 << 0, + VIR_DOMAIN_USB_SPEC_2_0 = 1 << 1, + VIR_DOMAIN_USB_SPEC_3_0 = 1 << 2, +}; + +enum virDomainUSBControllerPortNumber { + VIR_DOMAIN_USB_CONTROLLER_UHCI_PORTN_2 = 2, + VIR_DOMAIN_USB_CONTROLLER_OHCI_PORTN_3 = 3, + VIR_DOMAIN_USB_CONTROLLER_XHCI_PORTN_4 = 4, + VIR_DOMAIN_USB_CONTROLLER_EHCI_PORTN_6 = 6, +}; + +typedef struct _virDomainUSBControllerData virDomainUSBControllerData; +typedef virDomainUSBControllerData *virDomainUSBControllerDataPtr; +struct _virDomainUSBControllerData { + unsigned int spec; + size_t nports; +}; + /* Stores the virtual disk controller configuration */ struct _virDomainControllerDef { int type; @@ -708,7 +729,8 @@ struct _virDomainControllerDef { int model; /* -1 == undef */ union { virDomainVirtioSerialOpts vioserial; - } opts; + virDomainUSBControllerData usb; + } data; virDomainDeviceInfo info; }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 981c692..71e69f3 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3083,13 +3083,13 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef, } virBufferAsprintf(&buf, ",id=" QEMU_VIRTIO_SERIAL_PREFIX "%d", def->idx); - if (def->opts.vioserial.ports != -1) { + if (def->data.vioserial.ports != -1) { virBufferAsprintf(&buf, ",max_ports=%d", - def->opts.vioserial.ports); + def->data.vioserial.ports); } - if (def->opts.vioserial.vectors != -1) { + if (def->data.vioserial.vectors != -1) { virBufferAsprintf(&buf, ",vectors=%d", - def->opts.vioserial.vectors); + def->data.vioserial.vectors); } break; -- 1.7.11.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list