|
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