[PATCH 4/5] xfree86/linux: implement xf86DMIInit
Daniel Martin
consume.noise at gmail.com
Sat Dec 7 07:48:49 PST 2013
Read DMI identifiers from sysfs (/sys/devices/virtual/dmi/id).
Signed-off-by: Daniel Martin <consume.noise at gmail.com>
---
hw/xfree86/os-support/linux/Makefile.am | 2 +-
hw/xfree86/os-support/linux/lnx_dmi.c | 136 ++++++++++++++++++++++++++++++++
2 files changed, 137 insertions(+), 1 deletion(-)
diff --git a/hw/xfree86/os-support/linux/Makefile.am b/hw/xfree86/os-support/linux/Makefile.am
index 2918c38..4fe38a8 100644
--- a/hw/xfree86/os-support/linux/Makefile.am
+++ b/hw/xfree86/os-support/linux/Makefile.am
@@ -28,12 +28,12 @@ liblinux_la_SOURCES = \
$(srcdir)/../shared/posix_tty.c \
$(srcdir)/../shared/sigio.c \
$(srcdir)/../shared/vidmem.c \
- $(srcdir)/../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..cf98dfb
--- /dev/null
+++ b/hw/xfree86/os-support/linux/lnx_dmi.c
@@ -0,0 +1,136 @@
+#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;
+}
+/* map filenames in SYSFS_DMI_PATH to a key */
+static const SYSFS_DMI_ENTRY_MAP[] = {
+ {"bios_date", "BiosDate"},
+ {"bios_vendor", "BiosVendor"},
+ {"bios_version", "BiosVersion"},
+ {"board_name", "BoardName"},
+ {"board_vendor", "BoardVendor"},
+ {"board_version", "BoardVersion"},
+ {"chassis_type", "ChassisType"},
+ {"chassis_vendor", "ChassisVendor"},
+ {"chassis_version", "ChassisVersion"},
+ {"product_name", "ProductName"},
+ {"product_version", "ProductVersion"},
+ {"sys_vendor", "SystemVendor"},
+ {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;
+
+ for (cur = &SYSFS_DMI_ENTRY_MAP[0]; cur->d_name; cur++)
+ if (strcmp(cur->d_name, d_name) == 0)
+ return cur->key;
+
+ return NULL;
+}
+
+/*
+ * Get the DMI id value from a file in SYSFS_DMI_PATH. The content of the
+ * file will be written to 'value'.
+ *
+ * Returns FALSE if the file couldn't be read or the string length of the
+ * value is zeor.
+ */
+static Bool
+get_value(const char *const d_name, char *value, size_t value_sz)
+{
+ int fd;
+ char fn[PATH_MAX];
+ size_t num_read;
+
+ snprintf(fn, sizeof(fn), "%s/%s", SYSFS_DMI_PATH, d_name);
+ fd = open(fn, O_RDONLY, 0);
+ if (fd < 0)
+ return FALSE;
+
+ num_read = read(fd, value, value_sz);
+ close(fd);
+
+ return xrtrim(value, num_read) > 0 ? TRUE : FALSE;
+}
+
+/*
+ * Filter out uninteresting files.
+ */
+static int
+scandir_filter(const struct dirent *entry)
+{
+ /* skip none regular files */
+ if (entry->d_type != DT_REG)
+ return 0;
+
+ /* skip files without a mapping from filename to key */
+ return get_key(entry->d_name) ? 1 : 0;
+}
+
+void
+xf86DMIInit(void)
+{
+ int i, num_entries;
+ struct dirent **entries;
+
+ char buf[PATH_MAX];
+
+ Bool error = FALSE;
+
+ num_entries = scandir(SYSFS_DMI_PATH, &entries,
+ scandir_filter, alphasort);
+ if (num_entries < 0) {
+ xf86MsgVerb(X_ERROR, 3, "Can't read DMI 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);
+ if (!key)
+ continue;
+
+ if (!get_value(entries[i]->d_name, &buf[0], sizeof(buf)))
+ /* Couldn't open/read the file or strlen of the buf is zero. */
+ continue;
+
+ value = strdup(buf);
+ if (!value) {
+ error = TRUE;
+ break;
+ }
+
+ xf86DMIAdd(key, value);
+ }
+
+ /* always cleanup entries */
+ for (i = 0; i < num_entries; i++)
+ free(entries[i]);
+ free(entries);
+
+ if (error) {
+ xf86DMICleanup();
+ }
+}
--
1.8.4.2
More information about the xorg-devel
mailing list