Skip to content

Commit 0e2a9d1

Browse files
authored
Merge pull request #1629 from JarlEvanson/usb-2-hc-raw
uefi-raw: Add EFI_USB2_HC_PROTOCOL bindings
2 parents 93091da + 75dec6b commit 0e2a9d1

File tree

4 files changed

+285
-85
lines changed

4 files changed

+285
-85
lines changed

uefi-raw/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- Added `AtaPassThruProtocol`.
1414
- Added `DevicePathUtilitiesProtocol`.
1515
- Added `UsbIoProtocol`.
16+
- Added `Usb2HostControllerProtocol`.
1617

1718

1819
# uefi-raw - 0.10.0 (2025-02-07)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
// SPDX-License-Identifier: MIT OR Apache-2.0
2+
3+
use core::ffi;
4+
5+
use bitflags::bitflags;
6+
7+
use crate::{guid, Boolean, Guid, Status};
8+
9+
use super::{AsyncUsbTransferCallback, DataDirection, DeviceRequest, UsbTransferStatus};
10+
11+
newtype_enum! {
12+
pub enum Speed: u8 => {
13+
FULL = 0,
14+
LOW = 1,
15+
HIGH = 2,
16+
SUPER = 3,
17+
}
18+
}
19+
20+
bitflags! {
21+
#[repr(transparent)]
22+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
23+
pub struct ResetAttributes: u16 {
24+
/// Send a global reset signal to the USB bus.
25+
const RESET_GLOBAL = 0x0001;
26+
/// Reset the USB host controller hardware.
27+
///
28+
/// No reset signal will be sent to the USB bus.
29+
const RESET_HOST = 0x0002;
30+
/// Send a global reset signal to the USB bus.
31+
///
32+
/// Even if a debug port has been enabled, this still resets the host controller.
33+
const RESET_GLOBAL_WITH_DEBUG = 0x0004;
34+
/// Reset the USB host controller hardware.
35+
///
36+
/// Even if a debug port has been enabled, this still resets the host controller.
37+
const RESET_HOST_WITH_DEBUG = 0x0008;
38+
}
39+
}
40+
41+
newtype_enum! {
42+
pub enum HostControllerState: i32 => {
43+
HALT = 0,
44+
OPERATIONAL = 1,
45+
SUSPEND = 2,
46+
}
47+
}
48+
49+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
50+
#[repr(C)]
51+
pub struct TransactionTranslator {
52+
pub hub_address: u8,
53+
pub port_number: u8,
54+
}
55+
56+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
57+
#[repr(C)]
58+
pub struct PortStatus {
59+
pub port_status: u16,
60+
pub port_change_status: u16,
61+
}
62+
63+
newtype_enum! {
64+
pub enum PortFeature: i32 => {
65+
ENABLE = 1,
66+
SUSPEND = 2,
67+
RESET = 4,
68+
POWER = 8,
69+
OWNER = 13,
70+
CONNECT_CHANGE = 16,
71+
ENABLE_CHANGE = 17,
72+
SUSPEND_CHANGE = 18,
73+
OVER_CURRENT_CHARGE = 19,
74+
RESET_CHANGE = 20,
75+
}
76+
}
77+
78+
#[derive(Debug)]
79+
#[repr(C)]
80+
pub struct Usb2HostControllerProtocol {
81+
pub get_capability: unsafe extern "efiapi" fn(
82+
this: *const Self,
83+
max_speed: *mut Speed,
84+
port_number: *mut u8,
85+
is_64_bit_capable: *mut u8,
86+
) -> Status,
87+
pub reset: unsafe extern "efiapi" fn(this: *mut Self, attributes: ResetAttributes) -> Status,
88+
pub get_state:
89+
unsafe extern "efiapi" fn(this: *mut Self, state: *mut HostControllerState) -> Status,
90+
pub set_state: unsafe extern "efiapi" fn(this: *mut Self, state: HostControllerState) -> Status,
91+
pub control_transfer: unsafe extern "efiapi" fn(
92+
this: *mut Self,
93+
device_address: u8,
94+
device_speed: Speed,
95+
maximum_packet_length: usize,
96+
request: *const DeviceRequest,
97+
transfer_direction: DataDirection,
98+
data: *mut ffi::c_void,
99+
data_length: *mut usize,
100+
timeout: usize,
101+
translator: *const TransactionTranslator,
102+
transfer_result: *mut UsbTransferStatus,
103+
) -> Status,
104+
pub bulk_transfer: unsafe extern "efiapi" fn(
105+
this: *mut Self,
106+
device_address: u8,
107+
endpoint_address: u8,
108+
device_speed: Speed,
109+
maximum_packet_length: usize,
110+
data_buffers_number: u8,
111+
data: *const *const ffi::c_void,
112+
data_length: *mut usize,
113+
data_toggle: *mut u8,
114+
timeout: usize,
115+
translator: *const TransactionTranslator,
116+
transfer_result: *mut UsbTransferStatus,
117+
) -> Status,
118+
pub async_interrupt_transfer: unsafe extern "efiapi" fn(
119+
this: *mut Self,
120+
device_address: u8,
121+
endpoint_address: u8,
122+
device_speed: Speed,
123+
maximum_packet_length: usize,
124+
is_new_transfer: Boolean,
125+
data_toggle: *mut u8,
126+
polling_interval: usize,
127+
data_length: usize,
128+
translator: *const TransactionTranslator,
129+
callback_function: AsyncUsbTransferCallback,
130+
context: *mut ffi::c_void,
131+
) -> Status,
132+
pub sync_interrupt_transfer: unsafe extern "efiapi" fn(
133+
this: *mut Self,
134+
device_address: u8,
135+
endpoint_address: u8,
136+
device_speed: Speed,
137+
maximum_packet_length: usize,
138+
data: *mut ffi::c_void,
139+
data_length: *mut usize,
140+
data_toggle: *mut u8,
141+
timeout: usize,
142+
translator: *const TransactionTranslator,
143+
transfer_result: *mut UsbTransferStatus,
144+
) -> Status,
145+
pub isochronous_transfer: unsafe extern "efiapi" fn(
146+
this: *mut Self,
147+
device_address: u8,
148+
endpoint_address: u8,
149+
device_speed: Speed,
150+
maximum_packet_length: usize,
151+
data_buffers_number: u8,
152+
data: *const *const ffi::c_void,
153+
data_length: usize,
154+
translator: *const TransactionTranslator,
155+
transfer_result: *mut UsbTransferStatus,
156+
) -> Status,
157+
pub async_isochronous_transfer: unsafe extern "efiapi" fn(
158+
this: *mut Self,
159+
device_address: u8,
160+
endpoint_address: u8,
161+
device_speed: Speed,
162+
maximum_packet_length: usize,
163+
data_buffers_number: u8,
164+
data: *const *const ffi::c_void,
165+
data_length: usize,
166+
translator: *const TransactionTranslator,
167+
isochronous_callback: AsyncUsbTransferCallback,
168+
context: *mut ffi::c_void,
169+
) -> Status,
170+
pub get_root_hub_port_status: unsafe extern "efiapi" fn(
171+
this: *mut Self,
172+
port_number: u8,
173+
port_status: *mut PortStatus,
174+
) -> Status,
175+
pub set_root_hub_port_feature: unsafe extern "efiapi" fn(
176+
this: *mut Self,
177+
port_number: u8,
178+
port_feature: PortFeature,
179+
) -> Status,
180+
pub clear_root_hub_port_feature:
181+
unsafe extern "efiapi" fn(this: *mut Self, port_number: u8, feature: PortFeature) -> Status,
182+
183+
pub major_revision: u16,
184+
pub minor_revision: u16,
185+
}
186+
187+
impl Usb2HostControllerProtocol {
188+
pub const GUID: Guid = guid!("3e745226-9818-45b6-a2ac-d7cd0e8ba2bc");
189+
}

