[U-Boot] [PATCH 16/23] efi_loader: implement DisconnectController
Heinrich Schuchardt
xypron.glpk at gmx.de
Sat Aug 26 22:53:25 UTC 2017
Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
lib/efi_loader/efi_boottime.c | 77 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 76 insertions(+), 1 deletion(-)
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 1069da7d79..c5a17b6252 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -1052,9 +1052,84 @@ static efi_status_t EFIAPI efi_disconnect_controller(void *controller_handle,
void *driver_image_handle,
void *child_handle)
{
+ struct efi_driver_binding_protocol *binding_protocol;
+ efi_handle_t child_handle_buffer;
+ unsigned long driver_count;
+ efi_handle_t *driver_handle_buffer;
+ size_t i;
+ UINTN number_of_children;
+ efi_status_t r;
+ size_t stop_count = 0;
+
EFI_ENTRY("%p, %p, %p", controller_handle, driver_image_handle,
child_handle);
- return EFI_EXIT(EFI_INVALID_PARAMETER);
+
+ if (!efi_search_obj(controller_handle)) {
+ r = EFI_INVALID_PARAMETER;
+ goto out;
+ }
+
+ /* Create list of driver handles */
+ if (driver_image_handle) {
+ driver_handle_buffer = &driver_image_handle,
+ driver_count = 1;
+ /* Check that the handle supports driver binding protocol */
+ r = efi_search_protocol(driver_image_handle,
+ &efi_guid_driver_binding_protocol,
+ NULL);
+ } else {
+ /* Get buffer with all handles with driver binding protocol */
+ r = EFI_CALL(efi_locate_handle_buffer(
+ by_protocol, &efi_guid_driver_binding_protocol,
+ NULL, &driver_count, &driver_handle_buffer));
+ }
+ if (r != EFI_SUCCESS)
+ goto out;
+
+ /* Create list of child handles */
+ if (child_handle) {
+ number_of_children = 1;
+ child_handle_buffer = &child_handle;
+ } else {
+ /*
+ * We do not fully support child handles.
+ *
+ * It is unclear from which handle and which protocols the
+ * list of child controllers should be collected.
+ */
+ number_of_children = 0;
+ child_handle_buffer = NULL;
+ }
+
+ for (i = 0; i < driver_count; ++i) {
+ r = EFI_CALL(efi_open_protocol(
+ driver_handle_buffer[i],
+ &efi_guid_driver_binding_protocol,
+ (void **)&binding_protocol,
+ driver_handle_buffer[i], NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL));
+ if (r != EFI_SUCCESS)
+ continue;
+
+ r = EFI_CALL(binding_protocol->stop(binding_protocol,
+ controller_handle,
+ number_of_children,
+ child_handle_buffer));
+ if (r == EFI_SUCCESS)
+ ++stop_count;
+ EFI_CALL(efi_close_protocol(driver_handle_buffer[i],
+ &efi_guid_driver_binding_protocol,
+ driver_handle_buffer[i], NULL));
+ }
+
+ if (driver_image_handle)
+ efi_free_pool(driver_handle_buffer);
+ if (stop_count)
+ r = EFI_SUCCESS;
+ else
+ r = EFI_NOT_FOUND;
+out:
+ return EFI_EXIT(r);
}
efi_status_t EFIAPI efi_close_protocol(void *handle, const efi_guid_t *protocol,
--
2.14.1
More information about the U-Boot
mailing list