summary refs log tree commit diff
path: root/devices
diff options
context:
space:
mode:
authorZach Reizner <zachr@google.com>2019-03-18 20:58:31 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-04-27 01:36:47 -0700
commitaff94ca6da90b92503558b6ba7aa68e1180afd87 (patch)
tree74fc34c90d1f6e10e6e921dddea389bdd51ad3e6 /devices
parentd99cd0ae0b21d29d4e5145b889f97e9f6cd11b69 (diff)
downloadcrosvm-aff94ca6da90b92503558b6ba7aa68e1180afd87.tar
crosvm-aff94ca6da90b92503558b6ba7aa68e1180afd87.tar.gz
crosvm-aff94ca6da90b92503558b6ba7aa68e1180afd87.tar.bz2
crosvm-aff94ca6da90b92503558b6ba7aa68e1180afd87.tar.lz
crosvm-aff94ca6da90b92503558b6ba7aa68e1180afd87.tar.xz
crosvm-aff94ca6da90b92503558b6ba7aa68e1180afd87.tar.zst
crosvm-aff94ca6da90b92503558b6ba7aa68e1180afd87.zip
usb: support for listing attached usb devices
Originally, crosvm would list details about an attached usb device for a
given port. This change allows getting details about multiple ports at
once. This is intended to simplify command line usage and downstream
consumers like concierge.

TEST=various vmc commands
     Chrome UI for handling USB devices
BUG=chromium:831850

Change-Id: I55681a7fea7425c897a22a579dcc15567683ef54
Reviewed-on: https://chromium-review.googlesource.com/1529765
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'devices')
-rw-r--r--devices/src/usb/host_backend/host_backend_device_provider.rs45
1 files changed, 27 insertions, 18 deletions
diff --git a/devices/src/usb/host_backend/host_backend_device_provider.rs b/devices/src/usb/host_backend/host_backend_device_provider.rs
index 6a68951..8d39d80 100644
--- a/devices/src/usb/host_backend/host_backend_device_provider.rs
+++ b/devices/src/usb/host_backend/host_backend_device_provider.rs
@@ -18,7 +18,10 @@ use std::os::unix::io::{AsRawFd, RawFd};
 use std::time::Duration;
 use sys_util::net::UnixSeqpacket;
 use sys_util::{error, WatchingEvents};
-use vm_control::{UsbControlCommand, UsbControlResult, UsbControlSocket};
+use vm_control::{
+    UsbControlAttachedDevice, UsbControlCommand, UsbControlResult, UsbControlSocket,
+    USB_CONTROL_MAX_PORTS,
+};
 
 const SOCKET_TIMEOUT_MS: u64 = 2000;
 
@@ -142,6 +145,27 @@ impl ProviderInner {
         }
     }
 
+    fn handle_list_devices(&self, ports: [u8; USB_CONTROL_MAX_PORTS]) -> UsbControlResult {
+        let mut devices: [UsbControlAttachedDevice; USB_CONTROL_MAX_PORTS] = Default::default();
+        for (result_index, &port_id) in ports.iter().enumerate() {
+            match self.usb_hub.get_port(port_id).and_then(|p| {
+                p.get_backend_device()
+                    .as_ref()
+                    .map(|d| (d.get_vid(), d.get_pid()))
+            }) {
+                Some((vendor_id, product_id)) => {
+                    devices[result_index] = UsbControlAttachedDevice {
+                        port: port_id,
+                        vendor_id,
+                        product_id,
+                    }
+                }
+                None => continue,
+            }
+        }
+        UsbControlResult::Devices(devices)
+    }
+
     fn on_event_helper(&self) -> Result<()> {
         let cmd = self.sock.recv().map_err(Error::ReadControlSock)?;
         match cmd {
@@ -287,23 +311,8 @@ impl ProviderInner {
                 }
                 Ok(())
             }
-            UsbControlCommand::ListDevice { port } => {
-                let port_number = port;
-                let result = match self.usb_hub.get_port(port_number) {
-                    Some(port) => match port.get_backend_device().as_ref() {
-                        Some(device) => {
-                            let vid = device.get_vid();
-                            let pid = device.get_pid();
-                            UsbControlResult::Device {
-                                port: port_number,
-                                vid,
-                                pid,
-                            }
-                        }
-                        None => UsbControlResult::NoSuchDevice,
-                    },
-                    None => UsbControlResult::NoSuchPort,
-                };
+            UsbControlCommand::ListDevice { ports } => {
+                let result = self.handle_list_devices(ports);
                 // The send failure will be logged, but event loop still think the event is
                 // handled.
                 let _ = self.sock.send(&result).map_err(Error::WriteControlSock);