mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-11 09:17:52 +03:00
Add USB companion controllers support
Companion controllers take an extra 'master' attribute to associate them. Also add tests for this
This commit is contained in:
parent
22c0d433ab
commit
f3ce59621f
@ -1245,6 +1245,28 @@
|
||||
sub-element.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
USB companion controllers have an optional
|
||||
sub-element <code><master></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>
|
||||
...
|
||||
<devices>
|
||||
<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>
|
||||
...
|
||||
</devices>
|
||||
...</pre>
|
||||
|
||||
<h4><a name="elementsLease">Device leases</a></h4>
|
||||
|
||||
<p>
|
||||
|
@ -923,6 +923,9 @@
|
||||
</choice>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="usbmaster"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="address"/>
|
||||
</optional>
|
||||
@ -2379,6 +2382,15 @@
|
||||
</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"/>
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
30
tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.xml
Normal file
30
tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.xml
Normal file
@ -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>
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user