mirror of https://gitee.com/openkylin/qemu.git
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:
commit
7742fe64e5
|
@ -1836,8 +1836,7 @@ S: Maintained
|
||||||
F: hw/usb/*
|
F: hw/usb/*
|
||||||
F: stubs/usb-dev-stub.c
|
F: stubs/usb-dev-stub.c
|
||||||
F: tests/qtest/usb-*-test.c
|
F: tests/qtest/usb-*-test.c
|
||||||
F: docs/usb2.txt
|
F: docs/system/devices/usb.rst
|
||||||
F: docs/usb-storage.txt
|
|
||||||
F: include/hw/usb.h
|
F: include/hw/usb.h
|
||||||
F: include/hw/usb/
|
F: include/hw/usb/
|
||||||
|
|
||||||
|
|
|
@ -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
|
certain host operating systems). QEMU will automatically create and
|
||||||
connect virtual USB hubs as necessary to connect multiple USB devices.
|
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:
|
||||||
|
|
||||||
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``
|
``usb-storage,drive=drive_id``
|
||||||
Mass storage device backed by drive_id (see the :ref:`disk images`
|
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-uas``
|
||||||
USB attached SCSI device, see
|
USB attached SCSI device. This does not create a SCSI disk, so
|
||||||
`usb-storage.txt <https://git.qemu.org/?p=qemu.git;a=blob_plain;f=docs/usb-storage.txt>`__
|
you need to explicitly create a ``scsi-hd`` or ``scsi-cd`` device
|
||||||
for details
|
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``
|
``usb-bot``
|
||||||
Bulk-only transport storage device, see
|
Bulk-only transport storage device. This presents the guest with the
|
||||||
`usb-storage.txt <https://git.qemu.org/?p=qemu.git;a=blob_plain;f=docs/usb-storage.txt>`__
|
same USB bulk-only transport protocol interface as ``usb-storage``, but
|
||||||
for details here, too
|
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``
|
``usb-mtp,rootdir=dir``
|
||||||
Media transfer protocol device, using dir as root of the file tree
|
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}``
|
``u2f-{emulated,passthru}``
|
||||||
Universal Second Factor device
|
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:
|
.. _host_005fusb_005fdevices:
|
||||||
|
|
||||||
Using host USB devices on a Linux host
|
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
|
When relaunching QEMU, you may have to unplug and plug again the USB
|
||||||
device to make it work again (this is a bug).
|
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
|
||||||
|
|
|
@ -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>
|
|
172
docs/usb2.txt
172
docs/usb2.txt
|
@ -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>
|
|
|
@ -254,6 +254,29 @@ static void usb_host_del_fd(int fd, void *user_data)
|
||||||
qemu_set_fd_handler(fd, NULL, NULL, NULL);
|
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 */
|
#endif /* !CONFIG_WIN32 */
|
||||||
|
|
||||||
static int usb_host_init(void)
|
static int usb_host_init(void)
|
||||||
|
@ -276,7 +299,8 @@ static int usb_host_init(void)
|
||||||
libusb_set_debug(ctx, loglevel);
|
libusb_set_debug(ctx, loglevel);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_WIN32
|
#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
|
#else
|
||||||
libusb_set_pollfd_notifiers(ctx, usb_host_add_fd,
|
libusb_set_pollfd_notifiers(ctx, usb_host_add_fd,
|
||||||
usb_host_del_fd,
|
usb_host_del_fd,
|
||||||
|
@ -364,11 +388,18 @@ static USBHostRequest *usb_host_req_alloc(USBHostDevice *s, USBPacket *p,
|
||||||
r->buffer = g_malloc(bufsize);
|
r->buffer = g_malloc(bufsize);
|
||||||
}
|
}
|
||||||
QTAILQ_INSERT_TAIL(&s->requests, r, next);
|
QTAILQ_INSERT_TAIL(&s->requests, r, next);
|
||||||
|
#ifdef CONFIG_WIN32
|
||||||
|
request_count++;
|
||||||
|
usb_host_timer_kick();
|
||||||
|
#endif
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usb_host_req_free(USBHostRequest *r)
|
static void usb_host_req_free(USBHostRequest *r)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_WIN32
|
||||||
|
request_count--;
|
||||||
|
#endif
|
||||||
QTAILQ_REMOVE(&r->host->requests, r, next);
|
QTAILQ_REMOVE(&r->host->requests, r, next);
|
||||||
libusb_free_transfer(r->xfer);
|
libusb_free_transfer(r->xfer);
|
||||||
g_free(r->buffer);
|
g_free(r->buffer);
|
||||||
|
|
|
@ -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_dropping_packets) {
|
||||||
if (dev->endpoint[EP2I(ep)].bufpq_size >
|
if (dev->endpoint[EP2I(ep)].bufpq_size >
|
||||||
dev->endpoint[EP2I(ep)].bufpq_target_size) {
|
dev->endpoint[EP2I(ep)].bufpq_target_size) {
|
||||||
free(data);
|
free(free_on_destroy);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
|
dev->endpoint[EP2I(ep)].bufpq_dropping_packets = 0;
|
||||||
|
|
|
@ -23,6 +23,7 @@ ENV PACKAGES \
|
||||||
mingw32-libjpeg-turbo \
|
mingw32-libjpeg-turbo \
|
||||||
mingw32-libpng \
|
mingw32-libpng \
|
||||||
mingw32-libtasn1 \
|
mingw32-libtasn1 \
|
||||||
|
mingw32-libusbx \
|
||||||
mingw32-nettle \
|
mingw32-nettle \
|
||||||
mingw32-nsis \
|
mingw32-nsis \
|
||||||
mingw32-pixman \
|
mingw32-pixman \
|
||||||
|
|
|
@ -23,6 +23,7 @@ ENV PACKAGES \
|
||||||
mingw64-libjpeg-turbo \
|
mingw64-libjpeg-turbo \
|
||||||
mingw64-libpng \
|
mingw64-libpng \
|
||||||
mingw64-libtasn1 \
|
mingw64-libtasn1 \
|
||||||
|
mingw64-libusbx \
|
||||||
mingw64-pixman \
|
mingw64-pixman \
|
||||||
mingw64-pkg-config \
|
mingw64-pkg-config \
|
||||||
perl \
|
perl \
|
||||||
|
|
Loading…
Reference in New Issue