]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add USB companion controllers support
authorMarc-André Lureau <marcandre.lureau@redhat.com>
Fri, 2 Sep 2011 14:03:51 +0000 (22:03 +0800)
committerDaniel Veillard <veillard@redhat.com>
Fri, 2 Sep 2011 15:22:56 +0000 (23:22 +0800)
Companion controllers take an extra 'master' attribute to associate
them.

Also add tests for this

docs/formatdomain.html.in
docs/schemas/domain.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/qemu/qemu_command.c
tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.args [new file with mode: 0644]
tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.xml [new file with mode: 0644]
tests/qemuxml2argvtest.c

index ee9709436a6fae39ca5ad92e9ba04461742db7fd..8bd14337248289b7add612230c6e44b50292b8f0 100644 (file)
       sub-element.
     </p>
 
+    <p>
+      USB companion controllers have an optional
+      sub-element <code>&lt;master&gt;</code> to specify the exact
+      relationship of the companion to its master controller.
+      A companion controller is on the same bus as its master, so
+      the companion <code>index</code> value should be equal.
+    </p>
+
+<pre>
+  ...
+  &lt;devices&gt;
+    &lt;controller type='usb' index='0' model='ich9-ehci1'&gt;
+      &lt;address type='pci' domain='0' bus='0' slot='4' function='7'/&gt;
+    &lt;/controller&gt;
+    &lt;controller type='usb' index='0' model='ich9-uhci1'&gt;
+      &lt;master startport='0'/&gt;
+      &lt;address type='pci' domain='0' bus='0' slot='4' function='0'/&gt;
+    &lt;/controller&gt;
+    ...
+  &lt;/devices&gt;
+  ...</pre>
+
     <h4><a name="elementsLease">Device leases</a></h4>
 
     <p>
index 0c72a9f28ac30b3b56de5c38abcdc200372b2504..a4b5575c27878ec56dc8d569917243697e762907 100644 (file)
           </choice>
         </attribute>
       </optional>
+      <optional>
+        <ref name="usbmaster"/>
+      </optional>
       <optional>
         <ref name="address"/>
       </optional>
     </element>
   </define>
 
+  <define name="usbmaster">
+    <element name="master">
+      <attribute name="startport">
+        <ref name="usbAddr"/>
+      </attribute>
+      <empty/>
+    </element>
+  </define>
+
   <define name="filterref-node-attributes">
     <attribute name="filter">
       <data type="NCName"/>
index ef9fb53401c0a5ac42a493bf0ded249e752f92a7..73a7772fd69dd1b108711d047f94666963a3e772 100644 (file)
@@ -1556,6 +1556,11 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
         virBufferAsprintf(buf, "      <alias name='%s'/>\n", info->alias);
     }
 
+    if (info->mastertype == VIR_DOMAIN_CONTROLLER_MASTER_USB) {
+        virBufferAsprintf(buf, "      <master startport='%d'/>\n",
+                          info->master.usb.startport);
+    }
+
     if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
         return 0;
 
@@ -1833,6 +1838,31 @@ cleanup:
     return ret;
 }
 
+static int
+virDomainDeviceUSBMasterParseXML(xmlNodePtr node,
+                                 virDomainDeviceUSBMasterPtr master)
+{
+    char *startport;
+    int ret = -1;
+
+    memset(master, 0, sizeof(*master));
+
+    startport = virXMLPropString(node, "startport");
+
+    if (startport &&
+        virStrToLong_ui(startport, NULL, 10, &master->startport) < 0) {
+        virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                             _("Cannot parse <master> 'startport' attribute"));
+        goto cleanup;
+    }
+
+    ret = 0;
+
+cleanup:
+    VIR_FREE(startport);
+    return ret;
+}
+
 /* Parse the XML definition for a device address
  * @param node XML nodeset to parse for device address definition
  */
