diff --git a/include/efi_driver.h b/include/efi_driver.h index 71e0d3194e..63a95e4cf8 100644 --- a/include/efi_driver.h +++ b/include/efi_driver.h @@ -32,12 +32,15 @@ struct efi_driver_binding_extended_protocol { * EFI_DRIVER_BINDING_PROTOCOL. * @child_protocol: Protocol supported by the child handles generated by * the EFI driver. + * @init: Function called by the EFI uclass after installing the + * driver binding protocol. * @bind: Function called by the EFI uclass to attach the * driver to EFI driver to a handle. */ struct efi_driver_ops { const efi_guid_t *protocol; const efi_guid_t *child_protocol; + efi_status_t (*init)(struct efi_driver_binding_extended_protocol *this); efi_status_t (*bind)(struct efi_driver_binding_extended_protocol *this, efi_handle_t handle, void *interface); }; diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c index f440067f70..bd3688848b 100644 --- a/lib/efi_driver/efi_block_device.c +++ b/lib/efi_driver/efi_block_device.c @@ -197,6 +197,17 @@ static efi_status_t efi_bl_bind( return ret; } +/** + * efi_bl_init() - initialize block device driver + * + * @this: extended driver binding protocol + */ +static efi_status_t +efi_bl_init(struct efi_driver_binding_extended_protocol *this) +{ + return EFI_SUCCESS; +} + /* Block device driver operators */ static const struct blk_ops efi_blk_ops = { .read = efi_bl_read, @@ -215,6 +226,7 @@ U_BOOT_DRIVER(efi_blk) = { static const struct efi_driver_ops driver_ops = { .protocol = &efi_block_io_guid, .child_protocol = &efi_block_io_guid, + .init = efi_bl_init, .bind = efi_bl_bind, }; diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c index 0a16c594e3..2193f8493f 100644 --- a/lib/efi_driver/efi_uclass.c +++ b/lib/efi_driver/efi_uclass.c @@ -284,7 +284,7 @@ static efi_status_t efi_add_driver(struct driver *drv) bp->bp.start = efi_uc_start; bp->bp.stop = efi_uc_stop; bp->bp.version = 0xffffffff; - bp->ops = drv->ops; + bp->ops = ops; ret = efi_create_handle(&bp->bp.driver_binding_handle); if (ret != EFI_SUCCESS) { @@ -294,13 +294,20 @@ static efi_status_t efi_add_driver(struct driver *drv) 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) { - efi_delete_handle(bp->bp.driver_binding_handle); - free(bp); - goto out; + if (ret != EFI_SUCCESS) + goto err; + if (ops->init) { + ret = ops->init(bp); + if (ret != EFI_SUCCESS) + goto err; } out: return ret; + +err: + efi_delete_handle(bp->bp.driver_binding_handle); + free(bp); + return ret; } /** diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index c633fcd91e..113d5d5d56 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -198,6 +198,11 @@ static efi_status_t __efi_init_early(void) if (ret != EFI_SUCCESS) goto out; + /* Initialize EFI driver uclass */ + ret = efi_driver_init(); + if (ret != EFI_SUCCESS) + goto out; + ret = efi_disk_init(); out: return ret; @@ -319,11 +324,6 @@ efi_status_t efi_init_obj_list(void) if (ret != EFI_SUCCESS) goto out; - /* Initialize EFI driver uclass */ - ret = efi_driver_init(); - if (ret != EFI_SUCCESS) - goto out; - if (IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)) { ret = efi_load_capsule_drivers(); if (ret != EFI_SUCCESS)