|  | 
| 33 | 33 | #include <linux/memblock.h> | 
| 34 | 34 | #include <linux/security.h> | 
| 35 | 35 | #include <linux/notifier.h> | 
|  | 36 | +#include <linux/bsearch.h> | 
| 36 | 37 | 
 | 
| 37 | 38 | #include <asm/early_ioremap.h> | 
| 38 | 39 | 
 | 
| @@ -993,40 +994,101 @@ int efi_mem_type(unsigned long phys_addr) | 
| 993 | 994 | 	return -EINVAL; | 
| 994 | 995 | } | 
| 995 | 996 | 
 | 
|  | 997 | +struct efi_error_code { | 
|  | 998 | +	efi_status_t status; | 
|  | 999 | +	int errno; | 
|  | 1000 | +	const char *description; | 
|  | 1001 | +}; | 
|  | 1002 | + | 
|  | 1003 | +static const struct efi_error_code efi_error_codes[] = { | 
|  | 1004 | +	{ EFI_SUCCESS, 0, "Success"}, | 
|  | 1005 | +#if 0 | 
|  | 1006 | +	{ EFI_LOAD_ERROR, -EPICK_AN_ERRNO, "Load Error"}, | 
|  | 1007 | +#endif | 
|  | 1008 | +	{ EFI_INVALID_PARAMETER, -EINVAL, "Invalid Parameter"}, | 
|  | 1009 | +	{ EFI_UNSUPPORTED, -ENOSYS, "Unsupported"}, | 
|  | 1010 | +	{ EFI_BAD_BUFFER_SIZE, -ENOSPC, "Bad Buffer Size"}, | 
|  | 1011 | +	{ EFI_BUFFER_TOO_SMALL, -ENOSPC, "Buffer Too Small"}, | 
|  | 1012 | +	{ EFI_NOT_READY, -EAGAIN, "Not Ready"}, | 
|  | 1013 | +	{ EFI_DEVICE_ERROR, -EIO, "Device Error"}, | 
|  | 1014 | +	{ EFI_WRITE_PROTECTED, -EROFS, "Write Protected"}, | 
|  | 1015 | +	{ EFI_OUT_OF_RESOURCES, -ENOMEM, "Out of Resources"}, | 
|  | 1016 | +#if 0 | 
|  | 1017 | +	{ EFI_VOLUME_CORRUPTED, -EPICK_AN_ERRNO, "Volume Corrupt"}, | 
|  | 1018 | +	{ EFI_VOLUME_FULL, -EPICK_AN_ERRNO, "Volume Full"}, | 
|  | 1019 | +	{ EFI_NO_MEDIA, -EPICK_AN_ERRNO, "No Media"}, | 
|  | 1020 | +	{ EFI_MEDIA_CHANGED, -EPICK_AN_ERRNO, "Media changed"}, | 
|  | 1021 | +#endif | 
|  | 1022 | +	{ EFI_NOT_FOUND, -ENOENT, "Not Found"}, | 
|  | 1023 | +#if 0 | 
|  | 1024 | +	{ EFI_ACCESS_DENIED, -EPICK_AN_ERRNO, "Access Denied"}, | 
|  | 1025 | +	{ EFI_NO_RESPONSE, -EPICK_AN_ERRNO, "No Response"}, | 
|  | 1026 | +	{ EFI_NO_MAPPING, -EPICK_AN_ERRNO, "No mapping"}, | 
|  | 1027 | +	{ EFI_TIMEOUT, -EPICK_AN_ERRNO, "Time out"}, | 
|  | 1028 | +	{ EFI_NOT_STARTED, -EPICK_AN_ERRNO, "Not started"}, | 
|  | 1029 | +	{ EFI_ALREADY_STARTED, -EPICK_AN_ERRNO, "Already started"}, | 
|  | 1030 | +#endif | 
|  | 1031 | +	{ EFI_ABORTED, -EINTR, "Aborted"}, | 
|  | 1032 | +#if 0 | 
|  | 1033 | +	{ EFI_ICMP_ERROR, -EPICK_AN_ERRNO, "ICMP Error"}, | 
|  | 1034 | +	{ EFI_TFTP_ERROR, -EPICK_AN_ERRNO, "TFTP Error"}, | 
|  | 1035 | +	{ EFI_PROTOCOL_ERROR, -EPICK_AN_ERRNO, "Protocol Error"}, | 
|  | 1036 | +	{ EFI_INCOMPATIBLE_VERSION, -EPICK_AN_ERRNO, "Incompatible Version"}, | 
|  | 1037 | +#endif | 
|  | 1038 | +	{ EFI_SECURITY_VIOLATION, -EACCES, "Security Policy Violation"}, | 
|  | 1039 | +#if 0 | 
|  | 1040 | +	{ EFI_CRC_ERROR, -EPICK_AN_ERRNO, "CRC Error"}, | 
|  | 1041 | +	{ EFI_END_OF_MEDIA, -EPICK_AN_ERRNO, "End of Media"}, | 
|  | 1042 | +	{ EFI_END_OF_FILE, -EPICK_AN_ERRNO, "End of File"}, | 
|  | 1043 | +	{ EFI_INVALID_LANGUAGE, -EPICK_AN_ERRNO, "Invalid Languages"}, | 
|  | 1044 | +	{ EFI_COMPROMISED_DATA, -EPICK_AN_ERRNO, "Compromised Data"}, | 
|  | 1045 | + | 
|  | 1046 | +	// warnings | 
|  | 1047 | +	{ EFI_WARN_UNKOWN_GLYPH, -EPICK_AN_ERRNO, "Warning Unknown Glyph"}, | 
|  | 1048 | +	{ EFI_WARN_DELETE_FAILURE, -EPICK_AN_ERRNO, "Warning Delete Failure"}, | 
|  | 1049 | +	{ EFI_WARN_WRITE_FAILURE, -EPICK_AN_ERRNO, "Warning Write Failure"}, | 
|  | 1050 | +	{ EFI_WARN_BUFFER_TOO_SMALL, -EPICK_AN_ERRNO, "Warning Buffer Too Small"}, | 
|  | 1051 | +#endif | 
|  | 1052 | +}; | 
|  | 1053 | + | 
|  | 1054 | +static int | 
|  | 1055 | +efi_status_cmp_bsearch(const void *key, const void *item) | 
|  | 1056 | +{ | 
|  | 1057 | +	u64 status = (u64)(uintptr_t)key; | 
|  | 1058 | +	struct efi_error_code *code = (struct efi_error_code *)item; | 
|  | 1059 | + | 
|  | 1060 | +	if (status < code->status) | 
|  | 1061 | +		return -1; | 
|  | 1062 | +	if (status > code->status) | 
|  | 1063 | +		return 1; | 
|  | 1064 | +	return 0; | 
|  | 1065 | +} | 
|  | 1066 | + | 
| 996 | 1067 | int efi_status_to_err(efi_status_t status) | 
| 997 | 1068 | { | 
| 998 |  | -	int err; | 
| 999 |  | - | 
| 1000 |  | -	switch (status) { | 
| 1001 |  | -	case EFI_SUCCESS: | 
| 1002 |  | -		err = 0; | 
| 1003 |  | -		break; | 
| 1004 |  | -	case EFI_INVALID_PARAMETER: | 
| 1005 |  | -		err = -EINVAL; | 
| 1006 |  | -		break; | 
| 1007 |  | -	case EFI_OUT_OF_RESOURCES: | 
| 1008 |  | -		err = -ENOSPC; | 
| 1009 |  | -		break; | 
| 1010 |  | -	case EFI_DEVICE_ERROR: | 
| 1011 |  | -		err = -EIO; | 
| 1012 |  | -		break; | 
| 1013 |  | -	case EFI_WRITE_PROTECTED: | 
| 1014 |  | -		err = -EROFS; | 
| 1015 |  | -		break; | 
| 1016 |  | -	case EFI_SECURITY_VIOLATION: | 
| 1017 |  | -		err = -EACCES; | 
| 1018 |  | -		break; | 
| 1019 |  | -	case EFI_NOT_FOUND: | 
| 1020 |  | -		err = -ENOENT; | 
| 1021 |  | -		break; | 
| 1022 |  | -	case EFI_ABORTED: | 
| 1023 |  | -		err = -EINTR; | 
| 1024 |  | -		break; | 
| 1025 |  | -	default: | 
| 1026 |  | -		err = -EINVAL; | 
| 1027 |  | -	} | 
|  | 1069 | +	struct efi_error_code *found; | 
|  | 1070 | +	size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code); | 
| 1028 | 1071 | 
 | 
