Pablo Greco e6a3ae
From 7efd1d899d2478ad9fffcf0584907f38cd6d20ff Mon Sep 17 00:00:00 2001
Pablo Greco e6a3ae
From: Gerd Hoffmann <kraxel@redhat.com>
Pablo Greco e6a3ae
Date: Tue, 4 Jun 2019 05:12:43 +0100
Pablo Greco e6a3ae
Subject: [PATCH 1/8] Introduce new "no_guest_reset" parameter for usb-host
Pablo Greco e6a3ae
 device
Pablo Greco e6a3ae
Pablo Greco e6a3ae
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
Pablo Greco e6a3ae
Message-id: <20190604051246.11374-2-kraxel@redhat.com>
Pablo Greco e6a3ae
Patchwork-id: 88470
Pablo Greco e6a3ae
O-Subject: [RHEL-8.1.0 qemu-kvm PATCH 1/4] Introduce new "no_guest_reset" parameter for usb-host device
Pablo Greco e6a3ae
Bugzilla: 1713677
Pablo Greco e6a3ae
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Pablo Greco e6a3ae
RH-Acked-by: Max Reitz <mreitz@redhat.com>
Pablo Greco e6a3ae
RH-Acked-by: Danilo de Paula <ddepaula@redhat.com>
Pablo Greco e6a3ae
Pablo Greco e6a3ae
From: Alexander Kappner <agk@godking.net>
Pablo Greco e6a3ae
Pablo Greco e6a3ae
With certain USB devices passed through via usb-host, a guest attempting to
Pablo Greco e6a3ae
reset a usb-host device can trigger a reset loop that renders the USB device
Pablo Greco e6a3ae
unusable. In my use case, the device was an iPhone XR that was passed through to
Pablo Greco e6a3ae
a Mac OS X Mojave guest. Upon connecting the device, the following happens:
Pablo Greco e6a3ae
Pablo Greco e6a3ae
1) Guest recognizes new device, sends reset to emulated USB host
Pablo Greco e6a3ae
2) QEMU's USB host sends reset to host kernel
Pablo Greco e6a3ae
3) Host kernel resets device
Pablo Greco e6a3ae
4) After reset, host kernel determines that some part of the device descriptor
Pablo Greco e6a3ae
has changed ("device firmware changed" in dmesg), so host kernel decides to
Pablo Greco e6a3ae
re-enumerate the device.
Pablo Greco e6a3ae
5) Re-enumeration causes QEMU to disconnect and reconnect the device in the
Pablo Greco e6a3ae
guest.
Pablo Greco e6a3ae
6) goto 1)
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Here's from the host kernel (note the "device firmware changed" lines")
Pablo Greco e6a3ae
Pablo Greco e6a3ae
[3677704.473050] usb 1-1.3: new high-speed USB device number 53 using ehci-pci
Pablo Greco e6a3ae
[3677704.555594] usb 1-1.3: New USB device found, idVendor=05ac, idProduct=12a8, bcdDevice=11.08
Pablo Greco e6a3ae
[3677704.555599] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Pablo Greco e6a3ae
[3677704.555602] usb 1-1.3: Product: iPhone
Pablo Greco e6a3ae
[3677704.555605] usb 1-1.3: Manufacturer: Apple Inc.
Pablo Greco e6a3ae
[3677704.555607] usb 1-1.3: SerialNumber: [[removed]]
Pablo Greco e6a3ae
[3677709.401040] usb 1-1.3: reset high-speed USB device number 53 using ehci-pci
Pablo Greco e6a3ae
[3677709.479486] usb 1-1.3: device firmware changed
Pablo Greco e6a3ae
[3677709.479842] usb 1-1.3: USB disconnect, device number 53
Pablo Greco e6a3ae
[3677709.546039] usb 1-1.3: new high-speed USB device number 54 using ehci-pci
Pablo Greco e6a3ae
[3677709.627471] usb 1-1.3: New USB device found, idVendor=05ac, idProduct=12a8, bcdDevice=11.08
Pablo Greco e6a3ae
[3677709.627476] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Pablo Greco e6a3ae
[3677709.627479] usb 1-1.3: Product: iPhone
Pablo Greco e6a3ae
[3677709.627481] usb 1-1.3: Manufacturer: Apple Inc.
Pablo Greco e6a3ae
[3677709.627483] usb 1-1.3: SerialNumber: [[removed]]
Pablo Greco e6a3ae
[3677762.320044] usb 1-1.3: reset high-speed USB device number 54 using ehci-pci
Pablo Greco e6a3ae
[3677762.615630] usb 1-1.3: USB disconnect, device number 54
Pablo Greco e6a3ae
[3677762.787043] usb 1-1.3: new high-speed USB device number 55 using ehci-pci
Pablo Greco e6a3ae
[3677762.869016] usb 1-1.3: New USB device found, idVendor=05ac, idProduct=12a8, bcdDevice=11.08
Pablo Greco e6a3ae
[3677762.869024] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Pablo Greco e6a3ae
[3677762.869028] usb 1-1.3: Product: iPhone
Pablo Greco e6a3ae
[3677762.869032] usb 1-1.3: Manufacturer: Apple Inc.
Pablo Greco e6a3ae
[3677762.869035] usb 1-1.3: SerialNumber: [[removed]]
Pablo Greco e6a3ae
[3677815.662036] usb 1-1.3: reset high-speed USB device number 55 using ehci-pci
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Here's from QEMU:
Pablo Greco e6a3ae
Pablo Greco e6a3ae
libusb: error [_get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/005/022: No such file or directory
Pablo Greco e6a3ae
libusb: error [udev_hotplug_event] ignoring udev action bind
Pablo Greco e6a3ae
libusb: error [udev_hotplug_event] ignoring udev action bind
Pablo Greco e6a3ae
libusb: error [_open_sysfs_attr] open /sys/bus/usb/devices/5-1/bConfigurationValue failed ret=-1 errno=2
Pablo Greco e6a3ae
libusb: error [_get_usbfs_fd] File doesn't exist, wait 10 ms and try again
Pablo Greco e6a3ae
Pablo Greco e6a3ae
libusb: error [_get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/005/024: No such file or directory
Pablo Greco e6a3ae
libusb: error [udev_hotplug_event] ignoring udev action bind
Pablo Greco e6a3ae
libusb: error [udev_hotplug_event] ignoring udev action bind
Pablo Greco e6a3ae
libusb: error [_open_sysfs_attr] open /sys/bus/usb/devices/5-1/bConfigurationValue failed ret=-1 errno=2
Pablo Greco e6a3ae
libusb: error [_get_usbfs_fd] File doesn't exist, wait 10 ms and try again
Pablo Greco e6a3ae
Pablo Greco e6a3ae
libusb: error [_get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/005/026: No such file or directory
Pablo Greco e6a3ae
Pablo Greco e6a3ae
The result of this is that the device remains permanently unusable in the guest.
Pablo Greco e6a3ae
The same problem has been previously reported for an iPad:
Pablo Greco e6a3ae
https://stackoverflow.com/questions/52617634/how-do-i-get-qemu-usb-passthrough-to-work-for-ipad-iphone
Pablo Greco e6a3ae
Pablo Greco e6a3ae
This problem can be elegantly solved by interrupting step 2) above. Instead of
Pablo Greco e6a3ae
passing through the reset, QEMU simply ignores it. To allow this to be
Pablo Greco e6a3ae
configured on a per-device level,  a new parameter "no_guest_reset" is
Pablo Greco e6a3ae
introduced for the usb-host device. I can confirm that the configuration
Pablo Greco e6a3ae
described above (iPhone XS + Mojave guest) works flawlessly with
Pablo Greco e6a3ae
no_guest_reset=True specified.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Working command line for my scenario:
Pablo Greco e6a3ae
device_add usb-host,vendorid=0x05ac,productid=0x12a8,no_guest_reset=True,id=iphone
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Best regards
Pablo Greco e6a3ae
Alexander
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Signed-off-by: Alexander Kappner <agk@godking.net>
Pablo Greco e6a3ae
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Pablo Greco e6a3ae
Message-id: 20190128140027.9448-1-kraxel@redhat.com
Pablo Greco e6a3ae
Pablo Greco e6a3ae
[ kraxel: rename parameter to "guest-reset" ]
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Pablo Greco e6a3ae
(cherry picked from commit ba4c735b4fc74e309ce4b2551d258e442ef513a5)
Pablo Greco e6a3ae
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Pablo Greco e6a3ae
---
Pablo Greco e6a3ae
 hw/usb/host-libusb.c | 7 ++++++-
Pablo Greco e6a3ae
 1 file changed, 6 insertions(+), 1 deletion(-)
Pablo Greco e6a3ae
Pablo Greco e6a3ae
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
Pablo Greco e6a3ae
index f31e9cb..d82a10a 100644
Pablo Greco e6a3ae
--- a/hw/usb/host-libusb.c
Pablo Greco e6a3ae
+++ b/hw/usb/host-libusb.c
Pablo Greco e6a3ae
@@ -82,7 +82,7 @@ struct USBHostDevice {
Pablo Greco e6a3ae
     uint32_t                         options;
Pablo Greco e6a3ae
     uint32_t                         loglevel;
Pablo Greco e6a3ae
     bool                             needs_autoscan;
Pablo Greco e6a3ae
-
Pablo Greco e6a3ae
+    bool                             allow_guest_reset;
Pablo Greco e6a3ae
     /* state */
Pablo Greco e6a3ae
     QTAILQ_ENTRY(USBHostDevice)      next;
Pablo Greco e6a3ae
     int                              seen, errcount;
Pablo Greco e6a3ae
@@ -1451,6 +1451,10 @@ static void usb_host_handle_reset(USBDevice *udev)
Pablo Greco e6a3ae
     USBHostDevice *s = USB_HOST_DEVICE(udev);
Pablo Greco e6a3ae
     int rc;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
+    if (!s->allow_guest_reset) {
Pablo Greco e6a3ae
+        return;
Pablo Greco e6a3ae
+    }
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
     trace_usb_host_reset(s->bus_num, s->addr);
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
     rc = libusb_reset_device(s->dh);
Pablo Greco e6a3ae
@@ -1568,6 +1572,7 @@ static Property usb_host_dev_properties[] = {
Pablo Greco e6a3ae
     DEFINE_PROP_UINT32("productid", USBHostDevice, match.product_id, 0),
Pablo Greco e6a3ae
     DEFINE_PROP_UINT32("isobufs",  USBHostDevice, iso_urb_count,    4),
Pablo Greco e6a3ae
     DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames,   32),
Pablo Greco e6a3ae
+    DEFINE_PROP_BOOL("guest-reset", USBHostDevice, allow_guest_reset, true),
Pablo Greco e6a3ae
     DEFINE_PROP_UINT32("loglevel",  USBHostDevice, loglevel,
Pablo Greco e6a3ae
                        LIBUSB_LOG_LEVEL_WARNING),
Pablo Greco e6a3ae
     DEFINE_PROP_BIT("pipeline",    USBHostDevice, options,
Pablo Greco e6a3ae
-- 
Pablo Greco e6a3ae
1.8.3.1
Pablo Greco e6a3ae