• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 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 assertions::const_assert;
6 use data_model::DataInit;
7 
8 use std::mem::size_of;
9 
10 use crate::bindings;
11 
12 /// Speed of usb device. See usb spec for more details.
13 #[derive(Debug)]
14 pub enum Speed {
15     /// The OS doesn't report or know the device speed.
16     Unknown,
17     /// The device is operating at low speed (1.5MBit/s).
18     Low,
19     /// The device is operating at full speed (12MBit/s).
20     Full,
21     /// The device is operating at high speed (480MBit/s).
22     High,
23     /// The device is operating at super speed (5000MBit/s).
24     Super,
25 }
26 
27 impl From<bindings::libusb_speed> for Speed {
from(speed: bindings::libusb_speed) -> Speed28     fn from(speed: bindings::libusb_speed) -> Speed {
29         match speed {
30             bindings::LIBUSB_SPEED_LOW => Speed::Low,
31             bindings::LIBUSB_SPEED_FULL => Speed::Full,
32             bindings::LIBUSB_SPEED_HIGH => Speed::High,
33             bindings::LIBUSB_SPEED_SUPER => Speed::Super,
34             _ => Speed::Unknown,
35         }
36     }
37 }
38 
39 /// Endpoint types.
40 #[derive(PartialEq)]
41 pub enum EndpointType {
42     Control,
43     Isochronous,
44     Bulk,
45     Interrupt,
46 }
47 
48 /// Endpoint Directions.
49 #[derive(PartialEq, Clone, Copy)]
50 pub enum EndpointDirection {
51     HostToDevice = 0,
52     DeviceToHost = 1,
53 }
54 /// Endpoint direction offset.
55 pub const ENDPOINT_DIRECTION_OFFSET: u8 = 7;
56 
57 /// Offset of data phase transfer direction.
58 pub const DATA_PHASE_DIRECTION_OFFSET: u8 = 7;
59 /// Bit mask of data phase transfer direction.
60 pub const DATA_PHASE_DIRECTION: u8 = 1u8 << DATA_PHASE_DIRECTION_OFFSET;
61 // Types of data phase transfer directions.
62 #[derive(Copy, Clone, PartialEq)]
63 pub enum ControlRequestDataPhaseTransferDirection {
64     HostToDevice = 0,
65     DeviceToHost = 1,
66 }
67 
68 /// Offset of control request type.
69 pub const CONTROL_REQUEST_TYPE_OFFSET: u8 = 5;
70 /// Bit mask of control request type.
71 pub const CONTROL_REQUEST_TYPE: u8 = 0b11 << CONTROL_REQUEST_TYPE_OFFSET;
72 /// Request types.
73 #[derive(PartialEq)]
74 pub enum ControlRequestType {
75     Standard = 0,
76     Class = 1,
77     Vendor = 2,
78     Reserved = 3,
79 }
80 
81 /// Recipient type bits.
82 pub const REQUEST_RECIPIENT_TYPE: u8 = 0b1111;
83 /// Recipient type of control request.
84 #[derive(PartialEq)]
85 pub enum ControlRequestRecipient {
86     Device = 0,
87     Interface = 1,
88     Endpoint = 2,
89     Other = 3,
90     Reserved,
91 }
92 
93 /// Standard request defined in usb spec.
94 #[derive(PartialEq)]
95 pub enum StandardControlRequest {
96     GetStatus = 0x00,
97     ClearFeature = 0x01,
98     SetFeature = 0x03,
99     SetAddress = 0x05,
100     GetDescriptor = 0x06,
101     SetDescriptor = 0x07,
102     GetConfiguration = 0x08,
103     SetConfiguration = 0x09,
104     GetInterface = 0x0a,
105     SetInterface = 0x11,
106     SynchFrame = 0x12,
107 }
108 
109 /// RequestSetup is first part of control transfer buffer.
110 #[repr(C, packed)]
111 #[derive(Copy, Clone, Debug)]
112 pub struct UsbRequestSetup {
113     // USB Device Request. USB spec. rev. 2.0 9.3
114     pub request_type: u8, // bmRequestType
115     pub request: u8,      // bRequest
116     pub value: u16,       // wValue
117     pub index: u16,       // wIndex
118     pub length: u16,      // wLength
119 }
120 
_assert()121 fn _assert() {
122     const_assert!(size_of::<UsbRequestSetup>() == 8);
123 }
124 
125 unsafe impl DataInit for UsbRequestSetup {}
126 
127 impl UsbRequestSetup {
new( request_type: u8, request: u8, value: u16, index: u16, length: u16, ) -> UsbRequestSetup128     pub fn new(
129         request_type: u8,
130         request: u8,
131         value: u16,
132         index: u16,
133         length: u16,
134     ) -> UsbRequestSetup {
135         UsbRequestSetup {
136             request_type,
137             request,
138             value,
139             index,
140             length,
141         }
142     }
143 
144     /// Get type of request.
get_type(&self) -> ControlRequestType145     pub fn get_type(&self) -> ControlRequestType {
146         let ty = (self.request_type & CONTROL_REQUEST_TYPE) >> CONTROL_REQUEST_TYPE_OFFSET;
147         match ty {
148             0 => ControlRequestType::Standard,
149             1 => ControlRequestType::Class,
150             2 => ControlRequestType::Vendor,
151             _ => ControlRequestType::Reserved,
152         }
153     }
154 
155     /// Get request direction.
get_direction(&self) -> ControlRequestDataPhaseTransferDirection156     pub fn get_direction(&self) -> ControlRequestDataPhaseTransferDirection {
157         let dir = (self.request_type & DATA_PHASE_DIRECTION) >> DATA_PHASE_DIRECTION_OFFSET;
158         match dir {
159             0 => ControlRequestDataPhaseTransferDirection::HostToDevice,
160             _ => ControlRequestDataPhaseTransferDirection::DeviceToHost,
161         }
162     }
163 
164     /// Get recipient of this control transfer.
get_recipient(&self) -> ControlRequestRecipient165     pub fn get_recipient(&self) -> ControlRequestRecipient {
166         let recipient = self.request_type & REQUEST_RECIPIENT_TYPE;
167         match recipient {
168             0 => ControlRequestRecipient::Device,
169             1 => ControlRequestRecipient::Interface,
170             2 => ControlRequestRecipient::Endpoint,
171             3 => ControlRequestRecipient::Other,
172             _ => ControlRequestRecipient::Reserved,
173         }
174     }
175 
176     /// Return the type of standard control request.
get_standard_request(&self) -> Option<StandardControlRequest>177     pub fn get_standard_request(&self) -> Option<StandardControlRequest> {
178         if self.get_type() != ControlRequestType::Standard {
179             return None;
180         }
181         match self.request {
182             0x00 => Some(StandardControlRequest::GetStatus),
183             0x01 => Some(StandardControlRequest::ClearFeature),
184             0x03 => Some(StandardControlRequest::SetFeature),
185             0x05 => Some(StandardControlRequest::SetAddress),
186             0x06 => Some(StandardControlRequest::GetDescriptor),
187             0x07 => Some(StandardControlRequest::SetDescriptor),
188             0x08 => Some(StandardControlRequest::GetConfiguration),
189             0x09 => Some(StandardControlRequest::SetConfiguration),
190             0x0a => Some(StandardControlRequest::GetInterface),
191             0x11 => Some(StandardControlRequest::SetInterface),
192             0x12 => Some(StandardControlRequest::SynchFrame),
193             _ => None,
194         }
195     }
196 }
197