|
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};
|
@@ -137,6 +138,72 @@ pub unsafe fn free_pool(ptr: NonNull<u8>) -> Result {
|
137 | 138 | unsafe { (bt.free_pool)(ptr.as_ptr()) }.to_result()
|
138 | 139 | }
|
139 | 140 |
|
| 141 | +/// Connect one or more drivers to a controller. |
| 142 | +/// |
| 143 | +/// Usually one disconnects and then reconnects certain drivers |
| 144 | +/// to make them rescan some state that changed, e.g. reconnecting |
| 145 | +/// a block handle after your app modified disk partitions. |
| 146 | +/// |
| 147 | +/// # Errors |
| 148 | +/// |
| 149 | +/// * [`Status::NOT_FOUND`]: there are no driver-binding protocol instances |
| 150 | +/// present in the system, or no drivers are connected to `controller`. |
| 151 | +/// * [`Status::SECURITY_VIOLATION`]: the caller does not have permission to |
| 152 | +/// start drivers associated with `controller`. |
| 153 | +pub fn connect_controller( |
| 154 | + controller: Handle, |
| 155 | + driver_image: Option<Handle>, |
| 156 | + remaining_device_path: Option<&DevicePath>, |
| 157 | + recursive: bool, |
| 158 | +) -> Result { |
| 159 | + let bt = boot_services_raw_panicking(); |
| 160 | + let bt = unsafe { bt.as_ref() }; |
| 161 | + |
| 162 | + unsafe { |
| 163 | + (bt.connect_controller)( |
| 164 | + controller.as_ptr(), |
| 165 | + Handle::opt_to_ptr(driver_image), |
| 166 | + remaining_device_path |
| 167 | + .map(|dp| dp.as_ffi_ptr()) |
| 168 | + .unwrap_or(ptr::null()) |
| 169 | + .cast(), |
| 170 | + recursive, |
| 171 | + ) |
| 172 | + } |
| 173 | + .to_result_with_err(|_| ()) |
| 174 | +} |
| 175 | + |
| 176 | +/// Disconnect one or more drivers from a controller. |
| 177 | +/// |
| 178 | +/// See also [`connect_controller`]. |
| 179 | +/// |
| 180 | +/// # Errors |
| 181 | +/// |
| 182 | +/// * [`Status::INVALID_PARAMETER`]: `driver_image` is set but does not manage |
| 183 | +/// `controller`, or does not support the driver binding protocol, or one of |
| 184 | +/// the handles is invalid. |
| 185 | +/// * [`Status::OUT_OF_RESOURCES`]: not enough resources available to disconnect |
| 186 | +/// drivers. |
| 187 | +/// * [`Status::DEVICE_ERROR`]: the controller could not be disconnected due to |
| 188 | +/// a device error. |
| 189 | +pub fn disconnect_controller( |
| 190 | + controller: Handle, |
| 191 | + driver_image: Option<Handle>, |
| 192 | + child: Option<Handle>, |
| 193 | +) -> Result { |
| 194 | + let bt = boot_services_raw_panicking(); |
| 195 | + let bt = unsafe { bt.as_ref() }; |
| 196 | + |
| 197 | + unsafe { |
| 198 | + (bt.disconnect_controller)( |
| 199 | + controller.as_ptr(), |
| 200 | + Handle::opt_to_ptr(driver_image), |
| 201 | + Handle::opt_to_ptr(child), |
| 202 | + ) |
| 203 | + } |
| 204 | + .to_result_with_err(|_| ()) |
| 205 | +} |
| 206 | + |
140 | 207 | /// Returns an array of handles that support the requested protocol in a
|
141 | 208 | /// pool-allocated buffer.
|
142 | 209 | ///
|
|
0 commit comments