1use super::device_path::DevicePathProtocol;
4use crate::{Event, Status, newtype_enum};
5use core::ffi::c_void;
6use uguid::{Guid, guid};
7
8bitflags::bitflags! {
9 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
14 #[repr(transparent)]
15 pub struct AtaPassThruAttributes: u32 {
16 const PHYSICAL = 0x0001;
20
21 const LOGICAL = 0x0002;
25
26 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 #[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 #[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}