1 // Copyright 2019 The Chromium OS Authors. All rights reserved. 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 crate::usb::xhci::ring_buffer_controller::{ 6 Error as RingBufferControllerError, RingBufferController, TransferDescriptorHandler, 7 }; 8 use crate::utils::EventLoop; 9 use base::{error, Event}; 10 use std::sync::Arc; 11 use sync::Mutex; 12 use vm_memory::GuestMemory; 13 14 use super::interrupter::Interrupter; 15 use super::usb_hub::UsbPort; 16 use super::xhci_abi::TransferDescriptor; 17 use super::xhci_transfer::XhciTransferManager; 18 19 /// Transfer ring controller manages transfer ring. 20 pub type TransferRingController = RingBufferController<TransferRingTrbHandler>; 21 22 pub type TransferRingControllerError = RingBufferControllerError; 23 24 /// TransferRingTrbHandler handles trbs on transfer ring. 25 pub struct TransferRingTrbHandler { 26 mem: GuestMemory, 27 port: Arc<UsbPort>, 28 interrupter: Arc<Mutex<Interrupter>>, 29 slot_id: u8, 30 endpoint_id: u8, 31 transfer_manager: XhciTransferManager, 32 } 33 34 impl TransferDescriptorHandler for TransferRingTrbHandler { handle_transfer_descriptor( &self, descriptor: TransferDescriptor, completion_event: Event, ) -> Result<(), ()>35 fn handle_transfer_descriptor( 36 &self, 37 descriptor: TransferDescriptor, 38 completion_event: Event, 39 ) -> Result<(), ()> { 40 let xhci_transfer = self.transfer_manager.create_transfer( 41 self.mem.clone(), 42 self.port.clone(), 43 self.interrupter.clone(), 44 self.slot_id, 45 self.endpoint_id, 46 descriptor, 47 completion_event, 48 ); 49 xhci_transfer.send_to_backend_if_valid().map_err(|e| { 50 error!("failed to send transfer to backend: {}", e); 51 }) 52 } 53 stop(&self) -> bool54 fn stop(&self) -> bool { 55 let backend = self.port.get_backend_device(); 56 if backend.is_some() { 57 self.transfer_manager.cancel_all(); 58 true 59 } else { 60 false 61 } 62 } 63 } 64 65 impl TransferRingController { new( mem: GuestMemory, port: Arc<UsbPort>, event_loop: Arc<EventLoop>, interrupter: Arc<Mutex<Interrupter>>, slot_id: u8, endpoint_id: u8, ) -> Result<Arc<TransferRingController>, TransferRingControllerError>66 pub fn new( 67 mem: GuestMemory, 68 port: Arc<UsbPort>, 69 event_loop: Arc<EventLoop>, 70 interrupter: Arc<Mutex<Interrupter>>, 71 slot_id: u8, 72 endpoint_id: u8, 73 ) -> Result<Arc<TransferRingController>, TransferRingControllerError> { 74 RingBufferController::new_with_handler( 75 format!("transfer ring slot_{} ep_{}", slot_id, endpoint_id), 76 mem.clone(), 77 event_loop, 78 TransferRingTrbHandler { 79 mem, 80 port, 81 interrupter, 82 slot_id, 83 endpoint_id, 84 transfer_manager: XhciTransferManager::new(), 85 }, 86 ) 87 } 88 } 89