uefi-raw/src/protocol/usb/io.rs

+4-85
Original file line numberDiff line numberDiff line change
@@ -4,91 +4,10 @@ use core::ffi;
44

55
use crate::{guid, Boolean, Char16, Guid, Status};
66

7-
newtype_enum! {
8-
pub enum DataDirection: i32 => {
9-
DATA_IN = 0,
10-
DATA_OUT = 1,
11-
NO_DATA = 2,
12-
}
13-
}
14-
15-
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
16-
#[repr(C)]
17-
pub struct DeviceRequest {
18-
pub request_type: u8,
19-
pub request: u8,
20-
pub value: u16,
21-
pub index: u16,
22-
pub length: u16,
23-
}
24-
25-
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
26-
#[repr(transparent)]
27-
pub struct UsbTransferStatus(pub u32);
28-
29-
pub type AsyncUsbTransferCallback = unsafe extern "efiapi" fn(
30-
data: *mut ffi::c_void,
31-
data_length: usize,
32-
context: *mut ffi::c_void,
33-
status: UsbTransferStatus,
34-
) -> Status;
35-
36-
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
37-
#[repr(C)]
38-
pub struct DeviceDescriptor {
39-
pub length: u8,
40-
pub descriptor_type: u8,
41-
pub bcd_usb: u16,
42-
pub device_class: u8,
43-
pub device_subclass: u8,
44-
pub device_protocol: u8,
45-
pub max_packet_size: u8,
46-
pub id_vendor: u16,
47-
pub id_product: u16,
48-
pub bcd_device: u16,
49-
pub str_manufacturer: u8,
50-
pub str_product: u8,
51-
pub str_serial_number: u8,
52-
pub num_configurations: u8,
53-
}
54-
55-
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
56-
#[repr(C)]
57-
pub struct ConfigDescriptor {
58-
pub length: u8,
59-
pub descriptor_type: u8,
60-
pub total_length: u16,
61-
pub num_interfaces: u8,
62-
pub configuration_value: u8,
63-
pub configuration: u8,
64-
pub attributes: u8,
65-
pub max_power: u8,
66-
}
67-
68-
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
69-
#[repr(C)]
70-
pub struct InterfaceDescriptor {
71-
pub length: u8,
72-
pub descriptor_type: u8,
73-
pub interface_number: u8,
74-
pub alternate_setting: u8,
75-
pub num_endpoints: u8,
76-
pub interface_class: u8,
77-
pub interface_subclass: u8,
78-
pub interface_protocol: u8,
79-
pub interface: u8,
80-
}
81-
82-
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
83-
#[repr(C)]
84-
pub struct EndpointDescriptor {
85-
pub length: u8,
86-
pub descriptor_type: u8,
87-
pub endpoint_address: u8,
88-
pub attributes: u8,
89-
pub max_packet_size: u16,
90-
pub interval: u8,
91-
}
7+
use super::{
8+
AsyncUsbTransferCallback, ConfigDescriptor, DataDirection, DeviceDescriptor, DeviceRequest,
9+
EndpointDescriptor, InterfaceDescriptor, UsbTransferStatus,
10+
};
9211

