Add a new controller type 'usb' with optionnal 'model'

The model by default is piix3-uchi.

Example:
<controller type='usb' index='0' model='ich9-ehci'/>
This commit is contained in:
Marc-André Lureau 2011-09-02 21:21:23 +08:00 committed by Daniel Veillard
parent 2e4b5243b2
commit d6d54cd19e
8 changed files with 135 additions and 18 deletions

View File

@ -1219,17 +1219,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>&lt;address&gt;</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>&lt;address&gt;</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>

View File

@ -878,6 +878,7 @@
<value>scsi</value>
<value>sata</value>
<value>ccid</value>
<value>usb</value>
</choice>
</attribute>
</optional>

View File

@ -194,7 +194,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",
@ -2473,6 +2474,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;
}
@ -8756,6 +8759,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;
}

View File

@ -253,6 +253,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
};

View File

@ -85,6 +85,20 @@ VIR_ENUM_IMPL(qemuVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
"", /* don't support vbox */
"qxl");
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)
{
@ -1703,9 +1717,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;
@ -1737,6 +1802,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:
@ -2904,7 +2978,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)
@ -3423,14 +3498,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);
}
}
}
@ -4135,7 +4222,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];

View File

@ -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);

View File

@ -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;
}
}

View File

@ -487,6 +487,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);