The model by default is piix3-uchi. Example: <controller type='usb' index='0' model='ich9-ehci'/> --- docs/formatdomain.html.in | 17 ++- docs/schemas/domain.rng | 1 + src/conf/domain_conf.c | 7 +- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 117 ++++++++++++++++++-- src/qemu/qemu_command.h | 3 +- src/qemu/qemu_hotplug.c | 10 ++- .../qemuxml2argv-usb-controller.args | 1 + .../qemuxml2argv-usb-controller.xml | 16 +++ .../qemuxml2argv-usb-piix3-controller.args | 1 + .../qemuxml2argv-usb-piix3-controller.xml | 16 +++ tests/qemuxml2argvtest.c | 7 + 12 files changed, 179 insertions(+), 18 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-controller.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-controller.xml create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-piix3-controller.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-piix3-controller.xml diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index f46771d..5552fbc 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1217,17 +1217,22 @@ <p> Each controller has a mandatory attribute <code>type</code>, - which must be one of "ide", "fdc", "scsi", "sata", "ccid", or - "virtio-serial", and a mandatory attribute <code>index</code> - which is the decimal integer describing in which order the bus - controller is encountered (for use in <code>controller</code> - attributes of <code><address></code> elements). The - "virtio-serial" controller has two additional optional + which must be one of "ide", "fdc", "scsi", "sata", "usb", + "ccid", or "virtio-serial", and a mandatory + attribute <code>index</code> which is the decimal integer + describing in which order the bus controller is encountered (for + use in <code>controller</code> attributes + of <code><address></code> elements). The "virtio-serial" + controller has two additional optional attributes <code>ports</code> and <code>vectors</code>, which control how many devices can be connected through the controller. A "scsi" controller has an optional attribute <code>model</code>, which is one of "auto", "buslogic", "lsilogic", "lsias1068", or "vmpvscsi". + A "usb" controller has an optional attribute <code>model</code>, + which is one of "piix3-uhci", "piix4-uhci", "ehci", + "ich9-ehci1", "ich9-uhci1", "ich9-uhci2", "ich9-uhci3", + "vt82c686b-uhci" or "pci-ohci". </p> <p> diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 04c9b61..82a4339 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -877,6 +877,7 @@ <value>scsi</value> <value>sata</value> <value>ccid</value> + <value>usb</value> </choice> </attribute> </optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0361065..10bc130 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -193,7 +193,8 @@ VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST, "scsi", "sata", "virtio-serial", - "ccid") + "ccid", + "usb") VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST, "auto", @@ -2472,6 +2473,8 @@ virDomainControllerModelTypeFromString(const virDomainControllerDefPtr def, { if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) return virDomainControllerModelSCSITypeFromString(model); + else if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) + return virDomainControllerModelUSBTypeFromString(model); return -1; } @@ -8760,6 +8763,8 @@ virDomainControllerModelTypeToString(virDomainControllerDefPtr def, { if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_SCSI) return virDomainControllerModelSCSITypeToString(model); + else if (def->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) + return virDomainControllerModelUSBTypeToString(model); return NULL; } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index e378a9c..0f5e974 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -252,6 +252,7 @@ enum virDomainControllerType { VIR_DOMAIN_CONTROLLER_TYPE_SATA, VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL, VIR_DOMAIN_CONTROLLER_TYPE_CCID, + VIR_DOMAIN_CONTROLLER_TYPE_USB, VIR_DOMAIN_CONTROLLER_TYPE_LAST }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index dbfc7d9..2f32e37 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -83,6 +83,30 @@ VIR_ENUM_IMPL(qemuVideo, VIR_DOMAIN_VIDEO_TYPE_LAST, "", /* don't support vbox */ "qxl"); +VIR_ENUM_DECL(qemuControllerModelSCSI) + +VIR_ENUM_IMPL(qemuControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST, + "", /* auto */ + "", /* buslogic don't support */ + "", /* lsilogic don't support */ + "", /* lsisas don't support */ + "", /* vmpvscsi don't support */ + ); + +VIR_ENUM_DECL(qemuControllerModelUSB) + +VIR_ENUM_IMPL(qemuControllerModelUSB, VIR_DOMAIN_CONTROLLER_MODEL_USB_LAST, + "piix3-usb-uhci", + "piix4-usb-uhci", + "usb-ehci", + "ich9-usb-ehci1", + "ich9-usb-uhci1", + "ich9-usb-uhci2", + "ich9-usb-uhci3", + "vt82c686b-usb-uhci", + "pci-ohci"); + + static void uname_normalize (struct utsname *ut) { @@ -1684,9 +1708,60 @@ error: } +static int +qemuControllerModelUSBToCaps(int model) +{ + switch (model) { + case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI: + return QEMU_CAPS_PIIX3_USB_UHCI; + case VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX4_UHCI: + return QEMU_CAPS_PIIX4_USB_UHCI; + case VIR_DOMAIN_CONTROLLER_MODEL_USB_EHCI: + return QEMU_CAPS_USB_EHCI; + case VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1: + 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 QEMU_CAPS_ICH9_USB_EHCI1; + case VIR_DOMAIN_CONTROLLER_MODEL_USB_VT82C686B_UHCI: + return QEMU_CAPS_VT82C686B_USB_UHCI; + case VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI: + return QEMU_CAPS_PCI_OHCI; + default: + return -1; + } +} + + +static int +qemuBuildUSBControllerDevStr(virDomainControllerDefPtr def, + virBitmapPtr qemuCaps, + virBuffer *buf) +{ + const char *smodel; + int model, caps; + + model = def->model; + if (model == -1) + model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI; + + smodel = qemuControllerModelUSBTypeToString(model); + caps = qemuControllerModelUSBToCaps(model); + + if (caps == -1 || !qemuCapsGet(qemuCaps, caps)) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("%s not supported in this QEMU binary"), smodel); + return -1; + } + + virBufferAsprintf(buf, "%s,id=usb%d", smodel, def->idx); + return 0; +} + char * qemuBuildControllerDevStr(virDomainControllerDefPtr def, - virBitmapPtr qemuCaps) + virBitmapPtr qemuCaps, + int *nusbcontroller) { virBuffer buf = VIR_BUFFER_INITIALIZER; @@ -1718,6 +1793,15 @@ qemuBuildControllerDevStr(virDomainControllerDefPtr def, virBufferAsprintf(&buf, "usb-ccid,id=ccid%d", def->idx); break; + case VIR_DOMAIN_CONTROLLER_TYPE_USB: + if (qemuBuildUSBControllerDevStr(def, qemuCaps, &buf) == -1) + goto error; + + if (nusbcontroller) + *nusbcontroller += 1; + + break; + /* We always get an IDE controller, whether we want it or not. */ case VIR_DOMAIN_CONTROLLER_TYPE_IDE: default: @@ -2885,7 +2969,8 @@ qemuBuildCommandLine(virConnectPtr conn, bool has_rbd_hosts = false; virBuffer rbd_hosts = VIR_BUFFER_INITIALIZER; bool emitBootindex = false; - + int usbcontroller = 0; + bool usblegacy = false; uname_normalize(&ut); if (qemuAssignDeviceAliases(def, qemuCaps) < 0) @@ -3404,14 +3489,26 @@ qemuBuildCommandLine(virConnectPtr conn, goto error; } - virCommandAddArg(cmd, "-device"); + if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB && + def->controllers[i]->model == -1 && + !qemuCapsGet(qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI)) { + if (usblegacy) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Multiple legacy USB controller not supported")); + goto error; + } + usblegacy = true; + } else { + virCommandAddArg(cmd, "-device"); - char *devstr; - if (!(devstr = qemuBuildControllerDevStr(def->controllers[i], qemuCaps))) - goto error; + char *devstr; + if (!(devstr = qemuBuildControllerDevStr(def->controllers[i], qemuCaps, + &usbcontroller))) + goto error; - virCommandAddArg(cmd, devstr); - VIR_FREE(devstr); + virCommandAddArg(cmd, devstr); + VIR_FREE(devstr); + } } } @@ -4116,7 +4213,9 @@ qemuBuildCommandLine(virConnectPtr conn, } } - virCommandAddArg(cmd, "-usb"); + if (usbcontroller == 0) + virCommandAddArg(cmd, "-usb"); + for (i = 0 ; i < def->ninputs ; i++) { virDomainInputDefPtr input = def->inputs[i]; diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 87660f2..099d683 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -89,7 +89,8 @@ char * qemuBuildFSDevStr(virDomainFSDefPtr fs, virBitmapPtr qemuCaps); /* Current, best practice */ char * qemuBuildControllerDevStr(virDomainControllerDefPtr def, - virBitmapPtr qemuCaps); + virBitmapPtr qemuCaps, + int *nusbcontroller); char * qemuBuildWatchdogDevStr(virDomainWatchdogDefPtr dev, virBitmapPtr qemuCaps); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index b7fdfa0..b2da6d0 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -286,7 +286,15 @@ int qemuDomainAttachPciControllerDevice(struct qemud_driver *driver, if (qemuAssignDeviceControllerAlias(controller) < 0) goto cleanup; - if (!(devstr = qemuBuildControllerDevStr(controller, priv->qemuCaps))) { + if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_USB && + controller->model == -1 && + !qemuCapsGet(priv->qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI)) { + qemuReportError(VIR_ERR_OPERATION_FAILED, + _("USB controller hotplug unsupported in this QEMU binary")); + goto cleanup; + } + + if (!(devstr = qemuBuildControllerDevStr(controller, priv->qemuCaps, NULL))) { goto cleanup; } } diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-controller.args b/tests/qemuxml2argvdata/qemuxml2argv-usb-controller.args new file mode 100644 index 0000000..f21efc7 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-controller.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-controller.xml b/tests/qemuxml2argvdata/qemuxml2argv-usb-controller.xml new file mode 100644 index 0000000..82b503e --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-controller.xml @@ -0,0 +1,16 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219136</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <devices> + <emulator>/usr/bin/qemu</emulator> + <controller type='usb' index='0'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-piix3-controller.args b/tests/qemuxml2argvdata/qemuxml2argv-usb-piix3-controller.args new file mode 100644 index 0000000..799b75f --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-piix3-controller.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device piix3-usb-uhci,id=usb0,bus=pci.0,addr=0x3 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-piix3-controller.xml b/tests/qemuxml2argvdata/qemuxml2argv-usb-piix3-controller.xml new file mode 100644 index 0000000..1996d20 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-piix3-controller.xml @@ -0,0 +1,16 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory>219136</memory> + <currentMemory>219200</currentMemory> + <vcpu>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <devices> + <emulator>/usr/bin/qemu</emulator> + <controller type='usb' index='0' model='piix3-uhci'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 6e8da5e..692a02b 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -484,6 +484,13 @@ mymain(void) QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_CCID_EMULATED); + DO_TEST("usb-controller", false, + QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, + QEMU_CAPS_NODEFCONFIG); + DO_TEST("usb-piix3-controller", false, + QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, QEMU_CAPS_PIIX3_USB_UHCI, + QEMU_CAPS_NODEFCONFIG); + DO_TEST("smbios", false, QEMU_CAPS_SMBIOS_TYPE); DO_TEST("watchdog", false, NONE); -- 1.7.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list