summary refs log tree commit diff
path: root/devices/src
diff options
context:
space:
mode:
authorDaniel Verkamp <dverkamp@chromium.org>2020-03-18 13:10:49 -0700
committerCommit Bot <commit-bot@chromium.org>2020-03-24 11:29:57 +0000
commit0dcbfa1176386d1e2f8f52947fe93004db195abe (patch)
tree2b76da7fbf56d6cdb6ef55021fcecfdc8e408a69 /devices/src
parent83fc5c49ba930a62ef1f4d93bc2004d779b6d16f (diff)
downloadcrosvm-0dcbfa1176386d1e2f8f52947fe93004db195abe.tar
crosvm-0dcbfa1176386d1e2f8f52947fe93004db195abe.tar.gz
crosvm-0dcbfa1176386d1e2f8f52947fe93004db195abe.tar.bz2
crosvm-0dcbfa1176386d1e2f8f52947fe93004db195abe.tar.lz
crosvm-0dcbfa1176386d1e2f8f52947fe93004db195abe.tar.xz
crosvm-0dcbfa1176386d1e2f8f52947fe93004db195abe.tar.zst
crosvm-0dcbfa1176386d1e2f8f52947fe93004db195abe.zip
usb: avoid setting configuration when unnecessary
On devices with only one configuration, skip the code that attempts to
change the device's active configuration, since it must always be the
single available configuration.

This works around an issue observed with some USB devices (e.g. Servo
Micro) where the initial Get Configuration control request fails with
-EPIPE.

BUG=chromium:1061382
BUG=b:151408644
TEST=Attach servo micro, see /dev/ttyUSB[012], screen /dev/ttyUSB0

Change-Id: Ic3333e1d70a0c57b090de64e4d3b7932ce2cf81d
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2108871
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Tested-by: George Engelbrecht <engeg@google.com>
Commit-Queue: George Engelbrecht <engeg@google.com>
Diffstat (limited to 'devices/src')
-rw-r--r--devices/src/usb/host_backend/host_device.rs40
1 files changed, 27 insertions, 13 deletions
diff --git a/devices/src/usb/host_backend/host_device.rs b/devices/src/usb/host_backend/host_device.rs
index 3b85ea2..196fa50 100644
--- a/devices/src/usb/host_backend/host_device.rs
+++ b/devices/src/usb/host_backend/host_device.rs
@@ -305,22 +305,31 @@ impl HostDevice {
             config
         );
         self.release_interfaces();
-        let cur_config = self
-            .device
-            .lock()
-            .get_active_configuration()
-            .map_err(Error::GetActiveConfig)?;
-        usb_debug!("current config is: {}", cur_config);
-        if config != cur_config {
-            self.device
-                .lock()
-                .set_active_configuration(config)
-                .map_err(Error::SetActiveConfig)?;
+        if self.device.lock().get_num_configurations() > 1 {
+            let cur_config = match self.device.lock().get_active_configuration() {
+                Ok(c) => Some(c),
+                Err(e) => {
+                    // The device may be in the default state, in which case
+                    // GET_CONFIGURATION may fail.  Assume the device needs to be
+                    // reconfigured.
+                    usb_debug!("Failed to get active configuration: {}", e);
+                    error!("Failed to get active configuration: {}", e);
+                    None
+                }
+            };
+            if Some(config) != cur_config {
+                self.device
+                    .lock()
+                    .set_active_configuration(config)
+                    .map_err(Error::SetActiveConfig)?;
+            }
+        } else {
+            usb_debug!("Only one configuration - not calling set_active_configuration");
         }
         let config_descriptor = self
             .device
             .lock()
-            .get_active_config_descriptor()
+            .get_config_descriptor(config)
             .map_err(Error::GetActiveConfig)?;
         self.claim_interfaces(&config_descriptor);
         self.create_endpoints(&config_descriptor)?;
@@ -337,10 +346,15 @@ impl HostDevice {
             .set_interface_alt_setting(interface, alt_setting)
             .map_err(Error::SetInterfaceAltSetting)?;
         self.alt_settings.insert(interface, alt_setting);
+        let config = self
+            .device
+            .lock()
+            .get_active_configuration()
+            .map_err(Error::GetActiveConfig)?;
         let config_descriptor = self
             .device
             .lock()
-            .get_active_config_descriptor()
+            .get_config_descriptor(config)
             .map_err(Error::GetActiveConfig)?;
         self.create_endpoints(&config_descriptor)?;
         Ok(TransferStatus::Completed)