diff options
-rw-r--r-- | devices/src/usb/host_backend/host_device.rs | 40 | ||||
-rw-r--r-- | usb_util/src/device.rs | 13 |
2 files changed, 34 insertions, 19 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) diff --git a/usb_util/src/device.rs b/usb_util/src/device.rs index aad77db..3ac1403 100644 --- a/usb_util/src/device.rs +++ b/usb_util/src/device.rs @@ -261,12 +261,8 @@ impl Device { } /// Get active config descriptor of this device. - pub fn get_active_config_descriptor(&self) -> Result<ConfigDescriptorTree> { - let active_config = self.get_active_configuration()?; - match self - .device_descriptor_tree - .get_config_descriptor(active_config) - { + pub fn get_config_descriptor(&self, config: u8) -> Result<ConfigDescriptorTree> { + match self.device_descriptor_tree.get_config_descriptor(config) { Some(config_descriptor) => Ok(config_descriptor.clone()), None => Err(Error::NoSuchDescriptor), } @@ -297,6 +293,11 @@ impl Device { Ok(active_config) } + /// Get the total number of configurations for this device. + pub fn get_num_configurations(&self) -> u8 { + self.device_descriptor_tree.bNumConfigurations + } + /// Clear the halt/stall condition for an endpoint. pub fn clear_halt(&self, ep_addr: u8) -> Result<()> { let endpoint: c_uint = ep_addr.into(); |