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 <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
master
Heinrich Schuchardt 7 years ago committed by Alexander Graf
parent 56d9288858
commit 678e03a00c
  1. 2
      include/efi_loader.h
  2. 186
      lib/efi_loader/efi_boottime.c

@ -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 */

@ -360,6 +360,106 @@ efi_status_t efi_create_handle(void **handle)
}
/*
* 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.
*/
@ -718,39 +818,6 @@ struct efi_object *efi_search_obj(const void *handle)
}
/*
* 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.
*
* @handle handle on which the protocol shall be installed
@ -781,59 +848,6 @@ efi_status_t efi_add_protocol(const void *handle, const efi_guid_t *protocol,
}
/*
* 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.
*
* This function implements the InstallProtocolInterface service.

Loading…
Cancel
Save