usb: fixes for 6.1: usbredir, usb-host for windows, docs.

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEoDKM/7k6F6eZAf59TLbY7tPocTgFAmECpBgACgkQTLbY7tPo
 cTjl/xAAlTWFNLGpl0cQ3s6//XE2uGflbaVfc7Gj+JIktxP13rvX9aJYG8FTOyij
 QLCHlFKcDZWa/AbNZNAbILA8Qp3YRIQKhPqXH5uOgf8K6IG3WxsrjDVUQYousbZO
 eJ1INGh5GwIudEi1i8zyytfMjoT75lbx8hZPON1P8zAHoAqDXqLQnNoTwBmBXi78
 A2G3yb3o/SwiNtlcYy19WXSSx1FZb3Ll4P+v0KZvoffxdxdfUVZA15ZLOenHm6UL
 6ZjKB6JWgTYYQ2kQ1g0cRfHYIM+ubPSm0DteErzd3xcaTFtRHf6IwHKJ5l3QgIiD
 +Qi2MNC1uXQlPSet8yF8rQ7+SPORc6cwMGfAKOeHjVE0Q821ZvXu+SnTzJ/WHlgI
 4WoVndz7FX0Ewf/j7J1aL2+er0X7twipNLElm3oJkKg9kn4Phhl7JDu2HD8KiZMC
 R8FotiSYhjkFTV6fR0f+GQllAuK5e2rHSRscyuJgmuY07Mhr+Mi6IhPnLOayz/A6
 OYrVSszMF9giucm7vUl60wAWyxOgykIhnFCoEubJDW6XGu4BBekihaBr6b8pkoDL
 HD6oPgRsa8ZO6OhYrMkuWy8U0cE+BO3c2rvgRh+kq3300D6Stpfzj5obCG/xVH8Q
 dT+/ySGL0ANijrPp6WAn325NoHZCseQteqXvalWH/acEiZ/NayI=
 =eiMq
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kraxel/tags/usb-20210729-pull-request' into staging

usb: fixes for 6.1: usbredir, usb-host for windows, docs.

# gpg: Signature made Thu 29 Jul 2021 13:50:32 BST
# gpg:                using RSA key A0328CFFB93A17A79901FE7D4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/usb-20210729-pull-request:
  docs: Fold usb2.txt passthrough information into usb.rst
  docs: Fold usb2.txt physical port addressing info into usb.rst
  docs: Fold usb2.txt USB controller information into usb.rst
  docs: Incorporate information in usb-storage.txt into rST manual
  usbredir: fix free call
  ci: add libusb for windows builds
  usb-host: wire up timer for windows

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2021-07-29 18:49:39 +01:00
commit 7742fe64e5
8 changed files with 254 additions and 242 deletions

View File

