summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--devices/src/usb/host_backend/host_device.rs40
-rw-r--r--usb_util/src/device.rs13
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();