diff mbox series

[1/4,v2] efi_loader: reconnect drivers on failure

Message ID 20230620061932.113292-2-ilias.apalodimas@linaro.org
State Accepted
Commit 239d59a65e203171fb94d0ab935ced35902fed1b
Headers show
Series Reconnect controllers on failues | expand

Commit Message

Ilias Apalodimas June 20, 2023, 6:19 a.m. UTC
efi_disconnect_controller() doesn't reconnect drivers in case of
failure.  Reconnect the disconnected drivers properly

Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
---
 lib/efi_loader/efi_boottime.c | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)

--
2.40.1

Comments

Heinrich Schuchardt July 9, 2023, 9:07 a.m. UTC | #1
On 6/20/23 08:19, Ilias Apalodimas wrote:
> efi_disconnect_controller() doesn't reconnect drivers in case of
> failure.  Reconnect the disconnected drivers properly
>
> Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>

Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
diff mbox series

Patch

diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 5006c0e1e4af..d44562d8f4e0 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -97,6 +97,12 @@  static efi_status_t EFIAPI efi_disconnect_controller(
 					efi_handle_t driver_image_handle,
 					efi_handle_t child_handle);

+static
+efi_status_t EFIAPI efi_connect_controller(efi_handle_t controller_handle,
+					   efi_handle_t *driver_image_handle,
+					   struct efi_device_path *remain_device_path,
+					   bool recursive);
+
 /* Called on every callback entry */
 int __efi_entry_check(void)
 {
@@ -1298,7 +1304,7 @@  static efi_status_t efi_disconnect_all_drivers
 				 const efi_guid_t *protocol,
 				 efi_handle_t child_handle)
 {
-	efi_uintn_t number_of_drivers;
+	efi_uintn_t number_of_drivers, tmp;
 	efi_handle_t *driver_handle_buffer;
 	efi_status_t r, ret;

@@ -1308,15 +1314,30 @@  static efi_status_t efi_disconnect_all_drivers
 		return ret;
 	if (!number_of_drivers)
 		return EFI_SUCCESS;
-	ret = EFI_NOT_FOUND;
+
+	tmp = number_of_drivers;
 	while (number_of_drivers) {
-		r = EFI_CALL(efi_disconnect_controller(
+		ret = EFI_CALL(efi_disconnect_controller(
 				handle,
 				driver_handle_buffer[--number_of_drivers],
 				child_handle));
-		if (r == EFI_SUCCESS)
-			ret = r;
+		if (ret != EFI_SUCCESS)
+			goto reconnect;
+	}
+
+	free(driver_handle_buffer);
+	return ret;
+
+reconnect:
+	/* Reconnect all disconnected drivers */
+	for (; number_of_drivers < tmp; number_of_drivers++) {
+		r = EFI_CALL(efi_connect_controller(handle,
+						    &driver_handle_buffer[number_of_drivers],
+						    NULL, true));
+		if (r != EFI_SUCCESS)
+			EFI_PRINT("Failed to reconnect controller\n");
 	}
+
 	free(driver_handle_buffer);
 	return ret;
 }