diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/efi_driver/efi_uclass.c | 12 | ||||
-rw-r--r-- | lib/efi_loader/efi_boottime.c | 20 | ||||
-rw-r--r-- | lib/efi_loader/efi_disk.c | 7 |
3 files changed, 25 insertions, 14 deletions
diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c index 45f93519887..66a45e156d6 100644 --- a/lib/efi_driver/efi_uclass.c +++ b/lib/efi_driver/efi_uclass.c @@ -285,10 +285,8 @@ static efi_status_t efi_add_driver(struct driver *drv) bp->ops = ops; ret = efi_create_handle(&bp->bp.driver_binding_handle); - if (ret != EFI_SUCCESS) { - free(bp); - goto out; - } + if (ret != EFI_SUCCESS) + goto err; bp->bp.image_handle = bp->bp.driver_binding_handle; ret = efi_add_protocol(bp->bp.driver_binding_handle, &efi_guid_driver_binding_protocol, bp); @@ -299,11 +297,11 @@ static efi_status_t efi_add_driver(struct driver *drv) if (ret != EFI_SUCCESS) goto err; } -out: - return ret; + return ret; err: - efi_delete_handle(bp->bp.driver_binding_handle); + if (bp->bp.driver_binding_handle) + efi_delete_handle(bp->bp.driver_binding_handle); free(bp); return ret; } diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 052fe481e47..0e89c8505b1 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -59,6 +59,10 @@ static efi_handle_t current_image; static volatile gd_t *efi_gd, *app_gd; #endif +static efi_status_t efi_uninstall_protocol + (efi_handle_t handle, const efi_guid_t *protocol, + void *protocol_interface); + /* 1 if inside U-Boot code, 0 if inside EFI payload code */ static int entry_count = 1; static int nesting_level; @@ -610,8 +614,8 @@ static efi_status_t efi_remove_all_protocols(const efi_handle_t handle) list_for_each_entry_safe(protocol, pos, &efiobj->protocols, link) { efi_status_t ret; - ret = efi_remove_protocol(handle, &protocol->guid, - protocol->protocol_interface); + ret = efi_uninstall_protocol(handle, &protocol->guid, + protocol->protocol_interface); if (ret != EFI_SUCCESS) return ret; } @@ -622,19 +626,23 @@ static efi_status_t efi_remove_all_protocols(const efi_handle_t handle) * efi_delete_handle() - delete handle * * @handle: handle to delete + * + * Return: status code */ -void efi_delete_handle(efi_handle_t handle) +efi_status_t efi_delete_handle(efi_handle_t handle) { efi_status_t ret; ret = efi_remove_all_protocols(handle); - if (ret == EFI_INVALID_PARAMETER) { - log_err("Can't remove invalid handle %p\n", handle); - return; + if (ret != EFI_SUCCESS) { + log_err("Handle %p has protocols installed. Unable to delete\n", handle); + return ret; } list_del(&handle->link); free(handle); + + return ret; } /** diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 28c8cdf7100..46cb5704a72 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -708,6 +708,7 @@ int efi_disk_remove(void *ctx, struct event *event) efi_handle_t handle; struct blk_desc *desc; struct efi_disk_obj *diskobj = NULL; + efi_status_t ret; if (dev_tag_get_ptr(dev, DM_TAG_EFI, (void **)&handle)) return 0; @@ -727,10 +728,14 @@ int efi_disk_remove(void *ctx, struct event *event) return 0; } + ret = efi_delete_handle(handle); + /* Do not delete DM device if there are still EFI drivers attached. */ + if (ret != EFI_SUCCESS) + return -1; + if (diskobj) efi_free_pool(diskobj->dp); - efi_delete_handle(handle); dev_tag_del(dev, DM_TAG_EFI); return 0; |