diff mbox series

[4/4,v2] efi_selftests: add extra testcases on controller handling

Message ID 20230620061932.113292-5-ilias.apalodimas@linaro.org
State Accepted
Commit d9df8a5f37c924f79cf7a851f552e057d6f16fd0
Headers show
Series Reconnect controllers on failues | expand

Commit Message

Ilias Apalodimas June 20, 2023, 6:19 a.m. UTC
We recently fixed a few issues wrt to controller handling.  Add a few
test cases to cover the new code.
- return EFI_DEVICE_ERROR the first time the protocol interface of
  the controller is uninstalled, after all the children have been
  disconnected.  This should make the drivers reconnect
- add tests to verify controllers are reconnected when uninstalling a
  protocol fails
- add tests to make sure EFI_NOT_FOUND is returned if a non existent
  interface is being removed

Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
---
 lib/efi_selftest/efi_selftest_controllers.c | 44 +++++++++++++++++++--
 1 file changed, 41 insertions(+), 3 deletions(-)

--
2.40.1
diff mbox series

Patch

diff --git a/lib/efi_selftest/efi_selftest_controllers.c b/lib/efi_selftest/efi_selftest_controllers.c
index 79bc86fb0c3a..513c9868fda9 100644
--- a/lib/efi_selftest/efi_selftest_controllers.c
+++ b/lib/efi_selftest/efi_selftest_controllers.c
@@ -28,6 +28,7 @@  static efi_guid_t guid_child_controller =
 static efi_handle_t handle_controller;
 static efi_handle_t handle_child_controller[NUMBER_OF_CHILD_CONTROLLERS];
 static efi_handle_t handle_driver;
+static bool allow_removal;

 /*
  * Count child controllers
@@ -85,8 +86,8 @@  static efi_status_t EFIAPI supported(
 			controller_handle, EFI_OPEN_PROTOCOL_BY_DRIVER);
 	switch (ret) {
 	case EFI_ACCESS_DENIED:
-	case EFI_ALREADY_STARTED:
 		return ret;
+	case EFI_ALREADY_STARTED:
 	case EFI_SUCCESS:
 		break;
 	default:
@@ -124,8 +125,8 @@  static efi_status_t EFIAPI start(
 			controller_handle, EFI_OPEN_PROTOCOL_BY_DRIVER);
 	switch (ret) {
 	case EFI_ACCESS_DENIED:
-	case EFI_ALREADY_STARTED:
 		return ret;
+	case EFI_ALREADY_STARTED:
 	case EFI_SUCCESS:
 		break;
 	default:
@@ -238,6 +239,9 @@  static efi_status_t EFIAPI stop(
 	if (ret != EFI_SUCCESS)
 		efi_st_error("Cannot free buffer\n");

+	if (!allow_removal)
+		return EFI_DEVICE_ERROR;
+
 	/* Detach driver from controller */
 	ret = boottime->close_protocol(
 			controller_handle, &guid_controller,
@@ -342,6 +346,7 @@  static int execute(void)
 		return EFI_ST_FAILURE;
 	}
 	/* Destroy remaining child controllers and disconnect controller */
+	allow_removal = true;
 	ret = boottime->disconnect_controller(handle_controller, NULL, NULL);
 	if (ret != EFI_SUCCESS) {
 		efi_st_error("Failed to disconnect controller\n");
@@ -393,7 +398,40 @@  static int execute(void)
 		efi_st_error("Number of children %u != %u\n",
 			     (unsigned int)count, NUMBER_OF_CHILD_CONTROLLERS);
 	}
-	/* Uninstall controller protocol */
+
+	allow_removal = false;
+	/* Try to uninstall controller protocol using the wrong interface */
+	ret = boottime->uninstall_protocol_interface(handle_controller,
+						     &guid_controller,
+						     &interface1);
+	if (ret != EFI_NOT_FOUND) {
+		efi_st_error("Interface not checked when uninstalling protocol\n");
+		return EFI_ST_FAILURE;
+	}
+
+	/*
+	 * Uninstall a protocol while Disconnect controller won't
+	 * allow it.
+	 */
+	ret = boottime->uninstall_protocol_interface(handle_controller,
+						     &guid_controller,
+						     &interface2);
+	if (ret != EFI_ACCESS_DENIED) {
+		efi_st_error("Uninstall protocol interface failed\n");
+		return EFI_ST_FAILURE;
+	}
+	/*
+	 * Check number of child controllers and make sure children have
+	 * been reconnected
+	 */
+	ret = count_child_controllers(handle_controller, &guid_controller,
+				      &count);
+	if (ret != EFI_SUCCESS || count != NUMBER_OF_CHILD_CONTROLLERS) {
+		efi_st_error("Number of children %u != %u\n",
+			     (unsigned int)count, NUMBER_OF_CHILD_CONTROLLERS);
+	}
+
+	allow_removal = true;
 	ret = boottime->uninstall_protocol_interface(handle_controller,
 						     &guid_controller,
 						     &interface2);