From 4c1862c1e4927c9aa84e84ce76edaa481fd999e8 Mon Sep 17 00:00:00 2001 From: Greg V Date: Tue, 16 Mar 2021 01:06:01 +0300 Subject: quirks: implement DMI support on FreeBSD FreeBSD does not use Linux modaliases, so we have to generate these strings. Unfortunately for us, the data in kenv has the chassis type pre-parsed into a nice string, so we have to match these strings back into numbers. Only relevant types are included to avoid bloating the code. Signed-off-by: Greg V (cherry picked from commit 6941f74070ec0e639bb045107b969b7798947fae) --- src/quirks.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 5 deletions(-) diff --git a/src/quirks.c b/src/quirks.c index 2ea95ed3..af1e9625 100644 --- a/src/quirks.c +++ b/src/quirks.c @@ -35,6 +35,9 @@ #include #include #include +#ifdef __FreeBSD__ +#include +#endif #include "libinput-versionsort.h" #include "libinput-util.h" @@ -353,10 +356,11 @@ property_cleanup(struct property *p) } /** - * Return the dmi modalias from the udev device. + * Return the system DMI info in modalias format. */ +#ifdef __linux__ static inline char * -init_dmi(void) +init_dmi_linux(void) { struct udev *udev; struct udev_device *udev_device; @@ -364,9 +368,6 @@ init_dmi(void) char *copy = NULL; const char *syspath = "/sys/devices/virtual/dmi/id"; - if (getenv("LIBINPUT_RUNNING_TEST_SUITE")) - return safe_strdup("dmi:"); - udev = udev_new(); if (!udev) return NULL; @@ -389,6 +390,73 @@ init_dmi(void) return copy; } +#endif + +#ifdef __FreeBSD__ +static inline char * +init_dmi_freebsd(void) +{ +#define LEN (KENV_MVALLEN + 1) + char *modalias; + char bios_vendor[LEN], bios_version[LEN], bios_date[LEN]; + char sys_vendor[LEN], product_name[LEN], product_version[LEN]; + char board_vendor[LEN], board_name[LEN], board_version[LEN]; + char chassis_vendor[LEN], chassis_type[LEN], chassis_version[LEN]; + int chassis_type_num = 0x2; + + kenv(KENV_GET, "smbios.bios.vendor", bios_vendor, LEN); + kenv(KENV_GET, "smbios.bios.version", bios_version, LEN); + kenv(KENV_GET, "smbios.bios.reldate", bios_date, LEN); + kenv(KENV_GET, "smbios.system.maker", sys_vendor, LEN); + kenv(KENV_GET, "smbios.system.product", product_name, LEN); + kenv(KENV_GET, "smbios.system.version", product_version, LEN); + kenv(KENV_GET, "smbios.planar.maker", board_vendor, LEN); + kenv(KENV_GET, "smbios.planar.product", board_name, LEN); + kenv(KENV_GET, "smbios.planar.version", board_version, LEN); + kenv(KENV_GET, "smbios.chassis.vendor", chassis_vendor, LEN); + kenv(KENV_GET, "smbios.chassis.type", chassis_type, LEN); + kenv(KENV_GET, "smbios.chassis.version", chassis_version, LEN); +#undef LEN + + if (strcmp(chassis_type, "Desktop") == 0) + chassis_type_num = 0x3; + else if (strcmp(chassis_type, "Portable") == 0) + chassis_type_num = 0x8; + else if (strcmp(chassis_type, "Laptop") == 0) + chassis_type_num = 0x9; + else if (strcmp(chassis_type, "Notebook") == 0) + chassis_type_num = 0xA; + else if (strcmp(chassis_type, "Tablet") == 0) + chassis_type_num = 0x1E; + else if (strcmp(chassis_type, "Convertible") == 0) + chassis_type_num = 0x1F; + else if (strcmp(chassis_type, "Detachable") == 0) + chassis_type_num = 0x20; + + xasprintf(&modalias, + "dmi:bvn%s:bvr%s:bd%s:svn%s:pn%s:pvr%s:rvn%s:rn%s:rvr%s:cvn%s:ct%d:cvr%s:", + bios_vendor, bios_version, bios_date, sys_vendor, product_name, + product_version, board_vendor, board_name, board_version, chassis_vendor, + chassis_type_num, chassis_version); + + return modalias; +} +#endif + +static inline char * +init_dmi(void) +{ + if (getenv("LIBINPUT_RUNNING_TEST_SUITE")) + return safe_strdup("dmi:"); + +#if defined(__linux__) + return init_dmi_linux(); +#elif defined(__FreeBSD__) + return init_dmi_freebsd(); +#else + return NULL; +#endif +} /** * Return the dt compatible string -- cgit v1.2.1