Skip to content

Commit 3ee16d3

Browse files
Merge pull request #1625 from JarlEvanson/usb-io
uefi: Add safe EFI_USB_IO_PROTOCOL bindings
2 parents dfce69b + cc6bca7 commit 3ee16d3

File tree

8 files changed

+408
-0
lines changed

8 files changed

+408
-0
lines changed

uefi-test-runner/src/proto/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub fn test() {
2424
rng::test();
2525
shell_params::test();
2626
string::test();
27+
usb::test();
2728
misc::test();
2829

2930
// disable the ATA test on aarch64 for now. The aarch64 UEFI Firmware does not yet seem
@@ -96,3 +97,4 @@ mod shell_params;
9697
mod shim;
9798
mod string;
9899
mod tcg;
100+
mod usb;

uefi-test-runner/src/proto/usb/io.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// SPDX-License-Identifier: MIT OR Apache-2.0
2+
3+
use core::mem;
4+
use uefi::proto::usb::DeviceDescriptor;
5+
use uefi::proto::usb::io::{ControlTransfer, UsbIo};
6+
use uefi::{Status, boot};
7+
8+
const DEVICE_TO_HOST: u8 = 1 << 7;
9+
const STANDARD_REQUEST: u8 = 0b00 << 5;
10+
const DEVICE_RECIPIENT: u8 = 0b0_0000;
11+
const GET_DESCRIPTOR_REQUEST: u8 = 6;
12+
const DEVICE_DESCRIPTOR: u8 = 1;
13+
14+
/// This test iterates through all of the exposed active USB interfaces and
15+
/// performs checks on each to validate that descriptor acquisition and control
16+
/// transfers work correctly.
17+
pub fn test() {
18+
info!("Testing USB I/O protocol");
19+
20+
let handles = boot::locate_handle_buffer(boot::SearchType::from_proto::<UsbIo>())
21+
.expect("failed to acquire USB I/O handles");
22+
23+
for handle in handles.iter().copied() {
24+
let mut io = boot::open_protocol_exclusive::<UsbIo>(handle)
25+
.expect("failed to open USB I/O protocol");
26+
27+
let device = io
28+
.device_descriptor()
29+
.expect("failed to acquire USB device descriptor");
30+
io.config_descriptor()
31+
.expect("failed to acquire USB config descriptor");
32+
io.interface_descriptor()
33+
.expect("failed to acquire USB interface descriptor");
34+
35+
for endpoint_index in 0..16 {
36+
let result = io.endpoint_descriptor(endpoint_index);
37+
if result
38+
.as_ref()
39+
.is_err_and(|error| error.status() == Status::NOT_FOUND)
40+
{
41+
continue;
42+
}
43+
44+
result.expect("failed to acquire USB endpoint descriptor");
45+
}
46+
47+
let supported_languages = io
48+
.supported_languages()
49+
.expect("failed to acquire supported language list");
50+
let test_language = supported_languages[0];
51+
52+
for string_index in 0..=u8::MAX {
53+
let result = io.string_descriptor(test_language, string_index);
54+
if result
55+
.as_ref()
56+
.is_err_and(|error| error.status() == Status::NOT_FOUND)
57+
{
58+
continue;
59+
}
60+
61+
result.expect("failed to acquire string descriptor");
62+
}
63+
64+
let mut buffer = [0u8; mem::size_of::<DeviceDescriptor>()];
65+
66+
io.control_transfer(
67+
DEVICE_TO_HOST | STANDARD_REQUEST | DEVICE_RECIPIENT,
68+
GET_DESCRIPTOR_REQUEST,
69+
u16::from(DEVICE_DESCRIPTOR) << 8,
70+
0,
71+
ControlTransfer::DataIn(&mut buffer[..mem::size_of::<DeviceDescriptor>()]),
72+
0,
73+
)
74+
.expect("failed control transfer");
75+
unsafe {
76+
assert_eq!(
77+
device,
78+
buffer.as_ptr().cast::<DeviceDescriptor>().read_unaligned()
79+
)
80+
}
81+
}
82+
}

uefi-test-runner/src/proto/usb/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// SPDX-License-Identifier: MIT OR Apache-2.0
2+
3+
pub fn test() {
4+
info!("Testing USB protocols");
5+
6+
io::test();
7+
}
8+
9+
mod io;

uefi/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Added
44
- Added `ConfigTableEntry::MEMORY_ATTRIBUTES_GUID` and `ConfigTableEntry::IMAGE_SECURITY_DATABASE_GUID`.
5+
- Added `proto::usb::io::UsbIo`.
56

67
## Changed
78
- **Breaking:** `boot::stall` now take `core::time::Duration` instead of `usize`.

uefi/src/proto/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub mod shell_params;
3131
pub mod shim;
3232
pub mod string;
3333
pub mod tcg;
34+
pub mod usb;
3435

3536
mod boot_policy;
3637

0 commit comments

Comments
 (0)