summaryrefslogtreecommitdiff
path: root/drivers/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/dcdbas.c19
-rw-r--r--drivers/firmware/dmi_scan.c14
-rw-r--r--drivers/firmware/efi/efi-pstore.c27
-rw-r--r--drivers/firmware/efi/efivars.c3
4 files changed, 40 insertions, 23 deletions
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 8e77c02edb24..ff080ee20197 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -535,11 +535,12 @@ static struct attribute *dcdbas_dev_attrs[] = {
static struct attribute_group dcdbas_attr_group = {
.attrs = dcdbas_dev_attrs,
+ .bin_attrs = dcdbas_bin_attrs,
};
static int dcdbas_probe(struct platform_device *dev)
{
- int i, error;
+ int error;
host_control_action = HC_ACTION_NONE;
host_control_smi_type = HC_SMITYPE_NONE;
@@ -555,18 +556,6 @@ static int dcdbas_probe(struct platform_device *dev)
if (error)
return error;
- for (i = 0; dcdbas_bin_attrs[i]; i++) {
- error = sysfs_create_bin_file(&dev->dev.kobj,
- dcdbas_bin_attrs[i]);
- if (error) {
- while (--i >= 0)
- sysfs_remove_bin_file(&dev->dev.kobj,
- dcdbas_bin_attrs[i]);
- sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group);
- return error;
- }
- }
-
register_reboot_notifier(&dcdbas_reboot_nb);
dev_info(&dev->dev, "%s (version %s)\n",
@@ -577,11 +566,7 @@ static int dcdbas_probe(struct platform_device *dev)
static int dcdbas_remove(struct platform_device *dev)
{
- int i;
-
unregister_reboot_notifier(&dcdbas_reboot_nb);
- for (i = 0; dcdbas_bin_attrs[i]; i++)
- sysfs_remove_bin_file(&dev->dev.kobj, dcdbas_bin_attrs[i]);
sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group);
return 0;
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index eb760a218da4..232fa8fce26a 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -419,6 +419,13 @@ static void __init dmi_format_ids(char *buf, size_t len)
dmi_get_system_info(DMI_BIOS_DATE));
}
+/*
+ * Check for DMI/SMBIOS headers in the system firmware image. Any
+ * SMBIOS header must start 16 bytes before the DMI header, so take a
+ * 32 byte buffer and check for DMI at offset 16 and SMBIOS at offset
+ * 0. If the DMI header is present, set dmi_ver accordingly (SMBIOS
+ * takes precedence) and return 0. Otherwise return 1.
+ */
static int __init dmi_present(const u8 *buf)
{
int smbios_ver;
@@ -506,6 +513,13 @@ void __init dmi_scan_machine(void)
if (p == NULL)
goto error;
+ /*
+ * Iterate over all possible DMI header addresses q.
+ * Maintain the 32 bytes around q in buf. On the
+ * first iteration, substitute zero for the
+ * out-of-range bytes so there is no chance of falsely
+ * detecting an SMBIOS header.
+ */
memset(buf, 0, 16);
for (q = p; q < p + 0x10000; q += 16) {
memcpy_fromio(buf + 16, q, 16);
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index 73de5a9c2247..5002d50e3781 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -35,6 +35,7 @@ struct pstore_read_data {
enum pstore_type_id *type;
int *count;
struct timespec *timespec;
+ bool *compressed;
char **buf;
};
@@ -42,7 +43,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
{
efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
struct pstore_read_data *cb_data = data;
- char name[DUMP_NAME_LEN];
+ char name[DUMP_NAME_LEN], data_type;
int i;
int cnt;
unsigned int part;
@@ -54,12 +55,23 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
for (i = 0; i < DUMP_NAME_LEN; i++)
name[i] = entry->var.VariableName[i];
- if (sscanf(name, "dump-type%u-%u-%d-%lu",
+ if (sscanf(name, "dump-type%u-%u-%d-%lu-%c",
+ cb_data->type, &part, &cnt, &time, &data_type) == 5) {
+ *cb_data->id = part;
+ *cb_data->count = cnt;
+ cb_data->timespec->tv_sec = time;
+ cb_data->timespec->tv_nsec = 0;
+ if (data_type == 'C')
+ *cb_data->compressed = true;
+ else
+ *cb_data->compressed = false;
+ } else if (sscanf(name, "dump-type%u-%u-%d-%lu",
cb_data->type, &part, &cnt, &time) == 4) {
*cb_data->id = part;
*cb_data->count = cnt;
cb_data->timespec->tv_sec = time;
cb_data->timespec->tv_nsec = 0;
+ *cb_data->compressed = false;
} else if (sscanf(name, "dump-type%u-%u-%lu",
cb_data->type, &part, &time) == 3) {
/*
@@ -71,6 +83,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
*cb_data->count = 0;
cb_data->timespec->tv_sec = time;
cb_data->timespec->tv_nsec = 0;
+ *cb_data->compressed = false;
} else
return 0;
@@ -87,7 +100,8 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
int *count, struct timespec *timespec,
- char **buf, struct pstore_info *psi)
+ char **buf, bool *compressed,
+ struct pstore_info *psi)
{
struct pstore_read_data data;
@@ -95,6 +109,7 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
data.type = type;
data.count = count;
data.timespec = timespec;
+ data.compressed = compressed;
data.buf = buf;
return __efivar_entry_iter(efi_pstore_read_func, &efivar_sysfs_list, &data,
@@ -103,7 +118,7 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
static int efi_pstore_write(enum pstore_type_id type,
enum kmsg_dump_reason reason, u64 *id,
- unsigned int part, int count, size_t hsize, size_t size,
+ unsigned int part, int count, bool compressed, size_t size,
struct pstore_info *psi)
{
char name[DUMP_NAME_LEN];
@@ -111,8 +126,8 @@ static int efi_pstore_write(enum pstore_type_id type,
efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
int i, ret = 0;
- sprintf(name, "dump-type%u-%u-%d-%lu", type, part, count,
- get_seconds());
+ sprintf(name, "dump-type%u-%u-%d-%lu-%c", type, part, count,
+ get_seconds(), compressed ? 'C' : 'D');
for (i = 0; i < DUMP_NAME_LEN; i++)
efi_name[i] = name[i];
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index 8bd1bb6dbe47..8a7432a4b413 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -583,6 +583,9 @@ int efivars_sysfs_init(void)
struct kobject *parent_kobj = efivars_kobject();
int error = 0;
+ if (!efi_enabled(EFI_RUNTIME_SERVICES))
+ return -ENODEV;
+
/* No efivars has been registered yet */
if (!parent_kobj)
return 0;