diff mbox series

[1/1] efi_loader: fix DisconnectController() for sole child

Message ID 20201028180934.71087-1-xypron.glpk@gmx.de
State Accepted, archived
Commit 314bed6c854e41b2edd5cefb7009e3b6040abd28
Delegated to: Heinrich Schuchardt
Headers show
Series [1/1] efi_loader: fix DisconnectController() for sole child | expand

Commit Message

Heinrich Schuchardt Oct. 28, 2020, 6:09 p.m. UTC
If ChildHandle indicates the sole child of the driver, disconnect the
driver.

This fixes the test results for UEFI SCT 2.6 A
sub-tests 5.1.3.12.43, 5.1.3.12.44, 5.1.3.12.45.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
 lib/efi_loader/efi_boottime.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

--
2.28.0
diff mbox series

Patch

diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index b26ac9fbfc..dfa71b1774 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -3523,6 +3523,7 @@  static efi_status_t EFIAPI efi_disconnect_controller(
 	size_t number_of_children = 0;
 	efi_status_t r;
 	struct efi_object *efiobj;
+	bool sole_child;

 	EFI_ENTRY("%p, %p, %p", controller_handle, driver_image_handle,
 		  child_handle);
@@ -3545,16 +3546,18 @@  static efi_status_t EFIAPI efi_disconnect_controller(
 	}

 	/* Create list of child handles */
+	r = efi_get_child_controllers(efiobj,
+				      driver_image_handle,
+				      &number_of_children,
+				      &child_handle_buffer);
+	if (r != EFI_SUCCESS)
+		return r;
+	sole_child = (number_of_children == 1);
+
 	if (child_handle) {
 		number_of_children = 1;
+		free(child_handle_buffer);
 		child_handle_buffer = &child_handle;
-	} else {
-		r = efi_get_child_controllers(efiobj,
-					      driver_image_handle,
-					      &number_of_children,
-					      &child_handle_buffer);
-		if (r != EFI_SUCCESS)
-			return r;
 	}

 	/* Get the driver binding protocol */
@@ -3579,7 +3582,7 @@  static efi_status_t EFIAPI efi_disconnect_controller(
 		}
 	}
 	/* Remove the driver */
-	if (!child_handle) {
+	if (!child_handle || sole_child) {
 		r = EFI_CALL(binding_protocol->stop(binding_protocol,
 						    controller_handle,
 						    0, NULL));