| // SPDX-License-Identifier: GPL-2.0+ | 
 | /* | 
 |  * efi_selftest_hii | 
 |  * | 
 |  * Copyright (c) 2018 AKASHI Takahiro, Linaro Limited | 
 |  * | 
 |  * Test HII database protocols | 
 |  */ | 
 |  | 
 | #include <efi_selftest.h> | 
 | #include "efi_selftest_hii_data.c" | 
 |  | 
 | #define PRINT_TESTNAME efi_st_printf("%s:\n", __func__) | 
 |  | 
 | static struct efi_boot_services *boottime; | 
 |  | 
 | static const efi_guid_t hii_database_protocol_guid = | 
 | 	EFI_HII_DATABASE_PROTOCOL_GUID; | 
 | static const efi_guid_t hii_string_protocol_guid = | 
 | 	EFI_HII_STRING_PROTOCOL_GUID; | 
 |  | 
 | static struct efi_hii_database_protocol *hii_database_protocol; | 
 | static struct efi_hii_string_protocol *hii_string_protocol; | 
 |  | 
 | /* | 
 |  * Setup unit test. | 
 |  * | 
 |  * @handle:	handle of the loaded image | 
 |  * @systable:	system table | 
 |  * | 
 |  * Return:	EFI_ST_SUCCESS for success | 
 |  */ | 
 | static int setup(const efi_handle_t handle, | 
 | 		 const struct efi_system_table *systable) | 
 | { | 
 | 	efi_status_t ret; | 
 |  | 
 | 	boottime = systable->boottime; | 
 |  | 
 | 	/* HII database protocol */ | 
 | 	ret = boottime->locate_protocol(&hii_database_protocol_guid, NULL, | 
 | 					(void **)&hii_database_protocol); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		hii_database_protocol = NULL; | 
 | 		efi_st_error("HII database protocol is not available.\n"); | 
 | 		return EFI_ST_FAILURE; | 
 | 	} | 
 |  | 
 | 	/* HII string protocol */ | 
 | 	ret = boottime->locate_protocol(&hii_string_protocol_guid, NULL, | 
 | 					(void **)&hii_string_protocol); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		hii_string_protocol = NULL; | 
 | 		efi_st_error("HII string protocol is not available.\n"); | 
 | 		return EFI_ST_FAILURE; | 
 | 	} | 
 |  | 
 | 	return EFI_ST_SUCCESS; | 
 | } | 
 |  | 
 | /* | 
 |  * HII database protocol tests | 
 |  */ | 
 |  | 
 | /** | 
 |  * test_hii_database_new_package_list() - test creation and removal of | 
 |  *	package list | 
 |  * | 
 |  * This test adds a new package list and then tries to remove it using | 
 |  * the provided handle. | 
 |  * | 
 |  * @Return:     status code | 
 |  */ | 
 | static int test_hii_database_new_package_list(void) | 
 | { | 
 | 	efi_hii_handle_t handle; | 
 | 	efi_status_t ret; | 
 |  | 
 | 	PRINT_TESTNAME; | 
 | 	ret = hii_database_protocol->new_package_list(hii_database_protocol, | 
 | 			(struct efi_hii_package_list_header *)packagelist1, | 
 | 			NULL, &handle); | 
 | 	if (ret != EFI_SUCCESS || !handle) { | 
 | 		efi_st_error("new_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		return EFI_ST_FAILURE; | 
 | 	} | 
 |  | 
 | 	ret = hii_database_protocol->remove_package_list(hii_database_protocol, | 
 | 			handle); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("remove_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		return EFI_ST_FAILURE; | 
 | 	} | 
 |  | 
 | 	return EFI_ST_SUCCESS; | 
 | } | 
 |  | 
 | /** | 
 |  * test_hii_database_update_package_list() - test update of package list | 
 |  * | 
 |  * This test adds a new package list and then tries to update it using | 
 |  * another package list. | 
 |  * | 
 |  * @Return:     status code | 
 |  */ | 
 | static int test_hii_database_update_package_list(void) | 
 | { | 
 | 	efi_hii_handle_t handle = NULL; | 
 | 	efi_status_t ret; | 
 | 	int result = EFI_ST_FAILURE; | 
 |  | 
 | 	PRINT_TESTNAME; | 
 | 	ret = hii_database_protocol->new_package_list(hii_database_protocol, | 
 | 			(struct efi_hii_package_list_header *)packagelist1, | 
 | 			NULL, &handle); | 
 | 	if (ret != EFI_SUCCESS || !handle) { | 
 | 		efi_st_error("new_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		return EFI_ST_FAILURE; | 
 | 	} | 
 |  | 
 | 	ret = hii_database_protocol->update_package_list(hii_database_protocol, | 
 | 			handle, | 
 | 			(struct efi_hii_package_list_header *)packagelist2); | 
 | 	if (ret != EFI_SUCCESS || !handle) { | 
 | 		efi_st_error("new_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	result = EFI_ST_SUCCESS; | 
 |  | 
 | out: | 
 | 	if (handle) { | 
 | 		ret = hii_database_protocol->remove_package_list( | 
 | 				hii_database_protocol, handle); | 
 | 		if (ret != EFI_SUCCESS) { | 
 | 			efi_st_error("remove_package_list returned %u\n", | 
 | 				     (unsigned int)ret); | 
 | 			return EFI_ST_FAILURE; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return result; | 
 | } | 
 |  | 
 | /** | 
 |  * test_hii_database_list_package_lists() - test listing of package lists | 
 |  * | 
 |  * This test adds two package lists and then tries to enumerate them | 
 |  * against different package types. We will get an array of handles. | 
 |  * | 
 |  * @Return:     status code | 
 |  */ | 
 | static int test_hii_database_list_package_lists(void) | 
 | { | 
 | 	efi_hii_handle_t handle1 = NULL, handle2 = NULL, *handles; | 
 | 	efi_uintn_t handles_size; | 
 | 	efi_status_t ret; | 
 | 	int result = EFI_ST_FAILURE; | 
 |  | 
 | 	PRINT_TESTNAME; | 
 | 	ret = hii_database_protocol->new_package_list(hii_database_protocol, | 
 | 			(struct efi_hii_package_list_header *)packagelist1, | 
 | 			NULL, &handle1); | 
 | 	if (ret != EFI_SUCCESS || !handle1) { | 
 | 		efi_st_error("new_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	ret = hii_database_protocol->new_package_list(hii_database_protocol, | 
 | 			(struct efi_hii_package_list_header *)packagelist2, | 
 | 			NULL, &handle2); | 
 | 	if (ret != EFI_SUCCESS || !handle2) { | 
 | 		efi_st_error("new_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	/* TYPE_ALL */ | 
 | 	handles = NULL; | 
 | 	handles_size = 0; | 
 | 	ret = hii_database_protocol->list_package_lists(hii_database_protocol, | 
 | 			EFI_HII_PACKAGE_TYPE_ALL, NULL, | 
 | 			&handles_size, handles); | 
 | 	if (ret != EFI_BUFFER_TOO_SMALL) { | 
 | 		efi_st_error("list_package_lists returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 | 	ret = boottime->allocate_pool(EFI_LOADER_DATA, handles_size, | 
 | 				      (void **)&handles); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("AllocatePool failed\n"); | 
 | 		goto out; | 
 | 	} | 
 | 	ret = hii_database_protocol->list_package_lists(hii_database_protocol, | 
 | 			EFI_HII_PACKAGE_TYPE_ALL, NULL, | 
 | 			&handles_size, handles); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("list_package_lists returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 | 	ret = boottime->free_pool(handles); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("FreePool failed\n"); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	/* STRINGS */ | 
 | 	handles = NULL; | 
 | 	handles_size = 0; | 
 | 	ret = hii_database_protocol->list_package_lists(hii_database_protocol, | 
 | 			EFI_HII_PACKAGE_STRINGS, NULL, | 
 | 			&handles_size, handles); | 
 | 	if (ret != EFI_BUFFER_TOO_SMALL) { | 
 | 		efi_st_error("list_package_lists returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		ret = EFI_ST_FAILURE; | 
 | 		goto out; | 
 | 	} | 
 | 	ret = boottime->allocate_pool(EFI_LOADER_DATA, handles_size, | 
 | 				      (void **)&handles); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("AllocatePool failed\n"); | 
 | 		ret = EFI_ST_FAILURE; | 
 | 		goto out; | 
 | 	} | 
 | 	ret = hii_database_protocol->list_package_lists(hii_database_protocol, | 
 | 			EFI_HII_PACKAGE_STRINGS, NULL, | 
 | 			&handles_size, handles); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("list_package_lists returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		ret = EFI_ST_FAILURE; | 
 | 		goto out; | 
 | 	} | 
 | 	ret = boottime->free_pool(handles); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("FreePool failed\n"); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	/* GUID */ | 
 | 	handles = NULL; | 
 | 	handles_size = 0; | 
 | 	ret = hii_database_protocol->list_package_lists(hii_database_protocol, | 
 | 			EFI_HII_PACKAGE_TYPE_GUID, &package_guid, | 
 | 			&handles_size, handles); | 
 | 	if (ret != EFI_BUFFER_TOO_SMALL) { | 
 | 		efi_st_error("list_package_lists returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		ret = EFI_ST_FAILURE; | 
 | 		goto out; | 
 | 	} | 
 | 	ret = boottime->allocate_pool(EFI_LOADER_DATA, handles_size, | 
 | 				      (void **)&handles); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("AllocatePool failed\n"); | 
 | 		ret = EFI_ST_FAILURE; | 
 | 		goto out; | 
 | 	} | 
 | 	ret = hii_database_protocol->list_package_lists(hii_database_protocol, | 
 | 			EFI_HII_PACKAGE_TYPE_GUID, &package_guid, | 
 | 			&handles_size, handles); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("list_package_lists returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		ret = EFI_ST_FAILURE; | 
 | 		goto out; | 
 | 	} | 
 | 	ret = boottime->free_pool(handles); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("FreePool failed\n"); | 
 | 		ret = EFI_ST_FAILURE; | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	/* KEYBOARD_LAYOUT */ | 
 | 	handles = NULL; | 
 | 	handles_size = 0; | 
 | 	ret = hii_database_protocol->list_package_lists(hii_database_protocol, | 
 | 			EFI_HII_PACKAGE_KEYBOARD_LAYOUT, NULL, | 
 | 			&handles_size, handles); | 
 | 	if (ret != EFI_BUFFER_TOO_SMALL) { | 
 | 		efi_st_error("list_package_lists returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		ret = EFI_ST_FAILURE; | 
 | 		goto out; | 
 | 	} | 
 | 	ret = boottime->allocate_pool(EFI_LOADER_DATA, handles_size, | 
 | 				      (void **)&handles); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("AllocatePool failed\n"); | 
 | 		ret = EFI_ST_FAILURE; | 
 | 		goto out; | 
 | 	} | 
 | 	ret = hii_database_protocol->list_package_lists(hii_database_protocol, | 
 | 			EFI_HII_PACKAGE_KEYBOARD_LAYOUT, NULL, | 
 | 			&handles_size, handles); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("list_package_lists returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		ret = EFI_ST_FAILURE; | 
 | 		goto out; | 
 | 	} | 
 | 	ret = boottime->free_pool(handles); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("FreePool failed\n"); | 
 | 		ret = EFI_ST_FAILURE; | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	result = EFI_ST_SUCCESS; | 
 |  | 
 | out: | 
 | 	if (handle1) { | 
 | 		ret = hii_database_protocol->remove_package_list( | 
 | 				hii_database_protocol, handle1); | 
 | 		if (ret != EFI_SUCCESS) | 
 | 			efi_st_error("remove_package_list returned %u\n", | 
 | 				     (unsigned int)ret); | 
 | 	} | 
 | 	if (handle2) { | 
 | 		ret = hii_database_protocol->remove_package_list( | 
 | 				hii_database_protocol, handle2); | 
 | 		if (ret != EFI_SUCCESS) | 
 | 			efi_st_error("remove_package_list returned %u\n", | 
 | 				     (unsigned int)ret); | 
 | 	} | 
 |  | 
 | 	return result; | 
 | } | 
 |  | 
 | /** | 
 |  * test_hii_database_export_package_lists() - test export of package lists | 
 |  * | 
 |  * @Return:     status code | 
 |  */ | 
 | static int test_hii_database_export_package_lists(void) | 
 | { | 
 | 	PRINT_TESTNAME; | 
 | 	/* export_package_lists() not implemented yet */ | 
 | 	return EFI_ST_SUCCESS; | 
 | } | 
 |  | 
 | /** | 
 |  * test_hii_database_register_package_notify() - test registration of | 
 |  *	notification function | 
 |  * | 
 |  * @Return:     status code | 
 |  */ | 
 | static int test_hii_database_register_package_notify(void) | 
 | { | 
 | 	PRINT_TESTNAME; | 
 | 	/* register_package_notify() not implemented yet */ | 
 | 	return EFI_ST_SUCCESS; | 
 | } | 
 |  | 
 | /** | 
 |  * test_hii_database_unregister_package_notify() - test removal of | 
 |  *	notification function | 
 |  * | 
 |  * @Return:     status code | 
 |  */ | 
 | static int test_hii_database_unregister_package_notify(void) | 
 | { | 
 | 	PRINT_TESTNAME; | 
 | 	/* unregsiter_package_notify() not implemented yet */ | 
 | 	return EFI_ST_SUCCESS; | 
 | } | 
 |  | 
 | /** | 
 |  * test_hii_database_find_keyboard_layouts() - test listing of | 
 |  *	all the keyboard layouts in the system | 
 |  * | 
 |  * This test adds two package lists, each of which has two keyboard layouts | 
 |  * and then tries to enumerate them. We will get an array of handles. | 
 |  * | 
 |  * @Return:     status code | 
 |  */ | 
 | static int test_hii_database_find_keyboard_layouts(void) | 
 | { | 
 | 	efi_hii_handle_t handle1 = NULL, handle2 = NULL; | 
 | 	efi_guid_t *guids; | 
 | 	u16 guids_size; | 
 | 	efi_status_t ret; | 
 | 	int result = EFI_ST_FAILURE; | 
 |  | 
 | 	PRINT_TESTNAME; | 
 | 	ret = hii_database_protocol->new_package_list(hii_database_protocol, | 
 | 			(struct efi_hii_package_list_header *)packagelist1, | 
 | 			NULL, &handle1); | 
 | 	if (ret != EFI_SUCCESS || !handle1) { | 
 | 		efi_st_error("new_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	ret = hii_database_protocol->new_package_list(hii_database_protocol, | 
 | 			(struct efi_hii_package_list_header *)packagelist2, | 
 | 			NULL, &handle2); | 
 | 	if (ret != EFI_SUCCESS || !handle2) { | 
 | 		efi_st_error("new_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	guids = NULL; | 
 | 	guids_size = 0; | 
 | 	ret = hii_database_protocol->find_keyboard_layouts( | 
 | 			hii_database_protocol, &guids_size, guids); | 
 | 	if (ret != EFI_BUFFER_TOO_SMALL) { | 
 | 		efi_st_error("find_keyboard_layouts returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 | 	ret = boottime->allocate_pool(EFI_LOADER_DATA, guids_size, | 
 | 				      (void **)&guids); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("AllocatePool failed\n"); | 
 | 		goto out; | 
 | 	} | 
 | 	ret = hii_database_protocol->find_keyboard_layouts( | 
 | 			hii_database_protocol, &guids_size, guids); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("find_keyboard_layouts returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 | 	ret = boottime->free_pool(guids); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("FreePool failed\n"); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	result = EFI_ST_SUCCESS; | 
 |  | 
 | out: | 
 | 	if (handle1) { | 
 | 		ret = hii_database_protocol->remove_package_list( | 
 | 				hii_database_protocol, handle1); | 
 | 		if (ret != EFI_SUCCESS) | 
 | 			efi_st_error("remove_package_list returned %u\n", | 
 | 				     (unsigned int)ret); | 
 | 	} | 
 | 	if (handle2) { | 
 | 		ret = hii_database_protocol->remove_package_list( | 
 | 				hii_database_protocol, handle2); | 
 | 		if (ret != EFI_SUCCESS) | 
 | 			efi_st_error("remove_package_list returned %u\n", | 
 | 				     (unsigned int)ret); | 
 | 	} | 
 |  | 
 | 	return result; | 
 | } | 
 |  | 
 | /** | 
 |  * test_hii_database_get_keyboard_layout() - test retrieval of keyboard layout | 
 |  * | 
 |  * This test adds two package lists, each of which has two keyboard layouts | 
 |  * and then tries to get a handle to keyboard layout with a specific guid | 
 |  * and the current one. | 
 |  * | 
 |  * @Return:     status code | 
 |  */ | 
 | static int test_hii_database_get_keyboard_layout(void) | 
 | { | 
 | 	efi_hii_handle_t handle1 = NULL, handle2 = NULL; | 
 | 	struct efi_hii_keyboard_layout *kb_layout; | 
 | 	u16 kb_layout_size; | 
 | 	efi_status_t ret; | 
 | 	int result = EFI_ST_FAILURE; | 
 |  | 
 | 	PRINT_TESTNAME; | 
 | 	ret = hii_database_protocol->new_package_list(hii_database_protocol, | 
 | 			(struct efi_hii_package_list_header *)packagelist1, | 
 | 			NULL, &handle1); | 
 | 	if (ret != EFI_SUCCESS || !handle1) { | 
 | 		efi_st_error("new_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	ret = hii_database_protocol->new_package_list(hii_database_protocol, | 
 | 			(struct efi_hii_package_list_header *)packagelist2, | 
 | 			NULL, &handle2); | 
 | 	if (ret != EFI_SUCCESS || !handle2) { | 
 | 		efi_st_error("new_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	/* specific keyboard_layout(guid11) */ | 
 | 	kb_layout = NULL; | 
 | 	kb_layout_size = 0; | 
 | 	ret = hii_database_protocol->get_keyboard_layout(hii_database_protocol, | 
 | 			&kb_layout_guid11, &kb_layout_size, kb_layout); | 
 | 	if (ret != EFI_BUFFER_TOO_SMALL) { | 
 | 		efi_st_error("get_keyboard_layout returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 | 	ret = boottime->allocate_pool(EFI_LOADER_DATA, kb_layout_size, | 
 | 				      (void **)&kb_layout); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("AllocatePool failed\n"); | 
 | 		goto out; | 
 | 	} | 
 | 	ret = hii_database_protocol->get_keyboard_layout(hii_database_protocol, | 
 | 			&kb_layout_guid11, &kb_layout_size, kb_layout); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("get_keyboard_layout returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 | 	ret = boottime->free_pool(kb_layout); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("FreePool failed\n"); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	/* current */ | 
 | 	kb_layout = NULL; | 
 | 	kb_layout_size = 0; | 
 | 	ret = hii_database_protocol->get_keyboard_layout(hii_database_protocol, | 
 | 			NULL, &kb_layout_size, kb_layout); | 
 | 	if (ret != EFI_INVALID_PARAMETER) { | 
 | 		efi_st_error("get_keyboard_layout returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	result = EFI_ST_SUCCESS; | 
 |  | 
 | out: | 
 | 	if (handle1) { | 
 | 		ret = hii_database_protocol->remove_package_list( | 
 | 				hii_database_protocol, handle1); | 
 | 		if (ret != EFI_SUCCESS) | 
 | 			efi_st_error("remove_package_list returned %u\n", | 
 | 				     (unsigned int)ret); | 
 | 	} | 
 | 	if (handle2) { | 
 | 		ret = hii_database_protocol->remove_package_list( | 
 | 				hii_database_protocol, handle2); | 
 | 		if (ret != EFI_SUCCESS) | 
 | 			efi_st_error("remove_package_list returned %u\n", | 
 | 				     (unsigned int)ret); | 
 | 	} | 
 |  | 
 | 	return result; | 
 | } | 
 |  | 
 | /** | 
 |  * test_hii_database_set_keyboard_layout() - test change of | 
 |  *	current keyboard layout | 
 |  * | 
 |  * @Return:     status code | 
 |  */ | 
 | static int test_hii_database_set_keyboard_layout(void) | 
 | { | 
 | 	efi_status_t ret; | 
 |  | 
 | 	PRINT_TESTNAME; | 
 |  | 
 | 	/* Invalid key guid. */ | 
 | 	ret = hii_database_protocol->set_keyboard_layout( | 
 | 			hii_database_protocol, NULL); | 
 | 	if (ret != EFI_INVALID_PARAMETER) { | 
 | 		efi_st_error("set_keyboard_layout returned %u not invalid\n", | 
 | 			     (unsigned int)ret); | 
 | 		return EFI_ST_FAILURE; | 
 | 	} | 
 |  | 
 | 	/* set_keyboard_layout() not implemented yet */ | 
 | 	return EFI_ST_SUCCESS; | 
 | } | 
 |  | 
 | /** | 
 |  * test_hii_database_get_package_list_handle() - test retrieval of | 
 |  *	driver associated with a package list | 
 |  * | 
 |  * This test adds a package list, and then tries to get a handle to driver | 
 |  * which is associated with a package list. | 
 |  * | 
 |  * @Return:     status code | 
 |  */ | 
 | static int test_hii_database_get_package_list_handle(void) | 
 | { | 
 | 	efi_hii_handle_t handle = NULL; | 
 | 	efi_handle_t driver_handle; | 
 | 	efi_status_t ret; | 
 | 	int result = EFI_ST_FAILURE; | 
 |  | 
 | 	PRINT_TESTNAME; | 
 | 	driver_handle = (efi_handle_t)0x12345678; /* dummy */ | 
 | 	ret = hii_database_protocol->new_package_list(hii_database_protocol, | 
 | 			(struct efi_hii_package_list_header *)packagelist1, | 
 | 			driver_handle, &handle); | 
 | 	if (ret != EFI_SUCCESS || !handle) { | 
 | 		efi_st_error("new_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		return EFI_ST_FAILURE; | 
 | 	} | 
 |  | 
 | 	driver_handle = NULL; | 
 | 	ret = hii_database_protocol->get_package_list_handle( | 
 | 			hii_database_protocol, handle, &driver_handle); | 
 | 	if (ret != EFI_SUCCESS || driver_handle != (efi_handle_t)0x12345678) { | 
 | 		efi_st_error("get_package_list_handle returned %u, driver:%p\n", | 
 | 			     (unsigned int)ret, driver_handle); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	result = EFI_ST_SUCCESS; | 
 |  | 
 | out: | 
 | 	if (handle) { | 
 | 		ret = hii_database_protocol->remove_package_list( | 
 | 				hii_database_protocol, handle); | 
 | 		if (ret != EFI_SUCCESS) { | 
 | 			efi_st_error("remove_package_list returned %u\n", | 
 | 				     (unsigned int)ret); | 
 | 			return EFI_ST_FAILURE; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return result; | 
 | } | 
 |  | 
 | static int test_hii_database_protocol(void) | 
 | { | 
 | 	int ret; | 
 |  | 
 | 	ret = test_hii_database_new_package_list(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	ret = test_hii_database_update_package_list(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	ret = test_hii_database_list_package_lists(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	ret = test_hii_database_export_package_lists(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	ret = test_hii_database_register_package_notify(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	ret = test_hii_database_unregister_package_notify(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	ret = test_hii_database_find_keyboard_layouts(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	ret = test_hii_database_get_keyboard_layout(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	ret = test_hii_database_set_keyboard_layout(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	ret = test_hii_database_get_package_list_handle(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	return EFI_ST_SUCCESS; | 
 | } | 
 |  | 
 | /* | 
 |  * HII string protocol tests | 
 |  */ | 
 |  | 
 | /** | 
 |  * test_hii_string_new_string() - test creation of a new string entry | 
 |  * | 
 |  * This test adds a package list, and then tries to add a new string | 
 |  * entry for a specific language. | 
 |  * | 
 |  * @Return:     status code | 
 |  */ | 
 | static int test_hii_string_new_string(void) | 
 | { | 
 | 	efi_hii_handle_t handle = NULL; | 
 | 	efi_string_id_t id; | 
 | 	efi_status_t ret; | 
 | 	int result = EFI_ST_FAILURE; | 
 |  | 
 | 	PRINT_TESTNAME; | 
 | 	ret = hii_database_protocol->new_package_list(hii_database_protocol, | 
 | 			(struct efi_hii_package_list_header *)packagelist1, | 
 | 			NULL, &handle); | 
 | 	if (ret != EFI_SUCCESS || !handle) { | 
 | 		efi_st_error("new_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		return EFI_ST_FAILURE; | 
 | 	} | 
 |  | 
 | 	ret = hii_string_protocol->new_string(hii_string_protocol, handle, | 
 | 					      &id, (u8 *)"en-US", | 
 | 					      u"Japanese", u"Japanese", NULL); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("new_string returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 | 	efi_st_printf("new string id is %u\n", id); | 
 |  | 
 | 	result = EFI_ST_SUCCESS; | 
 |  | 
 | out: | 
 | 	if (handle) { | 
 | 		ret = hii_database_protocol->remove_package_list( | 
 | 				hii_database_protocol, handle); | 
 | 		if (ret != EFI_SUCCESS) { | 
 | 			efi_st_error("remove_package_list returned %u\n", | 
 | 				     (unsigned int)ret); | 
 | 			return EFI_ST_FAILURE; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return result; | 
 | } | 
 |  | 
 | /** | 
 |  * test_hii_string_get_string() - test retrieval of a string entry | 
 |  * | 
 |  * This test adds a package list, create a new string entry and then tries | 
 |  * to get it with its string id. | 
 |  * | 
 |  * @Return:     status code | 
 |  */ | 
 | static int test_hii_string_get_string(void) | 
 | { | 
 | 	efi_hii_handle_t handle = NULL; | 
 | 	efi_string_id_t id; | 
 | 	efi_string_t string; | 
 | 	efi_uintn_t string_len; | 
 | 	efi_status_t ret; | 
 | 	int result = EFI_ST_FAILURE; | 
 |  | 
 | 	PRINT_TESTNAME; | 
 | 	ret = hii_database_protocol->new_package_list(hii_database_protocol, | 
 | 			(struct efi_hii_package_list_header *)packagelist1, | 
 | 			NULL, &handle); | 
 | 	if (ret != EFI_SUCCESS || !handle) { | 
 | 		efi_st_error("new_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		return EFI_ST_FAILURE; | 
 | 	} | 
 |  | 
 | 	ret = hii_string_protocol->new_string(hii_string_protocol, handle, | 
 | 					      &id, (u8 *)"en-US", | 
 | 					      u"Japanese", u"Japanese", NULL); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("new_string returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	string = NULL; | 
 | 	string_len = 0; | 
 | 	ret = hii_string_protocol->get_string(hii_string_protocol, | 
 | 			(u8 *)"en-US", handle, id, string, &string_len, NULL); | 
 | 	if (ret != EFI_BUFFER_TOO_SMALL) { | 
 | 		efi_st_error("get_string returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 | 	string_len += sizeof(u16); | 
 | 	ret = boottime->allocate_pool(EFI_LOADER_DATA, string_len, | 
 | 				      (void **)&string); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("AllocatePool failed\n"); | 
 | 		goto out; | 
 | 	} | 
 | 	ret = hii_string_protocol->get_string(hii_string_protocol, | 
 | 			(u8 *)"en-US", handle, id, string, &string_len, NULL); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("get_string returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	if (efi_st_strcmp_16_8(string, "Japanese")) { | 
 | 		efi_st_error("get_string returned incorrect string\n"); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	result = EFI_ST_SUCCESS; | 
 |  | 
 | out: | 
 | 	if (handle) { | 
 | 		ret = hii_database_protocol->remove_package_list( | 
 | 				hii_database_protocol, handle); | 
 | 		if (ret != EFI_SUCCESS) { | 
 | 			efi_st_error("remove_package_list returned %u\n", | 
 | 				     (unsigned int)ret); | 
 | 			return EFI_ST_FAILURE; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return result; | 
 | } | 
 |  | 
 | /** | 
 |  * test_hii_string_set_string() - test change of a string entry | 
 |  * | 
 |  * This test adds a package list, create a new string entry and then tries | 
 |  * to modify it. | 
 |  * | 
 |  * @Return:     status code | 
 |  */ | 
 | static int test_hii_string_set_string(void) | 
 | { | 
 | 	efi_hii_handle_t handle = NULL; | 
 | 	efi_string_id_t id; | 
 | 	efi_status_t ret; | 
 | 	int result = EFI_ST_FAILURE; | 
 |  | 
 | 	PRINT_TESTNAME; | 
 | 	ret = hii_database_protocol->new_package_list(hii_database_protocol, | 
 | 			(struct efi_hii_package_list_header *)packagelist1, | 
 | 			NULL, &handle); | 
 | 	if (ret != EFI_SUCCESS || !handle) { | 
 | 		efi_st_error("new_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		return EFI_ST_FAILURE; | 
 | 	} | 
 |  | 
 | 	ret = hii_string_protocol->new_string(hii_string_protocol, handle, | 
 | 					      &id, (u8 *)"en-US", | 
 | 					      u"Japanese", u"Japanese", NULL); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("new_string returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	ret = hii_string_protocol->set_string(hii_string_protocol, handle, | 
 | 					      id, (u8 *)"en-US", | 
 | 					      u"Nihongo", NULL); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("set_string returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	result = EFI_ST_SUCCESS; | 
 |  | 
 | out: | 
 | 	if (handle) { | 
 | 		ret = hii_database_protocol->remove_package_list( | 
 | 				hii_database_protocol, handle); | 
 | 		if (ret != EFI_SUCCESS) { | 
 | 			efi_st_error("remove_package_list returned %u\n", | 
 | 				     (unsigned int)ret); | 
 | 			return EFI_ST_FAILURE; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return result; | 
 | } | 
 |  | 
 | /** | 
 |  * test_hii_string_get_languages() - test listing of languages | 
 |  * | 
 |  * This test adds a package list, and then tries to enumerate languages | 
 |  * in it. We will get an string of language names. | 
 |  * | 
 |  * @Return:     status code | 
 |  */ | 
 | static int test_hii_string_get_languages(void) | 
 | { | 
 | 	efi_hii_handle_t handle = NULL; | 
 | 	u8 *languages; | 
 | 	efi_uintn_t languages_len; | 
 | 	efi_status_t ret; | 
 | 	int result = EFI_ST_FAILURE; | 
 |  | 
 | 	PRINT_TESTNAME; | 
 | 	ret = hii_database_protocol->new_package_list(hii_database_protocol, | 
 | 			(struct efi_hii_package_list_header *)packagelist1, | 
 | 			NULL, &handle); | 
 | 	if (ret != EFI_SUCCESS || !handle) { | 
 | 		efi_st_error("new_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		return EFI_ST_FAILURE; | 
 | 	} | 
 |  | 
 | 	languages = NULL; | 
 | 	languages_len = 0; | 
 | 	ret = hii_string_protocol->get_languages(hii_string_protocol, handle, | 
 | 			languages, &languages_len); | 
 | 	if (ret != EFI_BUFFER_TOO_SMALL) { | 
 | 		efi_st_error("get_languages returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 | 	ret = boottime->allocate_pool(EFI_LOADER_DATA, languages_len, | 
 | 				      (void **)&languages); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("AllocatePool failed\n"); | 
 | 		goto out; | 
 | 	} | 
 | 	ret = hii_string_protocol->get_languages(hii_string_protocol, handle, | 
 | 			languages, &languages_len); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("get_languages returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	efi_st_printf("got languages are %s\n", languages); | 
 |  | 
 | 	result = EFI_ST_SUCCESS; | 
 |  | 
 | out: | 
 | 	if (handle) { | 
 | 		ret = hii_database_protocol->remove_package_list( | 
 | 				hii_database_protocol, handle); | 
 | 		if (ret != EFI_SUCCESS) { | 
 | 			efi_st_error("remove_package_list returned %u\n", | 
 | 				     (unsigned int)ret); | 
 | 			return EFI_ST_FAILURE; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return result; | 
 | } | 
 |  | 
 | /** | 
 |  * test_hii_string_get_secondary_languages() - test listing of secondary | 
 |  *	languages | 
 |  * | 
 |  * This test adds a package list, and then tries to enumerate secondary | 
 |  * languages with a specific language. We will get an string of language names. | 
 |  * | 
 |  * @Return:     status code | 
 |  */ | 
 | static int test_hii_string_get_secondary_languages(void) | 
 | { | 
 | 	efi_hii_handle_t handle = NULL; | 
 | 	u8 *languages; | 
 | 	efi_uintn_t languages_len; | 
 | 	efi_status_t ret; | 
 | 	int result = EFI_ST_FAILURE; | 
 |  | 
 | 	PRINT_TESTNAME; | 
 | 	ret = hii_database_protocol->new_package_list(hii_database_protocol, | 
 | 			(struct efi_hii_package_list_header *)packagelist1, | 
 | 			NULL, &handle); | 
 | 	if (ret != EFI_SUCCESS || !handle) { | 
 | 		efi_st_error("new_package_list returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		return EFI_ST_FAILURE; | 
 | 	} | 
 |  | 
 | 	languages = NULL; | 
 | 	languages_len = 0; | 
 | 	ret = hii_string_protocol->get_secondary_languages(hii_string_protocol, | 
 | 			handle, (u8 *)"en-US", languages, &languages_len); | 
 | 	if (ret == EFI_NOT_FOUND) { | 
 | 		efi_st_printf("no secondary languages\n"); | 
 | 		result = EFI_ST_SUCCESS; | 
 | 		goto out; | 
 | 	} | 
 | 	if (ret != EFI_BUFFER_TOO_SMALL) { | 
 | 		efi_st_error("get_secondary_languages returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 | 	ret = boottime->allocate_pool(EFI_LOADER_DATA, languages_len, | 
 | 				      (void **)&languages); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("AllocatePool failed\n"); | 
 | 		goto out; | 
 | 	} | 
 | 	ret = hii_string_protocol->get_secondary_languages(hii_string_protocol, | 
 | 			handle, (u8 *)"en-US", languages, &languages_len); | 
 | 	if (ret != EFI_SUCCESS) { | 
 | 		efi_st_error("get_secondary_languages returned %u\n", | 
 | 			     (unsigned int)ret); | 
 | 		goto out; | 
 | 	} | 
 |  | 
 | 	efi_st_printf("got secondary languages are %s\n", languages); | 
 |  | 
 | 	result = EFI_ST_SUCCESS; | 
 |  | 
 | out: | 
 | 	if (handle) { | 
 | 		ret = hii_database_protocol->remove_package_list( | 
 | 				hii_database_protocol, handle); | 
 | 		if (ret != EFI_SUCCESS) { | 
 | 			efi_st_error("remove_package_list returned %u\n", | 
 | 				     (unsigned int)ret); | 
 | 			return EFI_ST_FAILURE; | 
 | 		} | 
 | 	} | 
 |  | 
 | 	return result; | 
 | } | 
 |  | 
 | static int test_hii_string_protocol(void) | 
 | { | 
 | 	int ret; | 
 |  | 
 | 	ret = test_hii_string_new_string(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	ret = test_hii_string_get_string(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	ret = test_hii_string_set_string(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	ret = test_hii_string_get_languages(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	ret = test_hii_string_get_secondary_languages(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	return EFI_ST_SUCCESS; | 
 | } | 
 |  | 
 | /* | 
 |  * Execute unit test. | 
 |  * | 
 |  * Return:	EFI_ST_SUCCESS for success, EFI_ST_FAILURE for failure | 
 |  */ | 
 | static int execute(void) | 
 | { | 
 | 	int ret; | 
 |  | 
 | 	/* HII database protocol */ | 
 | 	ret = test_hii_database_protocol(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	/* HII string protocol */ | 
 | 	ret = test_hii_string_protocol(); | 
 | 	if (ret != EFI_ST_SUCCESS) | 
 | 		return EFI_ST_FAILURE; | 
 |  | 
 | 	return EFI_ST_SUCCESS; | 
 | } | 
 |  | 
 | EFI_UNIT_TEST(hii) = { | 
 | 	.name = "HII database protocols", | 
 | 	.phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, | 
 | 	.setup = setup, | 
 | 	.execute = execute, | 
 | }; |