9312
#[derive(Debug)]
9413
#[repr(C)]

uefi-raw/src/protocol/usb/mod.rs

+91
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,94 @@
11
// SPDX-License-Identifier: MIT OR Apache-2.0
22

3+
use core::ffi;
4+
5+
use crate::Status;
6+
7+
pub mod host_controller;
38
pub mod io;
9+
10+
newtype_enum! {
11+
pub enum DataDirection: i32 => {
12+
DATA_IN = 0,
13+
DATA_OUT = 1,
14+
NO_DATA = 2,
15+
}
16+
}
17+
18+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
19+
#[repr(C)]
20+
pub struct DeviceRequest {
21+
pub request_type: u8,
22+
pub request: u8,
23+
pub value: u16,
24+
pub index: u16,
25+
pub length: u16,
26+
}
27+
28+
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
29+
#[repr(transparent)]
30+
pub struct UsbTransferStatus(pub u32);
31+
32+
pub type AsyncUsbTransferCallback = unsafe extern "efiapi" fn(
33+
data: *mut ffi::c_void,
34+
data_length: usize,
35+
context: *mut ffi::c_void,
36+
status: UsbTransferStatus,
37+
) -> Status;
38+
39+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
40+
#[repr(C)]
41+
pub struct DeviceDescriptor {
42+
pub length: u8,
43+
pub descriptor_type: u8,
44+
pub bcd_usb: u16,
45+
pub device_class: u8,
46+
pub device_subclass: u8,
47+
pub device_protocol: u8,
48+
pub max_packet_size: u8,
49+
pub id_vendor: u16,
50+
pub id_product: u16,
51+
pub bcd_device: u16,
52+
pub str_manufacturer: u8,
53+
pub str_product: u8,
54+
pub str_serial_number: u8,
55+
pub num_configurations: u8,
56+
}
57+
58+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
59+
#[repr(C)]
60+
pub struct ConfigDescriptor {
61+
pub length: u8,
62+
pub descriptor_type: u8,
63+
pub total_length: u16,
64+
pub num_interfaces: u8,
65+
pub configuration_value: u8,
66+
pub configuration: u8,
67+
pub attributes: u8,
68+
pub max_power: u8,
69+
}
70+
71+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
72+
#[repr(C)]
73+
pub struct InterfaceDescriptor {
74+
pub length: u8,
75+
pub descriptor_type: u8,
76+
pub interface_number: u8,
77+
pub alternate_setting: u8,
78+
pub num_endpoints: u8,
79+
pub interface_class: u8,
80+
pub interface_subclass: u8,
81+
pub interface_protocol: u8,
82+
pub interface: u8,
83+
}
84+
85+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
86+
#[repr(C)]
87+
pub struct EndpointDescriptor {
88+
pub length: u8,
89+
pub descriptor_type: u8,
90+
pub endpoint_address: u8,
91+
pub attributes: u8,
92+
pub max_packet_size: u16,
93+
pub interval: u8,
94+
}

0 commit comments

Comments
 (0)