xref: /aosp_15_r20/external/crosvm/devices/src/usb/backend/device.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2024 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 
5 use std::mem;
6 use std::mem::drop;
7 use std::sync::Arc;
8 use std::sync::RwLock;
9 
10 use base::debug;
11 use base::error;
12 use base::warn;
13 use base::AsRawDescriptor;
14 use base::RawDescriptor;
15 use usb_util::ConfigDescriptorTree;
16 use usb_util::ControlRequestDataPhaseTransferDirection;
17 use usb_util::ControlRequestRecipient;
18 use usb_util::DescriptorType;
19 use usb_util::DeviceDescriptorTree;
20 use usb_util::DeviceSpeed;
21 use usb_util::StandardControlRequest;
22 use usb_util::Transfer;
23 use usb_util::TransferBuffer;
24 use usb_util::TransferStatus;
25 use usb_util::UsbRequestSetup;
26 use zerocopy::AsBytes;
27 
28 use crate::usb::backend::endpoint::ControlEndpointState;
29 use crate::usb::backend::endpoint::UsbEndpoint;
30 use crate::usb::backend::error::Error;
31 use crate::usb::backend::error::Result;
32 use crate::usb::backend::fido_backend::fido_passthrough::FidoPassthroughDevice;
33 use crate::usb::backend::fido_backend::transfer::FidoTransfer;
34 use crate::usb::backend::host_backend::host_device::HostDevice;
35 use crate::usb::backend::transfer::BackendTransfer;
36 use crate::usb::backend::transfer::BackendTransferHandle;
37 use crate::usb::backend::transfer::BackendTransferType;
38 use crate::usb::backend::transfer::ControlTransferState;
39 use crate::usb::backend::utils::multi_dispatch;
40 use crate::usb::backend::utils::update_transfer_state;
41 use crate::usb::xhci::scatter_gather_buffer::ScatterGatherBuffer;
42 use crate::usb::xhci::xhci_backend_device::BackendType;
43 use crate::usb::xhci::xhci_backend_device::UsbDeviceAddress;
44 use crate::usb::xhci::xhci_backend_device::XhciBackendDevice;
45 use crate::usb::xhci::xhci_transfer::XhciTransfer;
46 use crate::usb::xhci::xhci_transfer::XhciTransferState;
47 use crate::usb::xhci::xhci_transfer::XhciTransferType;
48 use crate::utils::AsyncJobQueue;
49 use crate::utils::EventLoop;
50 use crate::utils::FailHandle;
51 
52 /// This enum defines different USB backend implementations that we support. Each implementation
53 /// needs to implement the `BackendDevice` trait as we dispatch on the enum based on the type.
54 /// Each concrete implementation can take care of setting up the device-specific configurations.
55 pub enum BackendDeviceType {
56     // Real device on the host, backed by usbdevfs
57     HostDevice(HostDevice),
58     // Virtual security key implementation
59     FidoDevice(FidoPassthroughDevice),
60 }
61 
62 impl AsRawDescriptor for BackendDeviceType {
as_raw_descriptor(&self) -> RawDescriptor63     fn as_raw_descriptor(&self) -> RawDescriptor {
64         multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, as_raw_descriptor)
65     }
66 }
67 
68 impl BackendDevice for BackendDeviceType {
submit_backend_transfer( &mut self, transfer: BackendTransferType, ) -> Result<BackendTransferHandle>69     fn submit_backend_transfer(
70         &mut self,
71         transfer: BackendTransferType,
72     ) -> Result<BackendTransferHandle> {
73         multi_dispatch!(
74             self,
75             BackendDeviceType,
76             HostDevice FidoDevice,
77             submit_backend_transfer,
78             transfer
79         )
80     }
81 
detach_event_handler(&self, event_loop: &Arc<EventLoop>) -> Result<()>82     fn detach_event_handler(&self, event_loop: &Arc<EventLoop>) -> Result<()> {
83         multi_dispatch!(
84             self,
85             BackendDeviceType,
86             HostDevice FidoDevice,
87             detach_event_handler,
88             event_loop
89         )
90     }
91 
request_transfer_buffer(&mut self, size: usize) -> TransferBuffer92     fn request_transfer_buffer(&mut self, size: usize) -> TransferBuffer {
93         multi_dispatch!(
94             self,
95             BackendDeviceType,
96             HostDevice FidoDevice,
97             request_transfer_buffer,
98             size
99         )
100     }
101 
build_bulk_transfer( &mut self, ep_addr: u8, transfer_buffer: TransferBuffer, stream_id: Option<u16>, ) -> Result<BackendTransferType>102     fn build_bulk_transfer(
103         &mut self,
104         ep_addr: u8,
105         transfer_buffer: TransferBuffer,
106         stream_id: Option<u16>,
107     ) -> Result<BackendTransferType> {
108         multi_dispatch!(
109             self,
110             BackendDeviceType,
111             HostDevice FidoDevice,
112             build_bulk_transfer,
113             ep_addr,
114             transfer_buffer,
115             stream_id
116         )
117     }
118 
build_interrupt_transfer( &mut self, ep_addr: u8, transfer_buffer: TransferBuffer, ) -> Result<BackendTransferType>119     fn build_interrupt_transfer(
120         &mut self,
121         ep_addr: u8,
122         transfer_buffer: TransferBuffer,
123     ) -> Result<BackendTransferType> {
124         multi_dispatch!(
125             self,
126             BackendDeviceType,
127             HostDevice FidoDevice,
128             build_interrupt_transfer,
129             ep_addr,
130             transfer_buffer
131         )
132     }
133 
get_control_transfer_state(&mut self) -> Arc<RwLock<ControlTransferState>>134     fn get_control_transfer_state(&mut self) -> Arc<RwLock<ControlTransferState>> {
135         multi_dispatch!(
136             self,
137             BackendDeviceType,
138             HostDevice FidoDevice,
139             get_control_transfer_state
140         )
141     }
142 
get_device_state(&mut self) -> Arc<RwLock<DeviceState>>143     fn get_device_state(&mut self) -> Arc<RwLock<DeviceState>> {
144         multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, get_device_state)
145     }
146 
get_active_config_descriptor(&mut self) -> Result<ConfigDescriptorTree>147     fn get_active_config_descriptor(&mut self) -> Result<ConfigDescriptorTree> {
148         multi_dispatch!(
149             self,
150             BackendDeviceType,
151             HostDevice FidoDevice,
152             get_active_config_descriptor
153         )
154     }
155 
get_config_descriptor(&mut self, config: u8) -> Result<ConfigDescriptorTree>156     fn get_config_descriptor(&mut self, config: u8) -> Result<ConfigDescriptorTree> {
157         multi_dispatch!(
158             self,
159             BackendDeviceType,
160             HostDevice FidoDevice,
161             get_config_descriptor,
162             config
163         )
164     }
165 
get_config_descriptor_by_index(&mut self, config_index: u8) -> Result<ConfigDescriptorTree>166     fn get_config_descriptor_by_index(&mut self, config_index: u8) -> Result<ConfigDescriptorTree> {
167         multi_dispatch!(
168             self,
169             BackendDeviceType,
170             HostDevice FidoDevice,
171             get_config_descriptor_by_index,
172             config_index
173         )
174     }
175 
get_device_descriptor_tree(&mut self) -> Result<DeviceDescriptorTree>176     fn get_device_descriptor_tree(&mut self) -> Result<DeviceDescriptorTree> {
177         multi_dispatch!(
178             self,
179             BackendDeviceType,
180             HostDevice FidoDevice,
181             get_device_descriptor_tree
182         )
183     }
184 
get_active_configuration(&mut self) -> Result<u8>185     fn get_active_configuration(&mut self) -> Result<u8> {
186         multi_dispatch!(
187             self,
188             BackendDeviceType,
189             HostDevice FidoDevice,
190             get_active_configuration
191         )
192     }
193 
set_active_configuration(&mut self, config: u8) -> Result<()>194     fn set_active_configuration(&mut self, config: u8) -> Result<()> {
195         multi_dispatch!(
196             self,
197             BackendDeviceType,
198             HostDevice FidoDevice,
199             set_active_configuration,
200             config
201         )
202     }
203 
clear_feature(&mut self, value: u16, index: u16) -> Result<TransferStatus>204     fn clear_feature(&mut self, value: u16, index: u16) -> Result<TransferStatus> {
205         multi_dispatch!(
206             self,
207             BackendDeviceType,
208             HostDevice FidoDevice,
209             clear_feature,
210             value,
211             index
212         )
213     }
214 
create_endpoints(&mut self, config_descriptor: &ConfigDescriptorTree) -> Result<()>215     fn create_endpoints(&mut self, config_descriptor: &ConfigDescriptorTree) -> Result<()> {
216         multi_dispatch!(
217             self,
218             BackendDeviceType,
219             HostDevice FidoDevice,
220             create_endpoints,
221             config_descriptor
222         )
223     }
224 }
225 
226 impl XhciBackendDevice for BackendDeviceType {
get_backend_type(&self) -> BackendType227     fn get_backend_type(&self) -> BackendType {
228         multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, get_backend_type)
229     }
230 
get_vid(&self) -> u16231     fn get_vid(&self) -> u16 {
232         multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, get_vid)
233     }
234 
get_pid(&self) -> u16235     fn get_pid(&self) -> u16 {
236         multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, get_pid)
237     }
238 
set_address(&mut self, address: UsbDeviceAddress)239     fn set_address(&mut self, address: UsbDeviceAddress) {
240         multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, set_address, address)
241     }
242 
reset(&mut self) -> Result<()>243     fn reset(&mut self) -> Result<()> {
244         multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, reset)
245     }
246 
get_speed(&self) -> Option<DeviceSpeed>247     fn get_speed(&self) -> Option<DeviceSpeed> {
248         multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, get_speed)
249     }
250 
alloc_streams(&self, ep: u8, num_streams: u16) -> Result<()>251     fn alloc_streams(&self, ep: u8, num_streams: u16) -> Result<()> {
252         multi_dispatch!(
253             self,
254             BackendDeviceType,
255             HostDevice FidoDevice,
256             alloc_streams,
257             ep,
258             num_streams
259         )
260     }
261 
free_streams(&self, ep: u8) -> Result<()>262     fn free_streams(&self, ep: u8) -> Result<()> {
263         multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, free_streams, ep)
264     }
265 
stop(&mut self)266     fn stop(&mut self) {
267         multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, stop)
268     }
269 }
270 
271 pub struct DeviceState {
272     pub fail_handle: Arc<dyn FailHandle>,
273     // Endpoints only contains data endpoints (1 to 30). Control transfers are handled at device
274     // level.
275     pub endpoints: Vec<UsbEndpoint>,
276     pub initialized: bool,
277     pub job_queue: Arc<AsyncJobQueue>,
278 }
279 
280 impl DeviceState {
new(fail_handle: Arc<dyn FailHandle>, job_queue: Arc<AsyncJobQueue>) -> Self281     pub fn new(fail_handle: Arc<dyn FailHandle>, job_queue: Arc<AsyncJobQueue>) -> Self {
282         DeviceState {
283             fail_handle,
284             endpoints: vec![],
285             initialized: false,
286             job_queue,
287         }
288     }
289 }
290 
291 impl BackendDeviceType {
292     // Check for requests that should be intercepted and handled in a generic way
293     // rather than passed directly to the backend device for device-specific implementations.
294     // Returns true if the request has been intercepted or false if the request
295     // should be passed through.
intercepted_control_transfer( &mut self, xhci_transfer: &XhciTransfer, buffer: &Option<ScatterGatherBuffer>, control_request_setup: &UsbRequestSetup, ) -> Result<bool>296     fn intercepted_control_transfer(
297         &mut self,
298         xhci_transfer: &XhciTransfer,
299         buffer: &Option<ScatterGatherBuffer>,
300         control_request_setup: &UsbRequestSetup,
301     ) -> Result<bool> {
302         let direction = control_request_setup.get_direction();
303         let recipient = control_request_setup.get_recipient();
304         let standard_request = if let Some(req) = control_request_setup.get_standard_request() {
305             req
306         } else {
307             // Unknown control requests will be passed through to the device.
308             return Ok(false);
309         };
310 
311         let (status, bytes_transferred) = match (standard_request, recipient, direction) {
312             (
313                 StandardControlRequest::SetAddress,
314                 ControlRequestRecipient::Device,
315                 ControlRequestDataPhaseTransferDirection::HostToDevice,
316             ) => {
317                 usb_trace!("handling set address");
318                 let addr = control_request_setup.value as u32;
319                 self.set_address(addr);
320                 (TransferStatus::Completed, 0)
321             }
322             (
323                 StandardControlRequest::SetConfiguration,
324                 ControlRequestRecipient::Device,
325                 ControlRequestDataPhaseTransferDirection::HostToDevice,
326             ) => {
327                 usb_trace!("handling set config");
328                 let config = (control_request_setup.value & 0xff) as u8;
329                 match self.set_config(config) {
330                     Ok(status) => (status, 0),
331                     Err(e) => {
332                         error!("set config error: {}", e);
333                         (TransferStatus::Stalled, 0)
334                     }
335                 }
336             }
337             (
338                 StandardControlRequest::SetInterface,
339                 ControlRequestRecipient::Interface,
340                 ControlRequestDataPhaseTransferDirection::HostToDevice,
341             ) => {
342                 usb_trace!("handling set interface");
343                 match self {
344                     BackendDeviceType::HostDevice(host_device) => match host_device.set_interface(
345                         control_request_setup.index as u8,
346                         control_request_setup.value as u8,
347                     ) {
348                         Ok(status) => (status, 0),
349                         Err(e) => {
350                             error!("set interface error: {}", e);
351                             (TransferStatus::Stalled, 0)
352                         }
353                     },
354                     _ => {
355                         // Nothing to do for non-host devices
356                         (TransferStatus::Completed, 0)
357                     }
358                 }
359             }
360             (
361                 StandardControlRequest::ClearFeature,
362                 ControlRequestRecipient::Endpoint,
363                 ControlRequestDataPhaseTransferDirection::HostToDevice,
364             ) => {
365                 usb_trace!("handling clear feature");
366                 match self.clear_feature(control_request_setup.value, control_request_setup.index) {
367                     Ok(status) => (status, 0),
368                     Err(e) => {
369                         error!("clear feature error: {}", e);
370                         (TransferStatus::Stalled, 0)
371                     }
372                 }
373             }
374             (
375                 StandardControlRequest::GetDescriptor,
376                 ControlRequestRecipient::Device,
377                 ControlRequestDataPhaseTransferDirection::DeviceToHost,
378             ) => {
379                 let descriptor_type = (control_request_setup.value >> 8) as u8;
380                 if descriptor_type == DescriptorType::Configuration as u8 {
381                     let buffer = if let Some(buffer) = buffer {
382                         buffer
383                     } else {
384                         return Err(Error::MissingRequiredBuffer);
385                     };
386 
387                     match self {
388                         // If it's a host device we filter the descriptor tree
389                         BackendDeviceType::HostDevice(host_device) => {
390                             match host_device.get_config_descriptor_filtered(
391                                 buffer,
392                                 control_request_setup.value as u8,
393                             ) {
394                                 Ok((status, b)) => (status, b),
395                                 Err(e) => {
396                                     error!("get descriptor error: {}", e);
397                                     (TransferStatus::Stalled, 0)
398                                 }
399                             }
400                         }
401                         BackendDeviceType::FidoDevice(fido_passthrough) => {
402                             match fido_passthrough
403                                 .get_config_descriptor_by_index(control_request_setup.value as u8)
404                             {
405                                 Ok(descriptor_tree) => {
406                                     let device_descriptor =
407                                         fido_passthrough.get_device_descriptor_tree()?;
408                                     let offset = descriptor_tree.offset();
409                                     let data = device_descriptor.raw()
410                                         [offset..offset + descriptor_tree.wTotalLength as usize]
411                                         .to_vec();
412                                     let bytes = buffer.write(&data).map_err(Error::WriteBuffer)?;
413                                     (TransferStatus::Completed, bytes as u32)
414                                 }
415                                 Err(e) => {
416                                     error!("get fido descriptor error: {}", e);
417                                     (TransferStatus::Stalled, 0)
418                                 }
419                             }
420                         }
421                     }
422                 } else {
423                     return Ok(false);
424                 }
425             }
426             _ => {
427                 // Other requests will be passed through to the device.
428                 return Ok(false);
429             }
430         };
431 
432         xhci_transfer
433             .on_transfer_complete(&status, bytes_transferred)
434             .map_err(Error::TransferComplete)?;
435 
436         Ok(true)
437     }
438 
execute_control_transfer( &mut self, xhci_transfer: Arc<XhciTransfer>, buffer: Option<ScatterGatherBuffer>, control_request_setup: &UsbRequestSetup, ) -> Result<()>439     fn execute_control_transfer(
440         &mut self,
441         xhci_transfer: Arc<XhciTransfer>,
442         buffer: Option<ScatterGatherBuffer>,
443         control_request_setup: &UsbRequestSetup,
444     ) -> Result<()> {
445         if self.intercepted_control_transfer(&xhci_transfer, &buffer, control_request_setup)? {
446             return Ok(());
447         }
448 
449         // Allocate a buffer for the control transfer.
450         // This buffer will hold a UsbRequestSetup struct followed by the data.
451         let control_buffer_len =
452             mem::size_of::<UsbRequestSetup>() + control_request_setup.length as usize;
453         let mut control_buffer = vec![0u8; control_buffer_len];
454 
455         // Copy the control request header.
456         control_buffer[..mem::size_of::<UsbRequestSetup>()]
457             .copy_from_slice(control_request_setup.as_bytes());
458 
459         let direction = control_request_setup.get_direction();
460         let buffer = if direction == ControlRequestDataPhaseTransferDirection::HostToDevice {
461             if let Some(buffer) = buffer {
462                 buffer
463                     .read(&mut control_buffer[mem::size_of::<UsbRequestSetup>()..])
464                     .map_err(Error::ReadBuffer)?;
465             }
466             // buffer is consumed here for HostToDevice transfers.
467             None
468         } else {
469             // buffer will be used later in the callback for DeviceToHost transfers.
470             buffer
471         };
472 
473         // TODO(morg): Refactor this code so it doesn't need to match on each implementation type
474         let mut control_transfer = match self {
475             BackendDeviceType::HostDevice(_) => BackendTransferType::HostDevice(
476                 Transfer::new_control(TransferBuffer::Vector(control_buffer))
477                     .map_err(Error::CreateTransfer)?,
478             ),
479             BackendDeviceType::FidoDevice(_) => BackendTransferType::FidoDevice(FidoTransfer::new(
480                 0,
481                 TransferBuffer::Vector(control_buffer),
482             )),
483         };
484 
485         let tmp_transfer = xhci_transfer.clone();
486         let callback = move |t: BackendTransferType| {
487             usb_trace!("setup token control transfer callback");
488             update_transfer_state(&xhci_transfer, t.status())?;
489             let state = xhci_transfer.state().lock();
490             match *state {
491                 XhciTransferState::Cancelled => {
492                     drop(state);
493                     xhci_transfer
494                         .on_transfer_complete(&TransferStatus::Cancelled, 0)
495                         .map_err(Error::TransferComplete)?;
496                 }
497                 XhciTransferState::Completed => {
498                     let status = t.status();
499                     let actual_length = t.actual_length();
500                     if direction == ControlRequestDataPhaseTransferDirection::DeviceToHost {
501                         match t.buffer() {
502                             TransferBuffer::Vector(v) => {
503                                 if let Some(control_request_data) =
504                                     v.get(mem::size_of::<UsbRequestSetup>()..)
505                                 {
506                                     if let Some(buffer) = &buffer {
507                                         buffer
508                                             .write(control_request_data)
509                                             .map_err(Error::WriteBuffer)?;
510                                     }
511                                 }
512                             }
513                             // control buffer must use a vector for buffer
514                             TransferBuffer::Dma(_) => unreachable!(),
515                         }
516                     }
517                     drop(state);
518                     debug!(
519                         "xhci transfer completed with actual length {}",
520                         actual_length
521                     );
522                     xhci_transfer
523                         .on_transfer_complete(&status, actual_length as u32)
524                         .map_err(Error::TransferComplete)?;
525                 }
526                 _ => {
527                     // update_transfer_state is already invoked before match.
528                     // This transfer could only be `Cancelled` or `Completed`.
529                     // Any other state means there is a bug in crosvm implementation.
530                     error!("should not take this branch");
531                     return Err(Error::BadXhciTransferState);
532                 }
533             }
534             Ok(())
535         };
536 
537         let fail_handle = self.get_device_state().write().unwrap().fail_handle.clone();
538         control_transfer.set_callback(move |t: BackendTransferType| match callback(t) {
539             Ok(_) => {}
540             Err(e) => {
541                 error!("control transfer callback failed {:?}", e);
542                 fail_handle.fail();
543             }
544         });
545         // Create a temporary binding for the rwlock
546         let device_state_binding = self.get_device_state();
547         // Acquire the lock as a reader
548         let device_state_lock = device_state_binding.read().unwrap();
549         self.submit_transfer(
550             device_state_lock.fail_handle.clone(),
551             &device_state_lock.job_queue,
552             tmp_transfer,
553             control_transfer,
554         )
555     }
556 
handle_control_transfer(&mut self, transfer: XhciTransfer) -> Result<()>557     fn handle_control_transfer(&mut self, transfer: XhciTransfer) -> Result<()> {
558         let xhci_transfer = Arc::new(transfer);
559         let transfer_type = xhci_transfer
560             .get_transfer_type()
561             .map_err(Error::GetXhciTransferType)?;
562         let control_transfer_state_binding = self.get_control_transfer_state();
563         let mut control_transfer_state = control_transfer_state_binding.write().unwrap();
564         match transfer_type {
565             XhciTransferType::SetupStage => {
566                 let setup = xhci_transfer
567                     .create_usb_request_setup()
568                     .map_err(Error::CreateUsbRequestSetup)?;
569                 if control_transfer_state.ctl_ep_state != ControlEndpointState::SetupStage {
570                     error!("Control endpoint is in an inconsistant state");
571                     return Ok(());
572                 }
573                 usb_trace!("setup stage: setup buffer: {:?}", setup);
574                 control_transfer_state.control_request_setup = setup;
575                 xhci_transfer
576                     .on_transfer_complete(&TransferStatus::Completed, 0)
577                     .map_err(Error::TransferComplete)?;
578                 control_transfer_state.ctl_ep_state = ControlEndpointState::DataStage;
579             }
580             XhciTransferType::DataStage => {
581                 if control_transfer_state.ctl_ep_state != ControlEndpointState::DataStage {
582                     error!("Control endpoint is in an inconsistant state");
583                     return Ok(());
584                 }
585                 // Requests with a DataStage will be executed here.
586                 // Requests without a DataStage will be executed in StatusStage.
587                 let buffer = xhci_transfer.create_buffer().map_err(Error::CreateBuffer)?;
588                 self.execute_control_transfer(
589                     xhci_transfer,
590                     Some(buffer),
591                     &control_transfer_state.control_request_setup,
592                 )?;
593                 control_transfer_state.executed = true;
594                 control_transfer_state.ctl_ep_state = ControlEndpointState::StatusStage;
595             }
596             XhciTransferType::StatusStage => {
597                 if control_transfer_state.ctl_ep_state == ControlEndpointState::SetupStage {
598                     error!("Control endpoint is in an inconsistant state");
599                     return Ok(());
600                 }
601                 if control_transfer_state.executed {
602                     // Request was already executed during DataStage.
603                     // Just complete the StatusStage transfer.
604                     xhci_transfer
605                         .on_transfer_complete(&TransferStatus::Completed, 0)
606                         .map_err(Error::TransferComplete)?;
607                 } else {
608                     // Execute the request now since there was no DataStage.
609                     self.execute_control_transfer(
610                         xhci_transfer,
611                         None,
612                         &control_transfer_state.control_request_setup,
613                     )?;
614                 }
615                 control_transfer_state.executed = false;
616                 control_transfer_state.ctl_ep_state = ControlEndpointState::SetupStage;
617             }
618             _ => {
619                 // Non control transfer should not be handled in this function.
620                 error!(
621                     "Non control {} transfer sent to control endpoint.",
622                     transfer_type,
623                 );
624                 xhci_transfer
625                     .on_transfer_complete(&TransferStatus::Completed, 0)
626                     .map_err(Error::TransferComplete)?;
627             }
628         }
629         Ok(())
630     }
631 
set_config(&mut self, config: u8) -> Result<TransferStatus>632     fn set_config(&mut self, config: u8) -> Result<TransferStatus> {
633         // It's a standard, set_config, device request.
634         usb_trace!("set_config: {}", config);
635 
636         if let BackendDeviceType::HostDevice(host_device) = self {
637             host_device.release_interfaces();
638         }
639 
640         let cur_config = match self.get_active_configuration() {
641             Ok(c) => Some(c),
642             Err(e) => {
643                 // The device may be in the default state, in which case
644                 // GET_CONFIGURATION may fail.  Assume the device needs to be
645                 // reconfigured.
646                 error!("Failed to get active configuration: {}", e);
647                 None
648             }
649         };
650 
651         let mut need_set_config = true;
652         let device_state_binding = self.get_device_state();
653         let mut device_state = device_state_binding.write().unwrap();
654         if !device_state.initialized {
655             need_set_config = Some(config) != cur_config;
656             device_state.initialized = true;
657         }
658         // Drop the lock on the device state writer
659         drop(device_state);
660 
661         if need_set_config {
662             self.set_active_configuration(config)?;
663         }
664 
665         let config_descriptor = self.get_config_descriptor(config)?;
666 
667         if let BackendDeviceType::HostDevice(host_device) = self {
668             host_device.claim_interfaces(&config_descriptor);
669         }
670 
671         self.create_endpoints(&config_descriptor)?;
672         Ok(TransferStatus::Completed)
673     }
674 
submit_transfer( &mut self, fail_handle: Arc<dyn FailHandle>, job_queue: &Arc<AsyncJobQueue>, xhci_transfer: Arc<XhciTransfer>, usb_transfer: BackendTransferType, ) -> Result<()>675     pub fn submit_transfer(
676         &mut self,
677         fail_handle: Arc<dyn FailHandle>,
678         job_queue: &Arc<AsyncJobQueue>,
679         xhci_transfer: Arc<XhciTransfer>,
680         usb_transfer: BackendTransferType,
681     ) -> Result<()> {
682         let transfer_status = {
683             // We need to hold the lock to avoid race condition.
684             // While we are trying to submit the transfer, another thread might want to cancel the
685             // same transfer. Holding the lock here makes sure one of them is cancelled.
686             let mut state = xhci_transfer.state().lock();
687             match mem::replace(&mut *state, XhciTransferState::Cancelled) {
688                 XhciTransferState::Created => {
689                     match self.submit_backend_transfer(usb_transfer) {
690                         Err(e) => {
691                             error!("fail to submit transfer {:?}", e);
692                             *state = XhciTransferState::Completed;
693                             TransferStatus::NoDevice
694                         }
695                         Ok(canceller) => {
696                             let cancel_callback = Box::new(move || match canceller.cancel() {
697                                 Ok(()) => {
698                                     debug!("cancel issued to kernel");
699                                 }
700                                 Err(e) => {
701                                     error!("failed to cancel XhciTransfer: {}", e);
702                                 }
703                             });
704                             *state = XhciTransferState::Submitted { cancel_callback };
705                             // If it's submitted, we don't need to send on_transfer_complete now.
706                             return Ok(());
707                         }
708                     }
709                 }
710                 XhciTransferState::Cancelled => {
711                     warn!("Transfer is already cancelled");
712                     TransferStatus::Cancelled
713                 }
714                 _ => {
715                     // The transfer could not be in the following states:
716                     // Submitted: A transfer should only be submitted once.
717                     // Cancelling: Transfer is cancelling only when it's submitted and someone is
718                     // trying to cancel it.
719                     // Completed: A completed transfer should not be submitted again.
720                     error!("xhci trasfer state is invalid");
721                     return Err(Error::BadXhciTransferState);
722                 }
723             }
724         };
725         // We are holding locks to of backends, we want to call on_transfer_complete
726         // without any lock.
727         job_queue
728             .queue_job(move || {
729                 if let Err(e) = xhci_transfer.on_transfer_complete(&transfer_status, 0) {
730                     error!("transfer complete failed: {:?}", e);
731                     fail_handle.fail();
732                 }
733             })
734             .map_err(Error::QueueAsyncJob)
735     }
736 
submit_xhci_transfer(&mut self, transfer: XhciTransfer) -> Result<()>737     pub fn submit_xhci_transfer(&mut self, transfer: XhciTransfer) -> Result<()> {
738         // We catch the submit_xhci_transfer call at the top BackendDeviceType level because
739         // the implementation is generic for all backend types. If it's a control
740         // transfer we handle it accordingly, before dispatching into each specific
741         // endpoint logic.
742         if transfer.get_endpoint_number() == 0 {
743             return self.handle_control_transfer(transfer);
744         }
745 
746         for ep in &self.get_device_state().write().unwrap().endpoints {
747             if ep.match_ep(transfer.get_endpoint_number(), transfer.get_transfer_dir()) {
748                 return ep.handle_transfer(self, transfer);
749             }
750         }
751 
752         warn!("Could not find endpoint for transfer");
753         transfer
754             .on_transfer_complete(&TransferStatus::Error, 0)
755             .map_err(Error::TransferComplete)
756     }
757 }
758 
759 /// Backend device trait implementation is the interface of a generic backend device
760 /// to interact with concrete implementations
761 pub trait BackendDevice: Sync + Send {
762     /// Submits a transfer to the specific backend implementation.
submit_backend_transfer( &mut self, transfer: BackendTransferType, ) -> Result<BackendTransferHandle>763     fn submit_backend_transfer(
764         &mut self,
765         transfer: BackendTransferType,
766     ) -> Result<BackendTransferHandle>;
767     /// This is called by a generic backend provider when a USB detach message is received from the
768     /// vm control socket. It detaches the backend device from the backend provider event loop.
detach_event_handler(&self, event_loop: &Arc<EventLoop>) -> Result<()>769     fn detach_event_handler(&self, event_loop: &Arc<EventLoop>) -> Result<()>;
770     /// Gets a buffer used for data transfer between the host and this device. The buffer returned
771     /// by this function must be consumed by `submit_backend_transfer()`.
request_transfer_buffer(&mut self, size: usize) -> TransferBuffer772     fn request_transfer_buffer(&mut self, size: usize) -> TransferBuffer;
773 
774     /// Requests the backend to build a backend-specific bulk transfer request
build_bulk_transfer( &mut self, ep_addr: u8, transfer_buffer: TransferBuffer, stream_id: Option<u16>, ) -> Result<BackendTransferType>775     fn build_bulk_transfer(
776         &mut self,
777         ep_addr: u8,
778         transfer_buffer: TransferBuffer,
779         stream_id: Option<u16>,
780     ) -> Result<BackendTransferType>;
781     /// Requests the backend to build a backend-specific interrupt transfer request
build_interrupt_transfer( &mut self, ep_addr: u8, transfer_buffer: TransferBuffer, ) -> Result<BackendTransferType>782     fn build_interrupt_transfer(
783         &mut self,
784         ep_addr: u8,
785         transfer_buffer: TransferBuffer,
786     ) -> Result<BackendTransferType>;
787 
788     /// Returns the `ControlTransferState` for the given backend device.
get_control_transfer_state(&mut self) -> Arc<RwLock<ControlTransferState>>789     fn get_control_transfer_state(&mut self) -> Arc<RwLock<ControlTransferState>>;
790     /// Returns the `DeviceState` for the given backend device. This state contains all the
791     /// backend-agnostic state for all generic USB backends.
get_device_state(&mut self) -> Arc<RwLock<DeviceState>>792     fn get_device_state(&mut self) -> Arc<RwLock<DeviceState>>;
793 
794     /// Gets the device active config descriptor tree.
get_active_config_descriptor(&mut self) -> Result<ConfigDescriptorTree>795     fn get_active_config_descriptor(&mut self) -> Result<ConfigDescriptorTree>;
796     /// Gets a specific device config descriptor tree.
get_config_descriptor(&mut self, config: u8) -> Result<ConfigDescriptorTree>797     fn get_config_descriptor(&mut self, config: u8) -> Result<ConfigDescriptorTree>;
798     /// Gets a specific device config descriptor tree by index.
get_config_descriptor_by_index(&mut self, config_index: u8) -> Result<ConfigDescriptorTree>799     fn get_config_descriptor_by_index(&mut self, config_index: u8) -> Result<ConfigDescriptorTree>;
800     /// Gets the device descriptor tree.
get_device_descriptor_tree(&mut self) -> Result<DeviceDescriptorTree>801     fn get_device_descriptor_tree(&mut self) -> Result<DeviceDescriptorTree>;
802     /// Gets the device current active configuration.
get_active_configuration(&mut self) -> Result<u8>803     fn get_active_configuration(&mut self) -> Result<u8>;
804     /// Sets the device active configuration.
set_active_configuration(&mut self, config: u8) -> Result<()>805     fn set_active_configuration(&mut self, config: u8) -> Result<()>;
806     /// Handles a clear feature endpoint request for the given device.
clear_feature(&mut self, value: u16, index: u16) -> Result<TransferStatus>807     fn clear_feature(&mut self, value: u16, index: u16) -> Result<TransferStatus>;
808     /// Creates endpoints for the device with the given config descriptor tree.
create_endpoints(&mut self, config_descriptor: &ConfigDescriptorTree) -> Result<()>809     fn create_endpoints(&mut self, config_descriptor: &ConfigDescriptorTree) -> Result<()>;
810 }
811