Skip to content

uefi-raw: Add EFI_USB_IO_PROTOCOL bindings #1623

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions uefi-raw/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- Added `NvmExpressPassThruProtocol`.
- Added `AtaPassThruProtocol`.
- Added `DevicePathUtilitiesProtocol`.
- Added `UsbIoProtocol`.


# uefi-raw - 0.10.0 (2025-02-07)
Expand Down
1 change: 1 addition & 0 deletions uefi-raw/src/protocol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ pub mod scsi;
pub mod shell_params;
pub mod string;
pub mod tcg;
pub mod usb;
178 changes: 178 additions & 0 deletions uefi-raw/src/protocol/usb/io.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
// SPDX-License-Identifier: MIT OR Apache-2.0

use core::ffi;

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

newtype_enum! {
pub enum DataDirection: i32 => {
DATA_IN = 0,
DATA_OUT = 1,
NO_DATA = 2,
}
}

#[derive(Debug)]
#[repr(C)]
pub struct DeviceRequest {
pub request_type: u8,
pub request: u8,
pub value: u16,
pub index: u16,
pub length: u16,
}

#[derive(Default, Debug)]
#[repr(transparent)]
pub struct UsbTransferStatus(pub u32);

pub type AsyncUsbTransferCallback = unsafe extern "efiapi" fn(
data: *mut ffi::c_void,
data_length: usize,
context: *mut ffi::c_void,
status: UsbTransferStatus,
) -> Status;

#[derive(Debug)]
#[repr(C)]
pub struct DeviceDescriptor {
pub length: u8,
pub descriptor_type: u8,
pub bcd_usb: u16,
pub device_class: u8,
pub device_subclass: u8,
pub device_protocol: u8,
pub max_packet_size: u8,
pub id_vendor: u16,
pub id_product: u16,
pub bcd_device: u16,
pub str_manufacturer: u8,
pub str_product: u8,
pub str_serial_number: u8,
pub num_configurations: u8,
}

#[derive(Debug)]
#[repr(C)]
pub struct ConfigDescriptor {
pub length: u8,
pub descriptor_type: u8,
pub total_length: u16,
pub num_interfaces: u8,
pub configuration_value: u8,
pub configuration: u8,
pub attributes: u8,
pub max_power: u8,
}

#[derive(Debug)]
#[repr(C)]
pub struct InterfaceDescriptor {
pub length: u8,
pub descriptor_type: u8,
pub interface_number: u8,
pub alternate_setting: u8,
pub num_endpoints: u8,
pub interface_class: u8,
pub interface_subclass: u8,
pub interface_protocol: u8,
pub interface: u8,
}

#[derive(Debug)]
#[repr(C)]
pub struct EndpointDescriptor {
pub length: u8,
pub descriptor_type: u8,
pub endpoint_address: u8,
pub attributes: u8,
pub max_packet_size: u16,
pub interval: u8,
}

#[derive(Debug)]
#[repr(C)]
pub struct UsbIoProtocol {
pub control_transfer: unsafe extern "efiapi" fn(
this: *mut Self,
request: *mut DeviceRequest,
direction: DataDirection,
timeout: u32,
data: *mut ffi::c_void,
data_length: usize,
status: *mut UsbTransferStatus,
) -> Status,
pub bulk_transfer: unsafe extern "efiapi" fn(
this: *mut Self,
device_endpoint: u8,
data: *mut ffi::c_void,
data_length: usize,
timeout: u32,
status: *mut UsbTransferStatus,
) -> Status,
pub async_interrupt_transfer: unsafe extern "efiapi" fn(
this: *mut Self,
device_endpoint: u8,
is_new_transfer: Boolean,
polling_interval: usize,
data_length: usize,
interrupt_callback: AsyncUsbTransferCallback,
context: *mut ffi::c_void,
) -> Status,
pub sync_interrupt_transfer: unsafe extern "efiapi" fn(
this: *mut Self,
device_endpoint: u8,
data: *mut ffi::c_void,
data_length: *mut usize,
timeout: usize,
status: *mut UsbTransferStatus,
) -> Status,
pub isochronous_transfer: unsafe extern "efiapi" fn(
this: *mut Self,
device_endpoint: u8,
data: *mut ffi::c_void,
data_length: usize,
status: *mut UsbTransferStatus,
) -> Status,
pub async_isochronous_transfer: unsafe extern "efiapi" fn(
this: *mut Self,
device_endpoint: u8,
data: *mut ffi::c_void,
data_length: usize,
isochronous_callback: AsyncUsbTransferCallback,
context: *mut ffi::c_void,
) -> Status,
pub get_device_descriptor: unsafe extern "efiapi" fn(
this: *mut Self,
device_descriptor: *mut DeviceDescriptor,
) -> Status,
pub get_config_descriptor: unsafe extern "efiapi" fn(
this: *mut Self,
config_descriptor: *mut ConfigDescriptor,
) -> Status,
pub get_interface_descriptor: unsafe extern "efiapi" fn(
this: *mut Self,
interface_descriptor: *mut InterfaceDescriptor,
) -> Status,
pub get_endpoint_descriptor: unsafe extern "efiapi" fn(
this: *mut Self,
endpoint_index: u8,
endpoint_descriptor: *mut EndpointDescriptor,
) -> Status,
pub get_string_descriptor: unsafe extern "efiapi" fn(
this: *mut Self,
lang_id: u16,
string_id: u8,
string: *mut *mut Char16,
) -> Status,
pub get_supported_languages: unsafe extern "efiapi" fn(
this: *mut Self,
lang_id_table: *mut *mut u16,
table_size: *mut u16,
) -> Status,
pub port_reset: unsafe extern "efiapi" fn(this: *mut Self) -> Status,
}

impl UsbIoProtocol {
pub const GUID: Guid = guid!("2b2f68d6-0cd2-44cf-8e8b-bba20b1b5b75");
}
3 changes: 3 additions & 0 deletions uefi-raw/src/protocol/usb/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// SPDX-License-Identifier: MIT OR Apache-2.0

pub mod io;
Loading