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 <greg@unrelenting.technology>
(cherry picked from commit 6941f74070)
This commit is contained in:
Greg V 2021-03-16 01:06:01 +03:00 committed by Peter Hutterer
parent a49826a7a8
commit 4c1862c1e4

View file

@ -35,6 +35,9 @@
#include <dirent.h>
#include <fnmatch.h>
#include <libgen.h>
#ifdef __FreeBSD__
#include <kenv.h>
#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