summaryrefslogtreecommitdiffstats
path: root/dmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'dmi.c')
-rw-r--r--dmi.c64
1 files changed, 35 insertions, 29 deletions
diff --git a/dmi.c b/dmi.c
index 3b717cd23..94e47fb49 100644
--- a/dmi.c
+++ b/dmi.c
@@ -19,9 +19,7 @@
/* strnlen is in POSIX but was a GNU extension up to glibc 2.10 */
#if (__GLIBC__ == 2 && __GLIBC_MINOR__ < 10) || __GLIBC__ < 2
-#ifndef _GNU_SOURCE
#define _GNU_SOURCE
-#endif /* !GNU_SOURCE */
#else
#define _POSIX_C_SOURCE 200809L
#endif
@@ -29,11 +27,12 @@
#include <strings.h>
#include <string.h>
#include <ctype.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
-#include "platform.h"
#include "flash.h"
+#include "hwaccess_physmap.h"
#include "programmer.h"
/* Enable SMBIOS decoding. Currently legacy DMI decoding is enough. */
@@ -42,7 +41,12 @@
/* Strings longer than 4096 in DMI are just insane. */
#define DMI_MAX_ANSWER_LEN 4096
-int has_dmi_support = 0;
+static bool g_has_dmi_support = false;
+
+bool dmi_is_supported(void)
+{
+ return g_has_dmi_support;
+}
static struct {
const char *const keyword;
@@ -147,11 +151,11 @@ static char *dmi_string(const char *buf, uint8_t string_id, const char *limit)
return newbuf;
}
-static void dmi_chassis_type(uint8_t code)
+static int dmi_chassis_type(uint8_t code)
{
unsigned int i;
code &= 0x7f; /* bits 6:0 are chassis type, 7th bit is the lock bit */
- is_laptop = 2;
+ int is_laptop = 2;
for (i = 0; i < ARRAY_SIZE(dmi_chassis_types); i++) {
if (code == dmi_chassis_types[i].type) {
msg_pdbg("DMI string chassis-type: \"%s\"\n", dmi_chassis_types[i].name);
@@ -159,14 +163,15 @@ static void dmi_chassis_type(uint8_t code)
break;
}
}
+ return is_laptop;
}
-static void dmi_table(uint32_t base, uint16_t len, uint16_t num)
+static void dmi_table(uint32_t base, uint16_t len, uint16_t num, int *is_laptop)
{
unsigned int i = 0, j = 0;
uint8_t *dmi_table_mem = physmap_ro("DMI Table", base, len);
- if (dmi_table_mem == NULL) {
+ if (dmi_table_mem == ERROR_PTR) {
msg_perr("Unable to access DMI Table\n");
return;
}
@@ -184,7 +189,7 @@ static void dmi_table(uint32_t base, uint16_t len, uint16_t num)
* is invalid, but we cannot reliably locate the next entry.
* - If the length value indicates that this structure spreads
* across the table border, something is fishy too.
- * Better stop at this point, and let the user know his/her
+ * Better stop at this point, and let the user know their
* table is broken.
*/
if (data[1] < 4 || data + data[1] >= limit) {
@@ -194,7 +199,7 @@ static void dmi_table(uint32_t base, uint16_t len, uint16_t num)
if(data[0] == 3) {
if (data + 5 < limit)
- dmi_chassis_type(data[5]);
+ *is_laptop = dmi_chassis_type(data[5]);
else /* the table is broken, but laptop detection is optional, hence continue. */
msg_pwarn("DMI table is broken (chassis_type out of bounds)!\n");
} else
@@ -228,7 +233,7 @@ out:
}
#if SM_SUPPORT
-static int smbios_decode(uint8_t *buf)
+static int smbios_decode(uint8_t *buf, int *is_laptop)
{
/* TODO: other checks mentioned in the conformance guidelines? */
if (!dmi_checksum(buf, buf[0x05]) ||
@@ -236,23 +241,23 @@ static int smbios_decode(uint8_t *buf)
!dmi_checksum(buf + 0x10, 0x0F))
return 0;
- dmi_table(mmio_readl(buf + 0x18), mmio_readw(buf + 0x16), mmio_readw(buf + 0x1C));
+ dmi_table(mmio_readl(buf + 0x18), mmio_readw(buf + 0x16), mmio_readw(buf + 0x1C), is_laptop);
return 1;
}
#endif
-static int legacy_decode(uint8_t *buf)
+static int legacy_decode(uint8_t *buf, int *is_laptop)
{
if (!dmi_checksum(buf, 0x0F))
return 1;
- dmi_table(mmio_readl(buf + 0x08), mmio_readw(buf + 0x06), mmio_readw(buf + 0x0C));
+ dmi_table(mmio_readl(buf + 0x08), mmio_readw(buf + 0x06), mmio_readw(buf + 0x0C), is_laptop);
return 0;
}
-static int dmi_fill(void)
+static int dmi_fill(int *is_laptop)
{
size_t fp;
uint8_t *dmi_mem;
@@ -270,12 +275,12 @@ static int dmi_fill(void)
for (fp = 0; fp <= 0xFFF0; fp += 16) {
#if SM_SUPPORT
if (memcmp(dmi_mem + fp, "_SM_", 4) == 0 && fp <= 0xFFE0) {
- if (smbios_decode(dmi_mem + fp)) // FIXME: length check
+ if (smbios_decode(dmi_mem + fp), is_laptop) // FIXME: length check
goto out;
} else
#endif
if (memcmp(dmi_mem + fp, "_DMI_", 5) == 0)
- if (legacy_decode(dmi_mem + fp) == 0) {
+ if (legacy_decode(dmi_mem + fp, is_laptop) == 0) {
ret = 0;
goto out;
}
@@ -346,7 +351,7 @@ static char *get_dmi_string(const char *string_name)
return result;
}
-static int dmi_fill(void)
+static int dmi_fill(int *is_laptop)
{
unsigned int i;
char *chassis_type;
@@ -363,10 +368,10 @@ static int dmi_fill(void)
return 0; /* chassis-type handling is optional anyway */
msg_pdbg("DMI string chassis-type: \"%s\"\n", chassis_type);
- is_laptop = 2;
+ *is_laptop = 2;
for (i = 0; i < ARRAY_SIZE(dmi_chassis_types); i++) {
if (strcasecmp(chassis_type, dmi_chassis_types[i].name) == 0) {
- is_laptop = dmi_chassis_types[i].is_laptop;
+ *is_laptop = dmi_chassis_types[i].is_laptop;
break;
}
}
@@ -383,10 +388,11 @@ static int dmi_shutdown(void *data)
free(dmi_strings[i].value);
dmi_strings[i].value = NULL;
}
+ g_has_dmi_support = false;
return 0;
}
-void dmi_init(void)
+void dmi_init(int *is_laptop)
{
/* Register shutdown function before we allocate anything. */
if (register_shutdown(dmi_shutdown, NULL)) {
@@ -394,11 +400,11 @@ void dmi_init(void)
return;
}
- /* dmi_fill fills the dmi_strings array, and if possible sets the global is_laptop variable. */
- if (dmi_fill() != 0)
+ /* dmi_fill fills the dmi_strings array, and if possible set the is_laptop parameter. */
+ if (dmi_fill(is_laptop) != 0)
return;
- switch (is_laptop) {
+ switch (*is_laptop) {
case 1:
msg_pdbg("Laptop detected via DMI.\n");
break;
@@ -407,7 +413,7 @@ void dmi_init(void)
break;
}
- has_dmi_support = 1;
+ g_has_dmi_support = true;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(dmi_strings); i++) {
msg_pdbg("DMI string %s: \"%s\"\n", dmi_strings[i].keyword,
@@ -428,7 +434,7 @@ void dmi_init(void)
*/
static int dmi_compare(const char *value, const char *pattern)
{
- int anchored = 0;
+ bool anchored = false;
int patternlen;
msg_pspew("matching %s against %s\n", value, pattern);
@@ -437,7 +443,7 @@ static int dmi_compare(const char *value, const char *pattern)
return 1;
if (pattern[0] == '^') {
- anchored = 1;
+ anchored = true;
pattern++;
}
@@ -454,7 +460,7 @@ static int dmi_compare(const char *value, const char *pattern)
/* start character to make ends match */
value += valuelen - patternlen;
- anchored = 1;
+ anchored = true;
}
if (anchored)
@@ -467,7 +473,7 @@ int dmi_match(const char *pattern)
{
unsigned int i;
- if (!has_dmi_support)
+ if (!dmi_is_supported())
return 0;
for (i = 0; i < ARRAY_SIZE(dmi_strings); i++) {