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