fwupd/libfwupdplugin/fu-hwids-dmi.c
Richard Hughes 2b0f92506b Refactor the hwids functionality
This refactors the code as it was getting very confusing; before FuSmbios was
reading both SMBIOS and the kernel-provided DT -- and various things were
injecting overrides in three different place. To properly support FDT remove
one layer of indirection.

This also lets us use the compatible strings to enable plugins specifying the
flag _REQUIRE_HWID -- which means we only load the plugin if it's got a chance
of working. e.g.

    [aspeed,ast2500]
2023-01-18 07:04:44 +00:00

72 lines
2.0 KiB
C

/*
* Copyright (C) 2021 Richard Hughes <richard@hughsie.com>
*
* SPDX-License-Identifier: LGPL-2.1+
*/
#define G_LOG_DOMAIN "FuContext"
#include "config.h"
#include "fu-context-private.h"
#include "fu-hwids-private.h"
#include "fu-path.h"
#include "fu-string.h"
gboolean
fu_hwids_dmi_setup(FuContext *ctx, FuHwids *self, GError **error)
{
g_autofree gchar *path = fu_path_from_kind(FU_PATH_KIND_SYSFSDIR_DMI);
struct {
const gchar *hwid;
const gchar *key;
} map[] = {{FU_HWIDS_KEY_BASEBOARD_MANUFACTURER, "board_vendor"},
{FU_HWIDS_KEY_BASEBOARD_PRODUCT, "board_name"},
{FU_HWIDS_KEY_BIOS_VENDOR, "bios_vendor"},
{FU_HWIDS_KEY_BIOS_VERSION, "bios_version"},
{FU_HWIDS_KEY_FAMILY, "product_family"},
{FU_HWIDS_KEY_MANUFACTURER, "sys_vendor"},
{FU_HWIDS_KEY_PRODUCT_NAME, "product_name"},
{FU_HWIDS_KEY_PRODUCT_SKU, "product_sku"},
{FU_HWIDS_KEY_ENCLOSURE_KIND, "chassis_type"},
{NULL, NULL}};
/* the values the kernel parsed; these are world-readable */
if (!g_file_test(path, G_FILE_TEST_IS_DIR)) {
g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "no %s", path);
return FALSE;
}
for (guint i = 0; map[i].key != NULL; i++) {
gsize bufsz = 0;
g_autofree gchar *buf = NULL;
g_autofree gchar *fn = g_build_filename(path, map[i].key, NULL);
g_autoptr(GError) error_local = NULL;
if (!g_file_get_contents(fn, &buf, &bufsz, &error_local)) {
g_debug("unable to read SMBIOS data from %s: %s", fn, error_local->message);
continue;
}
/* trim trailing newline added by kernel */
if (buf[bufsz - 1] == '\n')
buf[bufsz - 1] = 0;
fu_hwids_add_value(self, map[i].hwid, buf);
if (g_strcmp0(map[i].hwid, FU_HWIDS_KEY_ENCLOSURE_KIND) == 0) {
guint64 val = 0;
if (!fu_strtoull(buf,
&val,
FU_SMBIOS_CHASSIS_KIND_OTHER,
FU_SMBIOS_CHASSIS_KIND_LAST,
&error_local)) {
g_warning("ignoring enclosure kind %s", buf);
continue;
}
fu_context_set_chassis_kind(ctx, val);
}
}
/* success */
return TRUE;
}