summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/efi_driver/efi_uclass.c12
-rw-r--r--lib/efi_loader/efi_boottime.c20
-rw-r--r--lib/efi_loader/efi_disk.c7
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;