diff options
author | Heinrich Schuchardt <xypron.glpk@gmx.de> | 2017-10-26 20:25:44 +0300 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2017-12-01 15:22:56 +0300 |
commit | 843ce54c7470c58fa7251ad07abeed67b4fc56c4 (patch) | |
tree | 4a6023cb76ac7526ffec958f0c08c874731f9205 | |
parent | af1408e080e21b1bf04c24740ceb39f118c3293b (diff) | |
download | u-boot-843ce54c7470c58fa7251ad07abeed67b4fc56c4.tar.xz |
efi_loader implement UninstallMultipleProtocolInterfaces
Implement UninstallMultipleProtocolInterfaces.
The efi_uninstall_multipled_protocol_interfaces tries to
uninstall protocols one by one. If an error occurs all
uninstalled protocols are reinstalled.
As the implementation efi_uninstall_protocol_interface is
still incomplete the function will fail.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 397759397f..b79b3aed49 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1809,7 +1809,45 @@ static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces( void *handle, ...) { EFI_ENTRY("%p", handle); - return EFI_EXIT(EFI_INVALID_PARAMETER); + + va_list argptr; + const efi_guid_t *protocol; + void *protocol_interface; + efi_status_t r = EFI_SUCCESS; + size_t i = 0; + + if (!handle) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + va_start(argptr, handle); + for (;;) { + protocol = va_arg(argptr, efi_guid_t*); + if (!protocol) + break; + protocol_interface = va_arg(argptr, void*); + r = EFI_CALL(efi_uninstall_protocol_interface( + handle, protocol, + protocol_interface)); + if (r != EFI_SUCCESS) + break; + i++; + } + va_end(argptr); + if (r == EFI_SUCCESS) + return EFI_EXIT(r); + + /* If an error occurred undo all changes. */ + va_start(argptr, handle); + for (; i; --i) { + protocol = va_arg(argptr, efi_guid_t*); + protocol_interface = va_arg(argptr, void*); + EFI_CALL(efi_install_protocol_interface(&handle, protocol, + EFI_NATIVE_INTERFACE, + protocol_interface)); + } + va_end(argptr); + + return EFI_EXIT(r); } /* |