summary refs log tree commit diff
path: root/devices
diff options
context:
space:
mode:
authorDaniel Verkamp <dverkamp@chromium.org>2020-04-22 10:35:34 -0700
committerCommit Bot <commit-bot@chromium.org>2020-04-23 21:29:12 +0000
commit9f22e23996d1542aa0978609e68c499c7263601e (patch)
treedb5b26d84cfb83bd0c0423d7ebc505c383fe91f1 /devices
parented1498678a80bfdcd844af27d13252d3c3c9f51c (diff)
downloadcrosvm-9f22e23996d1542aa0978609e68c499c7263601e.tar
crosvm-9f22e23996d1542aa0978609e68c499c7263601e.tar.gz
crosvm-9f22e23996d1542aa0978609e68c499c7263601e.tar.bz2
crosvm-9f22e23996d1542aa0978609e68c499c7263601e.tar.lz
crosvm-9f22e23996d1542aa0978609e68c499c7263601e.tar.xz
crosvm-9f22e23996d1542aa0978609e68c499c7263601e.tar.zst
crosvm-9f22e23996d1542aa0978609e68c499c7263601e.zip
devices: usb: allow arbitrary control request size
Previously, the maximum control request length that could be passed
through the USB host_backend layer was limited to 1024 bytes.

To lift this limit, remove the fixed-length ControlTransferBuffer
structure definition and replace it with manual buffer allocation.  This
mirrors the behavior of the later part of this function, which already
indexes into the control_buffer to copy the data back from a device to
host transfer.

BUG=chromium:1073503
TEST=Verify adb logcat still works

Change-Id: I7354f6fa237b4df6db7898f27be76ab10faed9f4
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2161440
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Tested-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
Diffstat (limited to 'devices')
-rw-r--r--devices/src/usb/host_backend/host_device.rs29
1 files changed, 9 insertions, 20 deletions
diff --git a/devices/src/usb/host_backend/host_device.rs b/devices/src/usb/host_backend/host_device.rs
index 196fa50..8f8723d 100644
--- a/devices/src/usb/host_backend/host_device.rs
+++ b/devices/src/usb/host_backend/host_device.rs
@@ -140,30 +140,21 @@ impl HostDevice {
             return Ok(());
         }
 
-        // Default buffer size for control data transfer.
-        const CONTROL_DATA_BUFFER_SIZE: usize = 1024;
-
-        // Buffer type for control transfer. The first 8 bytes is a UsbRequestSetup struct.
-        #[derive(Copy, Clone)]
-        #[repr(C, packed)]
-        struct ControlTransferBuffer {
-            pub setup: UsbRequestSetup,
-            pub data: [u8; CONTROL_DATA_BUFFER_SIZE],
-        }
-
-        // Safe because it only has data and has no implicit padding.
-        unsafe impl DataInit for ControlTransferBuffer {}
+        // Allocate a buffer for the control transfer.
+        // This buffer will hold a UsbRequestSetup struct followed by the data.
+        let control_buffer_len =
+            mem::size_of::<UsbRequestSetup>() + self.control_request_setup.length as usize;
+        let mut control_buffer = vec![0u8; control_buffer_len];
 
-        let mut control_request = ControlTransferBuffer {
-            setup: self.control_request_setup,
-            data: [0; CONTROL_DATA_BUFFER_SIZE],
-        };
+        // Copy the control request header.
+        control_buffer[..mem::size_of::<UsbRequestSetup>()]
+            .copy_from_slice(self.control_request_setup.as_slice());
 
         let direction = self.control_request_setup.get_direction();
         let buffer = if direction == ControlRequestDataPhaseTransferDirection::HostToDevice {
             if let Some(buffer) = buffer {
                 buffer
-                    .read(&mut control_request.data)
+                    .read(&mut control_buffer[mem::size_of::<UsbRequestSetup>()..])
                     .map_err(Error::ReadBuffer)?;
             }
             // buffer is consumed here for HostToDevice transfers.
@@ -173,8 +164,6 @@ impl HostDevice {
             buffer
         };
 
-        let control_buffer = control_request.as_slice().to_vec();
-
         let mut control_transfer =
             Transfer::new_control(control_buffer).map_err(Error::CreateTransfer)?;