return ret;
}
-/**
- * bootefi_run_finish() - finish up after running an EFI test
- *
- * @loaded_image_info: Pointer to a struct which holds the loaded image info
- * @image_obj: Pointer to a struct which holds the loaded image object
- */
-static void bootefi_run_finish(struct efi_loaded_image_obj *image_obj,
- struct efi_loaded_image *loaded_image_info)
-{
- efi_restore_gd();
- free(loaded_image_info->load_options);
- efi_delete_handle(&image_obj->header);
-}
-
/**
* do_efi_selftest() - execute EFI selftest
*
/* Execute the test */
ret = EFI_CALL(efi_selftest(&image_obj->header, &systab));
- bootefi_run_finish(image_obj, loaded_image_info);
+ efi_restore_gd();
+ free(loaded_image_info->load_options);
+ if (ret != EFI_SUCCESS)
+ efi_delete_handle(&image_obj->header);
+ else
+ ret = efi_delete_handle(&image_obj->header);
return ret != EFI_SUCCESS;
}
/* Create handle */
efi_status_t efi_create_handle(efi_handle_t *handle);
/* Delete handle */
-void efi_delete_handle(efi_handle_t obj);
+efi_status_t efi_delete_handle(efi_handle_t obj);
/* Call this to validate a handle and find the EFI object for it */
struct efi_object *efi_search_obj(const efi_handle_t handle);
/* Locate device_path handle */
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);
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;
}
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;
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;
}
* 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;
}
/**
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;
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;