summaryrefslogtreecommitdiff
path: root/platform-intel.c
diff options
context:
space:
mode:
authorHawrylewicz Czarnowski, Przemyslaw <przemyslaw.hawrylewicz.czarnowski@intel.com>2011-03-28 10:42:07 +1100
committerNeilBrown <neilb@suse.de>2011-03-28 10:42:07 +1100
commitaae4c1116639633ad7e48f0fd603f6d6cd39a653 (patch)
tree986ca43b46d40119c0c247b420398682b98c5cb4 /platform-intel.c
parent96687b797fe65dbac75a1c5b3a00ae9a4e921efb (diff)
downloadmdadm-aae4c1116639633ad7e48f0fd603f6d6cd39a653.tar.gz
imsm: reading of UEFI variables needs an update
Content of EFI variable is stored in "data" file. Moreover size of data provided by given variable can be initially validated by reading value of "size" file. Function read_efi_variable() has been introduced to simplify the code. Signed-off-by: Przemyslaw Czarnowski <przemyslaw.hawrylewicz.czarnowski@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'platform-intel.c')
-rw-r--r--platform-intel.c62
1 files changed, 45 insertions, 17 deletions
diff --git a/platform-intel.c b/platform-intel.c
index fe6785c..cb6c7dc 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -357,13 +357,52 @@ int populated_efi[SYS_DEV_MAX] = { 0, 0 };
static struct imsm_orom imsm_efi[SYS_DEV_MAX];
-const struct imsm_orom *find_imsm_efi(enum sys_dev_type hba_id)
+int read_efi_variable(void *buffer, ssize_t buf_size, char *variable_name, struct efi_guid guid)
{
- int dfd=-1;
char path[PATH_MAX];
char buf[GUID_STR_MAX];
- int n;
+ int dfd;
+ ssize_t n, var_data_len;
+
+ snprintf(path, PATH_MAX, "%s/%s-%s/size", SYS_EFI_VAR_PATH, variable_name, guid_str(buf, guid));
+
+ dprintf("EFI VAR: path=%s\n", path);
+ /* get size of variable data */
+ dfd = open(path, O_RDONLY);
+ if (dfd < 0)
+ return 1;
+
+ n = read(dfd, &buf, sizeof(buf));
+ close(dfd);
+ if (n < 0)
+ return 1;
+ buf[n] = '\0';
+
+ errno = 0;
+ var_data_len = strtoul(buf, NULL, 16);
+ if ((errno == ERANGE && (var_data_len == LONG_MAX))
+ || (errno != 0 && var_data_len == 0))
+ return 1;
+ /* get data */
+ snprintf(path, PATH_MAX, "%s/%s-%s/data", SYS_EFI_VAR_PATH, variable_name, guid_str(buf, guid));
+
+ dprintf("EFI VAR: path=%s\n", path);
+ dfd = open(path, O_RDONLY);
+ if (dfd < 0)
+ return 1;
+
+ n = read(dfd, buffer, buf_size);
+ close(dfd);
+ if (n != var_data_len || n < buf_size) {
+ return 1;
+ }
+
+ return 0;
+}
+
+const struct imsm_orom *find_imsm_efi(enum sys_dev_type hba_id)
+{
if (hba_id >= SYS_DEV_MAX)
return NULL;
@@ -383,25 +422,14 @@ const struct imsm_orom *find_imsm_efi(enum sys_dev_type hba_id)
return imsm_platform_test(hba_id, &populated_efi[hba_id], &imsm_efi[hba_id]);
}
/* OROM test is set, return that there is no EFI capabilities */
- if (check_env("IMSM_TEST_OROM")) {
+ if (check_env("IMSM_TEST_OROM"))
return NULL;
- }
- if (hba_id == SYS_DEV_SAS)
- snprintf(path, PATH_MAX, "%s/%s-%s", SYS_EFI_VAR_PATH, SCU_PROP, guid_str(buf, VENDOR_GUID));
- else
- snprintf(path, PATH_MAX, "%s/%s-%s", SYS_EFI_VAR_PATH, AHCI_PROP, guid_str(buf, VENDOR_GUID));
- dprintf("EFI VAR: path=%s\n", path);
- dfd = open(path, O_RDONLY);
- if (dfd < 0) {
+ if (read_efi_variable(&imsm_efi[hba_id], sizeof(imsm_efi[0]), hba_id == SYS_DEV_SAS ? SCU_PROP : AHCI_PROP, VENDOR_GUID)) {
populated_efi[hba_id] = 0;
return NULL;
}
- n = read(dfd, &imsm_efi[hba_id], sizeof(imsm_efi[0]));
- close(dfd);
- if (n < (int) (sizeof(imsm_efi[0]))) {
- return NULL;
- }
+
populated_efi[hba_id] = 1;
return &imsm_efi[hba_id];
}