@ -1836,8 +1836,7 @@ S: Maintained
F: hw/usb/*
F: stubs/usb-dev-stub.c
F: tests/qtest/usb-*-test.c
F: docs/usb2.txt
F: docs/usb-storage.txt
F: docs/system/devices/usb.rst
F: include/hw/usb.h
F: include/hw/usb/

View File

@ -8,6 +8,92 @@ plug virtual USB devices or real host USB devices (only works with
certain host operating systems). QEMU will automatically create and
connect virtual USB hubs as necessary to connect multiple USB devices.
USB controllers
~~~~~~~~~~~~~~~
XHCI controller support
^^^^^^^^^^^^^^^^^^^^^^^
QEMU has XHCI host adapter support. The XHCI hardware design is much
more virtualization-friendly when compared to EHCI and UHCI, thus XHCI
emulation uses less resources (especially CPU). So if your guest
supports XHCI (which should be the case for any operating system
released around 2010 or later) we recommend using it:
qemu -device qemu-xhci
XHCI supports USB 1.1, USB 2.0 and USB 3.0 devices, so this is the
only controller you need. With only a single USB controller (and
therefore only a single USB bus) present in the system there is no
need to use the bus= parameter when adding USB devices.
EHCI controller support
^^^^^^^^^^^^^^^^^^^^^^^
The QEMU EHCI Adapter supports USB 2.0 devices. It can be used either
standalone or with companion controllers (UHCI, OHCI) for USB 1.1
devices. The companion controller setup is more convenient to use
because it provides a single USB bus supporting both USB 2.0 and USB
1.1 devices. See next section for details.
When running EHCI in standalone mode you can add UHCI or OHCI
controllers for USB 1.1 devices too. Each controller creates its own
bus though, so there are two completely separate USB buses: One USB
1.1 bus driven by the UHCI controller and one USB 2.0 bus driven by
the EHCI controller. Devices must be attached to the correct
controller manually.
The easiest way to add a UHCI controller to a ``pc`` machine is the
``-usb`` switch. QEMU will create the UHCI controller as function of
the PIIX3 chipset. The USB 1.1 bus will carry the name ``usb-bus.0``.
You can use the standard ``-device`` switch to add a EHCI controller to
your virtual machine. It is strongly recommended to specify an ID for
the controller so the USB 2.0 bus gets an individual name, for example
``-device usb-ehci,id=ehci``. This will give you a USB 2.0 bus named
``ehci.0``.
When adding USB devices using the ``-device`` switch you can specify the
bus they should be attached to. Here is a complete example:
.. parsed-literal::
|qemu_system| -M pc ${otheroptions} \\
-drive if=none,id=usbstick,format=raw,file=/path/to/image \\
-usb \\
-device usb-ehci,id=ehci \\
-device usb-tablet,bus=usb-bus.0 \\
-device usb-storage,bus=ehci.0,drive=usbstick
This attaches a USB tablet to the UHCI adapter and a USB mass storage
device to the EHCI adapter.
Companion controller support
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The UHCI and OHCI controllers can attach to a USB bus created by EHCI
as companion controllers. This is done by specifying the ``masterbus``
and ``firstport`` properties. ``masterbus`` specifies the bus name the
controller should attach to. ``firstport`` specifies the first port the
controller should attach to, which is needed as usually one EHCI
controller with six ports has three UHCI companion controllers with
two ports each.
There is a config file in docs which will do all this for
you, which you can use like this:
.. parsed-literal::
|qemu_system| -readconfig docs/config/ich9-ehci-uhci.cfg
Then use ``bus=ehci.0`` to assign your USB devices to that bus.
Using the ``-usb`` switch for ``q35`` machines will create a similar
USB controller configuration.
.. _Connecting USB devices:
Connecting USB devices
@ -28,17 +114,46 @@ option or the ``device_add`` monitor command. Available devices are:
``usb-storage,drive=drive_id``
Mass storage device backed by drive_id (see the :ref:`disk images`
chapter in the System Emulation Users Guide)
chapter in the System Emulation Users Guide). This is the classic
bulk-only transport protocol used by 99% of USB sticks. This
example shows it connected to an XHCI USB controller and with
a drive backed by a raw format disk image:
.. parsed-literal::
|qemu_system| [...] \\
-drive if=none,id=stick,format=raw,file=/path/to/file.img \\
-device nec-usb-xhci,id=xhci \\
-device usb-storage,bus=xhci.0,drive=stick
``usb-uas``
USB attached SCSI device, see
`usb-storage.txt <https://git.qemu.org/?p=qemu.git;a=blob_plain;f=docs/usb-storage.txt>`__
for details
USB attached SCSI device. This does not create a SCSI disk, so
you need to explicitly create a ``scsi-hd`` or ``scsi-cd`` device
on the command line, as well as using the ``-drive`` option to
specify what those disks are backed by. One ``usb-uas`` device can
handle multiple logical units (disks). This example creates three
logical units: two disks and one cdrom drive:
.. parsed-literal::
|qemu_system| [...] \\
-drive if=none,id=uas-disk1,format=raw,file=/path/to/file1.img \\
-drive if=none,id=uas-disk2,format=raw,file=/path/to/file2.img \\
-drive if=none,id=uas-cdrom,media=cdrom,format=raw,file=/path/to/image.iso \\
-device nec-usb-xhci,id=xhci \\
-device usb-uas,id=uas,bus=xhci.0 \\
-device scsi-hd,bus=uas.0,scsi-id=0,lun=0,drive=uas-disk1 \\
-device scsi-hd,bus=uas.0,scsi-id=0,lun=1,drive=uas-disk2 \\
-device scsi-cd,bus=uas.0,scsi-id=0,lun=5,drive=uas-cdrom
``usb-bot``
Bulk-only transport storage device, see
`usb-storage.txt <https://git.qemu.org/?p=qemu.git;a=blob_plain;f=docs/usb-storage.txt>`__
for details here, too
Bulk-only transport storage device. This presents the guest with the
same USB bulk-only transport protocol interface as ``usb-storage``, but
the QEMU command line option works like ``usb-uas`` and does not
automatically create SCSI disks for you. ``usb-bot`` supports up to
16 LUNs. Unlike ``usb-uas``, the LUN numbers must be continuous,
i.e. for three devices you must use 0+1+2. The 0+1+5 numbering from the
``usb-uas`` example above won't work with ``usb-bot``.
``usb-mtp,rootdir=dir``
Media transfer protocol device, using dir as root of the file tree
@ -84,6 +199,53 @@ option or the ``device_add`` monitor command. Available devices are:
``u2f-{emulated,passthru}``
Universal Second Factor device
Physical port addressing
^^^^^^^^^^^^^^^^^^^^^^^^
For all the above USB devices, by default QEMU will plug the device
into the next available port on the specified USB bus, or onto
some available USB bus if you didn't specify one explicitly.
If you need to, you can also specify the physical port where
the device will show up in the guest. This can be done using the
``port`` property. UHCI has two root ports (1,2). EHCI has six root
ports (1-6), and the emulated (1.1) USB hub has eight ports.
Plugging a tablet into UHCI port 1 works like this::
-device usb-tablet,bus=usb-bus.0,port=1
Plugging a hub into UHCI port 2 works like this::
-device usb-hub,bus=usb-bus.0,port=2
Plugging a virtual USB stick into port 4 of the hub just plugged works
this way::
-device usb-storage,bus=usb-bus.0,port=2.4,drive=...
In the monitor, the ``device_add` command also accepts a ``port``
property specification. If you want to unplug devices too you should
specify some unique id which you can use to refer to the device.
You can then use ``device_del`` to unplug the device later.
For example::
(qemu) device_add usb-tablet,bus=usb-bus.0,port=1,id=my-tablet
(qemu) device_del my-tablet
Hotplugging USB storage
~~~~~~~~~~~~~~~~~~~~~~~
The ``usb-bot`` and ``usb-uas`` devices can be hotplugged. In the hotplug
case they are added with ``attached = false`` so the guest will not see
the device until the ``attached`` property is explicitly set to true.
That allows you to attach one or more scsi devices before making the
device visible to the guest. The workflow looks like this:
#. ``device-add usb-bot,id=foo``
#. ``device-add scsi-{hd,cd},bus=foo.0,lun=0``
#. optionally add more devices (luns 1 ... 15)
#. ``scripts/qmp/qom-set foo.attached = true``
.. _host_005fusb_005fdevices:
Using host USB devices on a Linux host
@ -138,3 +300,52 @@ are not supported yet.
When relaunching QEMU, you may have to unplug and plug again the USB
device to make it work again (this is a bug).
``usb-host`` properties for specifying the host device
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The example above uses the ``vendorid`` and ``productid`` to
specify which host device to pass through, but this is not
the only way to specify the host device. ``usb-host`` supports
the following properties:
``hostbus=<nr>``
Specifies the bus number the device must be attached to
``hostaddr=<nr>``
Specifies the device address the device got assigned by the guest os
``hostport=<str>``
Specifies the physical port the device is attached to
``vendorid=<hexnr>``
Specifies the vendor ID of the device
``productid=<hexnr>``
Specifies the product ID of the device.
In theory you can combine all these properties as you like. In
practice only a few combinations are useful:
- ``vendorid`` and ``productid`` -- match for a specific device, pass it to
the guest when it shows up somewhere in the host.
- ``hostbus`` and ``hostport`` -- match for a specific physical port in the
host, any device which is plugged in there gets passed to the
guest.
- ``hostbus`` and ``hostaddr`` -- most useful for ad-hoc pass through as the
hostaddr isn't stable. The next time you plug the device into the host it
will get a new hostaddr.
Note that on the host USB 1.1 devices are handled by UHCI/OHCI and USB
2.0 by EHCI. That means different USB devices plugged into the very
same physical port on the host may show up on different host buses
depending on the speed. Supposing that devices plugged into a given
physical port appear as bus 1 + port 1 for 2.0 devices and bus 3 + port 1
for 1.1 devices, you can pass through any device plugged into that port
and also assign it to the correct USB bus in QEMU like this:
.. parsed-literal::
|qemu_system| -M pc [...] \\
-usb \\
-device usb-ehci,id=ehci \\
-device usb-host,bus=usb-bus.0,hostbus=3,hostport=1 \\
-device usb-host,bus=ehci.0,hostbus=1,hostport=1

View File

@ -1,59 +0,0 @@
qemu usb storage emulation
--------------------------
QEMU has three devices for usb storage emulation.
Number one emulates the classic bulk-only transport protocol which is
used by 99% of the usb sticks on the market today and is called
"usb-storage". Usage (hooking up to xhci, other host controllers work
too):
qemu ${other_vm_args} \
-drive if=none,id=stick,file=/path/to/file.img \
-device nec-usb-xhci,id=xhci \
-device usb-storage,bus=xhci.0,drive=stick
Number two is the newer usb attached scsi transport. This one doesn't
automagically create a scsi disk, so you have to explicitly attach one
manually. Multiple logical units are supported. Here is an example
with tree logical units:
qemu ${other_vm_args} \
-drive if=none,id=uas-disk1,file=/path/to/file1.img \
-drive if=none,id=uas-disk2,file=/path/to/file2.img \
-drive if=none,id=uas-cdrom,media=cdrom,file=/path/to/image.iso \
-device nec-usb-xhci,id=xhci \
-device usb-uas,id=uas,bus=xhci.0 \
-device scsi-hd,bus=uas.0,scsi-id=0,lun=0,drive=uas-disk1 \
-device scsi-hd,bus=uas.0,scsi-id=0,lun=1,drive=uas-disk2 \
-device scsi-cd,bus=uas.0,scsi-id=0,lun=5,drive=uas-cdrom
Number three emulates the classic bulk-only transport protocol too.
It's called "usb-bot". It shares most code with "usb-storage", and
the guest will not be able to see the difference. The qemu command
line interface is similar to usb-uas though, i.e. no automatic scsi
disk creation. It also features support for up to 16 LUNs. The LUN
numbers must be continuous, i.e. for three devices you must use 0+1+2.
The 0+1+5 numbering from the "usb-uas" example isn't going to work
with "usb-bot".
Starting with qemu version 2.7 usb-bot and usb-uas devices can be
hotplugged. In the hotplug case they are added with "attached =
false" so the guest will not see the device until the "attached"
property is explicitly set to true. That allows to attach one or more
scsi devices before making the device visible to the guest, i.e. the
workflow looks like this:
(1) device-add usb-bot,id=foo
(2) device-add scsi-{hd,cd},bus=foo.0,lun=0
(2b) optionally add more devices (luns 1 ... 15).
(3) scripts/qmp/qom-set foo.attached = true
enjoy,
Gerd
--
Gerd Hoffmann <kraxel@redhat.com>

View File

@ -1,172 +0,0 @@
USB Quick Start
===============
XHCI controller support
-----------------------
QEMU has XHCI host adapter support. The XHCI hardware design is much
more virtualization-friendly when compared to EHCI and UHCI, thus XHCI
emulation uses less resources (especially cpu). So if your guest
supports XHCI (which should be the case for any operating system
released around 2010 or later) we recommend using it:
qemu -device qemu-xhci
XHCI supports USB 1.1, USB 2.0 and USB 3.0 devices, so this is the
only controller you need. With only a single USB controller (and
therefore only a single USB bus) present in the system there is no
need to use the bus= parameter when adding USB devices.
EHCI controller support
-----------------------
The QEMU EHCI Adapter supports USB 2.0 devices. It can be used either
standalone or with companion controllers (UHCI, OHCI) for USB 1.1
devices. The companion controller setup is more convenient to use
because it provides a single USB bus supporting both USB 2.0 and USB
1.1 devices. See next section for details.
When running EHCI in standalone mode you can add UHCI or OHCI
controllers for USB 1.1 devices too. Each controller creates its own
bus though, so there are two completely separate USB buses: One USB
1.1 bus driven by the UHCI controller and one USB 2.0 bus driven by
the EHCI controller. Devices must be attached to the correct
controller manually.
The easiest way to add a UHCI controller to a 'pc' machine is the
'-usb' switch. QEMU will create the UHCI controller as function of
the PIIX3 chipset. The USB 1.1 bus will carry the name "usb-bus.0".
You can use the standard -device switch to add a EHCI controller to
your virtual machine. It is strongly recommended to specify an ID for
the controller so the USB 2.0 bus gets an individual name, for example
'-device usb-ehci,id=ehci". This will give you a USB 2.0 bus named
"ehci.0".
When adding USB devices using the -device switch you can specify the
bus they should be attached to. Here is a complete example:
qemu -M pc ${otheroptions} \
-drive if=none,id=usbstick,file=/path/to/image \
-usb \
-device usb-ehci,id=ehci \
-device usb-tablet,bus=usb-bus.0 \
-device usb-storage,bus=ehci.0,drive=usbstick
This attaches a USB tablet to the UHCI adapter and a USB mass storage
device to the EHCI adapter.
Companion controller support
----------------------------
The UHCI and OHCI controllers can attach to a USB bus created by EHCI
as companion controllers. This is done by specifying the masterbus
and firstport properties. masterbus specifies the bus name the
controller should attach to. firstport specifies the first port the
controller should attach to, which is needed as usually one EHCI
controller with six ports has three UHCI companion controllers with
two ports each.
There is a config file in docs which will do all this for
you, just try ...
qemu -readconfig docs/config/ich9-ehci-uhci.cfg
... then use "bus=ehci.0" to assign your USB devices to that bus.
Using the '-usb' switch for 'q35' machines will create a similar
USB controller configuration.
More USB tips & tricks
======================
Recently the USB pass through driver (also known as usb-host) and the
QEMU USB subsystem gained a few capabilities which are available only
via qdev properties, i,e. when using '-device'.
physical port addressing
------------------------
First you can (for all USB devices) specify the physical port where
the device will show up in the guest. This can be done using the
"port" property. UHCI has two root ports (1,2). EHCI has six root
ports (1-6), the emulated (1.1) USB hub has eight ports.
Plugging a tablet into UHCI port 1 works like this:
-device usb-tablet,bus=usb-bus.0,port=1
Plugging a hub into UHCI port 2 works like this:
-device usb-hub,bus=usb-bus.0,port=2
Plugging a virtual USB stick into port 4 of the hub just plugged works
this way:
-device usb-storage,bus=usb-bus.0,port=2.4,drive=...
You can do basically the same in the monitor using the device_add
command. If you want to unplug devices too you should specify some
unique id which you can use to refer to the device ...
(qemu) device_add usb-tablet,bus=usb-bus.0,port=1,id=my-tablet
(qemu) device_del my-tablet
... when unplugging it with device_del.
USB pass through hints
----------------------
The usb-host driver has a bunch of properties to specify the device
which should be passed to the guest:
hostbus=<nr> -- Specifies the bus number the device must be attached
to.
hostaddr=<nr> -- Specifies the device address the device got
assigned by the guest os.
hostport=<str> -- Specifies the physical port the device is attached
to.
vendorid=<hexnr> -- Specifies the vendor ID of the device.
productid=<hexnr> -- Specifies the product ID of the device.
In theory you can combine all these properties as you like. In
practice only a few combinations are useful:
(1) vendorid+productid -- match for a specific device, pass it to
the guest when it shows up somewhere in the host.
(2) hostbus+hostport -- match for a specific physical port in the
host, any device which is plugged in there gets passed to the
guest.
(3) hostbus+hostaddr -- most useful for ad-hoc pass through as the
hostaddr isn't stable, the next time you plug in the device it
gets a new one ...
Note that USB 1.1 devices are handled by UHCI/OHCI and USB 2.0 by
EHCI. That means a device plugged into the very same physical port
may show up on different buses depending on the speed. The port I'm
using for testing is bus 1 + port 1 for 2.0 devices and bus 3 + port 1
for 1.1 devices. Passing through any device plugged into that port
and also assign them to the correct bus can be done this way:
qemu -M pc ${otheroptions} \
-usb \
-device usb-ehci,id=ehci \
-device usb-host,bus=usb-bus.0,hostbus=3,hostport=1 \
-device usb-host,bus=ehci.0,hostbus=1,hostport=1
enjoy,
Gerd
--
Gerd Hoffmann <kraxel@redhat.com>

View File

@ -254,6 +254,29 @@ static void usb_host_del_fd(int fd, void *user_data)
qemu_set_fd_handler(fd, NULL, NULL, NULL);
}
#else
static QEMUTimer *poll_timer;
static uint32_t request_count;
static void usb_host_timer_kick(void)
{
int64_t delay_ns;
delay_ns = request_count
? (NANOSECONDS_PER_SECOND / 100) /* 10 ms interval with active req */
: (NANOSECONDS_PER_SECOND); /* 1 sec interval otherwise */
timer_mod(poll_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + delay_ns);
}
static void usb_host_timer(void *opaque)
{
struct timeval tv = { 0, 0 };
libusb_handle_events_timeout(ctx, &tv);
usb_host_timer_kick();
}
#endif /* !CONFIG_WIN32 */
static int usb_host_init(void)
@ -276,7 +299,8 @@ static int usb_host_init(void)
libusb_set_debug(ctx, loglevel);
#endif
#ifdef CONFIG_WIN32
/* FIXME: add support for Windows. */
poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, usb_host_timer, NULL);
usb_host_timer_kick();
#else
libusb_set_pollfd_notifiers(ctx, usb_host_add_fd,
usb_host_del_fd,
@ -364,11 +388,18 @@ static USBHostRequest *usb_host_req_alloc(USBHostDevice *s, USBPacket *p,
r->buffer = g_malloc(bufsize);
}
QTAILQ_INSERT_TAIL(&s->requests, r, next);
#ifdef CONFIG_WIN32
request_count++;
usb_host_timer_kick();
#endif
return r;
}
static void usb_host_req_free(USBHostRequest *r)
{
#ifdef CONFIG_WIN32
request_count--;
#endif
QTAILQ_REMOVE(&r->host->requests, r, next);
libusb_free_transfer(r->xfer);
g_free(r->buffer);

View File

@ -476,7 +476,7 @@ static int bufp_alloc(USBRedirDevice *dev, uint8_t *data, uint16_t len,
if (dev->endpoint[EP2I(ep)].bufpq_dropping_packets) {
if (dev->endpoint[EP2I(ep)].bufpq_size >
dev->endpoint[EP2I(ep)].bufpq_target_size) {
free(data);
free(free_on_destroy);
return -1;
}
dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;

View File

@ -23,6 +23,7 @@ ENV PACKAGES \
mingw32-libjpeg-turbo \
mingw32-libpng \
mingw32-libtasn1 \
mingw32-libusbx \
mingw32-nettle \
mingw32-nsis \
mingw32-pixman \

View File

@ -23,6 +23,7 @@ ENV PACKAGES \
mingw64-libjpeg-turbo \
mingw64-libpng \
mingw64-libtasn1 \
mingw64-libusbx \
mingw64-pixman \
mingw64-pkg-config \
perl \