mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-03 03:56:30 +00:00
Allow server metadata to set the version format on some devices
It appears just choosing 'if Dell then QUAD else TRIPLET' isn't good enough.
This commit is contained in:
parent
984e29ca33
commit
b097603800
@ -187,6 +187,8 @@ fwupd_device_flag_to_string (FwupdDeviceFlags device_flag)
|
||||
return "md-set-name";
|
||||
if (device_flag == FWUPD_DEVICE_FLAG_MD_SET_NAME_CATEGORY)
|
||||
return "md-set-name-category";
|
||||
if (device_flag == FWUPD_DEVICE_FLAG_MD_SET_VERFMT)
|
||||
return "md-set-verfmt";
|
||||
if (device_flag == FWUPD_DEVICE_FLAG_UNKNOWN)
|
||||
return "unknown";
|
||||
return NULL;
|
||||
@ -275,6 +277,8 @@ fwupd_device_flag_from_string (const gchar *device_flag)
|
||||
return FWUPD_DEVICE_FLAG_MD_SET_NAME;
|
||||
if (g_strcmp0 (device_flag, "md-set-name-category") == 0)
|
||||
return FWUPD_DEVICE_FLAG_MD_SET_NAME_CATEGORY;
|
||||
if (g_strcmp0 (device_flag, "md-set-verfmt") == 0)
|
||||
return FWUPD_DEVICE_FLAG_MD_SET_VERFMT;
|
||||
return FWUPD_DEVICE_FLAG_UNKNOWN;
|
||||
}
|
||||
|
||||
|
@ -101,6 +101,7 @@ typedef enum {
|
||||
* @FWUPD_DEVICE_FLAG_INSTALL_ALL_RELEASES: Install each intermediate release rather than jumping direct to newest
|
||||
* @FWUPD_DEVICE_FLAG_MD_SET_NAME: Set the device name from the metadata <name> if available
|
||||
* @FWUPD_DEVICE_FLAG_MD_SET_NAME_CATEGORY: Set the device name from the metadata <category> if available
|
||||
* @FWUPD_DEVICE_FLAG_MD_SET_VERFMT: Set the device version format from the metadata if available
|
||||
*
|
||||
* The device flags.
|
||||
**/
|
||||
@ -139,6 +140,7 @@ typedef enum {
|
||||
#define FWUPD_DEVICE_FLAG_INSTALL_ALL_RELEASES (1u << 31) /* Since: 1.3.7 */
|
||||
#define FWUPD_DEVICE_FLAG_MD_SET_NAME (1llu << 32) /* Since: 1.3.9 */
|
||||
#define FWUPD_DEVICE_FLAG_MD_SET_NAME_CATEGORY (1llu << 33) /* Since: 1.3.9 */
|
||||
#define FWUPD_DEVICE_FLAG_MD_SET_VERFMT (1llu << 34) /* Since: 1.3.9 */
|
||||
#define FWUPD_DEVICE_FLAG_UNKNOWN G_MAXUINT64 /* Since: 0.7.3 */
|
||||
typedef guint64 FwupdDeviceFlags;
|
||||
|
||||
|
@ -44,8 +44,6 @@ gboolean fu_quirks_lookup_by_id_iter (FuQuirks *self,
|
||||
gpointer user_data);
|
||||
|
||||
#define FU_QUIRKS_PLUGIN "Plugin"
|
||||
#define FU_QUIRKS_UEFI_VERSION_FORMAT "UefiVersionFormat"
|
||||
#define FU_QUIRKS_DAEMON_VERSION_FORMAT "ComponentIDs"
|
||||
#define FU_QUIRKS_FLAGS "Flags"
|
||||
#define FU_QUIRKS_SUMMARY "Summary"
|
||||
#define FU_QUIRKS_ICON "Icon"
|
||||
|
@ -32,9 +32,3 @@ ParentGuid = e7ca1f36-bf73-4574-afe6-a4ccacabf479
|
||||
[Guid=MST-tb18-vmm3330-274]
|
||||
Plugin = synaptics_mst
|
||||
ParentGuid = e7ca1f36-bf73-4574-afe6-a4ccacabf479
|
||||
|
||||
[SmbiosManufacturer=Dell Inc.]
|
||||
UefiVersionFormat = dell-bios
|
||||
|
||||
[SmbiosManufacturer=Alienware]
|
||||
UefiVersionFormat = dell-bios
|
||||
|
@ -231,26 +231,6 @@ fu_plugin_dell_inject_fake_data (FuPlugin *plugin,
|
||||
data->can_switch_modes = TRUE;
|
||||
}
|
||||
|
||||
static FwupdVersionFormat
|
||||
fu_plugin_dell_get_version_format (FuPlugin *plugin)
|
||||
{
|
||||
const gchar *content;
|
||||
const gchar *quirk;
|
||||
g_autofree gchar *group = NULL;
|
||||
|
||||
content = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_MANUFACTURER);
|
||||
if (content == NULL)
|
||||
return FWUPD_VERSION_FORMAT_TRIPLET;
|
||||
|
||||
/* any quirks match */
|
||||
group = g_strdup_printf ("SmbiosManufacturer=%s", content);
|
||||
quirk = fu_plugin_lookup_quirk_by_id (plugin, group,
|
||||
FU_QUIRKS_UEFI_VERSION_FORMAT);
|
||||
if (quirk == NULL)
|
||||
return FWUPD_VERSION_FORMAT_TRIPLET;
|
||||
return fwupd_version_format_from_string (quirk);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_plugin_dell_capsule_supported (FuPlugin *plugin)
|
||||
{
|
||||
@ -319,7 +299,7 @@ fu_plugin_usb_device_added (FuPlugin *plugin,
|
||||
GError **error)
|
||||
{
|
||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||
FwupdVersionFormat version_format;
|
||||
FwupdVersionFormat version_format = FWUPD_VERSION_FORMAT_DELL_BIOS;
|
||||
guint16 pid;
|
||||
guint16 vid;
|
||||
const gchar *query_str;
|
||||
@ -372,7 +352,6 @@ fu_plugin_usb_device_added (FuPlugin *plugin,
|
||||
g_debug ("Dock cable type: %" G_GUINT32_FORMAT, dock_info->cable_type);
|
||||
g_debug ("Dock location: %d", dock_info->location);
|
||||
g_debug ("Dock component count: %d", dock_info->component_count);
|
||||
version_format = fu_plugin_dell_get_version_format (plugin);
|
||||
|
||||
for (guint i = 0; i < dock_info->component_count; i++) {
|
||||
g_autofree gchar *fw_str = NULL;
|
||||
|
@ -463,30 +463,6 @@ fu_plugin_device_registered (FuPlugin *plugin, FuDevice *device)
|
||||
}
|
||||
}
|
||||
|
||||
static FwupdVersionFormat
|
||||
fu_plugin_uefi_get_version_format_for_type (FuPlugin *plugin, FuUefiDeviceKind device_kind)
|
||||
{
|
||||
const gchar *content;
|
||||
const gchar *quirk;
|
||||
g_autofree gchar *group = NULL;
|
||||
|
||||
/* we have no information for devices */
|
||||
if (device_kind == FU_UEFI_DEVICE_KIND_DEVICE_FIRMWARE)
|
||||
return FWUPD_VERSION_FORMAT_TRIPLET;
|
||||
|
||||
content = fu_plugin_get_dmi_value (plugin, FU_HWIDS_KEY_MANUFACTURER);
|
||||
if (content == NULL)
|
||||
return FWUPD_VERSION_FORMAT_TRIPLET;
|
||||
|
||||
/* any quirks match */
|
||||
group = g_strdup_printf ("SmbiosManufacturer=%s", content);
|
||||
quirk = fu_plugin_lookup_quirk_by_id (plugin, group,
|
||||
FU_QUIRKS_UEFI_VERSION_FORMAT);
|
||||
if (quirk == NULL)
|
||||
return FWUPD_VERSION_FORMAT_TRIPLET;
|
||||
return fwupd_version_format_from_string (quirk);
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
fu_plugin_uefi_uefi_type_to_string (FuUefiDeviceKind device_kind)
|
||||
{
|
||||
@ -519,12 +495,6 @@ static gboolean
|
||||
fu_plugin_uefi_coldplug_device (FuPlugin *plugin, FuUefiDevice *dev, GError **error)
|
||||
{
|
||||
FuUefiDeviceKind device_kind;
|
||||
FwupdVersionFormat version_format;
|
||||
|
||||
/* set default version format */
|
||||
device_kind = fu_uefi_device_get_kind (dev);
|
||||
version_format = fu_plugin_uefi_get_version_format_for_type (plugin, device_kind);
|
||||
fu_device_set_version_format (FU_DEVICE (dev), version_format);
|
||||
|
||||
/* probe to get add GUIDs (and hence any quirk fixups) */
|
||||
if (!fu_device_probe (FU_DEVICE (dev), error))
|
||||
@ -540,6 +510,7 @@ fu_plugin_uefi_coldplug_device (FuPlugin *plugin, FuUefiDevice *dev, GError **er
|
||||
}
|
||||
|
||||
/* set fallback name if nothing else is set */
|
||||
device_kind = fu_uefi_device_get_kind (dev);
|
||||
if (fu_device_get_name (FU_DEVICE (dev)) == NULL) {
|
||||
g_autofree gchar *name = NULL;
|
||||
name = fu_plugin_uefi_get_name_for_type (plugin, device_kind);
|
||||
@ -761,6 +732,7 @@ fu_plugin_uefi_create_dummy (FuPlugin *plugin, const gchar *reason, GError **err
|
||||
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL);
|
||||
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_NEEDS_REBOOT);
|
||||
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_REQUIRE_AC);
|
||||
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_MD_SET_VERFMT);
|
||||
|
||||
fu_device_add_icon (dev, "computer");
|
||||
fu_device_set_id (dev, "UEFI-dummy");
|
||||
|
@ -695,6 +695,7 @@ fu_uefi_device_probe (FuDevice *device, GError **error)
|
||||
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_INTERNAL);
|
||||
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_NEEDS_REBOOT);
|
||||
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_REQUIRE_AC);
|
||||
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_MD_SET_VERFMT);
|
||||
|
||||
/* add icons */
|
||||
if (self->kind == FU_UEFI_DEVICE_KIND_DEVICE_FIRMWARE) {
|
||||
@ -726,6 +727,7 @@ static void
|
||||
fu_uefi_device_init (FuUefiDevice *self)
|
||||
{
|
||||
fu_device_set_protocol (FU_DEVICE (self), "org.uefi.capsule");
|
||||
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_NUMBER);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -13,21 +13,6 @@ Sets the plugin to use for a specific hardware device.
|
||||
* Key: the device ID, e.g. `DeviceInstanceId=USB\VID_0763&PID_2806`
|
||||
* Value: the plugin name, e.g. `csr`
|
||||
* Minimum fwupd version: **1.1.0**
|
||||
### UefiVersionFormat
|
||||
Assigns the version format to use for a specific manufacturer. A specific version
|
||||
format is sometimes chosen to match the appearance of other systems or
|
||||
specifications.
|
||||
* Key: a %FU_HWIDS_KEY_MANUFACTURER, e.g. `Alienware`
|
||||
* Value: the version format, e.g. `none`
|
||||
* Supported values: `none`, `use-triplet`
|
||||
* Minimum fwupd version: **1.0.1**
|
||||
### ComponentIDs
|
||||
Assigns the version format to use for a specific AppStream component. A specific
|
||||
version format is sometimes chosen to match the appearance of other systems or
|
||||
specifications.
|
||||
* Key: the optionally wildcarded AppStream ID e.g. `com.dell.uefi*.firmware`
|
||||
* Value: the version format, e.g. `none`
|
||||
* Minimum fwupd version: **1.0.1**
|
||||
### Flags
|
||||
Assigns optional quirks to use for a 8bitdo device
|
||||
* Key: the device ID, e.g. `DeviceInstanceId=USB\VID_0763&PID_2806`
|
||||
|
118
src/fu-engine.c
118
src/fu-engine.c
@ -263,61 +263,6 @@ fu_engine_device_changed_cb (FuDeviceList *device_list, FuDevice *device, FuEngi
|
||||
fu_engine_emit_device_changed (self, device);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fu_engine_set_device_version_format (FuEngine *self, FuDevice *device, XbNode *component, GError **error)
|
||||
{
|
||||
FwupdVersionFormat fmt;
|
||||
const gchar *developer_name;
|
||||
const gchar *version_format;
|
||||
|
||||
/* specified in metadata */
|
||||
version_format = xb_node_query_text (component,
|
||||
"custom/value[@key='LVFS::VersionFormat']",
|
||||
NULL);
|
||||
if (version_format != NULL) {
|
||||
fmt = fwupd_version_format_from_string (version_format);
|
||||
if (fmt == FWUPD_VERSION_FORMAT_UNKNOWN) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"version format from metadata %s unsupported",
|
||||
version_format);
|
||||
return FALSE;
|
||||
}
|
||||
g_debug ("using VersionFormat %s from metadata", version_format);
|
||||
fu_device_set_version_format (device, fmt);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* fall back to the SmbiosManufacturer quirk */
|
||||
developer_name = xb_node_query_text (component, "developer_name", NULL);
|
||||
if (developer_name != NULL &&
|
||||
fu_device_has_flag (device, FWUPD_DEVICE_FLAG_INTERNAL)) {
|
||||
g_autofree gchar *group = NULL;
|
||||
group = g_strdup_printf ("SmbiosManufacturer=%s", developer_name);
|
||||
version_format = fu_quirks_lookup_by_id (self->quirks, group,
|
||||
FU_QUIRKS_UEFI_VERSION_FORMAT);
|
||||
if (version_format != NULL) {
|
||||
fmt = fwupd_version_format_from_string (version_format);
|
||||
if (fmt == FWUPD_VERSION_FORMAT_UNKNOWN) {
|
||||
g_set_error (error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"version format %s from quirk %s unsupported",
|
||||
version_format, developer_name);
|
||||
return FALSE;
|
||||
}
|
||||
g_debug ("using VersionFormat %s from SmbiosManufacturer %s",
|
||||
version_format, developer_name);
|
||||
fu_device_set_version_format (device, fmt);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* nothing found, which is probably fine */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* convert hex and decimal versions to dotted style */
|
||||
static gchar *
|
||||
fu_engine_get_release_version (FuEngine *self, FuDevice *dev, XbNode *rel, GError **error)
|
||||
@ -2809,6 +2754,61 @@ fu_engine_md_refresh_device_name_category (FuEngine *self, FuDevice *device, XbN
|
||||
fu_device_set_name (device, name);
|
||||
}
|
||||
|
||||
static void
|
||||
_g_ptr_array_reverse (GPtrArray *array)
|
||||
{
|
||||
guint last_idx = array->len - 1;
|
||||
for (guint i = 0; i < array->len / 2; i++) {
|
||||
gpointer tmp = array->pdata[i];
|
||||
array->pdata[i] = array->pdata[last_idx - i];
|
||||
array->pdata[last_idx - i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fu_engine_md_refresh_device_verfmt (FuEngine *self, FuDevice *device, XbNode *component)
|
||||
{
|
||||
FwupdVersionFormat verfmt = FWUPD_VERSION_FORMAT_UNKNOWN;
|
||||
g_autoptr(GPtrArray) verfmts = NULL;
|
||||
|
||||
/* require data */
|
||||
if (component == NULL)
|
||||
return;
|
||||
|
||||
/* get metadata */
|
||||
verfmts = xb_node_query (component, "custom/value[@key='LVFS::VersionFormat']", 0, NULL);
|
||||
if (verfmts == NULL)
|
||||
return;
|
||||
_g_ptr_array_reverse (verfmts);
|
||||
for (guint i = 0; i < verfmts->len; i++) {
|
||||
XbNode *value = g_ptr_array_index (verfmts, i);
|
||||
verfmt = fwupd_version_format_from_string (xb_node_get_text (value));
|
||||
if (verfmt != FWUPD_VERSION_FORMAT_UNKNOWN)
|
||||
break;
|
||||
}
|
||||
|
||||
/* found and different to existing */
|
||||
if (verfmt != FWUPD_VERSION_FORMAT_UNKNOWN &&
|
||||
fu_device_get_version_format (device) != verfmt) {
|
||||
fu_device_set_version_format (device, verfmt);
|
||||
if (fu_device_get_version_raw (device) != 0x0) {
|
||||
g_autofree gchar *version = NULL;
|
||||
version = fu_common_version_from_uint32 (fu_device_get_version_raw (device), verfmt);
|
||||
fu_device_set_version (device, version);
|
||||
}
|
||||
if (fu_device_get_version_lowest_raw (device) != 0x0) {
|
||||
g_autofree gchar *version = NULL;
|
||||
version = fu_common_version_from_uint32 (fu_device_get_version_lowest_raw (device), verfmt);
|
||||
fu_device_set_version_lowest (device, version);
|
||||
}
|
||||
if (fu_device_get_version_bootloader_raw (device) != 0x0) {
|
||||
g_autofree gchar *version = NULL;
|
||||
version = fu_common_version_from_uint32 (fu_device_get_version_bootloader_raw (device), verfmt);
|
||||
fu_device_set_version_bootloader (device, version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fu_engine_md_refresh_device (FuEngine *self, FuDevice *device)
|
||||
{
|
||||
@ -2822,6 +2822,10 @@ fu_engine_md_refresh_device (FuEngine *self, FuDevice *device)
|
||||
fu_engine_md_refresh_device_name (self, device, component);
|
||||
if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_MD_SET_NAME_CATEGORY))
|
||||
fu_engine_md_refresh_device_name_category (self, device, component);
|
||||
|
||||
/* fix the version */
|
||||
if (fu_device_has_flag (device, FWUPD_DEVICE_FLAG_MD_SET_VERFMT))
|
||||
fu_engine_md_refresh_device_verfmt (self, device, component);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -3253,10 +3257,6 @@ fu_engine_get_result_from_component (FuEngine *self, XbNode *component, GError *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get (or guess) the component version format */
|
||||
if (!fu_engine_set_device_version_format (self, dev, component, error))
|
||||
return NULL;
|
||||
|
||||
/* check we can install it */
|
||||
task = fu_install_task_new (NULL, component);
|
||||
if (!fu_engine_check_requirements (self, task,
|
||||
|
@ -1092,6 +1092,10 @@ fu_util_device_flag_to_string (guint64 device_flag)
|
||||
/* skip */
|
||||
return NULL;
|
||||
}
|
||||
if (device_flag == FWUPD_DEVICE_FLAG_MD_SET_VERFMT) {
|
||||
/* skip */
|
||||
return NULL;
|
||||
}
|
||||
if (device_flag == FWUPD_DEVICE_FLAG_UNKNOWN) {
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user