Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/usb/backend/host_backend/host_device.rs
5394 views
1
// Copyright 2019 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::collections::HashMap;
6
use std::mem;
7
use std::sync::Arc;
8
use std::sync::RwLock;
9
10
use base::debug;
11
use base::error;
12
use base::AsRawDescriptor;
13
use base::RawDescriptor;
14
use sync::Mutex;
15
use usb_util::ConfigDescriptorTree;
16
use usb_util::DescriptorHeader;
17
use usb_util::Device;
18
use usb_util::DeviceDescriptorTree;
19
use usb_util::DeviceSpeed;
20
use usb_util::InterfaceDescriptor;
21
use usb_util::Transfer;
22
use usb_util::TransferBuffer;
23
use usb_util::TransferHandle;
24
use usb_util::TransferStatus;
25
use usb_util::UsbRequestSetup;
26
use zerocopy::IntoBytes;
27
28
use crate::usb::backend::device::BackendDevice;
29
use crate::usb::backend::device::DeviceState;
30
use crate::usb::backend::endpoint::ControlEndpointState;
31
use crate::usb::backend::endpoint::UsbEndpoint;
32
use crate::usb::backend::error::Error;
33
use crate::usb::backend::error::Result;
34
use crate::usb::backend::transfer::BackendTransfer;
35
use crate::usb::backend::transfer::BackendTransferHandle;
36
use crate::usb::backend::transfer::BackendTransferType;
37
use crate::usb::backend::transfer::ControlTransferState;
38
use crate::usb::backend::transfer::GenericTransferHandle;
39
use crate::usb::xhci::scatter_gather_buffer::ScatterGatherBuffer;
40
use crate::usb::xhci::xhci_backend_device::BackendType;
41
use crate::usb::xhci::xhci_backend_device::UsbDeviceAddress;
42
use crate::usb::xhci::xhci_backend_device::XhciBackendDevice;
43
use crate::utils::EventLoop;
44
45
/// Host device is a device connected to host.
46
pub struct HostDevice {
47
pub device: Arc<Mutex<Device>>,
48
alt_settings: HashMap<u8, u8>,
49
claimed_interfaces: Vec<u8>,
50
state: Arc<RwLock<DeviceState>>,
51
control_transfer_state: Arc<RwLock<ControlTransferState>>,
52
}
53
54
impl HostDevice {
55
/// Create a new host device.
56
pub fn new(device: Arc<Mutex<Device>>, state: DeviceState) -> Result<HostDevice> {
57
let control_transfer_state = ControlTransferState {
58
ctl_ep_state: ControlEndpointState::SetupStage,
59
control_request_setup: UsbRequestSetup::new(0, 0, 0, 0, 0),
60
executed: false,
61
};
62
let mut host_device = HostDevice {
63
device,
64
alt_settings: HashMap::new(),
65
claimed_interfaces: vec![],
66
state: Arc::new(RwLock::new(state)),
67
control_transfer_state: Arc::new(RwLock::new(control_transfer_state)),
68
};
69
70
let config_descriptor = host_device.get_active_config_descriptor()?;
71
host_device.claim_interfaces(&config_descriptor);
72
73
Ok(host_device)
74
}
75
76
// Execute a Get Descriptor control request with type Configuration.
77
// This function is used to return a filtered version of the host device's configuration
78
// descriptor that only includes the interfaces in `self.claimed_interfaces`.
79
pub fn get_config_descriptor_filtered(
80
&mut self,
81
buffer: &ScatterGatherBuffer,
82
descriptor_index: u8,
83
) -> Result<(TransferStatus, u32)> {
84
let _trace = cros_tracing::trace_event!(
85
USB,
86
"host_device get_config_descriptor_filtered",
87
descriptor_index
88
);
89
90
let config_descriptor = self.get_config_descriptor_by_index(descriptor_index)?;
91
92
let device_descriptor = self.get_device_descriptor_tree()?;
93
let config_start = config_descriptor.offset();
94
let config_end = config_start + config_descriptor.wTotalLength as usize;
95
let mut descriptor_data = device_descriptor.raw()[config_start..config_end].to_vec();
96
97
if config_descriptor.bConfigurationValue == self.get_active_configuration()? {
98
for i in 0..config_descriptor.bNumInterfaces {
99
if !self.claimed_interfaces.contains(&i) {
100
// Rewrite descriptors for unclaimed interfaces to vendor-specific class.
101
// This prevents them from being recognized by the guest drivers.
102
let alt_setting = self.alt_settings.get(&i).unwrap_or(&0);
103
let interface = config_descriptor
104
.get_interface_descriptor(i, *alt_setting)
105
.ok_or(Error::GetInterfaceDescriptor(i, *alt_setting))?;
106
let mut interface_data: InterfaceDescriptor = **interface;
107
interface_data.bInterfaceClass = 0xFF;
108
interface_data.bInterfaceSubClass = 0xFF;
109
interface_data.bInterfaceProtocol = 0xFF;
110
111
let interface_start =
112
interface.offset() + mem::size_of::<DescriptorHeader>() - config_start;
113
let interface_end = interface_start + mem::size_of::<InterfaceDescriptor>();
114
descriptor_data[interface_start..interface_end]
115
.copy_from_slice(interface_data.as_bytes());
116
}
117
}
118
}
119
120
let bytes_transferred = buffer.write(&descriptor_data).map_err(Error::WriteBuffer)?;
121
Ok((TransferStatus::Completed, bytes_transferred as u32))
122
}
123
124
pub fn set_interface(&mut self, interface: u8, alt_setting: u8) -> Result<TransferStatus> {
125
let _trace = cros_tracing::trace_event!(USB, "host_device set_interface");
126
// It's a standard, set_interface, interface request.
127
self.device
128
.lock()
129
.set_interface_alt_setting(interface, alt_setting)
130
.map_err(Error::SetInterfaceAltSetting)?;
131
self.alt_settings.insert(interface, alt_setting);
132
let config = self.get_active_configuration()?;
133
let config_descriptor = self.get_config_descriptor(config)?;
134
self.create_endpoints(&config_descriptor)?;
135
Ok(TransferStatus::Completed)
136
}
137
138
pub fn claim_interfaces(&mut self, config_descriptor: &ConfigDescriptorTree) {
139
for i in 0..config_descriptor.num_interfaces() {
140
match self.device.lock().claim_interface(i) {
141
Ok(()) => {
142
debug!("usb: claimed interface {}", i);
143
self.claimed_interfaces.push(i);
144
}
145
Err(e) => {
146
error!("unable to claim interface {}: {:?}", i, e);
147
}
148
}
149
}
150
}
151
152
pub fn release_interfaces(&mut self) {
153
let device_locked = self.device.lock();
154
for i in &self.claimed_interfaces {
155
if let Err(e) = device_locked.release_interface(*i) {
156
error!("could not release interface: {:?}", e);
157
}
158
}
159
self.claimed_interfaces = Vec::new();
160
}
161
}
162
163
impl Drop for HostDevice {
164
fn drop(&mut self) {
165
self.release_interfaces();
166
}
167
}
168
169
impl AsRawDescriptor for HostDevice {
170
fn as_raw_descriptor(&self) -> RawDescriptor {
171
self.device.lock().as_raw_descriptor()
172
}
173
}
174
175
impl GenericTransferHandle for TransferHandle {
176
fn cancel(&self) -> Result<()> {
177
TransferHandle::cancel(self).map_err(Error::TransferHandle)
178
}
179
}
180
181
impl BackendDevice for HostDevice {
182
fn submit_backend_transfer(
183
&mut self,
184
transfer: BackendTransferType,
185
) -> Result<BackendTransferHandle> {
186
match transfer {
187
BackendTransferType::HostDevice(transfer) => self
188
.device
189
.lock()
190
.submit_transfer(transfer)
191
.map_err(Error::CreateTransfer)
192
.map(BackendTransferHandle::new),
193
_ => Err(Error::MalformedBackendTransfer),
194
}
195
}
196
197
fn detach_event_handler(&self, event_loop: &Arc<EventLoop>) -> Result<()> {
198
event_loop
199
.remove_event_for_descriptor(self)
200
.map_err(Error::RemoveFromEventLoop)
201
}
202
203
fn request_transfer_buffer(&mut self, size: usize) -> TransferBuffer {
204
match self.device.lock().reserve_dma_buffer(size) {
205
Ok(dmabuf) => TransferBuffer::Dma(dmabuf),
206
Err(_) => TransferBuffer::Vector(vec![0u8; size]),
207
}
208
}
209
210
fn build_bulk_transfer(
211
&mut self,
212
ep_addr: u8,
213
transfer_buffer: TransferBuffer,
214
stream_id: Option<u16>,
215
) -> Result<BackendTransferType> {
216
Ok(BackendTransferType::HostDevice(
217
Transfer::new_bulk(ep_addr, transfer_buffer, stream_id)
218
.map_err(Error::CreateTransfer)?,
219
))
220
}
221
222
fn build_interrupt_transfer(
223
&mut self,
224
ep_addr: u8,
225
transfer_buffer: TransferBuffer,
226
) -> Result<BackendTransferType> {
227
Ok(BackendTransferType::HostDevice(
228
Transfer::new_interrupt(ep_addr, transfer_buffer).map_err(Error::CreateTransfer)?,
229
))
230
}
231
232
fn get_control_transfer_state(&mut self) -> Arc<RwLock<ControlTransferState>> {
233
self.control_transfer_state.clone()
234
}
235
236
fn get_device_state(&mut self) -> Arc<RwLock<DeviceState>> {
237
self.state.clone()
238
}
239
240
fn get_active_config_descriptor(&mut self) -> Result<ConfigDescriptorTree> {
241
let cur_config = self.get_active_configuration()?;
242
self.get_config_descriptor(cur_config)
243
}
244
245
fn get_config_descriptor(&mut self, config: u8) -> Result<ConfigDescriptorTree> {
246
self.device
247
.lock()
248
.get_config_descriptor(config)
249
.map_err(Error::GetActiveConfig)
250
}
251
252
fn get_config_descriptor_by_index(&mut self, config_index: u8) -> Result<ConfigDescriptorTree> {
253
self.device
254
.lock()
255
.get_config_descriptor_by_index(config_index)
256
.map_err(Error::GetConfigDescriptor)
257
}
258
259
fn get_device_descriptor_tree(&mut self) -> Result<DeviceDescriptorTree> {
260
Ok(self.device.lock().get_device_descriptor_tree().clone())
261
}
262
263
fn get_active_configuration(&mut self) -> Result<u8> {
264
self.device
265
.lock()
266
.get_active_configuration()
267
.map_err(Error::GetActiveConfig)
268
}
269
270
fn set_active_configuration(&mut self, config: u8) -> Result<()> {
271
self.device
272
.lock()
273
.set_active_configuration(config)
274
.map_err(Error::SetActiveConfig)
275
}
276
277
fn clear_feature(&mut self, value: u16, index: u16) -> Result<TransferStatus> {
278
// It's a standard, clear_feature, endpoint request.
279
const STD_FEATURE_ENDPOINT_HALT: u16 = 0;
280
if value == STD_FEATURE_ENDPOINT_HALT {
281
self.device
282
.lock()
283
.clear_halt(index as u8)
284
.map_err(Error::ClearHalt)?;
285
}
286
Ok(TransferStatus::Completed)
287
}
288
289
fn create_endpoints(&mut self, config_descriptor: &ConfigDescriptorTree) -> Result<()> {
290
let mut endpoints = Vec::new();
291
let device_state = self.get_device_state();
292
for i in &self.claimed_interfaces {
293
let alt_setting = self.alt_settings.get(i).unwrap_or(&0);
294
let interface = config_descriptor
295
.get_interface_descriptor(*i, *alt_setting)
296
.ok_or(Error::GetInterfaceDescriptor(*i, *alt_setting))?;
297
for ep_idx in 0..interface.bNumEndpoints {
298
let ep_dp = interface
299
.get_endpoint_descriptor(ep_idx)
300
.ok_or(Error::GetEndpointDescriptor(ep_idx))?;
301
let ep_num = ep_dp.get_endpoint_number();
302
if ep_num == 0 {
303
continue;
304
}
305
let direction = ep_dp.get_direction();
306
let ty = ep_dp.get_endpoint_type().ok_or(Error::GetEndpointType)?;
307
endpoints.push(UsbEndpoint::new(
308
device_state.read().unwrap().fail_handle.clone(),
309
device_state.read().unwrap().job_queue.clone(),
310
ep_num,
311
direction,
312
ty,
313
));
314
}
315
}
316
device_state.write().unwrap().endpoints = endpoints;
317
Ok(())
318
}
319
}
320
321
impl XhciBackendDevice for HostDevice {
322
fn get_backend_type(&self) -> BackendType {
323
let d = match self.device.lock().get_device_descriptor() {
324
Ok(d) => d,
325
Err(_) => return BackendType::Usb2,
326
};
327
328
// See definition of bcdUsb.
329
const USB3_MASK: u16 = 0x0300;
330
match d.bcdUSB & USB3_MASK {
331
USB3_MASK => BackendType::Usb3,
332
_ => BackendType::Usb2,
333
}
334
}
335
336
fn get_vid(&self) -> u16 {
337
match self.device.lock().get_device_descriptor() {
338
Ok(d) => d.idVendor,
339
Err(e) => {
340
error!("cannot get device descriptor: {:?}", e);
341
0
342
}
343
}
344
}
345
346
fn get_pid(&self) -> u16 {
347
match self.device.lock().get_device_descriptor() {
348
Ok(d) => d.idProduct,
349
Err(e) => {
350
error!("cannot get device descriptor: {:?}", e);
351
0
352
}
353
}
354
}
355
356
fn set_address(&mut self, _address: UsbDeviceAddress) {
357
// It's a standard, set_address, device request. We do nothing here. As described in XHCI
358
// spec. See set address command ring trb.
359
debug!(
360
"usb set address control transfer is received with address: {}",
361
_address
362
);
363
}
364
365
fn reset(&mut self) -> Result<()> {
366
self.device.lock().reset().map_err(Error::Reset)
367
}
368
369
fn get_speed(&self) -> Option<DeviceSpeed> {
370
self.device.lock().get_speed().unwrap_or(None)
371
}
372
373
fn alloc_streams(&self, ep: u8, num_streams: u16) -> Result<()> {
374
self.device
375
.lock()
376
.alloc_streams(ep, num_streams)
377
.map_err(Error::AllocStreams)
378
}
379
380
fn free_streams(&self, ep: u8) -> Result<()> {
381
self.device
382
.lock()
383
.free_streams(ep)
384
.map_err(Error::FreeStreams)
385
}
386
387
fn stop(&mut self) {
388
// NOOP, nothing to do
389
}
390
}
391
392
impl BackendTransfer for Transfer {
393
fn status(&self) -> TransferStatus {
394
Transfer::status(self)
395
}
396
397
fn actual_length(&self) -> usize {
398
Transfer::actual_length(self)
399
}
400
401
fn buffer(&self) -> &TransferBuffer {
402
&self.buffer
403
}
404
405
fn set_callback<C: 'static + Fn(BackendTransferType) + Send + Sync>(&mut self, cb: C) {
406
Transfer::set_callback(self, move |t| cb(BackendTransferType::HostDevice(t)));
407
}
408
}
409
410