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