devices/usb/backend/host_backend/
host_device.rs

1// Copyright 2019 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::collections::HashMap;
6use std::mem;
7use std::sync::Arc;
8use std::sync::RwLock;
9
10use base::debug;
11use base::error;
12use base::AsRawDescriptor;
13use base::RawDescriptor;
14use sync::Mutex;
15use usb_util::ConfigDescriptorTree;
16use usb_util::DescriptorHeader;
17use usb_util::Device;
18use usb_util::DeviceDescriptorTree;
19use usb_util::DeviceSpeed;
20use usb_util::InterfaceDescriptor;
21use usb_util::Transfer;
22use usb_util::TransferBuffer;
23use usb_util::TransferHandle;
24use usb_util::TransferStatus;
25use usb_util::UsbRequestSetup;
26use zerocopy::IntoBytes;
27
28use crate::usb::backend::device::BackendDevice;
29use crate::usb::backend::device::DeviceState;
30use crate::usb::backend::endpoint::ControlEndpointState;
31use crate::usb::backend::endpoint::UsbEndpoint;
32use crate::usb::backend::error::Error;
33use crate::usb::backend::error::Result;
34use crate::usb::backend::transfer::BackendTransfer;
35use crate::usb::backend::transfer::BackendTransferHandle;
36use crate::usb::backend::transfer::BackendTransferType;
37use crate::usb::backend::transfer::ControlTransferState;
38use crate::usb::backend::transfer::GenericTransferHandle;
39use crate::usb::xhci::scatter_gather_buffer::ScatterGatherBuffer;
40use crate::usb::xhci::xhci_backend_device::BackendType;
41use crate::usb::xhci::xhci_backend_device::UsbDeviceAddress;
42use crate::usb::xhci::xhci_backend_device::XhciBackendDevice;
43use crate::utils::EventLoop;
44
45/// Host device is a device connected to host.
46pub struct HostDevice {
47    pub device: Arc<Mutex<Device>>,
48    alt_settings: HashMap<u8, u8>,
49    claimed_interfaces: Vec<u8>,
50    state: Arc<RwLock<DeviceState>>,
51    control_transfer_state: Arc<RwLock<ControlTransferState>>,
52}
53
54impl HostDevice {
55    /// Create a new host device.
56    pub fn new(device: Arc<Mutex<Device>>, state: DeviceState) -> Result<HostDevice> {
57        let control_transfer_state = ControlTransferState {
58            ctl_ep_state: ControlEndpointState::SetupStage,
59            control_request_setup: UsbRequestSetup::new(0, 0, 0, 0, 0),
60            executed: false,
61        };
62        let mut host_device = HostDevice {
63            device,
64            alt_settings: HashMap::new(),
65            claimed_interfaces: vec![],
66            state: Arc::new(RwLock::new(state)),
67            control_transfer_state: Arc::new(RwLock::new(control_transfer_state)),
68        };
69
70        let config_descriptor = host_device.get_active_config_descriptor()?;
71        host_device.claim_interfaces(&config_descriptor)?;
72
73        Ok(host_device)
74    }
75
76    // Execute a Get Descriptor control request with type Configuration.
77    // This function is used to return a filtered version of the host device's configuration
78    // descriptor that only includes the interfaces in `self.claimed_interfaces`.
79    pub fn get_config_descriptor_filtered(
80        &mut self,
81        buffer: &ScatterGatherBuffer,
82        descriptor_index: u8,
83    ) -> Result<(TransferStatus, u32)> {
84        let _trace = cros_tracing::trace_event!(
85            USB,
86            "host_device get_config_descriptor_filtered",
87            descriptor_index
88        );
89
90        let config_descriptor = self.get_config_descriptor_by_index(descriptor_index)?;
91
92        let device_descriptor = self.get_device_descriptor_tree()?;
93        let config_start = config_descriptor.offset();
94        let config_end = config_start + config_descriptor.wTotalLength as usize;
95        let mut descriptor_data = device_descriptor.raw()[config_start..config_end].to_vec();
96
97        if config_descriptor.bConfigurationValue == self.get_active_configuration()? {
98            for i in 0..config_descriptor.bNumInterfaces {
99                if !self.claimed_interfaces.contains(&i) {
100                    // Rewrite descriptors for unclaimed interfaces to vendor-specific class.
101                    // This prevents them from being recognized by the guest drivers.
102                    let alt_setting = self.alt_settings.get(&i).unwrap_or(&0);
103                    let interface = config_descriptor
104                        .get_interface_descriptor(i, *alt_setting)
105                        .ok_or(Error::GetInterfaceDescriptor(i, *alt_setting))?;
106                    let mut interface_data: InterfaceDescriptor = **interface;
107                    interface_data.bInterfaceClass = 0xFF;
108                    interface_data.bInterfaceSubClass = 0xFF;
109                    interface_data.bInterfaceProtocol = 0xFF;
110
111                    let interface_start =
112                        interface.offset() + mem::size_of::<DescriptorHeader>() - config_start;
113                    let interface_end = interface_start + mem::size_of::<InterfaceDescriptor>();
114                    descriptor_data[interface_start..interface_end]
115                        .copy_from_slice(interface_data.as_bytes());
116                }
117            }
118        }
119
120        let bytes_transferred = buffer.write(&descriptor_data).map_err(Error::WriteBuffer)?;
121        Ok((TransferStatus::Completed, bytes_transferred as u32))
122    }
123
124    pub fn set_interface(&mut self, interface: u8, alt_setting: u8) -> Result<TransferStatus> {
125        let _trace = cros_tracing::trace_event!(USB, "host_device set_interface");
126        // It's a standard, set_interface, interface request.
127        self.device
128            .lock()
129            .set_interface_alt_setting(interface, alt_setting)
130            .map_err(Error::SetInterfaceAltSetting)?;
131        self.alt_settings.insert(interface, alt_setting);
132        let config = self.get_active_configuration()?;
133        let config_descriptor = self.get_config_descriptor(config)?;
134        self.create_endpoints(&config_descriptor)?;
135        Ok(TransferStatus::Completed)
136    }
137
138    /// Claims every interface of `config_descriptor`, detaching whatever host kernel driver is
139    /// bound to each.
140    ///
141    /// Either all of them are claimed or none are: a device the host still holds an interface of
142    /// has not really been handed over, and the guest has no way to find that out. Rewriting the
143    /// unclaimed interfaces to a vendor-specific class (see `get_config_descriptor_filtered`) hides
144    /// them from guest drivers, but it does not stop the host from using them.
145    pub fn claim_interfaces(&mut self, config_descriptor: &ConfigDescriptorTree) -> Result<()> {
146        for i in 0..config_descriptor.num_interfaces() {
147            // Bound to a variable, not matched on directly: matching on
148            // `self.device.lock().claim_interface(i)` would keep the lock guard alive through
149            // every arm, and the Err arm below calls release_interfaces(), which locks the same
150            // mutex again.
151            let claimed = self.device.lock().claim_interface(i);
152            match claimed {
153                Ok(()) => {
154                    debug!("usb: claimed interface {}", i);
155                    self.claimed_interfaces.push(i);
156                }
157                Err(e) => {
158                    // Drop the claims taken on the way here. This does not put the host drivers
159                    // back: USBDEVFS_DISCONNECT_CLAIM unbound them, and only USBDEVFS_CONNECT
160                    // rebinds, which we never issue. It does leave the interfaces unclaimed rather
161                    // than held by a device object we are about to throw away.
162                    self.release_interfaces();
163                    return Err(Error::ClaimInterface(i, e));
164                }
165            }
166        }
167        Ok(())
168    }
169
170    pub fn claim_interfaces_and_create_endpoints(
171        &mut self,
172        config_descriptor: &ConfigDescriptorTree,
173    ) -> Result<()> {
174        let claim_result = self.claim_interfaces(config_descriptor);
175        // Failed claims release every interface, so rebuilding also clears stale endpoints.
176        self.create_endpoints(config_descriptor)?;
177        claim_result
178    }
179
180    pub fn release_interfaces(&mut self) {
181        let device_locked = self.device.lock();
182        for i in &self.claimed_interfaces {
183            if let Err(e) = device_locked.release_interface(*i) {
184                error!("could not release interface: {:?}", e);
185            }
186        }
187        self.claimed_interfaces = Vec::new();
188    }
189}
190
191impl AsRawDescriptor for HostDevice {
192    fn as_raw_descriptor(&self) -> RawDescriptor {
193        self.device.lock().as_raw_descriptor()
194    }
195}
196
197impl GenericTransferHandle for TransferHandle {
198    fn cancel(&self) -> Result<()> {
199        TransferHandle::cancel(self).map_err(Error::TransferHandle)
200    }
201}
202
203impl BackendDevice for HostDevice {
204    fn submit_backend_transfer(
205        &mut self,
206        transfer: BackendTransferType,
207    ) -> Result<BackendTransferHandle> {
208        match transfer {
209            BackendTransferType::HostDevice(transfer) => self
210                .device
211                .lock()
212                .submit_transfer(transfer)
213                .map_err(Error::CreateTransfer)
214                .map(BackendTransferHandle::new),
215            _ => Err(Error::MalformedBackendTransfer),
216        }
217    }
218
219    fn detach_event_handler(&self, event_loop: &Arc<EventLoop>) -> Result<()> {
220        event_loop
221            .remove_event_for_descriptor(self)
222            .map_err(Error::RemoveFromEventLoop)
223    }
224
225    fn request_transfer_buffer(&mut self, size: usize) -> TransferBuffer {
226        match self.device.lock().reserve_dma_buffer(size) {
227            Ok(dmabuf) => TransferBuffer::Dma(dmabuf),
228            Err(_) => TransferBuffer::Vector(vec![0u8; size]),
229        }
230    }
231
232    fn build_bulk_transfer(
233        &mut self,
234        ep_addr: u8,
235        transfer_buffer: TransferBuffer,
236        stream_id: Option<u16>,
237    ) -> Result<BackendTransferType> {
238        Ok(BackendTransferType::HostDevice(
239            Transfer::new_bulk(ep_addr, transfer_buffer, stream_id)
240                .map_err(Error::CreateTransfer)?,
241        ))
242    }
243
244    fn build_interrupt_transfer(
245        &mut self,
246        ep_addr: u8,
247        transfer_buffer: TransferBuffer,
248    ) -> Result<BackendTransferType> {
249        Ok(BackendTransferType::HostDevice(
250            Transfer::new_interrupt(ep_addr, transfer_buffer).map_err(Error::CreateTransfer)?,
251        ))
252    }
253
254    fn build_isochronous_transfer(
255        &mut self,
256        ep_addr: u8,
257        transfer_buffer: TransferBuffer,
258        packet_size: u32,
259    ) -> Result<BackendTransferType> {
260        Ok(BackendTransferType::HostDevice(
261            Transfer::new_isochronous(ep_addr, transfer_buffer, packet_size)
262                .map_err(Error::CreateTransfer)?,
263        ))
264    }
265
266    fn get_control_transfer_state(&mut self) -> Arc<RwLock<ControlTransferState>> {
267        self.control_transfer_state.clone()
268    }
269
270    fn get_device_state(&mut self) -> Arc<RwLock<DeviceState>> {
271        self.state.clone()
272    }
273
274    fn get_active_config_descriptor(&mut self) -> Result<ConfigDescriptorTree> {
275        let cur_config = self.get_active_configuration()?;
276        self.get_config_descriptor(cur_config)
277    }
278
279    fn get_config_descriptor(&mut self, config: u8) -> Result<ConfigDescriptorTree> {
280        self.device
281            .lock()
282            .get_config_descriptor(config)
283            .map_err(Error::GetActiveConfig)
284    }
285
286    fn get_config_descriptor_by_index(&mut self, config_index: u8) -> Result<ConfigDescriptorTree> {
287        self.device
288            .lock()
289            .get_config_descriptor_by_index(config_index)
290            .map_err(Error::GetConfigDescriptor)
291    }
292
293    fn get_device_descriptor_tree(&mut self) -> Result<DeviceDescriptorTree> {
294        Ok(self.device.lock().get_device_descriptor_tree().clone())
295    }
296
297    fn get_active_configuration(&mut self) -> Result<u8> {
298        self.device
299            .lock()
300            .get_active_configuration()
301            .map_err(Error::GetActiveConfig)
302    }
303
304    fn set_active_configuration(&mut self, config: u8) -> Result<()> {
305        self.device
306            .lock()
307            .set_active_configuration(config)
308            .map_err(Error::SetActiveConfig)
309    }
310
311    fn clear_feature(&mut self, value: u16, index: u16) -> Result<TransferStatus> {
312        // It's a standard, clear_feature, endpoint request.
313        const STD_FEATURE_ENDPOINT_HALT: u16 = 0;
314        if value == STD_FEATURE_ENDPOINT_HALT {
315            self.device
316                .lock()
317                .clear_halt(index as u8)
318                .map_err(Error::ClearHalt)?;
319        }
320        Ok(TransferStatus::Completed)
321    }
322
323    fn create_endpoints(&mut self, config_descriptor: &ConfigDescriptorTree) -> Result<()> {
324        let mut endpoints = Vec::new();
325        let device_state = self.get_device_state();
326        for i in &self.claimed_interfaces {
327            let alt_setting = self.alt_settings.get(i).unwrap_or(&0);
328            let interface = config_descriptor
329                .get_interface_descriptor(*i, *alt_setting)
330                .ok_or(Error::GetInterfaceDescriptor(*i, *alt_setting))?;
331            for ep_idx in 0..interface.bNumEndpoints {
332                let ep_dp = interface
333                    .get_endpoint_descriptor(ep_idx)
334                    .ok_or(Error::GetEndpointDescriptor(ep_idx))?;
335                let ep_num = ep_dp.get_endpoint_number();
336                if ep_num == 0 {
337                    continue;
338                }
339                let direction = ep_dp.get_direction();
340                let ty = ep_dp.get_endpoint_type().ok_or(Error::GetEndpointType)?;
341                endpoints.push(UsbEndpoint::new(
342                    device_state.read().unwrap().fail_handle.clone(),
343                    device_state.read().unwrap().job_queue.clone(),
344                    ep_num,
345                    direction,
346                    ty,
347                ));
348            }
349        }
350        device_state.write().unwrap().endpoints = endpoints;
351        Ok(())
352    }
353
354    fn reset_control_transfer_state(&mut self) {
355        let control_transfer_state = ControlTransferState {
356            ctl_ep_state: ControlEndpointState::SetupStage,
357            control_request_setup: UsbRequestSetup::new(0, 0, 0, 0, 0),
358            executed: false,
359        };
360        self.control_transfer_state = Arc::new(RwLock::new(control_transfer_state));
361    }
362
363    fn is_lost(&self) -> bool {
364        self.device.lock().is_device_lost()
365    }
366
367    fn can_finalize(&self) -> bool {
368        self.device.lock().ready_to_detach()
369    }
370}
371
372impl XhciBackendDevice for HostDevice {
373    fn get_backend_type(&self) -> BackendType {
374        let d = match self.device.lock().get_device_descriptor() {
375            Ok(d) => d,
376            Err(_) => return BackendType::Usb2,
377        };
378
379        // See definition of bcdUsb.
380        const USB3_MASK: u16 = 0x0300;
381        match d.bcdUSB & USB3_MASK {
382            USB3_MASK => BackendType::Usb3,
383            _ => BackendType::Usb2,
384        }
385    }
386
387    fn get_vid(&self) -> u16 {
388        match self.device.lock().get_device_descriptor() {
389            Ok(d) => d.idVendor,
390            Err(e) => {
391                error!("cannot get device descriptor: {:?}", e);
392                0
393            }
394        }
395    }
396
397    fn get_pid(&self) -> u16 {
398        match self.device.lock().get_device_descriptor() {
399            Ok(d) => d.idProduct,
400            Err(e) => {
401                error!("cannot get device descriptor: {:?}", e);
402                0
403            }
404        }
405    }
406
407    fn set_address(&mut self, _address: UsbDeviceAddress) {
408        // It's a standard, set_address, device request. We do nothing here. As described in XHCI
409        // spec. See set address command ring trb.
410        debug!(
411            "usb set address control transfer is received with address: {}",
412            _address
413        );
414    }
415
416    fn reset(&mut self) -> Result<()> {
417        self.device.lock().reset().map_err(Error::Reset)
418    }
419
420    fn get_speed(&self) -> Option<DeviceSpeed> {
421        self.device.lock().get_speed().unwrap_or(None)
422    }
423
424    fn alloc_streams(&self, ep: u8, num_streams: u16) -> Result<()> {
425        self.device
426            .lock()
427            .alloc_streams(ep, num_streams)
428            .map_err(Error::AllocStreams)
429    }
430
431    fn free_streams(&self, ep: u8) -> Result<()> {
432        self.device
433            .lock()
434            .free_streams(ep)
435            .map_err(Error::FreeStreams)
436    }
437
438    fn stop(&mut self) {
439        let device = self.device.lock();
440        device.set_detaching();
441
442        // Actively release interfaces to force the host kernel to cancel all in-flight URBs
443        // immediately. This prevents lingering sessions from blocking subsequent attach requests
444        // for the same physical device.
445        for &ifnum in &self.claimed_interfaces {
446            // We ignore errors here because the device or interface might have been physically
447            // removed already.
448            let _ = device.release_interface(ifnum);
449        }
450        self.claimed_interfaces.clear();
451    }
452}
453
454impl BackendTransfer for Transfer {
455    fn status(&self) -> TransferStatus {
456        Transfer::status(self)
457    }
458
459    fn actual_length(&self) -> usize {
460        Transfer::actual_length(self)
461    }
462
463    fn buffer(&self) -> &TransferBuffer {
464        &self.buffer
465    }
466
467    fn set_callback<C: 'static + Fn(BackendTransferType) + Send + Sync>(&mut self, cb: C) {
468        Transfer::set_callback(self, move |t| cb(BackendTransferType::HostDevice(t)));
469    }
470}
471
472#[cfg(test)]
473mod tests {
474    use std::io::Write;
475
476    use super::*;
477    use crate::utils::AsyncJobQueue;
478    use crate::utils::FailHandle;
479
480    #[test]
481    fn failed_claim_clears_previous_endpoints() {
482        // A regular file supplies descriptors but rejects the USB claim ioctl.
483        let mut file = tempfile::tempfile().unwrap();
484        file.write_all(&[
485            18, 1, 0, 2, 0, 0, 0, 64, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, // device
486            9, 2, 25, 0, 1, 1, 0, 0x80, 50, // configuration
487            9, 4, 0, 0, 1, 0xff, 0, 0, 0, // interface
488            7, 5, 0x81, 2, 64, 0, 0, // bulk IN endpoint
489        ])
490        .unwrap();
491        let device = Device::new(file).unwrap();
492        let config_descriptor = device
493            .get_device_descriptor_tree()
494            .get_config_descriptor_by_index(0)
495            .unwrap()
496            .clone();
497        let (event_loop, join_handle) = EventLoop::start("claim_test".to_string(), None).unwrap();
498        let job_queue = AsyncJobQueue::init(&event_loop).unwrap();
499        let fail_handle: Arc<dyn FailHandle> = Arc::new(None::<Arc<dyn FailHandle>>);
500        let state = Arc::new(RwLock::new(DeviceState::new(fail_handle, job_queue)));
501        let mut host_device = HostDevice {
502            device: Arc::new(Mutex::new(device)),
503            alt_settings: HashMap::new(),
504            claimed_interfaces: vec![0],
505            state: state.clone(),
506            control_transfer_state: Arc::new(RwLock::new(ControlTransferState {
507                ctl_ep_state: ControlEndpointState::SetupStage,
508                control_request_setup: UsbRequestSetup::new(0, 0, 0, 0, 0),
509                executed: false,
510            })),
511        };
512        host_device.create_endpoints(&config_descriptor).unwrap();
513        assert_eq!(state.read().unwrap().endpoints.len(), 1);
514        assert!(state.read().unwrap().endpoints[0]
515            .match_ep(1, crate::usb::xhci::xhci_transfer::TransferDirection::In));
516
517        let result = host_device.claim_interfaces_and_create_endpoints(&config_descriptor);
518        event_loop.stop();
519        join_handle.join().unwrap();
520
521        assert!(matches!(result, Err(Error::ClaimInterface(0, _))));
522        assert!(host_device.claimed_interfaces.is_empty());
523        assert!(state.read().unwrap().endpoints.is_empty());
524    }
525}