Skip to content

Commit 6f98341

Browse files
authored
Merge pull request #1278 from nicholasbishop/bishop-connect-controller
boot: Add freestanding connect_controller and disconnect_controller
2 parents 71ebba1 + ff48052 commit 6f98341

File tree

3 files changed

+71
-5
lines changed

3 files changed

+71
-5
lines changed

uefi-test-runner/src/main.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ fn send_request_helper(serial: &mut Serial, request: HostRequest) -> Result {
143143
/// This must be called after opening the serial protocol in exclusive mode, as
144144
/// that breaks the connection to the console, which in turn prevents logs from
145145
/// getting to the host.
146-
fn reconnect_serial_to_console(boot_services: &BootServices, serial_handle: Handle) {
146+
fn reconnect_serial_to_console(serial_handle: Handle) {
147147
let mut storage = Vec::new();
148148
// Create a device path that specifies the terminal type.
149149
let terminal_guid = if cfg!(target_arch = "aarch64") {
@@ -160,8 +160,7 @@ fn reconnect_serial_to_console(boot_services: &BootServices, serial_handle: Hand
160160
.finalize()
161161
.unwrap();
162162

163-
boot_services
164-
.connect_controller(serial_handle, None, Some(terminal_device_path), true)
163+
uefi::boot::connect_controller(serial_handle, None, Some(terminal_device_path), true)
165164
.expect("failed to reconnect serial to console");
166165
}
167166

@@ -198,7 +197,7 @@ fn send_request_to_host(bt: &BootServices, request: HostRequest) {
198197
// device, which was broken when we opened the protocol in exclusive
199198
// mode above.
200199
drop(serial);
201-
reconnect_serial_to_console(bt, serial_handle);
200+
reconnect_serial_to_console(serial_handle);
202201

203202
if let Err(err) = res {
204203
panic!("request failed: \"{request:?}\": {:?}", err.status());

uefi-test-runner/src/proto/console/serial.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ pub unsafe fn test(bt: &BootServices) {
6767
// device, which was broken when we opened the protocol in exclusive
6868
// mode above.
6969
drop(serial);
70-
reconnect_serial_to_console(bt, handle);
70+
reconnect_serial_to_console(handle);
7171

7272
if let Err(err) = res {
7373
panic!("serial test failed: {:?}", err.status());

uefi/src/boot.rs

+67
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
//! These functions will panic if called after exiting boot services.
44
55
use crate::data_types::PhysicalAddress;
6+
use crate::proto::device_path::DevicePath;
67
use crate::proto::{Protocol, ProtocolPointer};
78
use core::ffi::c_void;
89
use core::ops::{Deref, DerefMut};
@@ -161,6 +162,72 @@ pub unsafe fn free_pool(ptr: NonNull<u8>) -> Result {
161162
unsafe { (bt.free_pool)(ptr.as_ptr()) }.to_result()
162163
}
163164

165+
/// Connect one or more drivers to a controller.
166+
///
167+
/// Usually one disconnects and then reconnects certain drivers
168+
/// to make them rescan some state that changed, e.g. reconnecting
169+
/// a block handle after your app modified disk partitions.
170+
///
171+
/// # Errors
172+
///
173+
/// * [`Status::NOT_FOUND`]: there are no driver-binding protocol instances
174+
/// present in the system, or no drivers are connected to `controller`.
175+
/// * [`Status::SECURITY_VIOLATION`]: the caller does not have permission to
176+
/// start drivers associated with `controller`.
177+
pub fn connect_controller(
178+
controller: Handle,
179+
driver_image: Option<Handle>,
180+
remaining_device_path: Option<&DevicePath>,
181+
recursive: bool,
182+
) -> Result {
183+
let bt = boot_services_raw_panicking();
184+
let bt = unsafe { bt.as_ref() };
185+
186+
unsafe {
187+
(bt.connect_controller)(
188+
controller.as_ptr(),
189+
Handle::opt_to_ptr(driver_image),
190+
remaining_device_path
191+
.map(|dp| dp.as_ffi_ptr())
192+
.unwrap_or(ptr::null())
193+
.cast(),
194+
recursive,
195+
)
196+
}
197+
.to_result_with_err(|_| ())
198+
}
199+
200+
/// Disconnect one or more drivers from a controller.
201+
///
202+
/// See also [`connect_controller`].
203+
///
204+
/// # Errors
205+
///
206+
/// * [`Status::INVALID_PARAMETER`]: `driver_image` is set but does not manage
207+
/// `controller`, or does not support the driver binding protocol, or one of
208+
/// the handles is invalid.
209+
/// * [`Status::OUT_OF_RESOURCES`]: not enough resources available to disconnect
210+
/// drivers.
211+
/// * [`Status::DEVICE_ERROR`]: the controller could not be disconnected due to
212+
/// a device error.
213+
pub fn disconnect_controller(
214+
controller: Handle,
215+
driver_image: Option<Handle>,
216+
child: Option<Handle>,
217+
) -> Result {
218+
let bt = boot_services_raw_panicking();
219+
let bt = unsafe { bt.as_ref() };
220+
221+
unsafe {
222+
(bt.disconnect_controller)(
223+
controller.as_ptr(),
224+
Handle::opt_to_ptr(driver_image),
225+
Handle::opt_to_ptr(child),
226+
)
227+
}
228+
.to_result_with_err(|_| ())
229+
}
230+
164231
/// Returns an array of handles that support the requested protocol in a
165232
/// pool-allocated buffer.
166233
///

0 commit comments

Comments
 (0)