diff options
author | Lukas Wunner <lukas@wunner.de> | 2017-01-31 16:21:33 +0300 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-02-01 10:45:42 +0300 |
commit | 2bd79f30eea1a7c3082c930a91370bb68435b86d (patch) | |
tree | 7899bb411403768836d29e3f714ad44254569546 /drivers/firmware/efi/libstub/efi-stub-helper.c | |
parent | bf29bddf0417a4783da3b24e8c9e017ac649326f (diff) | |
download | linux-2bd79f30eea1a7c3082c930a91370bb68435b86d.tar.xz |
efi: Deduplicate efi_file_size() / _read() / _close()
There's one ARM, one x86_32 and one x86_64 version which can be folded
into a single shared version by masking their differences with the shiny
new efi_call_proto() macro.
No functional change intended.
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: http://lkml.kernel.org/r/1485868902-20401-2-git-send-email-ard.biesheuvel@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/firmware/efi/libstub/efi-stub-helper.c')
-rw-r--r-- | drivers/firmware/efi/libstub/efi-stub-helper.c | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 757badc1debb..6ee9164251a9 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -338,6 +338,69 @@ void efi_free(efi_system_table_t *sys_table_arg, unsigned long size, efi_call_early(free_pages, addr, nr_pages); } +static efi_status_t efi_file_size(efi_system_table_t *sys_table_arg, void *__fh, + efi_char16_t *filename_16, void **handle, + u64 *file_sz) +{ + efi_file_handle_t *h, *fh = __fh; + efi_file_info_t *info; + efi_status_t status; + efi_guid_t info_guid = EFI_FILE_INFO_ID; + unsigned long info_sz; + + status = efi_call_proto(efi_file_handle, open, fh, &h, filename_16, + EFI_FILE_MODE_READ, (u64)0); + if (status != EFI_SUCCESS) { + efi_printk(sys_table_arg, "Failed to open file: "); + efi_char16_printk(sys_table_arg, filename_16); + efi_printk(sys_table_arg, "\n"); + return status; + } + + *handle = h; + + info_sz = 0; + status = efi_call_proto(efi_file_handle, get_info, h, &info_guid, + &info_sz, NULL); + if (status != EFI_BUFFER_TOO_SMALL) { + efi_printk(sys_table_arg, "Failed to get file info size\n"); + return status; + } + +grow: + status = efi_call_early(allocate_pool, EFI_LOADER_DATA, + info_sz, (void **)&info); + if (status != EFI_SUCCESS) { + efi_printk(sys_table_arg, "Failed to alloc mem for file info\n"); + return status; + } + + status = efi_call_proto(efi_file_handle, get_info, h, &info_guid, + &info_sz, info); + if (status == EFI_BUFFER_TOO_SMALL) { + efi_call_early(free_pool, info); + goto grow; + } + + *file_sz = info->file_size; + efi_call_early(free_pool, info); + + if (status != EFI_SUCCESS) + efi_printk(sys_table_arg, "Failed to get initrd info\n"); + + return status; +} + +static efi_status_t efi_file_read(void *handle, unsigned long *size, void *addr) +{ + return efi_call_proto(efi_file_handle, read, handle, size, addr); +} + +static efi_status_t efi_file_close(void *handle) +{ + return efi_call_proto(efi_file_handle, close, handle); +} + /* * Parse the ASCII string 'cmdline' for EFI options, denoted by the efi= * option, e.g. efi=nochunk. |