From 43a5891c66c8fe961999415b051c827ce1b543c4 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 3 Oct 2022 10:35:35 +0200 Subject: efi_driver: fix error handling If creating the block device fails, * delete all created objects and references * close the protocol interface on the controller Signed-off-by: Heinrich Schuchardt --- lib/efi_driver/efi_uclass.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'lib/efi_driver/efi_uclass.c') diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c index 74dd0032437..5a285aad898 100644 --- a/lib/efi_driver/efi_uclass.c +++ b/lib/efi_driver/efi_uclass.c @@ -11,7 +11,7 @@ * The uclass provides the bind, start, and stop entry points for the driver * binding protocol. * - * In bind() and stop() it checks if the controller implements the protocol + * In supported() and bind() it checks if the controller implements the protocol * supported by the EFI driver. In the start() function it calls the bind() * function of the EFI driver. In the stop() function it destroys the child * controllers. @@ -144,18 +144,19 @@ static efi_status_t EFIAPI efi_uc_start( goto out; } ret = check_node_type(controller_handle); - if (ret != EFI_SUCCESS) { - r = EFI_CALL(systab.boottime->close_protocol( - controller_handle, bp->ops->protocol, - this->driver_binding_handle, - controller_handle)); - if (r != EFI_SUCCESS) - EFI_PRINT("Failure to close handle\n"); + if (ret != EFI_SUCCESS) + goto err; + ret = bp->ops->bind(controller_handle, interface); + if (ret == EFI_SUCCESS) goto out; - } - /* TODO: driver specific stuff */ - bp->ops->bind(controller_handle, interface); +err: + r = EFI_CALL(systab.boottime->close_protocol( + controller_handle, bp->ops->protocol, + this->driver_binding_handle, + controller_handle)); + if (r != EFI_SUCCESS) + EFI_PRINT("Failure to close handle\n"); out: return EFI_EXIT(ret); -- cgit v1.2.3 From 8b1641680d220e7e6cf467f7e2d627c4cbd66436 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 4 Oct 2022 12:50:51 +0200 Subject: efi_driver: simplify efi_uc_stop(), call efi_free_pool() We have exported efi_free_pool(). There is no need to use EFI_CALL(). Signed-off-by: Heinrich Schuchardt --- lib/efi_driver/efi_uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/efi_driver/efi_uclass.c') diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c index 5a285aad898..aabee0e2601 100644 --- a/lib/efi_driver/efi_uclass.c +++ b/lib/efi_driver/efi_uclass.c @@ -246,7 +246,7 @@ static efi_status_t EFIAPI efi_uc_stop( goto out; } } - ret = EFI_CALL(systab.boottime->free_pool(entry_buffer)); + ret = efi_free_pool(entry_buffer); if (ret != EFI_SUCCESS) log_err("Cannot free EFI memory pool\n"); -- cgit v1.2.3 From ec4f675f9ebec2535f2cd050aed7f9c106a5bee9 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 4 Oct 2022 19:12:59 +0200 Subject: efi_driver: provide driver binding protocol to bind function DisconnectController() is based on the open protocol information created when the driver opens a protocol with BY_CHILD_CONTROLLER or BY_DRIVER. To create an open protocol information it is required to supply the handle of the driver as agent handle. This information is available as field DriverBindingHandle in the driver binding protocol. Signed-off-by: Heinrich Schuchardt --- lib/efi_driver/efi_uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/efi_driver/efi_uclass.c') diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c index aabee0e2601..0a16c594e3a 100644 --- a/lib/efi_driver/efi_uclass.c +++ b/lib/efi_driver/efi_uclass.c @@ -146,7 +146,7 @@ static efi_status_t EFIAPI efi_uc_start( ret = check_node_type(controller_handle); if (ret != EFI_SUCCESS) goto err; - ret = bp->ops->bind(controller_handle, interface); + ret = bp->ops->bind(bp, controller_handle, interface); if (ret == EFI_SUCCESS) goto out; -- cgit v1.2.3 From 8f8fe1d458664aaa15fa82de78dfdb0eca74b2ca Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 5 Oct 2022 11:28:47 +0200 Subject: efi_driver: add init function to EFI block driver For handling added and removed block devices we need to register events which has to be done when the driver is installed. This patch only creates an empty init function that will be filled with code later on. The function needs to be called before any EFI block devices are used. Move the efi_driver_init() call to early init. Signed-off-by: Heinrich Schuchardt --- lib/efi_driver/efi_uclass.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'lib/efi_driver/efi_uclass.c') diff --git a/lib/efi_driver/efi_uclass.c b/lib/efi_driver/efi_uclass.c index 0a16c594e3a..2193f8493fd 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; } /** -- cgit v1.2.3