1
1
use alloc:: string:: ToString ;
2
- use core:: ffi:: c_void;
3
2
use core:: ptr:: NonNull ;
4
3
use uefi:: prelude:: * ;
5
4
use uefi:: proto:: media:: block:: BlockIO ;
@@ -8,10 +7,8 @@ use uefi::proto::media::file::{
8
7
Directory , File , FileAttribute , FileInfo , FileMode , FileSystemInfo ,
9
8
} ;
10
9
use uefi:: proto:: media:: fs:: SimpleFileSystem ;
11
- use uefi:: table:: boot:: { EventType , MemoryType , OpenProtocolAttributes , OpenProtocolParams , Tpl } ;
10
+ use uefi:: table:: boot:: { EventType , OpenProtocolAttributes , OpenProtocolParams , Tpl } ;
12
11
use uefi:: table:: runtime:: { Daylight , Time , TimeParams } ;
13
- use uefi:: Event ;
14
- use uefi_services:: system_table;
15
12
16
13
/// Test directory entry iteration.
17
14
fn test_existing_dir ( directory : & mut Directory ) {
@@ -190,26 +187,8 @@ fn test_raw_disk_io(handle: Handle, image: Handle, bt: &BootServices) {
190
187
struct DiskIoTask {
191
188
/// Token for the transaction
192
189
token : DiskIo2Token ,
193
- /// Pointer to a buffer holding the read data
194
- buffer : * mut u8 ,
195
- }
196
-
197
- /// Asynchronous disk I/O 2 transaction callback
198
- unsafe extern "efiapi" fn disk_io2_callback ( event : Event , ctx : Option < NonNull < c_void > > ) {
199
- let task = ctx. unwrap ( ) . as_ptr ( ) as * mut DiskIoTask ;
200
-
201
- // Verify that the disk's MBR signature is correct
202
- assert_eq ! ( ( * task) . token. transaction_status, uefi:: Status :: SUCCESS ) ;
203
- assert_eq ! ( * ( * task) . buffer. offset( 510 ) , 0x55 ) ;
204
- assert_eq ! ( * ( * task) . buffer. offset( 511 ) , 0xaa ) ;
205
-
206
- // Close the completion event
207
- let bt = system_table ( ) . as_ref ( ) . boot_services ( ) ;
208
- bt. close_event ( event) . unwrap ( ) ;
209
-
210
- // Free the disk data buffer & task context
211
- bt. free_pool ( ( * task) . buffer ) . unwrap ( ) ;
212
- bt. free_pool ( task as * mut u8 ) . unwrap ( ) ;
190
+ /// Buffer holding the read data
191
+ buffer : [ u8 ; 512 ] ,
213
192
}
214
193
215
194
/// Tests raw disk I/O through the DiskIo2 protocol.
@@ -237,44 +216,54 @@ fn test_raw_disk_io2(handle: Handle, image: Handle, bt: &BootServices) {
237
216
)
238
217
. expect ( "Failed to get block I/O protocol" ) ;
239
218
240
- // Allocate the task context structure
241
- let task = bt
242
- . allocate_pool ( MemoryType :: LOADER_DATA , core:: mem:: size_of :: < DiskIoTask > ( ) )
243
- . expect ( "Failed to allocate task struct for disk I/O" )
244
- as * mut DiskIoTask ;
245
-
246
- // SAFETY: `task` refers to a valid allocation of at least `size_of::<DiskIoTask>()`
247
219
unsafe {
248
- // Create the completion event as part of the disk I/O token
249
- ( * task) . token . event = Some (
250
- bt. create_event (
251
- EventType :: NOTIFY_SIGNAL ,
220
+ // Create the task context structure
221
+ let mut task = core:: mem:: MaybeUninit :: uninit ( ) ;
222
+
223
+ // Create the completion event
224
+ let mut event = bt
225
+ . create_event (
226
+ EventType :: empty ( ) ,
252
227
Tpl :: NOTIFY ,
253
- Some ( disk_io2_callback ) ,
254
- NonNull :: new ( task as * mut c_void ) ,
228
+ None ,
229
+ NonNull :: new ( task. as_mut_ptr ( ) as _ ) ,
255
230
)
256
- . expect ( "Failed to create disk I/O completion event" ) ,
257
- ) ;
231
+ . expect ( "Failed to create disk I/O completion event" ) ;
232
+
233
+ // Initialise the task context
234
+ task. write ( DiskIoTask {
235
+ token : DiskIo2Token {
236
+ event : event. unsafe_clone ( ) ,
237
+ transaction_status : uefi:: Status :: NOT_READY ,
238
+ } ,
239
+ buffer : [ 0 ; 512 ] ,
240
+ } ) ;
258
241
259
- // Allocate a buffer for the transaction to read into
260
- const SIZE_TO_READ : usize = 512 ;
261
- ( * task) . buffer = bt
262
- . allocate_pool ( MemoryType :: LOADER_DATA , SIZE_TO_READ )
263
- . expect ( "Failed to allocate buffer for disk I/O" ) ;
242
+ // Get a mutable reference to the task to not move it
243
+ let task_ref = task. assume_init_mut ( ) ;
264
244
265
245
// Initiate the asynchronous read operation
266
246
disk_io2
267
247
. read_disk_raw (
268
248
block_io. media ( ) . media_id ( ) ,
269
249
0 ,
270
- & mut ( * task ) . token ,
271
- SIZE_TO_READ ,
272
- ( * task ) . buffer ,
250
+ NonNull :: new ( & mut task_ref . token as _ ) ,
251
+ task_ref . buffer . len ( ) ,
252
+ task_ref . buffer . as_mut_ptr ( ) ,
273
253
)
274
254
. expect ( "Failed to initiate asynchronous disk I/O read" ) ;
275
- }
276
255
277
- info ! ( "Raw disk I/O 2 succeeded" ) ;
256
+ // Wait for the transaction to complete
257
+ bt. wait_for_event ( core:: slice:: from_mut ( & mut event) )
258
+ . expect ( "Failed to wait on completion event" ) ;
259
+
260
+ // Verify that the disk's MBR signature is correct
261
+ assert_eq ! ( task_ref. token. transaction_status, uefi:: Status :: SUCCESS ) ;
262
+ assert_eq ! ( task_ref. buffer[ 510 ] , 0x55 ) ;
263
+ assert_eq ! ( task_ref. buffer[ 511 ] , 0xaa ) ;
264
+
265
+ info ! ( "Raw disk I/O 2 succeeded" ) ;
266
+ }
278
267
}
279
268
}
280
269
0 commit comments