• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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