9ae3a8
From d8c698663916222fea36f660f0e56a23a8688afc Mon Sep 17 00:00:00 2001
9ae3a8
From: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
Date: Wed, 6 Nov 2013 12:16:58 +0100
9ae3a8
Subject: [PATCH 63/81] usb-host-libusb: Fix reset handling
9ae3a8
9ae3a8
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
Message-id: <1383740220-2049-2-git-send-email-kraxel@redhat.com>
9ae3a8
Patchwork-id: 55513
9ae3a8
O-Subject: [RHEL-7 qemu-kvm PATCH 1/3] usb-host-libusb: Fix reset handling
9ae3a8
Bugzilla: 980415
9ae3a8
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
RH-Acked-by: Bandan Das <bsd@redhat.com>
9ae3a8
RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
9ae3a8
9ae3a8
From: Hans de Goede <hdegoede@redhat.com>
9ae3a8
9ae3a8
The guest will issue an initial device reset when the device is attached, but
9ae3a8
since the current usb-host-libusb code only actually does the reset when
9ae3a8
udev->configuration != 0, and on attach the device is not yet configured,
9ae3a8
the reset gets ignored. This means that the device gets passed to the guest
9ae3a8
in an unknown state, which is not good.
9ae3a8
9ae3a8
The udev->configuration check is there because of the release / claim
9ae3a8
interfaces done around the libusb_device_reset call, but these are not
9ae3a8
necessary. If interfaces are claimed when libusb_device_reset gets called
9ae3a8
libusb will release + reclaim them itself.
9ae3a8
9ae3a8
The usb_host_ep_update call also is not necessary. If the reset succeeds the
9ae3a8
original config and interface alt settings will be restored.
9ae3a8
9ae3a8
Last if the reset fails, that means the device has either disconnected or
9ae3a8
morphed into an another device and has been completely re-enumerated,
9ae3a8
so it is treated by the host as a new device and our handle is invalid,
9ae3a8
so on reset failure we need to call usb_host_nodev().
9ae3a8
9ae3a8
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
9ae3a8
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
9ae3a8
(cherry picked from commit 5af35d7feccaa7d26b72c6c3d14116421d736b36)
9ae3a8
---
9ae3a8
 hw/usb/host-libusb.c | 10 ++++------
9ae3a8
 1 file changed, 4 insertions(+), 6 deletions(-)
9ae3a8
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 hw/usb/host-libusb.c |   10 ++++------
9ae3a8
 1 files changed, 4 insertions(+), 6 deletions(-)
9ae3a8
9ae3a8
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
9ae3a8
index f660770..9c8905e 100644
9ae3a8
--- a/hw/usb/host-libusb.c
9ae3a8
+++ b/hw/usb/host-libusb.c
9ae3a8
@@ -1256,16 +1256,14 @@ static void usb_host_flush_ep_queue(USBDevice *dev, USBEndpoint *ep)
9ae3a8
 static void usb_host_handle_reset(USBDevice *udev)
9ae3a8
 {
9ae3a8
     USBHostDevice *s = USB_HOST_DEVICE(udev);
9ae3a8
+    int rc;
9ae3a8
 
9ae3a8
     trace_usb_host_reset(s->bus_num, s->addr);
9ae3a8
 
9ae3a8
-    if (udev->configuration == 0) {
9ae3a8
-        return;
9ae3a8
+    rc = libusb_reset_device(s->dh);
9ae3a8
+    if (rc != 0) {
9ae3a8
+        usb_host_nodev(s);
9ae3a8
     }
9ae3a8
-    usb_host_release_interfaces(s);
9ae3a8
-    libusb_reset_device(s->dh);
9ae3a8
-    usb_host_claim_interfaces(s, 0);
9ae3a8
-    usb_host_ep_update(s);
9ae3a8
 }
9ae3a8
 
9ae3a8
 /*
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8