| 1029 |  | -	return err; | 
|  | 1072 | +	found = bsearch((void *)(uintptr_t)status, efi_error_codes, | 
|  | 1073 | +			sizeof(struct efi_error_code), num, | 
|  | 1074 | +			efi_status_cmp_bsearch); | 
|  | 1075 | +	if (!found) | 
|  | 1076 | +		return -EINVAL; | 
|  | 1077 | +	return found->errno; | 
|  | 1078 | +} | 
|  | 1079 | + | 
|  | 1080 | +const char * | 
|  | 1081 | +efi_status_to_str(efi_status_t status) | 
|  | 1082 | +{ | 
|  | 1083 | +	struct efi_error_code *found; | 
|  | 1084 | +	size_t num = sizeof(efi_error_codes) / sizeof(struct efi_error_code); | 
|  | 1085 | + | 
|  | 1086 | +	found = bsearch((void *)(uintptr_t)status, efi_error_codes, | 
|  | 1087 | +			sizeof(struct efi_error_code), num, | 
|  | 1088 | +			efi_status_cmp_bsearch); | 
|  | 1089 | +	if (!found) | 
|  | 1090 | +		return "Unknown error code"; | 
|  | 1091 | +	return found->description; | 
| 1030 | 1092 | } | 
| 1031 | 1093 | EXPORT_SYMBOL_GPL(efi_status_to_err); | 
| 1032 | 1094 | 
 | 
|  | 
0 commit comments