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