}
/**
- * efi_install_multiple_protocol_interfaces() - Install multiple protocol
+ * efi_install_multiple_protocol_interfaces_int() - Install multiple protocol
* interfaces
* @handle: handle on which the protocol interfaces shall be installed
- * @...: NULL terminated argument list with pairs of protocol GUIDS and
- * interfaces
+ * @argptr: va_list of args
*
- * This function implements the MultipleProtocolInterfaces service.
- *
- * See the Unified Extensible Firmware Interface (UEFI) specification for
- * details.
+ * Core functionality of efi_install_multiple_protocol_interfaces
+ * Must not be called directly
*
* Return: status code
*/
-efi_status_t EFIAPI efi_install_multiple_protocol_interfaces
- (efi_handle_t *handle, ...)
+static efi_status_t EFIAPI
+efi_install_multiple_protocol_interfaces_int(efi_handle_t *handle,
+ efi_va_list argptr)
{
- EFI_ENTRY("%p", handle);
-
- efi_va_list argptr;
const efi_guid_t *protocol;
void *protocol_interface;
efi_handle_t old_handle;
- efi_status_t r = EFI_SUCCESS;
+ efi_status_t ret = EFI_SUCCESS;
int i = 0;
+ efi_va_list argptr_copy;
if (!handle)
- return EFI_EXIT(EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
- efi_va_start(argptr, handle);
+ efi_va_copy(argptr_copy, argptr);
for (;;) {
protocol = efi_va_arg(argptr, efi_guid_t*);
if (!protocol)
if (!guidcmp(protocol, &efi_guid_device_path)) {
struct efi_device_path *dp = protocol_interface;
- r = EFI_CALL(efi_locate_device_path(protocol, &dp,
- &old_handle));
- if (r == EFI_SUCCESS &&
+ ret = EFI_CALL(efi_locate_device_path(protocol, &dp,
+ &old_handle));
+ if (ret == EFI_SUCCESS &&
dp->type == DEVICE_PATH_TYPE_END) {
EFI_PRINT("Path %pD already installed\n",
protocol_interface);
- r = EFI_ALREADY_STARTED;
+ ret = EFI_ALREADY_STARTED;
break;
}
}
- r = EFI_CALL(efi_install_protocol_interface(
- handle, protocol,
- EFI_NATIVE_INTERFACE,
- protocol_interface));
- if (r != EFI_SUCCESS)
+ ret = EFI_CALL(efi_install_protocol_interface(handle, protocol,
+ EFI_NATIVE_INTERFACE,
+ protocol_interface));
+ if (ret != EFI_SUCCESS)
break;
i++;
}
- efi_va_end(argptr);
- if (r == EFI_SUCCESS)
- return EFI_EXIT(r);
+ if (ret == EFI_SUCCESS)
+ goto out;
/* If an error occurred undo all changes. */
- efi_va_start(argptr, handle);
for (; i; --i) {
- protocol = efi_va_arg(argptr, efi_guid_t*);
- protocol_interface = efi_va_arg(argptr, void*);
+ protocol = efi_va_arg(argptr_copy, efi_guid_t*);
+ protocol_interface = efi_va_arg(argptr_copy, void*);
EFI_CALL(efi_uninstall_protocol_interface(*handle, protocol,
protocol_interface));
}
- efi_va_end(argptr);
- return EFI_EXIT(r);
+out:
+ efi_va_end(argptr_copy);
+ return ret;
+
}
/**
- * efi_uninstall_multiple_protocol_interfaces() - uninstall multiple protocol
- * interfaces
- * @handle: handle from which the protocol interfaces shall be removed
+ * efi_install_multiple_protocol_interfaces() - Install multiple protocol
+ * interfaces
+ * @handle: handle on which the protocol interfaces shall be installed
* @...: NULL terminated argument list with pairs of protocol GUIDS and
* interfaces
*
- * This function implements the UninstallMultipleProtocolInterfaces service.
+ *
+ * This is the function for internal usage in U-Boot. For the API function
+ * implementing the InstallMultipleProtocol service see
+ * efi_install_multiple_protocol_interfaces_ext()
+ *
+ * Return: status code
+ */
+efi_status_t EFIAPI
+efi_install_multiple_protocol_interfaces(efi_handle_t *handle, ...)
+{
+ efi_status_t ret;
+ efi_va_list argptr;
+
+ efi_va_start(argptr, handle);
+ ret = efi_install_multiple_protocol_interfaces_int(handle, argptr);
+ efi_va_end(argptr);
+ return ret;
+}
+
+/**
+ * efi_install_multiple_protocol_interfaces_ext() - Install multiple protocol
+ * interfaces
+ * @handle: handle on which the protocol interfaces shall be installed
+ * @...: NULL terminated argument list with pairs of protocol GUIDS and
+ * interfaces
+ *
+ * This function implements the MultipleProtocolInterfaces service.
*
* See the Unified Extensible Firmware Interface (UEFI) specification for
* details.
*
* Return: status code
*/
-static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
- efi_handle_t handle, ...)
+static efi_status_t EFIAPI
+efi_install_multiple_protocol_interfaces_ext(efi_handle_t *handle, ...)
{
EFI_ENTRY("%p", handle);
-
+ efi_status_t ret;
efi_va_list argptr;
+
+ efi_va_start(argptr, handle);
+ ret = efi_install_multiple_protocol_interfaces_int(handle, argptr);
+ efi_va_end(argptr);
+ return EFI_EXIT(ret);
+}
+
+/**
+ * efi_uninstall_multiple_protocol_interfaces_int() - wrapper for uninstall
+ * multiple protocol
+ * interfaces
+ * @handle: handle from which the protocol interfaces shall be removed
+ * @argptr: va_list of args
+ *
+ * Core functionality of efi_uninstall_multiple_protocol_interfaces
+ * Must not be called directly
+ *
+ * Return: status code
+ */
+static efi_status_t EFIAPI
+efi_uninstall_multiple_protocol_interfaces_int(efi_handle_t handle,
+ efi_va_list argptr)
+{
const efi_guid_t *protocol;
void *protocol_interface;
- efi_status_t r = EFI_SUCCESS;
+ efi_status_t ret;
size_t i = 0;
+ efi_va_list argptr_copy;
if (!handle)
- return EFI_EXIT(EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
- efi_va_start(argptr, handle);
+ efi_va_copy(argptr_copy, argptr);
for (;;) {
protocol = efi_va_arg(argptr, efi_guid_t*);
if (!protocol)
break;
protocol_interface = efi_va_arg(argptr, void*);
- r = efi_uninstall_protocol(handle, protocol,
- protocol_interface);
- if (r != EFI_SUCCESS)
+ ret = efi_uninstall_protocol(handle, protocol,
+ protocol_interface);
+ if (ret != EFI_SUCCESS)
break;
i++;
}
- efi_va_end(argptr);
- if (r == EFI_SUCCESS) {
+ if (ret == EFI_SUCCESS) {
/* If the last protocol has been removed, delete the handle. */
if (list_empty(&handle->protocols)) {
list_del(&handle->link);
free(handle);
}
- return EFI_EXIT(r);
+ goto out;
}
/* If an error occurred undo all changes. */
- efi_va_start(argptr, handle);
for (; i; --i) {
- protocol = efi_va_arg(argptr, efi_guid_t*);
- protocol_interface = efi_va_arg(argptr, void*);
+ protocol = efi_va_arg(argptr_copy, efi_guid_t*);
+ protocol_interface = efi_va_arg(argptr_copy, void*);
EFI_CALL(efi_install_protocol_interface(&handle, protocol,
EFI_NATIVE_INTERFACE,
protocol_interface));
}
+ /*
+ * If any errors are generated while the protocol interfaces are being
+ * uninstalled, then the protocols uninstalled prior to the error will
+ * be reinstalled using InstallProtocolInterface() and the status code
+ * EFI_INVALID_PARAMETER is returned.
+ */
+ ret = EFI_INVALID_PARAMETER;
+
+out:
+ efi_va_end(argptr_copy);
+ return ret;
+}
+
+/**
+ * efi_uninstall_multiple_protocol_interfaces() - uninstall multiple protocol
+ * interfaces
+ * @handle: handle from which the protocol interfaces shall be removed
+ * @...: NULL terminated argument list with pairs of protocol GUIDS and
+ * interfaces
+ *
+ * This function implements the UninstallMultipleProtocolInterfaces service.
+ *
+ * This is the function for internal usage in U-Boot. For the API function
+ * implementing the UninstallMultipleProtocolInterfaces service see
+ * efi_uninstall_multiple_protocol_interfaces_ext()
+ *
+ * Return: status code
+ */
+efi_status_t EFIAPI
+efi_uninstall_multiple_protocol_interfaces(efi_handle_t handle, ...)
+{
+ efi_status_t ret;
+ efi_va_list argptr;
+
+ efi_va_start(argptr, handle);
+ ret = efi_uninstall_multiple_protocol_interfaces_int(handle, argptr);
efi_va_end(argptr);
+ return ret;
+}
+
+/**
+ * efi_uninstall_multiple_protocol_interfaces_ext() - uninstall multiple protocol
+ * interfaces
+ * @handle: handle from which the protocol interfaces shall be removed
+ * @...: NULL terminated argument list with pairs of protocol GUIDS and
+ * interfaces
+ *
+ * This function implements the UninstallMultipleProtocolInterfaces service.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * Return: status code
+ */
+static efi_status_t EFIAPI
+efi_uninstall_multiple_protocol_interfaces_ext(efi_handle_t handle, ...)
+{
+ EFI_ENTRY("%p", handle);
+ efi_status_t ret;
+ efi_va_list argptr;
- /* In case of an error always return EFI_INVALID_PARAMETER */
- return EFI_EXIT(EFI_INVALID_PARAMETER);
+ efi_va_start(argptr, handle);
+ ret = efi_uninstall_multiple_protocol_interfaces_int(handle, argptr);
+ efi_va_end(argptr);
+ return EFI_EXIT(ret);
}
/**
.locate_handle_buffer = efi_locate_handle_buffer,
.locate_protocol = efi_locate_protocol,
.install_multiple_protocol_interfaces =
- efi_install_multiple_protocol_interfaces,
+ efi_install_multiple_protocol_interfaces_ext,
.uninstall_multiple_protocol_interfaces =
- efi_uninstall_multiple_protocol_interfaces,
+ efi_uninstall_multiple_protocol_interfaces_ext,
.calculate_crc32 = efi_calculate_crc32,
.copy_mem = efi_copy_mem,
.set_mem = efi_set_mem,
dp->end.length = sizeof(struct efi_device_path);
/* Create root node and install protocols */
- ret = EFI_CALL(efi_install_multiple_protocol_interfaces
- (&efi_root,
- /* Device path protocol */
- &efi_guid_device_path, dp,
+ ret = efi_install_multiple_protocol_interfaces
+ (&efi_root,
+ /* Device path protocol */
+ &efi_guid_device_path, dp,
#if CONFIG_IS_ENABLED(EFI_DEVICE_PATH_TO_TEXT)
- /* Device path to text protocol */
- &efi_guid_device_path_to_text_protocol,
- (void *)&efi_device_path_to_text,
+ /* Device path to text protocol */
+ &efi_guid_device_path_to_text_protocol,
+ &efi_device_path_to_text,
#endif
-#ifdef CONFIG_EFI_DEVICE_PATH_UTIL
- /* Device path utilities protocol */
- &efi_guid_device_path_utilities_protocol,
- (void *)&efi_device_path_utilities,
+#if CONFIG_IS_ENABLED(EFI_DEVICE_PATH_UTIL)
+ /* Device path utilities protocol */
+ &efi_guid_device_path_utilities_protocol,
+ &efi_device_path_utilities,
#endif
-#ifdef CONFIG_EFI_DT_FIXUP
- /* Device-tree fix-up protocol */
- &efi_guid_dt_fixup_protocol,
- (void *)&efi_dt_fixup_prot,
+#if CONFIG_IS_ENABLED(EFI_DT_FIXUP)
+ /* Device-tree fix-up protocol */
+ &efi_guid_dt_fixup_protocol,
+ &efi_dt_fixup_prot,
#endif
#if CONFIG_IS_ENABLED(EFI_UNICODE_COLLATION_PROTOCOL2)
- &efi_guid_unicode_collation_protocol2,
- (void *)&efi_unicode_collation_protocol2,
+ &efi_guid_unicode_collation_protocol2,
+ &efi_unicode_collation_protocol2,
#endif
#if CONFIG_IS_ENABLED(EFI_LOADER_HII)
- /* HII string protocol */
- &efi_guid_hii_string_protocol,
- (void *)&efi_hii_string,
- /* HII database protocol */
- &efi_guid_hii_database_protocol,
- (void *)&efi_hii_database,
+ /* HII string protocol */
+ &efi_guid_hii_string_protocol,
+ &efi_hii_string,
+ /* HII database protocol */
+ &efi_guid_hii_database_protocol,
+ &efi_hii_database,
#endif
- NULL));
+ NULL);
efi_root->type = EFI_OBJECT_TYPE_U_BOOT_FIRMWARE;
return ret;
}