From 678e03a00cafc9009f05cbcc3192235f2b8f9a33 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 4 Dec 2017 18:03:02 +0100 Subject: [PATCH] efi_loader: new function efi_delete_handle() Provide a function to remove a handle from the object list after removing all protocols. To avoid forward declarations other functions have to move up in the coding. Signed-off-by: Heinrich Schuchardt Signed-off-by: Alexander Graf --- include/efi_loader.h | 2 + lib/efi_loader/efi_boottime.c | 186 ++++++++++++++++++---------------- 2 files changed, 102 insertions(+), 86 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index 78237f14ae..6185055e78 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -190,6 +190,8 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path); void efi_add_handle(struct efi_object *obj); /* Create handle */ efi_status_t efi_create_handle(void **handle); +/* Delete handle */ +void efi_delete_handle(struct efi_object *obj); /* Call this to validate a handle and find the EFI object for it */ struct efi_object *efi_search_obj(const void *handle); /* Find a protocol on a handle */ diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index a9ba1ac394..7c8f3134d1 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -359,6 +359,106 @@ efi_status_t efi_create_handle(void **handle) return r; } +/* + * Find a protocol on a handle. + * + * @handle handle + * @protocol_guid GUID of the protocol + * @handler reference to the protocol + * @return status code + */ +efi_status_t efi_search_protocol(const void *handle, + const efi_guid_t *protocol_guid, + struct efi_handler **handler) +{ + struct efi_object *efiobj; + struct list_head *lhandle; + + if (!handle || !protocol_guid) + return EFI_INVALID_PARAMETER; + efiobj = efi_search_obj(handle); + if (!efiobj) + return EFI_INVALID_PARAMETER; + list_for_each(lhandle, &efiobj->protocols) { + struct efi_handler *protocol; + + protocol = list_entry(lhandle, struct efi_handler, link); + if (!guidcmp(protocol->guid, protocol_guid)) { + if (handler) + *handler = protocol; + return EFI_SUCCESS; + } + } + return EFI_NOT_FOUND; +} + +/* + * Delete protocol from a handle. + * + * @handle handle from which the protocol shall be deleted + * @protocol GUID of the protocol to be deleted + * @protocol_interface interface of the protocol implementation + * @return status code + */ +efi_status_t efi_remove_protocol(const void *handle, const efi_guid_t *protocol, + void *protocol_interface) +{ + struct efi_handler *handler; + efi_status_t ret; + + ret = efi_search_protocol(handle, protocol, &handler); + if (ret != EFI_SUCCESS) + return ret; + if (guidcmp(handler->guid, protocol)) + return EFI_INVALID_PARAMETER; + list_del(&handler->link); + free(handler); + return EFI_SUCCESS; +} + +/* + * Delete all protocols from a handle. + * + * @handle handle from which the protocols shall be deleted + * @return status code + */ +efi_status_t efi_remove_all_protocols(const void *handle) +{ + struct efi_object *efiobj; + struct list_head *lhandle; + struct list_head *pos; + + efiobj = efi_search_obj(handle); + if (!efiobj) + return EFI_INVALID_PARAMETER; + list_for_each_safe(lhandle, pos, &efiobj->protocols) { + struct efi_handler *protocol; + efi_status_t ret; + + protocol = list_entry(lhandle, struct efi_handler, link); + + ret = efi_remove_protocol(handle, protocol->guid, + protocol->protocol_interface); + if (ret != EFI_SUCCESS) + return ret; + } + return EFI_SUCCESS; +} + +/* + * Delete handle. + * + * @handle handle to delete + */ +void efi_delete_handle(struct efi_object *obj) +{ + if (!obj) + return; + efi_remove_all_protocols(obj->handle); + list_del(&obj->link); + free(obj); +} + /* * Our event capabilities are very limited. Only a small limited * number of events is allowed to coexist. @@ -717,39 +817,6 @@ struct efi_object *efi_search_obj(const void *handle) return NULL; } -/* - * Find a protocol on a handle. - * - * @handle handle - * @protocol_guid GUID of the protocol - * @handler reference to the protocol - * @return status code - */ -efi_status_t efi_search_protocol(const void *handle, - const efi_guid_t *protocol_guid, - struct efi_handler **handler) -{ - struct efi_object *efiobj; - struct list_head *lhandle; - - if (!handle || !protocol_guid) - return EFI_INVALID_PARAMETER; - efiobj = efi_search_obj(handle); - if (!efiobj) - return EFI_INVALID_PARAMETER; - list_for_each(lhandle, &efiobj->protocols) { - struct efi_handler *protocol; - - protocol = list_entry(lhandle, struct efi_handler, link); - if (!guidcmp(protocol->guid, protocol_guid)) { - if (handler) - *handler = protocol; - return EFI_SUCCESS; - } - } - return EFI_NOT_FOUND; -} - /* * Install new protocol on a handle. * @@ -780,59 +847,6 @@ efi_status_t efi_add_protocol(const void *handle, const efi_guid_t *protocol, return EFI_SUCCESS; } -/* - * Delete protocol from a handle. - * - * @handle handle from which the protocol shall be deleted - * @protocol GUID of the protocol to be deleted - * @protocol_interface interface of the protocol implementation - * @return status code - */ -efi_status_t efi_remove_protocol(const void *handle, const efi_guid_t *protocol, - void *protocol_interface) -{ - struct efi_handler *handler; - efi_status_t ret; - - ret = efi_search_protocol(handle, protocol, &handler); - if (ret != EFI_SUCCESS) - return ret; - if (guidcmp(handler->guid, protocol)) - return EFI_INVALID_PARAMETER; - list_del(&handler->link); - free(handler); - return EFI_SUCCESS; -} - -/* - * Delete all protocols from a handle. - * - * @handle handle from which the protocols shall be deleted - * @return status code - */ -efi_status_t efi_remove_all_protocols(const void *handle) -{ - struct efi_object *efiobj; - struct list_head *lhandle; - struct list_head *pos; - - efiobj = efi_search_obj(handle); - if (!efiobj) - return EFI_INVALID_PARAMETER; - list_for_each_safe(lhandle, pos, &efiobj->protocols) { - struct efi_handler *protocol; - efi_status_t ret; - - protocol = list_entry(lhandle, struct efi_handler, link); - - ret = efi_remove_protocol(handle, protocol->guid, - protocol->protocol_interface); - if (ret != EFI_SUCCESS) - return ret; - } - return EFI_SUCCESS; -} - /* * Install protocol interface. * -- 2.39.5