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 <[email protected]>
---
 lib/efi_loader/efi_boottime.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

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));
--
2.28.0

Reply via email to