So that devices can be attached to hubs. Example, to attach to first port of a usb-hub on port 1. <hub type='usb'> <address type='usb' bus='0' port='1'/> </hub> <input type='mouse' type='usb'> <address type='usb' bus='0' port='1.1'/> </hub> --- docs/schemas/domain.rng | 11 +++++-- src/conf/domain_conf.c | 24 ++++++++++----- src/conf/domain_conf.h | 2 +- src/qemu/qemu_command.c | 2 +- tests/qemuxml2argvdata/qemuxml2argv-usb-ports.args | 1 + tests/qemuxml2argvdata/qemuxml2argv-usb-ports.xml | 31 ++++++++++++++++++++ tests/qemuxml2argvtest.c | 3 ++ 7 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-ports.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-ports.xml diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 16e9687..b496a32 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -2040,7 +2040,7 @@ <ref name="usbAddr"/> </attribute> <attribute name="device"> - <ref name="usbAddr"/> + <ref name="usbPort"/> </attribute> </element> </define> @@ -2049,7 +2049,7 @@ <ref name="usbAddr"/> </attribute> <attribute name="port"> - <ref name="usbAddr"/> + <ref name="usbPort"/> </attribute> </define> <define name="pciaddress"> @@ -2397,7 +2397,7 @@ <define name="usbmaster"> <element name="master"> <attribute name="startport"> - <ref name="usbAddr"/> + <ref name="usbPort"/> </attribute> <empty/> </element> @@ -2548,6 +2548,11 @@ <param name="pattern">(0x)?[0-9a-fA-F]{1,3}</param> </data> </define> + <define name="usbPort"> + <data type="string"> + <param name="pattern">((0x)?[0-9a-fA-F]{1,3}\.){0,3}(0x)?[0-9a-fA-F]{1,3}</param> + </data> + </define> <define name="pciDomain"> <data type="string"> <param name="pattern">(0x)?[0-9a-fA-F]{1,4}</param> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index af08a03..4fe92d7 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1443,12 +1443,9 @@ int virDomainDeviceDriveAddressIsValid(virDomainDeviceDriveAddressPtr addr ATTRI return 1; /* 0 is valid for all fields, so any successfully parsed addr is valid */ } -int virDomainDeviceUSBAddressIsValid(virDomainDeviceUSBAddressPtr addr) +int virDomainDeviceUSBAddressIsValid(virDomainDeviceUSBAddressPtr addr ATTRIBUTE_UNUSED) { - if (addr->port >= 128) /* FIXME: is this correct */ - return 0; - - return 1; + return 1; /* FIXME.. any successfully parsed addr is valid */ } int virDomainDeviceVirtioSerialAddressIsValid( @@ -1472,6 +1469,10 @@ virDomainDeviceInfoIsSet(virDomainDeviceInfoPtr info, unsigned int flags) void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info) { VIR_FREE(info->alias); + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) { + VIR_FREE(info->addr.usb.port); + } + VIR_FREE(info->alias); memset(&info->addr, 0, sizeof(info->addr)); info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; } @@ -1620,7 +1621,7 @@ virDomainDeviceInfoFormat(virBufferPtr buf, break; case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB: - virBufferAsprintf(buf, " bus='%d' port='%d'", + virBufferAsprintf(buf, " bus='%d' port='%s'", info->addr.usb.bus, info->addr.usb.port); break; @@ -1836,7 +1837,8 @@ static int virDomainDeviceUSBAddressParseXML(xmlNodePtr node, virDomainDeviceUSBAddressPtr addr) { - char *port, *bus; + char *port, *bus, *tmp; + unsigned int p; int ret = -1; memset(addr, 0, sizeof(*addr)); @@ -1845,12 +1847,18 @@ virDomainDeviceUSBAddressParseXML(xmlNodePtr node, bus = virXMLPropString(node, "bus"); if (port && - virStrToLong_ui(port, NULL, 10, &addr->port) < 0) { + ((virStrToLong_ui(port, &tmp, 10, &p) < 0 || (*tmp != '\0' && *tmp != '.')) || + (*tmp == '.' && (virStrToLong_ui(tmp + 1, &tmp, 10, &p) < 0 || (*tmp != '\0' && *tmp != '.'))) || + (*tmp == '.' && (virStrToLong_ui(tmp + 1, &tmp, 10, &p) < 0 || (*tmp != '\0' && *tmp != '.'))) || + (*tmp == '.' && (virStrToLong_ui(tmp + 1, &tmp, 10, &p) < 0 || (*tmp != '\0'))))) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Cannot parse <address> 'port' attribute")); goto cleanup; } + addr->port = port; + port = NULL; + if (bus && virStrToLong_ui(bus, NULL, 10, &addr->bus) < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 569e840..48bfd0f 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -110,7 +110,7 @@ typedef struct _virDomainDeviceUSBAddress virDomainDeviceUSBAddress; typedef virDomainDeviceUSBAddress *virDomainDeviceUSBAddressPtr; struct _virDomainDeviceUSBAddress { unsigned int bus; - unsigned int port; + char *port; }; enum virDomainControllerMaster { diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6962862..2b8f548 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1326,7 +1326,7 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, virBufferAsprintf(buf, ",addr=0x%x", info->addr.pci.slot); } else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) { virBufferAsprintf(buf, ",bus=usb%d.0", info->addr.usb.bus); - virBufferAsprintf(buf, ",port=%d", info->addr.usb.port); + virBufferAsprintf(buf, ",port=%s", info->addr.usb.port); } return 0; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-ports.args b/tests/qemuxml2argvdata/qemuxml2argv-usb-ports.args new file mode 100644 index 0000000..556eb4c --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-ports.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 usb-hub,id=hub0,bus=usb.0,port=1 -device usb-hub,id=hub1,bus=usb.0,port=1.2 -device usb-mouse,id=input0,bus=usb.0,port=1.1 -device usb-mouse,id=input1,bus=usb.0,port=1.2.1 -device usb-mouse,id=input2,bus=usb.0,port=1.2.2 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-ports.xml b/tests/qemuxml2argvdata/qemuxml2argv-usb-ports.xml new file mode 100644 index 0000000..e31e5bc --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-ports.xml @@ -0,0 +1,31 @@ +<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'/> + <hub type='usb'> + <address type='usb' bus='0' port='1'/> + </hub> + <input type='mouse' bus='usb'> + <address type='usb' bus='0' port='1.1'/> + </input> + <hub type='usb'> + <address type='usb' bus='0' port='1.2'/> + </hub> + <input type='mouse' bus='usb'> + <address type='usb' bus='0' port='1.2.1'/> + </input> + <input type='mouse' bus='usb'> + <address type='usb' bus='0' port='1.2.2'/> + </input> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index a053693..4c6c486 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -501,6 +501,9 @@ mymain(void) DO_TEST("usb-hub", false, QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, QEMU_CAPS_USB_HUB, QEMU_CAPS_NODEFCONFIG); + DO_TEST("usb-ports", false, + QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, QEMU_CAPS_USB_HUB, + QEMU_CAPS_NODEFCONFIG); DO_TEST("smbios", false, QEMU_CAPS_SMBIOS_TYPE); -- 1.7.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list