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::{EfiAndroidBootProtocol, EfiGuid, EFI_STATUS_NOT_FOUND};
16 use crate::protocol::{Protocol, ProtocolInfo};
17 use crate::{efi_call, map_efi_err, EfiResult, Event};
18 
19 /// EFI_ANDROID_BOOT_PROTOCOL
20 pub struct AndroidBootProtocol;
21 
22 impl ProtocolInfo for AndroidBootProtocol {
23     type InterfaceType = EfiAndroidBootProtocol;
24 
25     const GUID: EfiGuid =
26         EfiGuid::new(0x6281a893, 0xac23, 0x4ca7, [0xb2, 0x81, 0x34, 0x0e, 0xf8, 0x16, 0x89, 0x55]);
27 }
28 
29 // Protocol interface wrappers.
30 impl Protocol<'_, AndroidBootProtocol> {
31     /// Wrapper of `EFI_ANDROID_BOOT_PROTOCOL.fastboot_usb_interface_start()`
fastboot_usb_interface_start(&self) -> EfiResult<usize>32     pub fn fastboot_usb_interface_start(&self) -> EfiResult<usize> {
33         let mut max_packet_size = 0;
34         // SAFETY:
35         // `self.interface()?` guarantees self.interface is non-null and points to a valid object
36         // established by `Protocol::new()`.
37         // `self.interface` and `max_packet_size` are input/output parameters, outlive the call and
38         // will not be retained.
39         unsafe {
40             efi_call!(
41                 self.interface()?.fastboot_usb_interface_start,
42                 self.interface,
43                 &mut max_packet_size,
44             )?;
45         }
46         Ok(max_packet_size)
47     }
48 
49     /// Wrapper of `EFI_ANDROID_BOOT_PROTOCOL.fastboot_usb_interface_stop()`
fastboot_usb_interface_stop(&self) -> EfiResult<()>50     pub fn fastboot_usb_interface_stop(&self) -> EfiResult<()> {
51         // SAFETY:
52         // `self.interface()?` guarantees self.interface is non-null and points to a valid object
53         // established by `Protocol::new()`.
54         // `self.interface` is input parameter, outlives the call, and will not be retained.
55         unsafe { efi_call!(self.interface()?.fastboot_usb_interface_stop, self.interface,) }
56     }
57 
58     /// Wrapper of `EFI_ANDROID_BOOT_PROTOCOL.fastboot_usb_receive()`
fastboot_usb_receive(&self, out: &mut [u8], out_size: &mut usize) -> EfiResult<()>59     pub fn fastboot_usb_receive(&self, out: &mut [u8], out_size: &mut usize) -> EfiResult<()> {
60         *out_size = out.len();
61         // SAFETY:
62         // `self.interface()?` guarantees self.interface is non-null and points to a valid object
63         // established by `Protocol::new()`.
64         // `self.interface`, `out_size` and `buffer` are input/output parameters, outlive the call
65         // and will not be retained.
66         unsafe {
67             efi_call!(
68                 self.interface()?.fastboot_usb_receive,
69                 self.interface,
70                 out_size,
71                 out.as_mut_ptr() as _,
72             )
73         }
74     }
75 
76     /// Wrapper of `EFI_ANDROID_BOOT_PROTOCOL.fastboot_usb_send()`
fastboot_usb_send(&self, data: &[u8], out_size: &mut usize) -> EfiResult<()>77     pub fn fastboot_usb_send(&self, data: &[u8], out_size: &mut usize) -> EfiResult<()> {
78         *out_size = data.len();
79         // SAFETY:
80         // `self.interface()?` guarantees self.interface is non-null and points to a valid object
81         // established by `Protocol::new()`.
82         // `self.interface`, `out_size` and `buffer` are input/output parameters, outlive the call
83         // and will not be retained.
84         unsafe {
85             efi_call!(
86                 self.interface()?.fastboot_usb_send,
87                 self.interface,
88                 out_size,
89                 data.as_ptr() as _,
90             )
91         }
92     }
93 
94     /// Returns the `EFI_ANDROID_BOOT_PROTOCOL.wait_for_send_completion` EFI event.
wait_for_send_completion(&self) -> EfiResult<Event>95     pub fn wait_for_send_completion(&self) -> EfiResult<Event> {
96         Ok(Event::new_unowned(self.interface()?.wait_for_send_completion))
97     }
98 }
99