0001
0002
0003
0004
0005
0006 #include <linux/string.h>
0007 #include <linux/string_helpers.h>
0008
0009 #include "efivar.h"
0010
0011
0012 #define HFI1_EFIVAR_GUID EFI_GUID(0xc50a953e, 0xa8b2, 0x42a6, \
0013 0xbf, 0x89, 0xd3, 0x33, 0xa6, 0xe9, 0xe6, 0xd4)
0014
0015 #define EFI_DATA_SIZE 4096
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 static int read_efi_var(const char *name, unsigned long *size,
0026 void **return_data)
0027 {
0028 efi_status_t status;
0029 efi_char16_t *uni_name;
0030 efi_guid_t guid;
0031 unsigned long temp_size;
0032 void *temp_buffer;
0033 void *data;
0034 int i;
0035 int ret;
0036
0037
0038 *size = 0;
0039 *return_data = NULL;
0040
0041 if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
0042 return -EOPNOTSUPP;
0043
0044 uni_name = kcalloc(strlen(name) + 1, sizeof(efi_char16_t), GFP_KERNEL);
0045 temp_buffer = kzalloc(EFI_DATA_SIZE, GFP_KERNEL);
0046
0047 if (!uni_name || !temp_buffer) {
0048 ret = -ENOMEM;
0049 goto fail;
0050 }
0051
0052
0053 temp_size = EFI_DATA_SIZE;
0054
0055
0056 for (i = 0; name[i]; i++)
0057 uni_name[i] = name[i];
0058
0059
0060 guid = HFI1_EFIVAR_GUID;
0061
0062
0063 status = efi.get_variable(
0064 uni_name,
0065 &guid,
0066 NULL,
0067 &temp_size,
0068 temp_buffer);
0069
0070
0071
0072
0073
0074
0075
0076
0077 ret = status == EFI_SUCCESS ? 0 :
0078 status == EFI_NOT_FOUND ? -ENOENT :
0079 -EINVAL;
0080 if (ret)
0081 goto fail;
0082
0083
0084
0085
0086
0087
0088 data = kmemdup(temp_buffer, temp_size, GFP_KERNEL);
0089 if (!data) {
0090 ret = -ENOMEM;
0091 goto fail;
0092 }
0093
0094 *size = temp_size;
0095 *return_data = data;
0096
0097 fail:
0098 kfree(uni_name);
0099 kfree(temp_buffer);
0100
0101 return ret;
0102 }
0103
0104
0105
0106
0107
0108
0109
0110
0111 int read_hfi1_efi_var(struct hfi1_devdata *dd, const char *kind,
0112 unsigned long *size, void **return_data)
0113 {
0114 char prefix_name[64];
0115 char name[64];
0116 int result;
0117
0118
0119 snprintf(prefix_name, sizeof(prefix_name), "%04x:%02x:%02x.%x",
0120 pci_domain_nr(dd->pcidev->bus),
0121 dd->pcidev->bus->number,
0122 PCI_SLOT(dd->pcidev->devfn),
0123 PCI_FUNC(dd->pcidev->devfn));
0124 snprintf(name, sizeof(name), "%s-%s", prefix_name, kind);
0125 result = read_efi_var(name, size, return_data);
0126
0127
0128
0129
0130
0131 if (result) {
0132 string_upper(prefix_name, prefix_name);
0133 snprintf(name, sizeof(name), "%s-%s", prefix_name, kind);
0134 result = read_efi_var(name, size, return_data);
0135 }
0136
0137 return result;
0138 }