@@ -1843,6 +1873,7 @@ virDomainDeviceInfoParseXML(xmlNodePtr node,
 {
     xmlNodePtr cur;
     xmlNodePtr address = NULL;
+    xmlNodePtr master = NULL;
     xmlNodePtr alias = NULL;
     char *type = NULL;
     int ret = -1;
@@ -1859,6 +1890,9 @@ virDomainDeviceInfoParseXML(xmlNodePtr node,
             } else if (address == NULL &&
                        xmlStrEqual(cur->name, BAD_CAST "address")) {
                 address = cur;
+            } else if (master == NULL &&
+                       xmlStrEqual(cur->name, BAD_CAST "master")) {
+                master = cur;
             }
         }
         cur = cur->next;
@@ -1867,6 +1901,12 @@ virDomainDeviceInfoParseXML(xmlNodePtr node,
     if (alias)
         info->alias = virXMLPropString(alias, "name");
 
+    if (master) {
+        info->mastertype = VIR_DOMAIN_CONTROLLER_MASTER_USB;
+        if (virDomainDeviceUSBMasterParseXML(master, &info->master.usb) < 0)
+            goto cleanup;
+    }
+
     if (!address)
         return 0;
 
index 60a296a42d2648395d47040fc480692647a01aae..09c13383b76f0ad1250c3f5a65720534907b0128 100644 (file)
@@ -113,6 +113,19 @@ struct _virDomainDeviceUSBAddress {
     unsigned int port;
 };
 
+enum virDomainControllerMaster {
+    VIR_DOMAIN_CONTROLLER_MASTER_NONE,
+    VIR_DOMAIN_CONTROLLER_MASTER_USB,
+
+    VIR_DOMAIN_CONTROLLER_MASTER_LAST
+};
+
+typedef struct _virDomainDeviceUSBMaster virDomainDeviceUSBMaster;
+typedef virDomainDeviceUSBMaster *virDomainDeviceUSBMasterPtr;
+struct _virDomainDeviceUSBMaster {
+    unsigned int startport;
+};
+
 typedef struct _virDomainDeviceInfo virDomainDeviceInfo;
 typedef virDomainDeviceInfo *virDomainDeviceInfoPtr;
 struct _virDomainDeviceInfo {
@@ -125,6 +138,10 @@ struct _virDomainDeviceInfo {
         virDomainDeviceCcidAddress ccid;
         virDomainDeviceUSBAddress usb;
     } addr;
+    int mastertype;
+    union {
+        virDomainDeviceUSBMaster usb;
+    } master;
 };
 
 typedef struct _virDomainLeaseDef virDomainLeaseDef;
index c8e76ada8e25f3c71a2c0f349c28d84649c92448..e8d6068508039a2d6729f48f2197111182c27d65 100644 (file)
@@ -1767,7 +1767,16 @@ qemuBuildUSBControllerDevStr(virDomainControllerDefPtr def,
         return -1;
     }
 
-    virBufferAsprintf(buf, "%s,id=usb%d", smodel, def->idx);
+    virBufferAsprintf(buf, "%s", smodel);
+
+    if (def->info.mastertype == VIR_DOMAIN_CONTROLLER_MASTER_USB) {
+        virBufferAsprintf(buf, ",masterbus=usb%d.0", def->idx);
+        virBufferAsprintf(buf, ",firstport=%d", def->info.master.usb.startport);
+    } else {
+        virBufferAsprintf(buf, ",id=usb%d", def->idx);
+    }
+
+
     return 0;
 }
 
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.args b/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.args
new file mode 100644 (file)
index 0000000..b37dbf6
--- /dev/null
@@ -0,0 +1,6 @@
+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 ich9-usb-ehci1,id=usb0,bus=pci.0,multifunction=on,addr=0x4.0x7 \
+-device ich9-usb-uhci1,masterbus=usb0.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4.0x0 \
+-device ich9-usb-uhci2,masterbus=usb0.0,firstport=2,bus=pci.0,multifunction=on,addr=0x4.0x1 \
+-device ich9-usb-uhci3,masterbus=usb0.0,firstport=4,bus=pci.0,multifunction=on,addr=0x4.0x2 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.xml b/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.xml
new file mode 100644 (file)
index 0000000..05a6adf
--- /dev/null
@@ -0,0 +1,30 @@
+<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='ich9-ehci1'>
+      <address type='pci' domain='0' bus='0' slot='4' function='7'/>
+    </controller>
+    <controller type='usb' index='0' model='ich9-uhci1'>
+      <master startport='0'/>
+      <address type='pci' domain='0' bus='0' slot='4' function='0'/>
+    </controller>
+    <controller type='usb' index='0' model='ich9-uhci2'>
+      <master startport='2'/>
+      <address type='pci' domain='0' bus='0' slot='4' function='1'/>
+    </controller>
+    <controller type='usb' index='0' model='ich9-uhci3'>
+      <master startport='4'/>
+      <address type='pci' domain='0' bus='0' slot='4' function='2'/>
+    </controller>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
index 9d3409e58f73098a46e3e44c5cecdc3573040522..f44536b882b43ddd67e878afd156e636bfef38d1 100644 (file)
@@ -498,6 +498,9 @@ mymain(void)
             QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1);
     DO_TEST("input-usbmouse-addr", false,
             QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG);
+    DO_TEST("usb-ich9-companion", false,
+            QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
+            QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1);
 
     DO_TEST("smbios", false, QEMU_CAPS_SMBIOS_TYPE);