]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add a new controller type 'usb' with optionnal 'model'
authorMarc-André Lureau <marcandre.lureau@redhat.com>
Fri, 2 Sep 2011 13:21:23 +0000 (21:21 +0800)
committerDaniel Veillard <veillard@redhat.com>
Fri, 2 Sep 2011 15:22:56 +0000 (23:22 +0800)
The model by default is piix3-uchi.

Example:
<controller type='usb' index='0' model='ich9-ehci'/>

docs/formatdomain.html.in
docs/schemas/domain.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_command.c
src/qemu/qemu_command.h
src/qemu/qemu_hotplug.c
tests/qemuxml2argvtest.c

index 8fd6ca1f8da27d669c5c05a8e1b79f308207c969..ee9709436a6fae39ca5ad92e9ba04461742db7fd 100644 (file)
 
     <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>
index 5830421f7d241cf0a4af1e7d675ea879078c8edd..086d2718dcde655afa9a530be7882a35d6403daa 100644 (file)
                 <value>scsi</value>
                 <value>sata</value>
                 <value>ccid</value>
+                <value>usb</value>
               </choice>
             </attribute>
           </optional>
index 8c04a32fd87fabdb4aee5df2c84314159dd18ff7..82338d64c2e7620668786c482226996a04a5079e 100644 (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;
 }
index 5396f7ae1459144031d7990bf519737534ae5d74..68cfa213a7e7883bb3f2aeb1f1e1bdb4bf598f83 100644 (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
 };
index fa52dc0ab962ec3e571bcc2194caee59f07cfc29..5e2fad0754e318bc0649599f93c79fb2a286d519 100644 (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];
 
index 87660f2f8ff63c1c632ea6bb5a87db359b39d312..099d683f350a07031486ebc0b679fbd988fdf3fb 100644 (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);
index b7fdfa04bb841e77db105188b3f5c30b1a639a58..b2da6d06df3e654fdc44dfd700723e4b6e1e8f77 100644 (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;
         }
     }
index b009bf3cb52da932329b70c0e02ee6905507c23b..3a317b22c6e8403821995e0835ddb96c701f916e 100644 (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);