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 std::mem::drop; 6 use std::sync::Arc; 7 use sync::Mutex; 8 9 use super::error::*; 10 use super::usb_endpoint::UsbEndpoint; 11 use super::utils::{submit_transfer, update_transfer_state}; 12 use crate::usb::xhci::scatter_gather_buffer::ScatterGatherBuffer; 13 use crate::usb::xhci::xhci_backend_device::{BackendType, UsbDeviceAddress, XhciBackendDevice}; 14 use crate::usb::xhci::xhci_transfer::{XhciTransfer, XhciTransferState, XhciTransferType}; 15 use crate::utils::AsyncJobQueue; 16 use crate::utils::FailHandle; 17 use std::collections::HashMap; 18 use sys_util::{error, warn}; 19 use usb_util::device_handle::DeviceHandle; 20 use usb_util::error::Error as LibUsbError; 21 use usb_util::libusb_device::LibUsbDevice; 22 use usb_util::types::{ 23 ControlRequestDataPhaseTransferDirection, ControlRequestRecipient, StandardControlRequest, 24 UsbRequestSetup, 25 }; 26 use usb_util::usb_transfer::{ 27 control_transfer, ControlTransferBuffer, TransferStatus, UsbTransfer, 28 }; 29 30 #[derive(PartialEq)] 31 pub enum ControlEndpointState { 32 /// Control endpoint should receive setup stage next. 33 SetupStage, 34 /// Control endpoint should receive data stage next. 35 DataStage, 36 /// Control endpoint should receive status stage next. 37 StatusStage, 38 } 39 40 /// Host device is a device connected to host. 41 pub struct HostDevice { 42 fail_handle: Arc<dyn FailHandle>, 43 // Endpoints only contains data endpoints (1 to 30). Control transfers are handled at device 44 // level. 45 endpoints: Vec<UsbEndpoint>, 46 device: LibUsbDevice, 47 device_handle: Arc<Mutex<DeviceHandle>>, 48 ctl_ep_state: ControlEndpointState, 49 alt_settings: HashMap<u16, u16>, 50 claimed_interfaces: Vec<i32>, 51 control_request_setup: UsbRequestSetup, 52 executed: bool, 53 job_queue: Arc<AsyncJobQueue>, 54 } 55 56 impl Drop for HostDevice { drop(&mut self)57 fn drop(&mut self) { 58 self.release_interfaces(); 59 } 60 } 61 62 impl HostDevice { 63 /// Create a new host device. new( fail_handle: Arc<dyn FailHandle>, job_queue: Arc<AsyncJobQueue>, device: LibUsbDevice, device_handle: DeviceHandle, ) -> HostDevice64 pub fn new( 65 fail_handle: Arc<dyn FailHandle>, 66 job_queue: Arc<AsyncJobQueue>, 67 device: LibUsbDevice, 68 device_handle: DeviceHandle, 69 ) -> HostDevice { 70 HostDevice { 71 fail_handle, 72 endpoints: vec![], 73 device, 74 device_handle: Arc::new(Mutex::new(device_handle)), 75 ctl_ep_state: ControlEndpointState::SetupStage, 76 alt_settings: HashMap::new(), 77 claimed_interfaces: vec![], 78 control_request_setup: UsbRequestSetup::new(0, 0, 0, 0, 0), 79 executed: false, 80 job_queue, 81 } 82 } 83 get_interface_number_of_active_config(&self) -> i3284 fn get_interface_number_of_active_config(&self) -> i32 { 85 match self.device.get_active_config_descriptor() { 86 Err(LibUsbError::NotFound) => { 87 usb_debug!("device is in unconfigured state"); 88 0 89 } 90 Err(e) => { 91 // device might be disconnected now. 92 error!("unexpected error: {:?}", e); 93 0 94 } 95 Ok(descriptor) => descriptor.bNumInterfaces as i32, 96 } 97 } 98 release_interfaces(&mut self)99 fn release_interfaces(&mut self) { 100 for i in &self.claimed_interfaces { 101 if let Err(e) = self.device_handle.lock().release_interface(*i) { 102 error!("could not release interface: {:?}", e); 103 } 104 } 105 self.claimed_interfaces = Vec::new(); 106 } 107 108 // Check for requests that should be intercepted and emulated using libusb 109 // functions rather than passed directly to the device. 110 // Returns true if the request has been intercepted or false if the request 111 // should be passed through to the device. intercepted_control_transfer(&mut self, xhci_transfer: &XhciTransfer) -> Result<bool>112 fn intercepted_control_transfer(&mut self, xhci_transfer: &XhciTransfer) -> Result<bool> { 113 let direction = self.control_request_setup.get_direction(); 114 let recipient = self.control_request_setup.get_recipient(); 115 let standard_request = self.control_request_setup.get_standard_request(); 116 117 if direction != ControlRequestDataPhaseTransferDirection::HostToDevice { 118 // Only host to device requests are intercepted currently. 119 return Ok(false); 120 } 121 122 let status = match standard_request { 123 Some(StandardControlRequest::SetAddress) => { 124 if recipient != ControlRequestRecipient::Device { 125 return Ok(false); 126 } 127 usb_debug!("host device handling set address"); 128 let addr = self.control_request_setup.value as u32; 129 self.set_address(addr); 130 TransferStatus::Completed 131 } 132 Some(StandardControlRequest::SetConfiguration) => { 133 if recipient != ControlRequestRecipient::Device { 134 return Ok(false); 135 } 136 usb_debug!("host device handling set config"); 137 self.set_config()? 138 } 139 Some(StandardControlRequest::SetInterface) => { 140 if recipient != ControlRequestRecipient::Interface { 141 return Ok(false); 142 } 143 usb_debug!("host device handling set interface"); 144 self.set_interface()? 145 } 146 Some(StandardControlRequest::ClearFeature) => { 147 if recipient != ControlRequestRecipient::Endpoint { 148 return Ok(false); 149 } 150 usb_debug!("host device handling clear feature"); 151 self.clear_feature()? 152 } 153 _ => { 154 // Other requests will be passed through to the device. 155 return Ok(false); 156 } 157 }; 158 159 xhci_transfer 160 .on_transfer_complete(&status, 0) 161 .map_err(Error::TransferComplete)?; 162 Ok(true) 163 } 164 execute_control_transfer( &mut self, xhci_transfer: Arc<XhciTransfer>, buffer: Option<ScatterGatherBuffer>, ) -> Result<()>165 fn execute_control_transfer( 166 &mut self, 167 xhci_transfer: Arc<XhciTransfer>, 168 buffer: Option<ScatterGatherBuffer>, 169 ) -> Result<()> { 170 let mut control_transfer = control_transfer(0); 171 control_transfer 172 .buffer_mut() 173 .set_request_setup(&self.control_request_setup); 174 175 if self.intercepted_control_transfer(&xhci_transfer)? { 176 return Ok(()); 177 } 178 179 let direction = self.control_request_setup.get_direction(); 180 let buffer = if direction == ControlRequestDataPhaseTransferDirection::HostToDevice { 181 if let Some(buffer) = buffer { 182 buffer 183 .read(&mut control_transfer.buffer_mut().data_buffer) 184 .map_err(Error::ReadBuffer)?; 185 } 186 // buffer is consumed here for HostToDevice transfers. 187 None 188 } else { 189 // buffer will be used later in the callback for DeviceToHost transfers. 190 buffer 191 }; 192 193 let tmp_transfer = xhci_transfer.clone(); 194 let callback = move |t: UsbTransfer<ControlTransferBuffer>| { 195 usb_debug!("setup token control transfer callback invoked"); 196 update_transfer_state(&xhci_transfer, &t)?; 197 let state = xhci_transfer.state().lock(); 198 match *state { 199 XhciTransferState::Cancelled => { 200 usb_debug!("transfer cancelled"); 201 drop(state); 202 xhci_transfer 203 .on_transfer_complete(&TransferStatus::Cancelled, 0) 204 .map_err(Error::TransferComplete)?; 205 } 206 XhciTransferState::Completed => { 207 let status = t.status(); 208 let actual_length = t.actual_length(); 209 if direction == ControlRequestDataPhaseTransferDirection::DeviceToHost { 210 if let Some(buffer) = &buffer { 211 buffer 212 .write(&t.buffer().data_buffer) 213 .map_err(Error::WriteBuffer)?; 214 } 215 } 216 drop(state); 217 usb_debug!("transfer completed with actual length {}", actual_length); 218 xhci_transfer 219 .on_transfer_complete(&status, actual_length as u32) 220 .map_err(Error::TransferComplete)?; 221 } 222 _ => { 223 // update_transfer_state is already invoked before match. 224 // This transfer could only be `Cancelled` or `Completed`. 225 // Any other state means there is a bug in crosvm implementation. 226 error!("should not take this branch"); 227 return Err(Error::BadXhciTransferState); 228 } 229 } 230 Ok(()) 231 }; 232 233 let fail_handle = self.fail_handle.clone(); 234 control_transfer.set_callback( 235 move |t: UsbTransfer<ControlTransferBuffer>| match callback(t) { 236 Ok(_) => {} 237 Err(e) => { 238 error!("control transfer callback failed {:?}", e); 239 fail_handle.fail(); 240 } 241 }, 242 ); 243 submit_transfer( 244 self.fail_handle.clone(), 245 &self.job_queue, 246 tmp_transfer, 247 &self.device_handle, 248 control_transfer, 249 ) 250 } 251 handle_control_transfer(&mut self, transfer: XhciTransfer) -> Result<()>252 fn handle_control_transfer(&mut self, transfer: XhciTransfer) -> Result<()> { 253 let xhci_transfer = Arc::new(transfer); 254 match xhci_transfer 255 .get_transfer_type() 256 .map_err(Error::GetXhciTransferType)? 257 { 258 XhciTransferType::SetupStage(setup) => { 259 if self.ctl_ep_state != ControlEndpointState::SetupStage { 260 error!("Control endpoint is in an inconsistant state"); 261 return Ok(()); 262 } 263 usb_debug!("setup stage setup buffer: {:?}", setup); 264 self.control_request_setup = setup; 265 xhci_transfer 266 .on_transfer_complete(&TransferStatus::Completed, 0) 267 .map_err(Error::TransferComplete)?; 268 self.ctl_ep_state = ControlEndpointState::DataStage; 269 } 270 XhciTransferType::DataStage(buffer) => { 271 if self.ctl_ep_state != ControlEndpointState::DataStage { 272 error!("Control endpoint is in an inconsistant state"); 273 return Ok(()); 274 } 275 // Requests with a DataStage will be executed here. 276 // Requests without a DataStage will be executed in StatusStage. 277 self.execute_control_transfer(xhci_transfer, Some(buffer))?; 278 self.executed = true; 279 self.ctl_ep_state = ControlEndpointState::StatusStage; 280 } 281 XhciTransferType::StatusStage => { 282 if self.ctl_ep_state == ControlEndpointState::SetupStage { 283 error!("Control endpoint is in an inconsistant state"); 284 return Ok(()); 285 } 286 if self.executed { 287 // Request was already executed during DataStage. 288 // Just complete the StatusStage transfer. 289 xhci_transfer 290 .on_transfer_complete(&TransferStatus::Completed, 0) 291 .map_err(Error::TransferComplete)?; 292 } else { 293 // Execute the request now since there was no DataStage. 294 self.execute_control_transfer(xhci_transfer, None)?; 295 } 296 self.executed = false; 297 self.ctl_ep_state = ControlEndpointState::SetupStage; 298 } 299 _ => { 300 // Non control transfer should not be handled in this function. 301 error!("Non control (could be noop) transfer sent to control endpoint."); 302 xhci_transfer 303 .on_transfer_complete(&TransferStatus::Completed, 0) 304 .map_err(Error::TransferComplete)?; 305 } 306 } 307 Ok(()) 308 } 309 set_config(&mut self) -> Result<TransferStatus>310 fn set_config(&mut self) -> Result<TransferStatus> { 311 // It's a standard, set_config, device request. 312 let config = (self.control_request_setup.value & 0xff) as i32; 313 usb_debug!( 314 "Set config control transfer is received with config: {}", 315 config 316 ); 317 self.release_interfaces(); 318 let cur_config = self 319 .device_handle 320 .lock() 321 .get_active_configuration() 322 .map_err(Error::GetActiveConfig)?; 323 usb_debug!("current config is: {}", cur_config); 324 if config != cur_config { 325 self.device_handle 326 .lock() 327 .set_active_configuration(config) 328 .map_err(Error::SetActiveConfig)?; 329 } 330 self.claim_interfaces(); 331 self.create_endpoints()?; 332 Ok(TransferStatus::Completed) 333 } 334 set_interface(&mut self) -> Result<TransferStatus>335 fn set_interface(&mut self) -> Result<TransferStatus> { 336 usb_debug!("set interface"); 337 // It's a standard, set_interface, interface request. 338 let interface = self.control_request_setup.index; 339 let alt_setting = self.control_request_setup.value; 340 self.device_handle 341 .lock() 342 .set_interface_alt_setting(interface as i32, alt_setting as i32) 343 .map_err(Error::SetInterfaceAltSetting)?; 344 self.alt_settings.insert(interface, alt_setting); 345 self.create_endpoints()?; 346 Ok(TransferStatus::Completed) 347 } 348 clear_feature(&mut self) -> Result<TransferStatus>349 fn clear_feature(&mut self) -> Result<TransferStatus> { 350 usb_debug!("clear feature"); 351 let request_setup = &self.control_request_setup; 352 // It's a standard, clear_feature, endpoint request. 353 const STD_FEATURE_ENDPOINT_HALT: u16 = 0; 354 if request_setup.value == STD_FEATURE_ENDPOINT_HALT { 355 self.device_handle 356 .lock() 357 .clear_halt(request_setup.index as u8) 358 .map_err(Error::ClearHalt)?; 359 } 360 Ok(TransferStatus::Completed) 361 } 362 claim_interfaces(&mut self)363 fn claim_interfaces(&mut self) { 364 for i in 0..self.get_interface_number_of_active_config() { 365 match self.device_handle.lock().claim_interface(i) { 366 Ok(()) => { 367 usb_debug!("claimed interface {}", i); 368 self.claimed_interfaces.push(i); 369 } 370 Err(e) => { 371 error!("unable to claim interface {}: {:?}", i, e); 372 } 373 } 374 } 375 } 376 create_endpoints(&mut self) -> Result<()>377 fn create_endpoints(&mut self) -> Result<()> { 378 self.endpoints = Vec::new(); 379 let config_descriptor = match self.device.get_active_config_descriptor() { 380 Err(e) => { 381 error!("device might be disconnected: {:?}", e); 382 return Ok(()); 383 } 384 Ok(descriptor) => descriptor, 385 }; 386 for i in &self.claimed_interfaces { 387 let alt_setting = self.alt_settings.get(&(*i as u16)).unwrap_or(&0); 388 let interface = config_descriptor 389 .get_interface_descriptor(*i as u8, *alt_setting as i32) 390 .ok_or(Error::GetInterfaceDescriptor((*i, *alt_setting)))?; 391 for ep_idx in 0..interface.bNumEndpoints { 392 let ep_dp = interface 393 .endpoint_descriptor(ep_idx) 394 .ok_or(Error::GetEndpointDescriptor(ep_idx))?; 395 let ep_num = ep_dp.get_endpoint_number(); 396 if ep_num == 0 { 397 usb_debug!("endpoint 0 in endpoint descriptors"); 398 continue; 399 } 400 let direction = ep_dp.get_direction(); 401 let ty = ep_dp.get_endpoint_type().ok_or(Error::GetEndpointType)?; 402 self.endpoints.push(UsbEndpoint::new( 403 self.fail_handle.clone(), 404 self.job_queue.clone(), 405 self.device_handle.clone(), 406 ep_num, 407 direction, 408 ty, 409 )); 410 } 411 } 412 Ok(()) 413 } 414 submit_transfer_helper(&mut self, transfer: XhciTransfer) -> Result<()>415 fn submit_transfer_helper(&mut self, transfer: XhciTransfer) -> Result<()> { 416 if transfer.get_endpoint_number() == 0 { 417 return self.handle_control_transfer(transfer); 418 } 419 for ep in &self.endpoints { 420 if ep.match_ep(transfer.get_endpoint_number(), transfer.get_transfer_dir()) { 421 return ep.handle_transfer(transfer); 422 } 423 } 424 warn!("Could not find endpoint for transfer"); 425 transfer 426 .on_transfer_complete(&TransferStatus::Error, 0) 427 .map_err(Error::TransferComplete) 428 } 429 } 430 431 impl XhciBackendDevice for HostDevice { get_backend_type(&self) -> BackendType432 fn get_backend_type(&self) -> BackendType { 433 let d = match self.device.get_device_descriptor() { 434 Ok(d) => d, 435 Err(_) => return BackendType::Usb2, 436 }; 437 438 // See definition of bcdUsb. 439 const USB3_MASK: u16 = 0x0300; 440 match d.bcdUSB & USB3_MASK { 441 USB3_MASK => BackendType::Usb3, 442 _ => BackendType::Usb2, 443 } 444 } 445 host_bus(&self) -> u8446 fn host_bus(&self) -> u8 { 447 self.device.get_bus_number() 448 } 449 host_address(&self) -> u8450 fn host_address(&self) -> u8 { 451 self.device.get_address() 452 } 453 get_vid(&self) -> u16454 fn get_vid(&self) -> u16 { 455 match self.device.get_device_descriptor() { 456 Ok(d) => d.idVendor, 457 Err(e) => { 458 error!("cannot get device descriptor: {:?}", e); 459 0 460 } 461 } 462 } 463 get_pid(&self) -> u16464 fn get_pid(&self) -> u16 { 465 match self.device.get_device_descriptor() { 466 Ok(d) => d.idProduct, 467 Err(e) => { 468 error!("cannot get device descriptor: {:?}", e); 469 0 470 } 471 } 472 } 473 submit_transfer(&mut self, transfer: XhciTransfer) -> std::result::Result<(), ()>474 fn submit_transfer(&mut self, transfer: XhciTransfer) -> std::result::Result<(), ()> { 475 self.submit_transfer_helper(transfer).map_err(|e| { 476 error!("failed to submit transfer: {}", e); 477 }) 478 } 479 set_address(&mut self, _address: UsbDeviceAddress)480 fn set_address(&mut self, _address: UsbDeviceAddress) { 481 // It's a standard, set_address, device request. We do nothing here. As described in XHCI 482 // spec. See set address command ring trb. 483 usb_debug!( 484 "Set address control transfer is received with address: {}", 485 _address 486 ); 487 } 488 reset(&mut self) -> std::result::Result<(), ()>489 fn reset(&mut self) -> std::result::Result<(), ()> { 490 usb_debug!("resetting host device"); 491 let result = self.device_handle.lock().reset(); 492 match result { 493 Err(LibUsbError::NotFound) => { 494 // libusb will return NotFound if it fails to re-claim 495 // the interface after the reset. 496 Ok(()) 497 } 498 _ => result.map_err(|e| { 499 error!("failed to reset device: {:?}", e); 500 }), 501 } 502 } 503 } 504