#include <sys/stat.h>
#include <limits.h>
-
static int devpath_to_ll(const char *dev_path, const char *entry,
unsigned long long *val);
static __u16 devpath_to_vendor(const char *dev_path);
-void free_sys_dev(struct sys_dev **list)
+static void free_sys_dev(struct sys_dev **list)
{
while (*list) {
struct sys_dev *next = (*list)->next;
/* start / add list entry */
if (!head) {
- head = malloc(sizeof(*head));
+ head = xmalloc(sizeof(*head));
list = head;
} else {
- list->next = malloc(sizeof(*head));
+ list->next = xmalloc(sizeof(*head));
list = list->next;
}
list->dev_id = (__u16) dev_id;
list->type = type;
- list->path = canonicalize_file_name(path);
+ list->path = realpath(path, NULL);
list->next = NULL;
if ((list->pci_id = strrchr(list->path, '/')) != NULL)
list->pci_id++;
return head;
}
-
static struct sys_dev *intel_devices=NULL;
+static time_t valid_time = 0;
static enum sys_dev_type device_type_by_id(__u16 device_id)
{
return n;
}
-
static __u16 devpath_to_vendor(const char *dev_path)
{
char path[strlen(dev_path) + strlen("/vendor") + 1];
{
struct sys_dev *ahci, *isci;
+ if (valid_time > time(0) - 10)
+ return intel_devices;
+
+ if (intel_devices)
+ free_sys_dev(&intel_devices);
+
isci = find_driver_devices("pci", "isci");
ahci = find_driver_devices("pci", "ahci");
elem = elem->next;
elem->next = isci;
}
- return ahci;
+ intel_devices = ahci;
+ valid_time = time(0);
+ return intel_devices;
}
/*
for (offset = 0; offset < len; offset += 4) {
imsm_mem = start + offset;
- if ((memcmp(imsm_mem->signature, "$VER", 4) == 0) ||
- (memcmp(imsm_mem->signature, "$OEM", 4) == 0)) {
+ if ((memcmp(imsm_mem->signature, "$VER", 4) == 0)) {
imsm_orom[dev] = *imsm_mem;
populated_orom[dev] = 1;
return populated_orom[SYS_DEV_SATA] && populated_orom[SYS_DEV_SAS];
return 0;
}
-
const struct imsm_orom *imsm_platform_test(enum sys_dev_type hba_id, int *populated,
struct imsm_orom *imsm_orom)
{
return imsm_orom;
}
-
-
static const struct imsm_orom *find_imsm_hba_orom(enum sys_dev_type hba_id)
{
unsigned long align;
}
if (check_env("IMSM_TEST_OROM")) {
dprintf("OROM CAP: %p, pid: %d pop: %d\n",
- &imsm_orom[hba_id], (int) getpid(), populated_orom[hba_id]);
+ &imsm_orom[hba_id], (int) getpid(), populated_orom[hba_id]);
return imsm_platform_test(hba_id, &populated_orom[hba_id], &imsm_orom[hba_id]);
}
/* return empty OROM capabilities in EFI test mode */
check_env("IMSM_TEST_SCU_EFI"))
return NULL;
-
- if (intel_devices != NULL)
- free_sys_dev(&intel_devices);
-
- intel_devices = find_intel_devices();
+ find_intel_devices();
if (intel_devices == NULL)
return NULL;
scan_adapter_roms(scan);
probe_roms_exit();
- if (intel_devices != NULL)
- free_sys_dev(&intel_devices);
- intel_devices = NULL;
-
if (populated_orom[hba_id])
return &imsm_orom[hba_id];
return NULL;
(c) & 0xff, ((c) >> 8) & 0xff, \
(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }})
-
#define SYS_EFI_VAR_PATH "/sys/firmware/efi/vars"
#define SCU_PROP "RstScuV"
#define AHCI_PROP "RstSataV"
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;
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);
- if ((dfd = open(path, O_RDONLY)) < 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];
}
{
const struct imsm_orom *cap=NULL;
-
if ((cap = find_imsm_efi(hba_id)) != NULL)
return cap;
if ((cap = find_imsm_hba_orom(hba_id)) != NULL)
char device[46];
sprintf(device, "/sys/dev/block/%d:%d/device", major(dev), minor(dev));
- return canonicalize_file_name(device);
+ return realpath(device, NULL);
}
char *diskfd_to_devpath(int fd)