diff options
author | Daniel Verkamp <dverkamp@chromium.org> | 2020-03-18 13:10:49 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-03-24 11:29:57 +0000 |
commit | 0dcbfa1176386d1e2f8f52947fe93004db195abe (patch) | |
tree | 2b76da7fbf56d6cdb6ef55021fcecfdc8e408a69 /devices/src | |
parent | 83fc5c49ba930a62ef1f4d93bc2004d779b6d16f (diff) | |
download | crosvm-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.rs | 40 |
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) |