devices/usb/backend/
device.rs

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
5use std::mem;
6use std::mem::drop;
7use std::sync::Arc;
8use std::sync::RwLock;
9
10use base::debug;
11use base::error;
12use base::warn;
13use base::AsRawDescriptor;
14use base::RawDescriptor;
15use usb_util::ConfigDescriptorTree;
16use usb_util::ControlRequestDataPhaseTransferDirection;
17use usb_util::ControlRequestRecipient;
18use usb_util::DescriptorType;
19use usb_util::DeviceDescriptorTree;
20use usb_util::DeviceSpeed;
21use usb_util::StandardControlRequest;
22use usb_util::Transfer;
23use usb_util::TransferBuffer;
24use usb_util::TransferStatus;
25use usb_util::UsbRequestSetup;
26use zerocopy::IntoBytes;
27
28use crate::usb::backend::endpoint::ControlEndpointState;
29use crate::usb::backend::endpoint::UsbEndpoint;
30use crate::usb::backend::error::Error;
31use crate::usb::backend::error::Result;
32use crate::usb::backend::fido_backend::fido_passthrough::FidoPassthroughDevice;
33use crate::usb::backend::fido_backend::transfer::FidoTransfer;
34use crate::usb::backend::host_backend::host_device::HostDevice;
35use crate::usb::backend::transfer::BackendTransfer;
36use crate::usb::backend::transfer::BackendTransferHandle;
37use crate::usb::backend::transfer::BackendTransferType;
38use crate::usb::backend::transfer::ControlTransferState;
39use crate::usb::backend::utils::multi_dispatch;
40use crate::usb::backend::utils::update_transfer_state;
41use crate::usb::xhci::scatter_gather_buffer::ScatterGatherBuffer;
42use crate::usb::xhci::xhci_backend_device::BackendType;
43use crate::usb::xhci::xhci_backend_device::UsbDeviceAddress;
44use crate::usb::xhci::xhci_backend_device::XhciBackendDevice;
45use crate::usb::xhci::xhci_transfer::XhciTransfer;
46use crate::usb::xhci::xhci_transfer::XhciTransferState;
47use crate::usb::xhci::xhci_transfer::XhciTransferType;
48use crate::utils::AsyncJobQueue;
49use crate::utils::EventLoop;
50use 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.
55pub enum BackendDeviceType {
56    // Real device on the host, backed by usbdevfs
57    HostDevice(HostDevice),
58    // Virtual security key implementation
59    FidoDevice(FidoPassthroughDevice),
60}
61
62impl AsRawDescriptor for BackendDeviceType {
63    fn as_raw_descriptor(&self) -> RawDescriptor {
64        multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, as_raw_descriptor)
65    }
66}
67
68impl BackendDevice for BackendDeviceType {
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
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
92    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
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
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
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
143    fn get_device_state(&mut self) -> Arc<RwLock<DeviceState>> {
144        multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, get_device_state)
145    }
146
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
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
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
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
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
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
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
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
226impl XhciBackendDevice for BackendDeviceType {
227    fn get_backend_type(&self) -> BackendType {
228        multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, get_backend_type)
229    }
230
231    fn get_vid(&self) -> u16 {
232        multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, get_vid)
233    }
234
235    fn get_pid(&self) -> u16 {
236        multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, get_pid)
237    }
238
239    fn set_address(&mut self, address: UsbDeviceAddress) {
240        multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, set_address, address)
241    }
242
243    fn reset(&mut self) -> Result<()> {
244        multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, reset)
245    }
246
247    fn get_speed(&self) -> Option<DeviceSpeed> {
248        multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, get_speed)
249    }
250
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
262    fn free_streams(&self, ep: u8) -> Result<()> {
263        multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, free_streams, ep)
264    }
265
266    fn stop(&mut self) {
267        multi_dispatch!(self, BackendDeviceType, HostDevice FidoDevice, stop)
268    }
269}
270
271pub 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
280impl DeviceState {
281    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
291impl 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.
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
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
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
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
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
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
761pub trait BackendDevice: Sync + Send {
762    /// Submits a transfer to the specific backend implementation.
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.
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()`.
772    fn request_transfer_buffer(&mut self, size: usize) -> TransferBuffer;
773
774    /// Requests the backend to build a backend-specific bulk transfer request
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
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.
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.
792    fn get_device_state(&mut self) -> Arc<RwLock<DeviceState>>;
793
794    /// Gets the device active config descriptor tree.
795    fn get_active_config_descriptor(&mut self) -> Result<ConfigDescriptorTree>;
796    /// Gets a specific device config descriptor tree.
797    fn get_config_descriptor(&mut self, config: u8) -> Result<ConfigDescriptorTree>;
798    /// Gets a specific device config descriptor tree by index.
799    fn get_config_descriptor_by_index(&mut self, config_index: u8) -> Result<ConfigDescriptorTree>;
800    /// Gets the device descriptor tree.
801    fn get_device_descriptor_tree(&mut self) -> Result<DeviceDescriptorTree>;
802    /// Gets the device current active configuration.
803    fn get_active_configuration(&mut self) -> Result<u8>;
804    /// Sets the device active configuration.
805    fn set_active_configuration(&mut self, config: u8) -> Result<()>;
806    /// Handles a clear feature endpoint request for the given device.
807    fn clear_feature(&mut self, value: u16, index: u16) -> Result<TransferStatus>;
808    /// Creates endpoints for the device with the given config descriptor tree.
809    fn create_endpoints(&mut self, config_descriptor: &ConfigDescriptorTree) -> Result<()>;
810}