diff options
Diffstat (limited to 'app-emulation/qemu/files/qemu-5.1.0-usb-host-workaround-libusb-bug.patch')
-rw-r--r-- | app-emulation/qemu/files/qemu-5.1.0-usb-host-workaround-libusb-bug.patch | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/app-emulation/qemu/files/qemu-5.1.0-usb-host-workaround-libusb-bug.patch b/app-emulation/qemu/files/qemu-5.1.0-usb-host-workaround-libusb-bug.patch new file mode 100644 index 000000000000..34a50a9bfb58 --- /dev/null +++ b/app-emulation/qemu/files/qemu-5.1.0-usb-host-workaround-libusb-bug.patch @@ -0,0 +1,82 @@ +From 202d69a715a4b1824dcd7ec1683d027ed2bae6d3 Mon Sep 17 00:00:00 2001 +Message-Id: <202d69a715a4b1824dcd7ec1683d027ed2bae6d3.1606202550.git.mprivozn@redhat.com> +From: Gerd Hoffmann <kraxel@redhat.com> +Date: Mon, 24 Aug 2020 13:00:57 +0200 +Subject: [PATCH] usb-host: workaround libusb bug + +libusb_get_device_speed() does not work for +libusb_wrap_sys_device() devices in v1.0.23. + +Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1871090 +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> +Message-id: 20200824110057.32089-1-kraxel@redhat.com +Signed-off-by: Michal Privoznik <mprivozn@redhat.com> +--- + hw/usb/host-libusb.c | 37 ++++++++++++++++++++++++++++++++++++- + 1 file changed, 36 insertions(+), 1 deletion(-) + +diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c +index c474551d84..08604f787f 100644 +--- a/hw/usb/host-libusb.c ++++ b/hw/usb/host-libusb.c +@@ -39,6 +39,11 @@ + #endif + #include <libusb.h> + ++#ifdef CONFIG_LINUX ++#include <sys/ioctl.h> ++#include <linux/usbdevice_fs.h> ++#endif ++ + #include "qapi/error.h" + #include "migration/vmstate.h" + #include "monitor/monitor.h" +@@ -885,6 +890,7 @@ static void usb_host_ep_update(USBHostDevice *s) + static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd) + { + USBDevice *udev = USB_DEVICE(s); ++ int libusb_speed; + int bus_num = 0; + int addr = 0; + int rc; +@@ -935,7 +941,36 @@ static int usb_host_open(USBHostDevice *s, libusb_device *dev, int hostfd) + usb_ep_init(udev); + usb_host_ep_update(s); + +- udev->speed = speed_map[libusb_get_device_speed(dev)]; ++ libusb_speed = libusb_get_device_speed(dev); ++#ifdef CONFIG_LINUX ++ if (hostfd && libusb_speed == 0) { ++ /* ++ * Workaround libusb bug: libusb_get_device_speed() does not ++ * work for libusb_wrap_sys_device() devices in v1.0.23. ++ * ++ * Speeds are defined in linux/usb/ch9.h, file not included ++ * due to name conflicts. ++ */ ++ int rc = ioctl(hostfd, USBDEVFS_GET_SPEED, NULL); ++ switch (rc) { ++ case 1: /* low */ ++ libusb_speed = LIBUSB_SPEED_LOW; ++ break; ++ case 2: /* full */ ++ libusb_speed = LIBUSB_SPEED_FULL; ++ break; ++ case 3: /* high */ ++ case 4: /* wireless */ ++ libusb_speed = LIBUSB_SPEED_HIGH; ++ break; ++ case 5: /* super */ ++ case 6: /* super plus */ ++ libusb_speed = LIBUSB_SPEED_SUPER; ++ break; ++ } ++ } ++#endif ++ udev->speed = speed_map[libusb_speed]; + usb_host_speed_compat(s); + + if (s->ddesc.iProduct) { +-- +2.26.2 + |