diff options
author | xypron.glpk@gmx.de <xypron.glpk@gmx.de> | 2017-07-11 22:06:24 +0200 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2017-07-19 14:14:40 +0200 |
commit | 88adae5ef057845f6bc69c63123df4332fe835b1 (patch) | |
tree | 349755e54709b23c59264acedea2cd510615727b /lib | |
parent | 011f432745ae7fdb645e16c03382a4181d262619 (diff) | |
download | u-boot-88adae5ef057845f6bc69c63123df4332fe835b1.tar.gz u-boot-88adae5ef057845f6bc69c63123df4332fe835b1.tar.xz u-boot-88adae5ef057845f6bc69c63123df4332fe835b1.zip |
efi_loader: reimplement efi_locate_protocol
The UEFI specification requires that LocateProtol finds the first
handle supporting the protocol and to return a pointer to its
interface.
So we have to assign the protocols to an efi_object and not use
any separate storage.
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 6f093290eb..339fe55cde 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -786,27 +786,35 @@ out: return EFI_EXIT(r); } -static struct efi_class_map efi_class_maps[] = { - { - .guid = &efi_guid_console_control, - .interface = &efi_console_control - }, -}; - static efi_status_t EFIAPI efi_locate_protocol(efi_guid_t *protocol, void *registration, void **protocol_interface) { + struct list_head *lhandle; int i; EFI_ENTRY("%p, %p, %p", protocol, registration, protocol_interface); - for (i = 0; i < ARRAY_SIZE(efi_class_maps); i++) { - struct efi_class_map *curmap = &efi_class_maps[i]; - if (!guidcmp(protocol, curmap->guid)) { - *protocol_interface = (void*)curmap->interface; - return EFI_EXIT(EFI_SUCCESS); + + if (!protocol || !protocol_interface) + return EFI_EXIT(EFI_INVALID_PARAMETER); + + list_for_each(lhandle, &efi_obj_list) { + struct efi_object *efiobj; + + efiobj = list_entry(lhandle, struct efi_object, link); + for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) { + struct efi_handler *handler = &efiobj->protocols[i]; + + if (!handler->guid) + continue; + if (!guidcmp(handler->guid, protocol)) { + *protocol_interface = + handler->protocol_interface; + return EFI_EXIT(EFI_SUCCESS); + } } } + *protocol_interface = NULL; return EFI_EXIT(EFI_NOT_FOUND); } |