summaryrefslogtreecommitdiff
path: root/lib/efi_loader
diff options
context:
space:
mode:
authorIlias Apalodimas <ilias.apalodimas@linaro.org>2023-06-20 09:19:28 +0300
committerHeinrich Schuchardt <heinrich.schuchardt@canonical.com>2023-07-15 12:20:41 +0300
commit239d59a65e203171fb94d0ab935ced35902fed1b (patch)
tree17121d76687fac859848b846143c875fa6c49c99 /lib/efi_loader
parent7aa022c797171e4405b66ee41e5644835ca9c9dd (diff)
downloadu-boot-239d59a65e203171fb94d0ab935ced35902fed1b.tar.xz
efi_loader: reconnect drivers on failure
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>
Diffstat (limited to 'lib/efi_loader')
-rw-r--r--lib/efi_loader/efi_boottime.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index d5065f296a..5e932ee273 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;
}