• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 use crate::defs::{
16     EfiBlockIoMedia, EfiBlockIoProtocol, EfiGuid, EFI_STATUS_INVALID_PARAMETER,
17     EFI_STATUS_NOT_FOUND,
18 };
19 use crate::protocol::{Protocol, ProtocolInfo};
20 use crate::{efi_call, map_efi_err, EfiResult};
21 
22 /// EFI_BLOCK_IO_PROTOCOL
23 pub struct BlockIoProtocol;
24 
25 impl ProtocolInfo for BlockIoProtocol {
26     type InterfaceType = EfiBlockIoProtocol;
27 
28     const GUID: EfiGuid =
29         EfiGuid::new(0x964e5b21, 0x6459, 0x11d2, [0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b]);
30 }
31 
32 // Protocol interface wrappers.
33 impl Protocol<'_, BlockIoProtocol> {
34     /// Wrapper of `EFI_BLOCK_IO_PROTOCOL.read_blocks()`
read_blocks(&self, lba: u64, buffer: &mut [u8]) -> EfiResult<()>35     pub fn read_blocks(&self, lba: u64, buffer: &mut [u8]) -> EfiResult<()> {
36         // SAFETY:
37         // `self.interface()?` guarantees self.interface is non-null and points to a valid object
38         // established by `Protocol::new()`.
39         // `self.interface` is input parameter and will not be retained. It outlives the call.
40         // `buffer` remains valid during the call.
41         unsafe {
42             efi_call!(
43                 self.interface()?.read_blocks,
44                 self.interface,
45                 self.media()?.media_id,
46                 lba,
47                 buffer.len(),
48                 buffer.as_mut_ptr() as *mut _
49             )
50         }
51     }
52 
53     /// Wrapper of `EFI_BLOCK_IO_PROTOCOL.write_blocks()`
write_blocks(&self, lba: u64, buffer: &mut [u8]) -> EfiResult<()>54     pub fn write_blocks(&self, lba: u64, buffer: &mut [u8]) -> EfiResult<()> {
55         // SAFETY:
56         // `self.interface()?` guarantees self.interface is non-null and points to a valid object
57         // established by `Protocol::new()`.
58         // `self.interface` is input parameter and will not be retained. It outlives the call.
59         // `buffer` remains valid during the call.
60         unsafe {
61             efi_call!(
62                 self.interface()?.write_blocks,
63                 self.interface,
64                 self.media()?.media_id,
65                 lba,
66                 buffer.len(),
67                 buffer.as_mut_ptr() as _
68             )
69         }
70     }
71 
72     /// Wrapper of `EFI_BLOCK_IO_PROTOCOL.flush_blocks()`
flush_blocks(&self) -> EfiResult<()>73     pub fn flush_blocks(&self) -> EfiResult<()> {
74         // SAFETY:
75         // `self.interface()?` guarantees `self.interface` is non-null and points to a valid object
76         // established by `Protocol::new()`.
77         // `self.interface` is input parameter and will not be retained. It outlives the call.
78         unsafe { efi_call!(self.interface()?.flush_blocks, self.interface) }
79     }
80 
81     /// Wrapper of `EFI_BLOCK_IO_PROTOCOL.reset()`
reset(&self, extended_verification: bool) -> EfiResult<()>82     pub fn reset(&self, extended_verification: bool) -> EfiResult<()> {
83         // SAFETY:
84         // `self.interface()?` guarantees `self.interface` is non-null and points to a valid object
85         // established by `Protocol::new()`.
86         // `self.interface` is input parameter and will not be retained. It outlives the call.
87         unsafe { efi_call!(self.interface()?.reset, self.interface, extended_verification) }
88     }
89 
90     /// Get a copy to the EFI_BLOCK_IO_PROTOCOL.Media structure.
media(&self) -> EfiResult<EfiBlockIoMedia>91     pub fn media(&self) -> EfiResult<EfiBlockIoMedia> {
92         let ptr = self.interface()?.media;
93         // SFETY: Pointers to EFI data structure.
94         Ok(*unsafe { ptr.as_ref() }.ok_or_else(|| EFI_STATUS_INVALID_PARAMETER)?)
95     }
96 }
97