Skip to main content

uefi_raw/protocol/
ata.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3use super::device_path::DevicePathProtocol;
4use crate::{Event, Status, newtype_enum};
5use core::ffi::c_void;
6use uguid::{Guid, guid};
7
8bitflags::bitflags! {
9    /// ATA Controller attributes.
10    ///
11    /// These flags defines attributes that describe the nature and capabilities
12    /// of the ATA controller represented by this `EFI_ATA_PASS_THRU_PROTOCOL` instance.
13    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
14    #[repr(transparent)]
15    pub struct AtaPassThruAttributes: u32 {
16        /// The protocol interface is for physical devices on the ATA controller.
17        ///
18        /// This allows access to hardware-level details of devices directly attached to the controller.
19        const PHYSICAL = 0x0001;
20
21        /// The protocol interface is for logical devices on the ATA controller.
22        ///
23        /// Logical devices include RAID volumes and other high-level abstractions.
24        const LOGICAL = 0x0002;
25
26        /// The protocol interface supports non-blocking I/O in addition to blocking I/O.
27        ///
28        /// While all protocol interfaces must support blocking I/O, this attribute indicates
29        /// the additional capability for non-blocking operations.
30        const NONBLOCKIO = 0x0004;
31    }
32}
33
34#[derive(Clone, Debug)]
35#[repr(C)]
36pub struct AtaPassThruMode {
37    pub attributes: AtaPassThruAttributes,
38    pub io_align: u32,
39}
40
41newtype_enum! {
42    /// Corresponds to the `EFI_ATA_PASS_THRU_PROTOCOL_*` defines.
43    #[derive(Default)]
44    pub enum AtaPassThruCommandProtocol: u8 => {
45        ATA_HARDWARE_RESET = 0x00,
46        ATA_SOFTWARE_RESET = 0x01,
47        ATA_NON_DATA = 0x02,
48        PIO_DATA_IN = 0x04,
49        PIO_DATA_OUT = 0x05,
50        DMA = 0x06,
51        DMA_QUEUED = 0x07,
52        DEVICE_DIAGNOSTIC = 0x08,
53        DEVICE_RESET = 0x09,
54        UDMA_DATA_IN = 0x0A,
55        UDMA_DATA_OUT = 0x0B,
56        FPDMA = 0x0C,
57        RETURN_RESPONSE = 0xFF,
58    }
59}
60
61newtype_enum! {
62    /// Corresponds to the `EFI_ATA_PASS_THRU_LENGTH_*` defines.
63    #[derive(Default)]
64    pub enum AtaPassThruLength: u8 => {
65        BYTES = 0x80,
66        MASK = 0x70,
67        NO_DATA_TRANSFER = 0x00,
68        FEATURES = 0x10,
69        SECTOR_COUNT = 0x20,
70        TPSIU = 0x30,
71        COUNT = 0x0F,
72    }
73}
74
75#[derive(Debug)]
76#[repr(C)]
77pub struct AtaStatusBlock {
78    pub reserved1: [u8; 2],
79    pub status: u8,
80    pub error: u8,
81    pub sector_number: u8,
82    pub cylinder_low: u8,
83    pub cylinder_high: u8,
84    pub device_head: u8,
85    pub sector_number_exp: u8,
86    pub cylinder_low_exp: u8,
87    pub cylinder_high_exp: u8,
88    pub reserved2: u8,
89    pub sector_count: u8,
90    pub sector_count_exp: u8,
91    pub reserved3: [u8; 6],
92}
93
94#[derive(Debug, Default)]
95#[repr(C)]
96pub struct AtaCommandBlock {
97    pub reserved1: [u8; 2],
98    pub command: u8,
99    pub features: u8,
100    pub sector_number: u8,
101    pub cylinder_low: u8,
102    pub cylinder_high: u8,
103    pub device_head: u8,
104    pub sector_number_exp: u8,
105    pub cylinder_low_exp: u8,
106    pub cylinder_high_exp: u8,
107    pub features_exp: u8,
108    pub sector_count: u8,
109    pub sector_count_exp: u8,
110    pub reserved2: [u8; 6],
111}
112
113#[derive(Debug)]
114#[repr(C)]
115pub struct AtaPassThruCommandPacket {
116    pub asb: *mut AtaStatusBlock,
117    pub acb: *const AtaCommandBlock,
118    pub timeout: u64,
119    pub in_data_buffer: *mut c_void,
120    pub out_data_buffer: *const c_void,
121    pub in_transfer_length: u32,
122    pub out_transfer_length: u32,
123    pub protocol: AtaPassThruCommandProtocol,
124    pub length: AtaPassThruLength,
125}
126
127#[derive(Debug)]
128#[repr(C)]
129pub struct AtaPassThruProtocol {
130    pub mode: *const AtaPassThruMode,
131    pub pass_thru: unsafe extern "efiapi" fn(
132        this: *mut Self,
133        port: u16,
134        port_multiplier_port: u16,
135        packet: *mut AtaPassThruCommandPacket,
136        event: Event,
137    ) -> Status,
138    pub get_next_port: unsafe extern "efiapi" fn(this: *const Self, port: *mut u16) -> Status,
139    pub get_next_device: unsafe extern "efiapi" fn(
140        this: *const Self,
141        port: u16,
142        port_multiplier_port: *mut u16,
143    ) -> Status,
144    pub build_device_path: unsafe extern "efiapi" fn(
145        this: *const Self,
146        port: u16,
147        port_multiplier_port: u16,
148        device_path: *mut *const DevicePathProtocol,
149    ) -> Status,
150    pub get_device: unsafe extern "efiapi" fn(
151        this: *const Self,
152        device_path: *const DevicePathProtocol,
153        port: *mut u16,
154        port_multiplier_port: *mut u16,
155    ) -> Status,
156    pub reset_port: unsafe extern "efiapi" fn(this: *mut Self, port: u16) -> Status,
157    pub reset_device:
158        unsafe extern "efiapi" fn(this: *mut Self, port: u16, port_multiplier_port: u16) -> Status,
159}
160
161impl AtaPassThruProtocol {
162    pub const GUID: Guid = guid!("1d3de7f0-0807-424f-aa69-11a54e19a46f");
163}