Skip to content

Commit 6b96a65

Browse files
committed
Add and protocols
1 parent 22d6974 commit 6b96a65

File tree

2 files changed

+201
-0
lines changed

2 files changed

+201
-0
lines changed

src/proto/media/disk.rs

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
//! Disk I/O protocols.
2+
3+
use crate::proto::Protocol;
4+
use crate::{unsafe_guid, Event, Result, Status};
5+
6+
/// The disk I/O protocol.
7+
///
8+
/// This protocol is used to abstract the block accesses of the block I/O
9+
/// protocol to a more general offset-length protocol. Firmware is
10+
/// reponsible for adding this protocol to any block I/O interface that
11+
/// appears in the system that does not already have a disk I/O protocol.
12+
#[repr(C)]
13+
#[unsafe_guid("ce345171-ba0b-11d2-4f8e-00a0c969723b")]
14+
#[derive(Protocol)]
15+
pub struct DiskIo {
16+
revision: u64,
17+
read_disk: extern "efiapi" fn(
18+
this: &DiskIo,
19+
media_id: u32,
20+
offset: u64,
21+
len: usize,
22+
buffer: *mut u8,
23+
) -> Status,
24+
write_disk: extern "efiapi" fn(
25+
this: &mut DiskIo,
26+
media_id: u32,
27+
offset: u64,
28+
len: usize,
29+
buffer: *const u8,
30+
) -> Status,
31+
}
32+
33+
impl DiskIo {
34+
/// Reads bytes from the disk device.
35+
///
36+
/// # Arguments:
37+
/// * `media_id` - ID of the medium to be read.
38+
/// * `offset` - Starting byte offset on the logical block I/O device to read from.
39+
/// * `buffer` - Pointer to a buffer to read into.
40+
///
41+
/// # Errors:
42+
/// * `uefi::status::INVALID_PARAMETER` The read request contains device addresses that
43+
/// are not valid for the device.
44+
/// * `uefi::status::DEVICE_ERROR` The device reported an error while performing
45+
/// the read operation.
46+
/// * `uefi::status::NO_MEDIA` There is no medium in the device.
47+
/// * `uefi::status::MEDIA_CHANGED` `media_id` is not for the current medium.
48+
pub fn read_disk(&self, media_id: u32, offset: u64, buffer: &mut [u8]) -> Result {
49+
(self.read_disk)(self, media_id, offset, buffer.len(), buffer.as_mut_ptr()).into()
50+
}
51+
52+
/// Writes bytes to the disk device.
53+
///
54+
/// # Arguments:
55+
/// * `media_id` - ID of the medium to be written.
56+
/// * `offset` - Starting byte offset on the logical block I/O device to write to.
57+
/// * `buffer` - Pointer to a buffer to write from.
58+
///
59+
/// # Errors:
60+
/// * `uefi::status::INVALID_PARAMETER` The write request contains device addresses that
61+
/// are not valid for the device.
62+
/// * `uefi::status::DEVICE_ERROR` The device reported an error while performing
63+
/// the write operation.
64+
/// * `uefi::status::NO_MEDIA` There is no medium in the device.
65+
/// * `uefi::status::MEDIA_CHANGED` `media_id` is not for the current medium.
66+
/// * `uefi::status::WRITE_PROTECTED` The device cannot be written to.
67+
pub fn write_disk(&mut self, media_id: u32, offset: u64, buffer: &[u8]) -> Result {
68+
(self.write_disk)(self, media_id, offset, buffer.len(), buffer.as_ptr()).into()
69+
}
70+
}
71+
72+
/// Asynchronous transaction token for disk I/O 2 operations.
73+
#[repr(C)]
74+
pub struct DiskIo2Token {
75+
/// Event to be signalled when an asynchronous disk I/O operation completes.
76+
event: Option<Event>,
77+
/// Transaction status code.
78+
transaction_status: Status,
79+
}
80+
81+
/// The disk I/O 2 protocol.
82+
///
83+
/// This protocol provides an extension to the disk I/O protocol to enable
84+
/// non-blocking / asynchronous byte-oriented disk operation.
85+
#[repr(C)]
86+
#[unsafe_guid("151c8eae-7f2c-472c-549e-9828194f6a88")]
87+
#[derive(Protocol)]
88+
pub struct DiskIo2 {
89+
revision: u64,
90+
cancel: extern "efiapi" fn(this: &mut DiskIo2) -> Status,
91+
read_disk_ex: extern "efiapi" fn(
92+
this: &DiskIo2,
93+
media_id: u32,
94+
offset: u64,
95+
token: &mut DiskIo2Token,
96+
len: usize,
97+
buffer: *mut u8,
98+
) -> Status,
99+
write_disk_ex: extern "efiapi" fn(
100+
this: &mut DiskIo2,
101+
media_id: u32,
102+
offset: u64,
103+
token: &mut DiskIo2Token,
104+
len: usize,
105+
buffer: *const u8,
106+
) -> Status,
107+
flush_disk_ex: extern "efiapi" fn(this: &mut DiskIo2, token: &mut DiskIo2Token) -> Status,
108+
}
109+
110+
impl DiskIo2 {
111+
/// Terminates outstanding asynchronous requests to the device.
112+
///
113+
/// # Errors:
114+
/// * `uefi::status::DEVICE_ERROR` The device reported an error while performing
115+
/// the cancel operation.
116+
pub fn cancel(&mut self) -> Result {
117+
(self.cancel)(self).into()
118+
}
119+
120+
/// Reads bytes from the disk device.
121+
///
122+
/// # Arguments:
123+
/// * `media_id` - ID of the medium to be read from.
124+
/// * `offset` - Starting byte offset on the logical block I/O device to read from.
125+
/// * `token` - Transaction token for asynchronous read.
126+
/// * `buffer` - Buffer to read into.
127+
///
128+
/// # Errors:
129+
/// * `uefi::status::INVALID_PARAMETER` The read request contains device addresses
130+
/// that are not valid for the device.
131+
/// * `uefi::status::OUT_OF_RESOURCES` The request could not be completed due to
132+
/// a lack of resources.
133+
/// * `uefi::status::MEDIA_CHANGED` `media_id` is not for the current medium.
134+
/// * `uefi::status::NO_MEDIA` There is no medium in the device.
135+
/// * `uefi::status::DEVICE_ERROR` The device reported an error while performing
136+
/// the read operation.
137+
pub fn read_disk(
138+
&self,
139+
media_id: u32,
140+
offset: u64,
141+
token: &mut DiskIo2Token,
142+
buffer: &mut [u8],
143+
) -> Result {
144+
(self.read_disk_ex)(
145+
self,
146+
media_id,
147+
offset,
148+
token,
149+
buffer.len(),
150+
buffer.as_mut_ptr(),
151+
)
152+
.into()
153+
}
154+
155+
/// Writes bytes to the disk device.
156+
///
157+
/// # Arguments:
158+
/// * `media_id` - ID of the medium to write to.
159+
/// * `offset` - Starting byte offset on the logical block I/O device to write to.
160+
/// * `token` - Transaction token for asynchronous write.
161+
/// * `buffer` - Buffer to write from.
162+
///
163+
/// # Errors:
164+
/// * `uefi::status::INVALID_PARAMETER` The write request contains device addresses
165+
/// that are not valid for the device.
166+
/// * `uefi::status::OUT_OF_RESOURCES` The request could not be completed due to
167+
/// a lack of resources.
168+
/// * `uefi::status::MEDIA_CHANGED` `media_id` is not for the current medium.
169+
/// * `uefi::status::NO_MEDIA` There is no medium in the device.
170+
/// * `uefi::status::DEVICE_ERROR` The device reported an error while performing
171+
/// the write operation.
172+
/// * `uefi::status::WRITE_PROTECTED` The device cannot be written to.
173+
pub fn write_disk(
174+
&mut self,
175+
media_id: u32,
176+
offset: u64,
177+
token: &mut DiskIo2Token,
178+
buffer: &[u8],
179+
) -> Result {
180+
(self.write_disk_ex)(self, media_id, offset, token, buffer.len(), buffer.as_ptr()).into()
181+
}
182+
183+
/// Flushes all modified data to the physical device.
184+
///
185+
/// # Arguments:
186+
/// * `token` - Transaction token for the asynchronous flush.
187+
///
188+
/// # Errors:
189+
/// * `uefi::status::OUT_OF_RESOURCES` The request could not be completed due to
190+
/// a lack of resources.
191+
/// * `uefi::status::MEDIA_CHANGED` The medium in the device has changed since
192+
/// the last access.
193+
/// * `uefi::status::NO_MEDIA` There is no medium in the device.
194+
/// * `uefi::status::DEVICE_ERROR` The device reported an error while performing
195+
/// the flush operation.
196+
/// * `uefi::status::WRITE_PROTECTED` The device cannot be written to.
197+
pub fn flush_disk(&mut self, token: &mut DiskIo2Token) -> Result {
198+
(self.flush_disk_ex)(self, token).into()
199+
}
200+
}

src/proto/media/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
pub mod file;
88

99
pub mod block;
10+
pub mod disk;
1011
pub mod fs;
1112
pub mod partition;

0 commit comments

Comments
 (0)