[v2 5/6] xfree86/linux: implement xf86DMIInit

Daniel Martin consume.noise at gmail.com
Tue Dec 17 14:35:58 PST 2013


Read DMI identifiers from sysfs (/sys/devices/virtual/dmi/id).

Signed-off-by: Daniel Martin <consume.noise at gmail.com>
---
v2: get_value returns a strduped string, fixed typos

 hw/xfree86/os-support/linux/Makefile.am |   2 +-
 hw/xfree86/os-support/linux/lnx_dmi.c   | 118 ++++++++++++++++++++++++++++++++
 2 files changed, 119 insertions(+), 1 deletion(-)
 create mode 100644 hw/xfree86/os-support/linux/lnx_dmi.c

diff --git a/hw/xfree86/os-support/linux/Makefile.am b/hw/xfree86/os-support/linux/Makefile.am
index e1f8bd8..22c98ea 100644
--- a/hw/xfree86/os-support/linux/Makefile.am
+++ b/hw/xfree86/os-support/linux/Makefile.am
@@ -28,12 +28,12 @@ liblinux_la_SOURCES = \
 	../shared/posix_tty.c \
 	../shared/sigio.c \
 	../shared/vidmem.c \
-	../stub/stub_dmi.c \
 	$(ACPI_SRCS) \
 	$(APM_SRCS) \
 	$(PLATFORM_PCI_SUPPORT) \
 	lnx_agp.c \
 	lnx_bell.c \
+	lnx_dmi.c \
 	lnx_init.c \
 	lnx_kmod.c \
 	lnx_platform.c \
diff --git a/hw/xfree86/os-support/linux/lnx_dmi.c b/hw/xfree86/os-support/linux/lnx_dmi.c
new file mode 100644
index 0000000..7820a19
--- /dev/null
+++ b/hw/xfree86/os-support/linux/lnx_dmi.c
@@ -0,0 +1,118 @@
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <dirent.h>
+
+#include "parser/xf86Parser.h"
+#include "xf86.h"
+#include "xf86_OSlib.h"
+
+
+static const char SYSFS_DMI_PATH[] = "/sys/devices/virtual/dmi/id";
+
+struct dname_to_key {
+    const char *const d_name;
+    const char *const key;
+}
+/* Filename that need to be mapped to a key. */
+static const SYSFS_ENTRY_TO_KEYMAP[] = {
+    {"sys_vendor", "system_vendor"},
+    {NULL, NULL}
+};
+
+/*
+ * Get the key for a filename.
+ */
+static const char *const
+get_key(const char *const d_name)
+{
+    const struct dname_to_key *cur;
+
+    if (xf86DMIIsValidKey(d_name))
+        return d_name;
+
+    for (cur = SYSFS_ENTRY_TO_KEYMAP; cur->key; cur++)
+        if ((strcmp(cur->d_name, d_name) == 0) && xf86DMIIsValidKey(cur->key))
+            return cur->key;
+
+    return NULL;
+}
+
+/*
+ * Get the DMI id value from a file in SYSFS_DMI_PATH. Returns a
+ * zero-terminated allocated string on success, NULL otherwise.
+ */
+static char *
+get_value(const char *const d_name)
+{
+    char buf[PATH_MAX];
+    int fd;
+    size_t num_read;
+
+    snprintf(buf, sizeof(buf), "%s/%s", SYSFS_DMI_PATH, d_name);
+    fd = open(buf, O_RDONLY, 0);
+    if (fd < 0)
+        return NULL;
+
+    num_read = read(fd, buf, sizeof(buf));
+    close(fd);
+
+    if (xstrnrtrim(buf, num_read) < 1)
+        return NULL;
+
+    return strdup(buf);
+}
+
+/*
+ * Filter out uninteresting files.
+ */
+static int
+scandir_filter(const struct dirent *entry)
+{
+    /* Skip non-regular files. */
+    if (entry->d_type != DT_REG)
+        return 0;
+
+    /* Skip unsupported keys. */
+    return get_key(entry->d_name) ? 1 : 0;
+}
+
+void
+xf86DMIInit(void)
+{
+    int i, num_entries;
+    struct dirent **entries;
+
+    Bool error = FALSE;
+
+    num_entries = scandir(SYSFS_DMI_PATH, &entries,
+                          scandir_filter, alphasort);
+    if (num_entries < 0) {
+        xf86Msg(X_ERROR, "DMI: Can't read identifiers: %s %s\n",
+                SYSFS_DMI_PATH, strerror(errno));
+        return;
+    }
+
+    for (i = 0; i < num_entries; i++) {
+        const char *key;
+        char *value;
+
+        key = get_key(entries[i]->d_name);
+        value = get_value(entries[i]->d_name);
+        if (!key || !value || !xf86DMIAdd(key, value)) {
+            free(value);
+            error = TRUE;
+            break;
+        }
+    }
+
+    /* always cleanup entries */
+    for (i = 0; i < num_entries; i++)
+        free(entries[i]);
+    free(entries);
+
+    if (error) {
+        xf86DMICleanup();
+    }
+}
-- 
1.8.5.1



More information about the xorg-devel mailing list