diff --git a/MAINTAINERS b/MAINTAINERS index 42ac45c3e5..2089e71007 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -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/ diff --git a/docs/system/devices/usb.rst b/docs/system/devices/usb.rst index eeab78dcfb..afb7d6c226 100644 --- a/docs/system/devices/usb.rst +++ b/docs/system/devices/usb.rst @@ -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 `__ - 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 `__ - 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=`` + Specifies the bus number the device must be attached to +``hostaddr=`` + Specifies the device address the device got assigned by the guest os +``hostport=`` + Specifies the physical port the device is attached to +``vendorid=`` + Specifies the vendor ID of the device +``productid=`` + 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 diff --git a/docs/usb-storage.txt b/docs/usb-storage.txt deleted file mode 100644 index 551af6f88b..0000000000 --- a/docs/usb-storage.txt +++ /dev/null @@ -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 diff --git a/docs/usb2.txt b/docs/usb2.txt deleted file mode 100644 index 172614d3a7..0000000000 --- a/docs/usb2.txt +++ /dev/null @@ -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= -- Specifies the bus number the device must be attached - to. - - hostaddr= -- Specifies the device address the device got - assigned by the guest os. - - hostport= -- Specifies the physical port the device is attached - to. - - vendorid= -- Specifies the vendor ID of the device. - productid= -- 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 diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index c0f314462a..00f6fbb29b 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -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); diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index 4ec9326e05..1ec909a63a 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -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; diff --git a/tests/docker/dockerfiles/fedora-win32-cross.docker b/tests/docker/dockerfiles/fedora-win32-cross.docker index 5a03e1af43..aad39dd97f 100644 --- a/tests/docker/dockerfiles/fedora-win32-cross.docker +++ b/tests/docker/dockerfiles/fedora-win32-cross.docker @@ -23,6 +23,7 @@ ENV PACKAGES \ mingw32-libjpeg-turbo \ mingw32-libpng \ mingw32-libtasn1 \ + mingw32-libusbx \ mingw32-nettle \ mingw32-nsis \ mingw32-pixman \ diff --git a/tests/docker/dockerfiles/fedora-win64-cross.docker b/tests/docker/dockerfiles/fedora-win64-cross.docker index d3f13666e8..9a224a619b 100644 --- a/tests/docker/dockerfiles/fedora-win64-cross.docker +++ b/tests/docker/dockerfiles/fedora-win64-cross.docker @@ -23,6 +23,7 @@ ENV PACKAGES \ mingw64-libjpeg-turbo \ mingw64-libpng \ mingw64-libtasn1 \ + mingw64-libusbx \ mingw64-pixman \ mingw64-pkg-config \ perl \