Pablo Greco e6a3ae
From c7150963b7db0123299f2430eea956c6a83f69d4 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:46 +0100
Pablo Greco e6a3ae
Subject: [PATCH 4/8] usb-host: avoid libusb_set_configuration calls
Pablo Greco e6a3ae
MIME-Version: 1.0
Pablo Greco e6a3ae
Content-Type: text/plain; charset=UTF-8
Pablo Greco e6a3ae
Content-Transfer-Encoding: 8bit
Pablo Greco e6a3ae
Pablo Greco e6a3ae
RH-Author: Gerd Hoffmann <kraxel@redhat.com>
Pablo Greco e6a3ae
Message-id: <20190604051246.11374-5-kraxel@redhat.com>
Pablo Greco e6a3ae
Patchwork-id: 88472
Pablo Greco e6a3ae
O-Subject: [RHEL-8.1.0 qemu-kvm PATCH 4/4] usb-host: avoid libusb_set_configuration calls
Pablo Greco e6a3ae
Bugzilla: 1713677
Pablo Greco e6a3ae
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Pablo Greco e6a3ae
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Pablo Greco e6a3ae
RH-Acked-by: Max Reitz <mreitz@redhat.com>
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Seems some devices become confused when we call
Pablo Greco e6a3ae
libusb_set_configuration().  So before calling the function check
Pablo Greco e6a3ae
whenever the device has multiple configurations in the first place, and
Pablo Greco e6a3ae
in case it hasn't (which is the case for the majority of devices) simply
Pablo Greco e6a3ae
skip the call as it will have no effect anyway.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Pablo Greco e6a3ae
Message-id: 20190522094702.17619-4-kraxel@redhat.com
Pablo Greco e6a3ae
(cherry picked from commit bfe44898848614cfcb3a269bc965afbe1f0f331c)
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 | 18 ++++++++++--------
Pablo Greco e6a3ae
 1 file changed, 10 insertions(+), 8 deletions(-)
Pablo Greco e6a3ae
Pablo Greco e6a3ae
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
Pablo Greco e6a3ae
index dd3ed02..587ff70 100644
Pablo Greco e6a3ae
--- a/hw/usb/host-libusb.c
Pablo Greco e6a3ae
+++ b/hw/usb/host-libusb.c
Pablo Greco e6a3ae
@@ -1220,19 +1220,21 @@ static void usb_host_set_address(USBHostDevice *s, int addr)
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 static void usb_host_set_config(USBHostDevice *s, int config, USBPacket *p)
Pablo Greco e6a3ae
 {
Pablo Greco e6a3ae
-    int rc;
Pablo Greco e6a3ae
+    int rc = 0;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
     trace_usb_host_set_config(s->bus_num, s->addr, config);
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
     usb_host_release_interfaces(s);
Pablo Greco e6a3ae
-    rc = libusb_set_configuration(s->dh, config);
Pablo Greco e6a3ae
-    if (rc != 0) {
Pablo Greco e6a3ae
-        usb_host_libusb_error("libusb_set_configuration", rc);
Pablo Greco e6a3ae
-        p->status = USB_RET_STALL;
Pablo Greco e6a3ae
-        if (rc == LIBUSB_ERROR_NO_DEVICE) {
Pablo Greco e6a3ae
-            usb_host_nodev(s);
Pablo Greco e6a3ae
+    if (s->ddesc.bNumConfigurations != 1) {
Pablo Greco e6a3ae
+        rc = libusb_set_configuration(s->dh, config);
Pablo Greco e6a3ae
+        if (rc != 0) {
Pablo Greco e6a3ae
+            usb_host_libusb_error("libusb_set_configuration", rc);
Pablo Greco e6a3ae
+            p->status = USB_RET_STALL;
Pablo Greco e6a3ae
+            if (rc == LIBUSB_ERROR_NO_DEVICE) {
Pablo Greco e6a3ae
+                usb_host_nodev(s);
Pablo Greco e6a3ae
+            }
Pablo Greco e6a3ae
+            return;
Pablo Greco e6a3ae
         }
Pablo Greco e6a3ae
-        return;
Pablo Greco e6a3ae
     }
Pablo Greco e6a3ae
     p->status = usb_host_claim_interfaces(s, config);
Pablo Greco e6a3ae
     if (p->status != USB_RET_SUCCESS) {
Pablo Greco e6a3ae
-- 
Pablo Greco e6a3ae
1.8.3.1
Pablo Greco e6a3ae