|
3 | 3 | //! These functions will panic if called after exiting boot services.
|
4 | 4 |
|
5 | 5 | use crate::data_types::PhysicalAddress;
|
| 6 | +use crate::proto::device_path::DevicePath; |
6 | 7 | use crate::proto::{Protocol, ProtocolPointer};
|
7 | 8 | use core::ffi::c_void;
|
8 | 9 | use core::ops::{Deref, DerefMut};
|
@@ -161,6 +162,72 @@ pub unsafe fn free_pool(ptr: NonNull<u8>) -> Result {
|
161 | 162 | unsafe { (bt.free_pool)(ptr.as_ptr()) }.to_result()
|
162 | 163 | }
|
163 | 164 |
|
| 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 | + |
164 | 231 | /// Returns an array of handles that support the requested protocol in a
|
165 | 232 | /// pool-allocated buffer.
|
166 | 233 | ///
|
|
0 commit comments