diff --git a/RELEASE b/RELEASE index 2112fce13..7647c2806 100644 --- a/RELEASE +++ b/RELEASE @@ -10,7 +10,7 @@ To make sure it's done right, you can reference commit 433e809318c68c9ab6d4ae50e Write release entries: -git log --format="%s" --cherry-pick --right-only 1.8.8... | grep -i -v trivial | grep -v Merge | sort | uniq +git log --format="%s" --cherry-pick --right-only 1.8.9... | grep -i -v trivial | grep -v Merge | sort | uniq Add any user visible changes into ../data/org.freedesktop.fwupd.metainfo.xml appstream-util appdata-to-news ../data/org.freedesktop.fwupd.metainfo.xml > NEWS @@ -25,7 +25,7 @@ git add ../po/*.po 2. Commit changes to git: # MAKE SURE THIS IS CORRECT -export release_ver="1.8.9" +export release_ver="1.8.10" git commit -a -m "Release fwupd ${release_ver}" --no-verify git tag -s -f -m "Release fwupd ${release_ver}" "${release_ver}" diff --git a/contrib/ci/check-abi b/contrib/ci/check-abi index 4a1f6c8a3..3cd19b3e4 100755 --- a/contrib/ci/check-abi +++ b/contrib/ci/check-abi @@ -87,7 +87,6 @@ def build_install(revision): "--prefix=/usr", "--libdir=lib", "-Dauto_features=disabled", - "-Ddocs=none", "-Db_coverage=false", "-Dgusb:docs=false", "-Dtests=false", diff --git a/contrib/ci/fwupd_setup_helpers.py b/contrib/ci/fwupd_setup_helpers.py index 936589851..903791cc4 100755 --- a/contrib/ci/fwupd_setup_helpers.py +++ b/contrib/ci/fwupd_setup_helpers.py @@ -178,7 +178,7 @@ def install_packages(os, variant, yes, debugging, packages): installer += packages if debugging: print(installer) - subprocess.call(installer) + subprocess.check_call(installer) if __name__ == "__main__": diff --git a/contrib/fwupd.spec.in b/contrib/fwupd.spec.in index 3fefe3a32..c06bc21d4 100644 --- a/contrib/fwupd.spec.in +++ b/contrib/fwupd.spec.in @@ -463,6 +463,8 @@ done %if 0%{?have_uefi} %{_datadir}/installed-tests/fwupd/efi %endif +%{_datadir}/installed-tests/fwupd/chassis_type +%{_datadir}/installed-tests/fwupd/sys_vendor %{_datadir}/fwupd/device-tests/*.json %{_libexecdir}/installed-tests/fwupd/* %dir %{_sysconfdir}/fwupd/remotes.d diff --git a/data/cfi.quirk b/data/cfi.quirk index 72e59e978..c2cc96548 100644 --- a/data/cfi.quirk +++ b/data/cfi.quirk @@ -191,6 +191,9 @@ FirmwareSizeMax = 0x20000 [CFI\FLASHID_EF4018] Name = W25Q128 FirmwareSizeMax = 0x1000000 +[CFI\FLASHID_EF4019] +Name = W25Q256 +FirmwareSizeMax = 0x2000000 # Fidelix [CFI\FLASHID_F8] diff --git a/data/org.freedesktop.fwupd.metainfo.xml b/data/org.freedesktop.fwupd.metainfo.xml index 08a1313f4..bb198a239 100644 --- a/data/org.freedesktop.fwupd.metainfo.xml +++ b/data/org.freedesktop.fwupd.metainfo.xml @@ -33,6 +33,36 @@ fwupdtool + + +

+ This release adds the following features: +

+
    +
  • Add a PE/COFF firmware parser to allow reading coSWID SBoM data
  • +
  • Allow dumping CFI SPI chips using devices like CH341a
  • +
  • Refactor the HWIDs functionality to include FDT data
  • +
+

This release fixes the following bugs:

+
    +
  • Add back a legacy eMMC GUID to fix a regression
  • +
  • Always search for uSWID SBoM data in the image
  • +
  • Do not allow LZX compressed cabinet archives
  • +
  • Fallback to the checksum if the metadata artifact is invalid
  • +
  • Improve FDT parsing compatibility with new OpenBMC images
  • +
  • Never call grub2-probe without arguments
  • +
  • Respect user requested paths for the ESP even if they are not volumes
  • +
  • Speed up ChromeOS startup by a huge amount when using directory remotes
  • +
  • Verify the Synaptics RMI signature in more cases
  • +
+

This release adds support for the following hardware:

+
    +
  • Quectel RM520
  • +
  • StarBook Mk VI
  • +
  • System76 launch_heavy_1
  • +
+
+

diff --git a/docs/ds20.md b/docs/ds20.md index a010c478c..028f400ce 100644 --- a/docs/ds20.md +++ b/docs/ds20.md @@ -1,4 +1,6 @@ -# fwupd BOS DS20 Specification +--- +title: BOS DS20 Specification +--- ## Introduction diff --git a/docs/env.md b/docs/env.md index 8f80af156..ffe9cb59a 100644 --- a/docs/env.md +++ b/docs/env.md @@ -85,6 +85,7 @@ for details. * `FWUPD_OFFLINE_TRIGGER` * `FWUPD_PROCFS` * `FWUPD_SYSCONFDIR` +* `FWUPD_SYSFSDMIDIR` * `FWUPD_SYSFSDRIVERDIR` * `FWUPD_SYSFSFWATTRIBDIR` * `FWUPD_SYSFSFWDIR` diff --git a/docs/fwupdplugin.toml.in b/docs/fwupdplugin.toml.in index 32a5ef5c0..de9bd99e6 100644 --- a/docs/fwupdplugin.toml.in +++ b/docs/fwupdplugin.toml.in @@ -46,7 +46,9 @@ content_files = [ "tutorial.md", "hsi.md", "ds20.md", + "hwids.md", "bios-settings.md", + @plugin_readme_outputs@, ] content_images = [ "architecture-plan.svg", diff --git a/docs/hsi-tests.d/org.fwupd.hsi.Amd.PlatformRollbackProtection.json b/docs/hsi-tests.d/org.fwupd.hsi.Amd.PlatformRollbackProtection.json index b404ed1ef..737da8e98 100644 --- a/docs/hsi-tests.d/org.fwupd.hsi.Amd.PlatformRollbackProtection.json +++ b/docs/hsi-tests.d/org.fwupd.hsi.Amd.PlatformRollbackProtection.json @@ -5,6 +5,11 @@ "AMD SOCs include the ability to prevent a rollback attack by a rollback protection feature on the secure processor.", "This feature prevents an attacker from loading an older firmware onto the part after a security vulnerability has been fixed." ], + "more-information": [ + "This particular check is not for the Microsoft Pluton Security processor which is present on some chips.", + "End users are not able to directly modify rollback protection, this is controlled by the manufacturer.", + "On Lenovo systems it has been reported that if this is disabled it may potentially be enabled by loading 'OS Optimized Defaults' in BIOS setup." + ], "failure-impact": [ "SOCs without this feature may be attacked by an attacker installing an older firmware that takes advantage of a well-known vulnerability." ], @@ -16,7 +21,10 @@ }, "hsi-level": 4, "references": { - "https://www.psacertified.org/blog/anti-rollback-explained/": "Rollback protection" + "https://www.psacertified.org/blog/anti-rollback-explained/": "Rollback protection", + "https://www.amd.com/en/technologies/pro-security": "AMD Secure Processor", + "https://forums.lenovo.com/t5/Fedora/AMD-Rollback-protection-not-detected-by-fwupd-on-T14-G3-AMD/m-p/5182708?page=1#5810366": + "Loading OS Optimized Defaults on Lenovo systems" }, "fwupd-version": "1.8.0" } diff --git a/docs/hsi-tests.d/org.fwupd.hsi.SupportedCpu.json b/docs/hsi-tests.d/org.fwupd.hsi.SupportedCpu.json index ff708634f..ae464979c 100644 --- a/docs/hsi-tests.d/org.fwupd.hsi.SupportedCpu.json +++ b/docs/hsi-tests.d/org.fwupd.hsi.SupportedCpu.json @@ -15,6 +15,12 @@ "success-results" : { "valid" : "the CPU platform is supported and has HSI tests" }, + "more-information": [ + "On AMD APUs or CPUs this information is reported on kernel 5.19 or later via the `ccp` kernel module. ", + "If the kernel module is enabled but is not being auto-loaded, this is a kernel bug and should be reported to kernel bugzilla. ", + "If the kernel module has loaded but you still don't have data this is NOT a fwupd bug. You will have to contact ", + "your motherboard or system manufacturer to enable reporting this information." + ], "hsi-level" : 1, "fwupd-version" : "1.8.0" } diff --git a/docs/hwids.md b/docs/hwids.md new file mode 100644 index 000000000..ad7fdc613 --- /dev/null +++ b/docs/hwids.md @@ -0,0 +1,85 @@ +--- +title: Hardware IDs +--- + +## Introduction + +Hardware IDs are used by fwupd to identify specific hardware. +This is useful as the device-specific identifiers may be the same for different firmware streams. +Each hardware ID has varying levels of specificity for the hardware, for instance matching only the +system OEM, or matching up to 8 fields including the system BIOS version. + +For instance, Dell and Lenovo might ship a wireless broadband modem with the same chip vendor and +product IDs of `USB\VID_0BDA&PID_5850` and although the two OEMs share the same internal device, +the firmware may be different. +To cover this case fwupd allows adding `hardware` requirements that mean we can deploy firmware that +targets `USB\VID_0BDA&PID_5850`, but *only for Dell* or *only for Lenovo* systems. + +Microsoft calls these values "CHIDs" and they are generated on Windows from the SBMIOS tables using `ComputerHardwareIds.exe` +binary which can be found [here](https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/computerhardwareids). +The list of CHIDs used in Microsoft Windows is: + + HardwareID-0 ← Manufacturer + Family + Product Name + SKU Number + BIOS Vendor + BIOS Version + BIOS Major Release + BIOS Minor Release + HardwareID-1 ← Manufacturer + Family + Product Name + BIOS Vendor + BIOS Version + BIOS Major Release + BIOS Minor Release + HardwareID-2 ← Manufacturer + Product Name + BIOS Vendor + BIOS Version + BIOS Major Release + BIOS Minor Release + HardwareID-3 ← Manufacturer + Family + ProductName + SKU Number + Baseboard_Manufacturer + Baseboard_Product + HardwareID-4 ← Manufacturer + Family + ProductName + SKU Number + HardwareID-5 ← Manufacturer + Family + ProductName + HardwareID-6 ← Manufacturer + SKU Number + Baseboard_Manufacturer + Baseboard_Product + HardwareID-7 ← Manufacturer + SKU Number + HardwareID-8 ← Manufacturer + ProductName + Baseboard_Manufacturer + Baseboard_Product + HardwareID-9 ← Manufacturer + ProductName + HardwareID-10 ← Manufacturer + Family + Baseboard_Manufacturer + Baseboard_Product + HardwareID-11 ← Manufacturer + Family + HardwareID-12 ← Manufacturer + Enclosure Type + HardwareID-13 ← Manufacturer + Baseboard_Manufacturer + Baseboard_Product + HardwareID-14 ← Manufacturer + +On Windows, CHIDs are generated from the ASCII representation of SMBIOS strings, and on Linux the same +mechanism is used. Additionally, on Linux, the Device Tree, DMI and `kenv` data sources +are used to construct emulations of the Microsoft CHIDs. + +When installing firmware and drivers in Windows vendors *already use* the generated HardwareID GUIDs +that match SMBIOS keys like the BIOS vendor and the product SKU. + +Both `fwupdtool hwids` and `ComputerHardwareIds.exe` only compute results that have the necessary +data values available. +If a data field is missing, then any related CHIDs are not generated. +For example, if the SKU field is missing, then `HardwareID` 0, 3, 4 6 and 7 will not be available for +that particular system. + +## Implementation + +Users with versions of fwupd newer than 1.1.1 can run `sudo fwupdtool hwids`. For example: + + Computer Information + -------------------- + BiosVendor: LENOVO + BiosVersion: GJET75WW (2.25 ) + Manufacturer: LENOVO + Family: ThinkPad T440s + ProductName: 20ARS19C0C + ProductSku: LENOVO_MT_20AR_BU_Think_FM_ThinkPad T440s + EnclosureKind: 10 + BaseboardManufacturer: LENOVO + BaseboardProduct: 20ARS19C0C + + Hardware IDs + ------------ + {c4159f74-3d2c-526f-b6d1-fe24a2fbc881} <- Manufacturer + Family + ProductName + ProductSku + BiosVendor + BiosVersion + BiosMajorRelease + BiosMinorRelease + {ff66cb74-5f5d-5669-875a-8a8f97be22c1} <- Manufacturer + Family + ProductName + BiosVendor + BiosVersion + BiosMajorRelease + BiosMinorRelease + {2e4dad4e-27a0-5de0-8e92-f395fc3fa5ba} <- Manufacturer + ProductName + BiosVendor + BiosVersion + BiosMajorRelease + BiosMinorRelease + {3faec92a-3ae3-5744-be88-495e90a7d541} <- Manufacturer + Family + ProductName + ProductSku + BaseboardManufacturer + BaseboardProduct + {660ccba8-1b78-5a33-80e6-9fb8354ee873} <- Manufacturer + Family + ProductName + ProductSku + {8dc9b7c5-f5d5-5850-9ab3-bd6f0549d814} <- Manufacturer + Family + ProductName + {178cd22d-ad9f-562d-ae0a-34009822cdbe} <- Manufacturer + ProductSku + BaseboardManufacturer + BaseboardProduct + {da1da9b6-62f5-5f22-8aaa-14db7eeda2a4} <- Manufacturer + ProductSku + {059eb22d-6dc7-59af-abd3-94bbe017f67c} <- Manufacturer + ProductName + BaseboardManufacturer + BaseboardProduct + {0cf8618d-9eff-537c-9f35-46861406eb9c} <- Manufacturer + ProductName + {f4275c1f-6130-5191-845c-3426247eb6a1} <- Manufacturer + Family + BaseboardManufacturer + BaseboardProduct + {db73af4c-4612-50f7-b8a7-787cf4871847} <- Manufacturer + Family + {5e820764-888e-529d-a6f9-dfd12bacb160} <- Manufacturer + EnclosureKind + {f8e1de5f-b68c-5f52-9d1a-f1ba52f1f773} <- Manufacturer + BaseboardManufacturer + BaseboardProduct + {6de5d951-d755-576b-bd09-c5cf66b27234} <- Manufacturer + +Which matches the output of `ComputerHardwareIds.exe` on the same hardware. diff --git a/docs/index.html b/docs/index.html index 512e14907..13086a6b4 100644 --- a/docs/index.html +++ b/docs/index.html @@ -45,6 +45,9 @@

+ diff --git a/docs/meson.build b/docs/meson.build index 7eaecda1b..d600ae026 100644 --- a/docs/meson.build +++ b/docs/meson.build @@ -1,3 +1,16 @@ +plugin_readme_targets = [] +plugin_readme_outputs = [] +foreach plugin: plugins + plugin_readme_output = '@0@-README.md'.format(plugin) + plugin_readme_targets += custom_target('doc-plugin-@0@'.format(plugin), + input: join_paths(meson.project_source_root(), 'plugins', plugin, 'README.md'), + output: plugin_readme_output, + command: ['ln', '-sf', '@INPUT0@', '@OUTPUT@'], + build_by_default: true, + ) + plugin_readme_outputs += '"@0@"'.format(plugin_readme_output) +endforeach + if build_docs and introspection.allowed() toml_conf = configuration_data() docgen_version = source_version @@ -5,6 +18,7 @@ if build_docs and introspection.allowed() docgen_version = run_command([git, 'branch', '--show-current'], check: true).stdout().strip() endif toml_conf.set('version', docgen_version) + toml_conf.set('plugin_readme_outputs', ','.join(plugin_readme_outputs)) fwupd_toml = configure_file( input: 'fwupd.toml.in', @@ -89,6 +103,7 @@ if build_docs and introspection.allowed() depends: [ fwupdplugin_gir[0], hsi_md, + plugin_readme_targets, ], build_by_default: true, install: true, diff --git a/libfwupdplugin/fu-backend.c b/libfwupdplugin/fu-backend.c index e8402228e..88436ef17 100644 --- a/libfwupdplugin/fu-backend.c +++ b/libfwupdplugin/fu-backend.c @@ -59,6 +59,10 @@ fu_backend_device_added(FuBackend *self, FuDevice *device) if (priv->ctx != NULL) fu_device_set_context(device, priv->ctx); + /* set backend ID if required */ + if (fu_device_get_backend_id(device) == NULL) + fu_device_set_backend_id(device, priv->name); + /* add */ g_hash_table_insert(priv->devices, g_strdup(fu_device_get_backend_id(device)), diff --git a/libfwupdplugin/fu-bluez-device.h b/libfwupdplugin/fu-bluez-device.h index b2084aa1e..af59b7b00 100644 --- a/libfwupdplugin/fu-bluez-device.h +++ b/libfwupdplugin/fu-bluez-device.h @@ -13,7 +13,6 @@ G_DECLARE_DERIVABLE_TYPE(FuBluezDevice, fu_bluez_device, FU, BLUEZ_DEVICE, FuDev struct _FuBluezDeviceClass { FuDeviceClass parent_class; - gpointer __reserved[31]; }; GByteArray * diff --git a/libfwupdplugin/fu-cabinet.c b/libfwupdplugin/fu-cabinet.c index d11fda5a7..63bf1b9ac 100644 --- a/libfwupdplugin/fu-cabinet.c +++ b/libfwupdplugin/fu-cabinet.c @@ -69,6 +69,10 @@ fu_cabinet_init(FuCabinet *self) { self->size_max = 1024 * 1024 * 100; self->gcab_cabinet = gcab_cabinet_new(); +#ifdef HAVE_GCAB_CABINET_ADD_ALLOWED_COMPRESSION + gcab_cabinet_add_allowed_compression(self->gcab_cabinet, GCAB_COMPRESSION_NONE); + gcab_cabinet_add_allowed_compression(self->gcab_cabinet, GCAB_COMPRESSION_MSZIP); +#endif self->builder = xb_builder_new(); self->jcat_file = jcat_file_new(); self->jcat_context = jcat_context_new(); diff --git a/libfwupdplugin/fu-cfi-device.h b/libfwupdplugin/fu-cfi-device.h index 08dd4dfdb..a3b66097b 100644 --- a/libfwupdplugin/fu-cfi-device.h +++ b/libfwupdplugin/fu-cfi-device.h @@ -14,7 +14,6 @@ G_DECLARE_DERIVABLE_TYPE(FuCfiDevice, fu_cfi_device, FU, CFI_DEVICE, FuDevice) struct _FuCfiDeviceClass { FuDeviceClass parent_class; gboolean (*chip_select)(FuCfiDevice *self, gboolean value, GError **error); - gpointer __reserved[30]; }; /** diff --git a/libfwupdplugin/fu-context-private.h b/libfwupdplugin/fu-context-private.h index 5e14bbd16..994c00228 100644 --- a/libfwupdplugin/fu-context-private.h +++ b/libfwupdplugin/fu-context-private.h @@ -11,12 +11,22 @@ #include "fu-quirks.h" #include "fu-volume.h" +typedef enum { + FU_CONTEXT_HWID_FLAG_NONE = 0, + FU_CONTEXT_HWID_FLAG_LOAD_CONFIG = 1 << 0, + FU_CONTEXT_HWID_FLAG_LOAD_SMBIOS = 1 << 1, + FU_CONTEXT_HWID_FLAG_LOAD_FDT = 1 << 2, + FU_CONTEXT_HWID_FLAG_LOAD_DMI = 1 << 3, + FU_CONTEXT_HWID_FLAG_LOAD_KENV = 1 << 4, + FU_CONTEXT_HWID_FLAG_LOAD_ALL = G_MAXUINT, +} FuContextHwidFlags; + FuContext * fu_context_new(void); gboolean fu_context_reload_bios_settings(FuContext *self, GError **error); gboolean -fu_context_load_hwinfo(FuContext *self, GError **error); +fu_context_load_hwinfo(FuContext *self, FuContextHwidFlags flags, GError **error); gboolean fu_context_load_quirks(FuContext *self, FuQuirksLoadFlags flags, GError **error); void @@ -35,3 +45,9 @@ GPtrArray * fu_context_get_udev_subsystems(FuContext *self); void fu_context_add_esp_volume(FuContext *self, FuVolume *volume); +FuSmbios * +fu_context_get_smbios(FuContext *self); +FuHwids * +fu_context_get_hwids(FuContext *self); +void +fu_context_set_chassis_kind(FuContext *self, FuSmbiosChassisKind chassis_kind); diff --git a/libfwupdplugin/fu-context.c b/libfwupdplugin/fu-context.c index 65650a590..08618b435 100644 --- a/libfwupdplugin/fu-context.c +++ b/libfwupdplugin/fu-context.c @@ -10,7 +10,9 @@ #include "fu-bios-settings-private.h" #include "fu-context-private.h" -#include "fu-hwids.h" +#include "fu-fdt-firmware.h" +#include "fu-hwids-private.h" +#include "fu-path.h" #include "fu-smbios-private.h" #include "fu-volume-private.h" @@ -25,6 +27,7 @@ typedef struct { FuContextFlags flags; FuHwids *hwids; FuSmbios *smbios; + FuSmbiosChassisKind chassis_kind; FuQuirks *quirks; GHashTable *runtime_versions; GHashTable *compile_versions; @@ -38,6 +41,7 @@ typedef struct { guint battery_threshold; FuBiosSettings *host_bios_settings; gboolean loaded_hwinfo; + FuFirmware *fdt; /* optional */ } FuContextPrivate; enum { SIGNAL_SECURITY_CHANGED, SIGNAL_LAST }; @@ -48,6 +52,7 @@ enum { PROP_LID_STATE, PROP_BATTERY_LEVEL, PROP_BATTERY_THRESHOLD, + PROP_FLAGS, PROP_LAST }; @@ -57,11 +62,116 @@ G_DEFINE_TYPE_WITH_PRIVATE(FuContext, fu_context, G_TYPE_OBJECT) #define GET_PRIVATE(o) (fu_context_get_instance_private(o)) +static GFile * +fu_context_get_fdt_file(GError **error) +{ + g_autofree gchar *fdtfn_local = NULL; + g_autofree gchar *fdtfn_sys = NULL; + g_autofree gchar *localstatedir_pkg = fu_path_from_kind(FU_PATH_KIND_LOCALSTATEDIR_PKG); + g_autofree gchar *sysfsdir = NULL; + + /* look for override first, fall back to system value */ + fdtfn_local = g_build_filename(localstatedir_pkg, "system.dtb", NULL); + if (g_file_test(fdtfn_local, G_FILE_TEST_EXISTS)) + return g_file_new_for_path(fdtfn_local); + + /* actual hardware value */ + sysfsdir = fu_path_from_kind(FU_PATH_KIND_SYSFSDIR_FW); + fdtfn_sys = g_build_filename(sysfsdir, "fdt", NULL); + if (g_file_test(fdtfn_sys, G_FILE_TEST_EXISTS)) + return g_file_new_for_path(fdtfn_sys); + + /* failed */ + g_set_error(error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_SUPPORTED, + "cannot find %s or override %s", + fdtfn_sys, + fdtfn_local); + return NULL; +} + +/** + * fu_context_get_fdt: + * @self: a #FuContext + * @error: (nullable): optional return location for an error + * + * Gets and parses the system FDT, aka. the Flat Device Tree. + * + * The results are cached internally to the context, and subsequent calls to this function + * returns the pre-parsed object. + * + * Returns: (transfer full): a #FuFdtFirmware, or %NULL + * + * Since: 1.8.10 + **/ +FuFirmware * +fu_context_get_fdt(FuContext *self, GError **error) +{ + FuContextPrivate *priv = GET_PRIVATE(self); + + g_return_val_if_fail(FU_IS_CONTEXT(self), NULL); + g_return_val_if_fail(error == NULL || *error == NULL, NULL); + + /* load if not already parsed */ + if (priv->fdt == NULL) { + g_autoptr(FuFirmware) fdt_tmp = fu_fdt_firmware_new(); + g_autoptr(GFile) file = fu_context_get_fdt_file(error); + if (file == NULL) + return NULL; + if (!fu_firmware_parse_file(fdt_tmp, file, FWUPD_INSTALL_FLAG_NO_SEARCH, error)) { + g_prefix_error(error, "failed to parse FDT: "); + return NULL; + } + priv->fdt = g_steal_pointer(&fdt_tmp); + } + + /* success */ + return g_object_ref(priv->fdt); +} + +/** + * fu_context_get_smbios: + * @self: a #FuContext + * + * Gets the SMBIOS store. + * + * Returns: (transfer none): a #FuSmbios + * + * Since: 1.8.10 + **/ +FuSmbios * +fu_context_get_smbios(FuContext *self) +{ + FuContextPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(FU_IS_CONTEXT(self), NULL); + return priv->smbios; +} + +/** + * fu_context_get_hwids: + * @self: a #FuContext + * + * Gets the HWIDs store. + * + * Returns: (transfer none): a #FuHwids + * + * Since: 1.8.10 + **/ +FuHwids * +fu_context_get_hwids(FuContext *self) +{ + FuContextPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(FU_IS_CONTEXT(self), NULL); + return priv->hwids; +} + /** * fu_context_get_smbios_string: * @self: a #FuContext * @structure_type: a SMBIOS structure type, e.g. %FU_SMBIOS_STRUCTURE_TYPE_BIOS * @offset: a SMBIOS offset + * @error: (nullable): optional return location for an error * * Gets a hardware SMBIOS string. * @@ -73,7 +183,7 @@ G_DEFINE_TYPE_WITH_PRIVATE(FuContext, fu_context, G_TYPE_OBJECT) * Since: 1.6.0 **/ const gchar * -fu_context_get_smbios_string(FuContext *self, guint8 structure_type, guint8 offset) +fu_context_get_smbios_string(FuContext *self, guint8 structure_type, guint8 offset, GError **error) { FuContextPrivate *priv = GET_PRIVATE(self); g_return_val_if_fail(FU_IS_CONTEXT(self), NULL); @@ -81,7 +191,7 @@ fu_context_get_smbios_string(FuContext *self, guint8 structure_type, guint8 offs g_critical("cannot use SMBIOS before calling ->load_hwinfo()"); return NULL; } - return fu_smbios_get_string(priv->smbios, structure_type, offset, NULL); + return fu_smbios_get_string(priv->smbios, structure_type, offset, error); } /** @@ -125,6 +235,7 @@ fu_context_get_smbios_data(FuContext *self, guint8 structure_type, GError **erro * @self: a #FuContext * @type: a structure type, e.g. %FU_SMBIOS_STRUCTURE_TYPE_BIOS * @offset: a structure offset + * @error: (nullable): optional return location for an error * * Reads an integer value from the SMBIOS string table of a specific structure. * @@ -136,7 +247,7 @@ fu_context_get_smbios_data(FuContext *self, guint8 structure_type, GError **erro * Since: 1.6.0 **/ guint -fu_context_get_smbios_integer(FuContext *self, guint8 type, guint8 offset) +fu_context_get_smbios_integer(FuContext *self, guint8 type, guint8 offset, GError **error) { FuContextPrivate *priv = GET_PRIVATE(self); g_return_val_if_fail(FU_IS_CONTEXT(self), G_MAXUINT); @@ -144,7 +255,7 @@ fu_context_get_smbios_integer(FuContext *self, guint8 type, guint8 offset) g_critical("cannot use SMBIOS before calling ->load_hwinfo()"); return G_MAXUINT; } - return fu_smbios_get_integer(priv->smbios, type, offset, NULL); + return fu_smbios_get_integer(priv->smbios, type, offset, error); } /** @@ -222,6 +333,41 @@ fu_context_get_bios_setting_pending_reboot(FuContext *self) return ret; } +/** + * fu_context_get_chassis_kind: + * @self: a #FuContext + * + * Gets the chassis kind, if known. + * + * Returns: a #FuSmbiosChassisKind, e.g. %FU_SMBIOS_CHASSIS_KIND_LAPTOP + * + * Since: 1.8.10 + **/ +FuSmbiosChassisKind +fu_context_get_chassis_kind(FuContext *self) +{ + FuContextPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(FU_IS_CONTEXT(self), FALSE); + return priv->chassis_kind; +} + +/** + * fu_context_set_chassis_kind: + * @self: a #FuContext + * @chassis_kind: a #FuSmbiosChassisKind, e.g. %FU_SMBIOS_CHASSIS_KIND_TABLET + * + * Sets the chassis kind. + * + * Since: 1.8.10 + **/ +void +fu_context_set_chassis_kind(FuContext *self, FuSmbiosChassisKind chassis_kind) +{ + FuContextPrivate *priv = GET_PRIVATE(self); + g_return_if_fail(FU_IS_CONTEXT(self)); + priv->chassis_kind = chassis_kind; +} + /** * fu_context_has_hwid_guid: * @self: a #FuContext @@ -310,8 +456,11 @@ gchar * fu_context_get_hwid_replace_value(FuContext *self, const gchar *keys, GError **error) { FuContextPrivate *priv = GET_PRIVATE(self); + g_return_val_if_fail(FU_IS_CONTEXT(self), NULL); g_return_val_if_fail(keys != NULL, NULL); + g_return_val_if_fail(error == NULL || *error == NULL, NULL); + if (!priv->loaded_hwinfo) { g_critical("cannot use HWIDs before calling ->load_hwinfo()"); g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED, "no data"); @@ -621,31 +770,84 @@ fu_context_security_changed(FuContext *self) /** * fu_context_load_hwinfo: * @self: a #FuContext + * @flags: a #FuContextHwidFlags, e.g. %FU_CONTEXT_HWID_FLAG_LOAD_SMBIOS * @error: (nullable): optional return location for an error * * Loads all hardware information parts of the context. * * Returns: %TRUE for success * - * Since: 1.6.0 + * Since: 1.8.10 **/ gboolean -fu_context_load_hwinfo(FuContext *self, GError **error) +fu_context_load_hwinfo(FuContext *self, FuContextHwidFlags flags, GError **error) { FuContextPrivate *priv = GET_PRIVATE(self); GPtrArray *guids; - g_autoptr(GError) error_smbios = NULL; g_autoptr(GError) error_hwids = NULL; g_autoptr(GError) error_bios_settings = NULL; g_return_val_if_fail(FU_IS_CONTEXT(self), FALSE); g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - if (!fu_smbios_setup(priv->smbios, &error_smbios)) - g_warning("Failed to load SMBIOS: %s", error_smbios->message); - if (!fu_hwids_setup(priv->hwids, priv->smbios, &error_hwids)) - g_warning("Failed to load HWIDs: %s", error_hwids->message); + if ((flags & FU_CONTEXT_HWID_FLAG_LOAD_CONFIG) > 0) { + g_autoptr(GError) error_local = NULL; + if (!fu_hwids_config_setup(self, priv->hwids, &error_local)) { + if (!g_error_matches(error_local, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED)) { + g_propagate_prefixed_error(error, + g_steal_pointer(&error_local), + "Failed to load HWIDs config: "); + return FALSE; + } + } + } + if ((flags & FU_CONTEXT_HWID_FLAG_LOAD_DMI) > 0) { + g_autoptr(GError) error_local = NULL; + if (!fu_hwids_dmi_setup(self, priv->hwids, &error_local)) { + if (!g_error_matches(error_local, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED)) { + g_propagate_prefixed_error(error, + g_steal_pointer(&error_local), + "Failed to load HWIDs DMI: "); + return FALSE; + } + } + } + if ((flags & FU_CONTEXT_HWID_FLAG_LOAD_FDT) > 0) { + g_autoptr(GError) error_local = NULL; + if (!fu_hwids_fdt_setup(self, priv->hwids, &error_local)) { + if (!g_error_matches(error_local, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED)) { + g_propagate_prefixed_error(error, + g_steal_pointer(&error_local), + "Failed to load HWIDs FDT: "); + return FALSE; + } + } + } + if ((flags & FU_CONTEXT_HWID_FLAG_LOAD_KENV) > 0) { + g_autoptr(GError) error_local = NULL; + if (!fu_hwids_kenv_setup(self, priv->hwids, &error_local)) { + if (!g_error_matches(error_local, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED)) { + g_propagate_prefixed_error(error, + g_steal_pointer(&error_local), + "Failed to load HWIDs kenv: "); + return FALSE; + } + } + } + if ((flags & FU_CONTEXT_HWID_FLAG_LOAD_SMBIOS) > 0) { + g_autoptr(GError) error_local = NULL; + if (!fu_hwids_smbios_setup(self, priv->hwids, &error_local)) { + if (!g_error_matches(error_local, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED)) { + g_propagate_prefixed_error(error, + g_steal_pointer(&error_local), + "Failed to load SMBIOS: "); + return FALSE; + } + } + } priv->loaded_hwinfo = TRUE; + if (!fu_hwids_setup(priv->hwids, &error_hwids)) + g_warning("Failed to load HWIDs: %s", error_hwids->message); /* set the hwid flags */ guids = fu_context_get_hwid_guids(self); @@ -891,7 +1093,30 @@ fu_context_add_flag(FuContext *context, FuContextFlags flag) { FuContextPrivate *priv = GET_PRIVATE(context); g_return_if_fail(FU_IS_CONTEXT(context)); + if (priv->flags & flag) + return; priv->flags |= flag; + g_object_notify(G_OBJECT(context), "flags"); +} + +/** + * fu_context_remove_flag: + * @context: a #FuContext + * @flag: the context flag + * + * Removes a specific flag from the context. + * + * Since: 1.8.10 + **/ +void +fu_context_remove_flag(FuContext *context, FuContextFlags flag) +{ + FuContextPrivate *priv = GET_PRIVATE(context); + g_return_if_fail(FU_IS_CONTEXT(context)); + if ((priv->flags & flag) == 0) + return; + priv->flags &= ~flag; + g_object_notify(G_OBJECT(context), "flags"); } /** @@ -1039,6 +1264,9 @@ fu_context_get_property(GObject *object, guint prop_id, GValue *value, GParamSpe case PROP_BATTERY_THRESHOLD: g_value_set_uint(value, priv->battery_threshold); break; + case PROP_FLAGS: + g_value_set_uint64(value, priv->flags); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -1049,6 +1277,7 @@ static void fu_context_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { FuContext *self = FU_CONTEXT(object); + FuContextPrivate *priv = GET_PRIVATE(self); switch (prop_id) { case PROP_BATTERY_STATE: fu_context_set_battery_state(self, g_value_get_uint(value)); @@ -1062,6 +1291,9 @@ fu_context_set_property(GObject *object, guint prop_id, const GValue *value, GPa case PROP_BATTERY_THRESHOLD: fu_context_set_battery_threshold(self, g_value_get_uint(value)); break; + case PROP_FLAGS: + priv->flags = g_value_get_uint64(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -1078,6 +1310,8 @@ fu_context_finalize(GObject *object) g_hash_table_unref(priv->runtime_versions); if (priv->compile_versions != NULL) g_hash_table_unref(priv->compile_versions); + if (priv->fdt != NULL) + g_object_unref(priv->fdt); g_object_unref(priv->hwids); g_hash_table_unref(priv->hwid_flags); g_object_unref(priv->quirks); @@ -1163,6 +1397,22 @@ fu_context_class_init(FuContextClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_NAME); g_object_class_install_property(object_class, PROP_BATTERY_THRESHOLD, pspec); + /** + * FuContext:flags: + * + * The context flags. + * + * Since: 1.8.10 + */ + pspec = g_param_spec_uint64("flags", + NULL, + NULL, + FU_CONTEXT_FLAG_NONE, + G_MAXUINT64, + FU_CONTEXT_FLAG_NONE, + G_PARAM_READWRITE | G_PARAM_STATIC_NAME); + g_object_class_install_property(object_class, PROP_FLAGS, pspec); + /** * FuContext::security-changed: * @self: the #FuContext instance that emitted the signal @@ -1190,6 +1440,7 @@ static void fu_context_init(FuContext *self) { FuContextPrivate *priv = GET_PRIVATE(self); + priv->chassis_kind = FU_SMBIOS_CHASSIS_KIND_UNKNOWN; priv->battery_level = FWUPD_BATTERY_LEVEL_INVALID; priv->battery_threshold = FWUPD_BATTERY_LEVEL_INVALID; priv->smbios = fu_smbios_new(); diff --git a/libfwupdplugin/fu-context.h b/libfwupdplugin/fu-context.h index 2baabce1e..acdcbb376 100644 --- a/libfwupdplugin/fu-context.h +++ b/libfwupdplugin/fu-context.h @@ -10,6 +10,8 @@ #include "fu-bios-settings.h" #include "fu-common.h" +#include "fu-firmware.h" +#include "fu-smbios.h" #define FU_TYPE_CONTEXT (fu_context_get_type()) G_DECLARE_DERIVABLE_TYPE(FuContext, fu_context, FU, CONTEXT, GObject) @@ -61,13 +63,15 @@ typedef guint64 FuContextFlags; void fu_context_add_flag(FuContext *context, FuContextFlags flag); +void +fu_context_remove_flag(FuContext *context, FuContextFlags flag); gboolean fu_context_has_flag(FuContext *context, FuContextFlags flag); const gchar * -fu_context_get_smbios_string(FuContext *self, guint8 structure_type, guint8 offset); +fu_context_get_smbios_string(FuContext *self, guint8 structure_type, guint8 offset, GError **error); guint -fu_context_get_smbios_integer(FuContext *self, guint8 type, guint8 offset); +fu_context_get_smbios_integer(FuContext *self, guint8 type, guint8 offset, GError **error); GBytes * fu_context_get_smbios_data(FuContext *self, guint8 structure_type, GError **error); gboolean @@ -124,3 +128,7 @@ fu_context_get_bios_setting(FuContext *self, const gchar *name); GPtrArray * fu_context_get_esp_volumes(FuContext *self, GError **error) G_GNUC_WARN_UNUSED_RESULT; +FuFirmware * +fu_context_get_fdt(FuContext *self, GError **error) G_GNUC_WARN_UNUSED_RESULT; +FuSmbiosChassisKind +fu_context_get_chassis_kind(FuContext *self); diff --git a/libfwupdplugin/fu-fdt-firmware.c b/libfwupdplugin/fu-fdt-firmware.c index 3d72f9f89..a31131bfb 100644 --- a/libfwupdplugin/fu-fdt-firmware.c +++ b/libfwupdplugin/fu-fdt-firmware.c @@ -169,7 +169,7 @@ fu_fdt_firmware_get_image_by_path(FuFdtFirmware *self, const gchar *path, GError } static gboolean -fu_fdt_firmware_parse_dt_struct(FuFdtFirmware *self, GBytes *fw, GHashTable *strtab, GError **error) +fu_fdt_firmware_parse_dt_struct(FuFdtFirmware *self, GBytes *fw, GBytes *strtab, GError **error) { gsize bufsz = 0; gsize offset = 0; @@ -258,8 +258,8 @@ fu_fdt_firmware_parse_dt_struct(FuFdtFirmware *self, GBytes *fw, GHashTable *str if (token == FDT_PROP) { guint32 prop_len = 0; guint32 prop_nameoff = 0; - gpointer value = NULL; g_autoptr(GBytes) blob = NULL; + g_autoptr(GString) str = NULL; /* sanity check */ if (firmware_current == FU_FIRMWARE(self)) { @@ -288,23 +288,18 @@ fu_fdt_firmware_parse_dt_struct(FuFdtFirmware *self, GBytes *fw, GHashTable *str offset += sizeof(FuFdtProp); /* add property */ - if (!g_hash_table_lookup_extended(strtab, - GINT_TO_POINTER(prop_nameoff), - NULL, - &value)) { - g_set_error(error, - G_IO_ERROR, - G_IO_ERROR_INVALID_DATA, - "invalid strtab offset 0x%x", - prop_nameoff); + str = fu_string_new_safe(g_bytes_get_data(strtab, NULL), + g_bytes_get_size(strtab), + prop_nameoff, + error); + if (str == NULL) { + g_prefix_error(error, "invalid strtab offset 0x%x: ", prop_nameoff); return FALSE; } blob = fu_bytes_new_offset(fw, offset, prop_len, error); if (blob == NULL) return FALSE; - fu_fdt_image_set_attr(FU_FDT_IMAGE(firmware_current), - (const gchar *)value, - blob); + fu_fdt_image_set_attr(FU_FDT_IMAGE(firmware_current), str->str, blob); offset += prop_len; continue; } @@ -332,43 +327,6 @@ fu_fdt_firmware_parse_dt_struct(FuFdtFirmware *self, GBytes *fw, GHashTable *str return TRUE; } -static gboolean -fu_fdt_firmware_parse_dt_strings(FuFdtFirmware *self, - GBytes *fw, - GHashTable *strtab, - GError **error) -{ - gsize bufsz = 0; - const guint8 *buf = g_bytes_get_data(fw, &bufsz); - - /* debug */ - if (g_getenv("FU_FDT_FIRMWARE_VERBOSE") != NULL) - fu_dump_bytes(G_LOG_DOMAIN, "dt_strings", fw); - - /* parse */ - for (gsize offset = 0; offset < bufsz; offset++) { - g_autoptr(GString) str = NULL; - str = fu_string_new_safe(buf, bufsz, offset, error); - if (str == NULL) - return FALSE; - if (str->len == 0) { - g_set_error(error, - G_IO_ERROR, - G_IO_ERROR_INVALID_DATA, - "strtab invalid @0x%x", - (guint)offset); - return FALSE; - } - if (g_getenv("FU_FDT_FIRMWARE_VERBOSE") != NULL) - g_debug("strtab: %s", str->str); - g_hash_table_insert(strtab, GINT_TO_POINTER(offset), g_strdup(str->str)); - offset += str->len; - } - - /* success */ - return TRUE; -} - static gboolean fu_fdt_firmware_parse_mem_rsvmap(FuFdtFirmware *self, const guint8 *buf, @@ -451,7 +409,6 @@ fu_fdt_firmware_parse(FuFirmware *firmware, guint32 size_dt_strings = 0; guint32 size_dt_struct = 0; const guint8 *buf = g_bytes_get_data(fw, &bufsz); - g_autoptr(GHashTable) strtab = NULL; /* uint:str */ /* sanity check */ if (!fu_memread_uint32_safe(buf, @@ -472,8 +429,7 @@ fu_fdt_firmware_parse(FuFirmware *firmware, } fu_firmware_set_size(firmware, totalsize); - /* read string table */ - strtab = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); + /* read header */ if (!fu_memread_uint32_safe(buf, bufsz, offset + G_STRUCT_OFFSET(FuFdtHeader, off_dt_strings), @@ -488,17 +444,6 @@ fu_fdt_firmware_parse(FuFirmware *firmware, G_BIG_ENDIAN, error)) return FALSE; - if (size_dt_strings != 0x0) { - g_autoptr(GBytes) dt_strings = NULL; - dt_strings = - fu_bytes_new_offset(fw, offset + off_dt_strings, size_dt_strings, error); - if (dt_strings == NULL) - return FALSE; - if (!fu_fdt_firmware_parse_dt_strings(self, dt_strings, strtab, error)) - return FALSE; - } - - /* read out DT struct */ if (!fu_memread_uint32_safe(buf, bufsz, offset + G_STRUCT_OFFSET(FuFdtHeader, off_dt_struct), @@ -513,16 +458,6 @@ fu_fdt_firmware_parse(FuFirmware *firmware, G_BIG_ENDIAN, error)) return FALSE; - if (size_dt_struct != 0x0) { - g_autoptr(GBytes) dt_struct = NULL; - dt_struct = fu_bytes_new_offset(fw, offset + off_dt_struct, size_dt_struct, error); - if (dt_struct == NULL) - return FALSE; - if (!fu_fdt_firmware_parse_dt_struct(self, dt_struct, strtab, error)) - return FALSE; - } - - /* read out reserved map */ if (!fu_memread_uint32_safe(buf, bufsz, offset + G_STRUCT_OFFSET(FuFdtHeader, off_mem_rsvmap), @@ -538,8 +473,6 @@ fu_fdt_firmware_parse(FuFirmware *firmware, error)) return FALSE; } - - /* read in CPUID */ if (!fu_memread_uint32_safe(buf, bufsz, offset + G_STRUCT_OFFSET(FuFdtHeader, boot_cpuid_phys), @@ -547,8 +480,6 @@ fu_fdt_firmware_parse(FuFirmware *firmware, G_BIG_ENDIAN, error)) return FALSE; - - /* header version */ if (!fu_memread_uint32_safe(buf, bufsz, offset + G_STRUCT_OFFSET(FuFdtHeader, last_comp_version), @@ -573,6 +504,23 @@ fu_fdt_firmware_parse(FuFirmware *firmware, error)) return FALSE; fu_firmware_set_version_raw(firmware, version); + + /* parse device tree struct */ + if (size_dt_struct != 0x0 && size_dt_strings != 0x0) { + g_autoptr(GBytes) dt_strings = NULL; + g_autoptr(GBytes) dt_struct = NULL; + dt_strings = + fu_bytes_new_offset(fw, offset + off_dt_strings, size_dt_strings, error); + if (dt_strings == NULL) + return FALSE; + dt_struct = fu_bytes_new_offset(fw, offset + off_dt_struct, size_dt_struct, error); + if (dt_struct == NULL) + return FALSE; + if (!fu_fdt_firmware_parse_dt_struct(self, dt_struct, dt_strings, error)) + return FALSE; + } + + /* success */ return TRUE; } diff --git a/libfwupdplugin/fu-firmware.c b/libfwupdplugin/fu-firmware.c index b66009d48..2a6e52b75 100644 --- a/libfwupdplugin/fu-firmware.c +++ b/libfwupdplugin/fu-firmware.c @@ -1392,6 +1392,7 @@ gboolean fu_firmware_write_file(FuFirmware *self, GFile *file, GError **error) { g_autoptr(GBytes) blob = NULL; + g_autoptr(GFile) parent = NULL; g_return_val_if_fail(FU_IS_FIRMWARE(self), FALSE); g_return_val_if_fail(G_IS_FILE(file), FALSE); @@ -1400,6 +1401,11 @@ fu_firmware_write_file(FuFirmware *self, GFile *file, GError **error) blob = fu_firmware_write(self, error); if (blob == NULL) return FALSE; + parent = g_file_get_parent(file); + if (!g_file_query_exists(parent, NULL)) { + if (!g_file_make_directory_with_parents(parent, NULL, error)) + return FALSE; + } return g_file_replace_contents(file, g_bytes_get_data(blob, NULL), g_bytes_get_size(blob), diff --git a/libfwupdplugin/fu-hid-device.h b/libfwupdplugin/fu-hid-device.h index 324b76db3..d7813b53b 100644 --- a/libfwupdplugin/fu-hid-device.h +++ b/libfwupdplugin/fu-hid-device.h @@ -13,7 +13,6 @@ G_DECLARE_DERIVABLE_TYPE(FuHidDevice, fu_hid_device, FU, HID_DEVICE, FuUsbDevice struct _FuHidDeviceClass { FuUsbDeviceClass parent_class; - gpointer __reserved[31]; }; /** diff --git a/libfwupdplugin/fu-hwids-config.c b/libfwupdplugin/fu-hwids-config.c new file mode 100644 index 000000000..808440aa5 --- /dev/null +++ b/libfwupdplugin/fu-hwids-config.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2021 Richard Hughes + * + * 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" + +gboolean +fu_hwids_config_setup(FuContext *ctx, FuHwids *self, GError **error) +{ + g_autofree gchar *localstatedir = fu_path_from_kind(FU_PATH_KIND_LOCALSTATEDIR_PKG); + g_autofree gchar *sysconfigdir = fu_path_from_kind(FU_PATH_KIND_SYSCONFDIR_PKG); + g_autoptr(GKeyFile) kf = g_key_file_new(); + g_autoptr(GPtrArray) fns = g_ptr_array_new_with_free_func(g_free); + g_autoptr(GPtrArray) keys = fu_hwids_get_keys(self); + + /* per-system configuration and optional overrides */ + g_ptr_array_add(fns, g_build_filename(sysconfigdir, "daemon.conf", NULL)); + g_ptr_array_add(fns, g_build_filename(localstatedir, "daemon.conf", NULL)); + for (guint i = 0; i < fns->len; i++) { + const gchar *fn = g_ptr_array_index(fns, i); + if (g_file_test(fn, G_FILE_TEST_EXISTS)) { + g_debug("loading HwId overrides from %s", fn); + if (!g_key_file_load_from_file(kf, fn, G_KEY_FILE_NONE, error)) + return FALSE; + } else { + g_debug("not loading HwId overrides from %s", fn); + } + } + + /* all keys are optional */ + for (guint i = 0; i < keys->len; i++) { + const gchar *key = g_ptr_array_index(keys, i); + g_autofree gchar *value = g_key_file_get_string(kf, "fwupd", key, NULL); + if (value != NULL) + fu_hwids_add_value(self, key, value); + } + + /* success */ + return TRUE; +} diff --git a/libfwupdplugin/fu-hwids-dmi.c b/libfwupdplugin/fu-hwids-dmi.c new file mode 100644 index 000000000..280795f67 --- /dev/null +++ b/libfwupdplugin/fu-hwids-dmi.c @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2021 Richard Hughes + * + * 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; +} diff --git a/libfwupdplugin/fu-hwids-fdt.c b/libfwupdplugin/fu-hwids-fdt.c new file mode 100644 index 000000000..64aee4610 --- /dev/null +++ b/libfwupdplugin/fu-hwids-fdt.c @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2023 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#define G_LOG_DOMAIN "FuContext" + +#include "config.h" + +#include "fu-context-private.h" +#include "fu-fdt-firmware.h" +#include "fu-hwids-private.h" + +gboolean +fu_hwids_fdt_setup(FuContext *ctx, FuHwids *self, GError **error) +{ + g_autofree gchar *chassis_type = NULL; + g_auto(GStrv) compatible = NULL; + g_autoptr(FuFirmware) fdt_img = NULL; + g_autoptr(FuFdtImage) fdt_img_fwver = NULL; + g_autoptr(FuFirmware) fdt = NULL; + struct { + const gchar *hwid; + const gchar *key; + } map[] = {{FU_HWIDS_KEY_MANUFACTURER, "vendor"}, + {FU_HWIDS_KEY_FAMILY, "model-name"}, + {FU_HWIDS_KEY_PRODUCT_NAME, "model"}, + {NULL, NULL}}; + + /* adds compatible GUIDs */ + fdt = fu_context_get_fdt(ctx, error); + if (fdt == NULL) + return FALSE; + fdt_img = fu_firmware_get_image_by_id(fdt, NULL, error); + if (fdt_img == NULL) + return FALSE; + if (!fu_fdt_image_get_attr_strlist(FU_FDT_IMAGE(fdt_img), "compatible", &compatible, error)) + return FALSE; + for (guint i = 0; compatible[i] != NULL; i++) { + g_autofree gchar *guid = fwupd_guid_hash_string(compatible[i]); + g_debug("using %s for DT compatible %s", guid, compatible[i]); + fu_hwids_add_guid(self, guid); + } + + /* root node */ + for (guint i = 0; map[i].key != NULL; i++) { + g_autofree gchar *tmp = NULL; + fu_fdt_image_get_attr_str(FU_FDT_IMAGE(fdt_img), map[i].key, &tmp, NULL); + fu_hwids_add_value(self, map[i].hwid, tmp); + } + + /* chassis kind */ + fu_fdt_image_get_attr_str(FU_FDT_IMAGE(fdt_img), "chassis-type", &chassis_type, NULL); + if (chassis_type != NULL) { + struct { + FuSmbiosChassisKind chassis_kind; + const gchar *dt; + } chassis_map[] = {{FU_SMBIOS_CHASSIS_KIND_CONVERTIBLE, "convertible"}, + {FU_SMBIOS_CHASSIS_KIND_EMBEDDED_PC, "embedded"}, + {FU_SMBIOS_CHASSIS_KIND_HAND_HELD, "handset"}, + {FU_SMBIOS_CHASSIS_KIND_LAPTOP, "laptop"}, + {FU_SMBIOS_CHASSIS_KIND_TABLET, "tablet"}, + {FU_SMBIOS_CHASSIS_KIND_UNKNOWN, NULL}}; + for (guint i = 0; chassis_map[i].dt != NULL; i++) { + if (g_strcmp0(chassis_type, chassis_map[i].dt) == 0) { + fu_context_set_chassis_kind(ctx, chassis_map[i].chassis_kind); + break; + } + } + } + + /* fallback */ + if (g_strv_length(compatible) > 0) + fu_hwids_add_value(self, FU_HWIDS_KEY_MANUFACTURER, compatible[0]); + if (g_strv_length(compatible) > 1) + fu_hwids_add_value(self, FU_HWIDS_KEY_PRODUCT_NAME, compatible[1]); + if (g_strv_length(compatible) > 2) + fu_hwids_add_value(self, FU_HWIDS_KEY_FAMILY, compatible[2]); + if (fu_context_get_chassis_kind(ctx) == FU_SMBIOS_CHASSIS_KIND_UNKNOWN) { + if (fu_fdt_image_get_attr_str(FU_FDT_IMAGE(fdt_img), "battery", NULL, NULL)) + fu_context_set_chassis_kind(ctx, FU_SMBIOS_CHASSIS_KIND_PORTABLE); + } + fdt_img_fwver = + fu_fdt_firmware_get_image_by_path(FU_FDT_FIRMWARE(fdt), "ibm,firmware-versions", NULL); + if (fdt_img_fwver != NULL) { + g_autofree gchar *version = NULL; + fu_fdt_image_get_attr_str(FU_FDT_IMAGE(fdt_img), "version", &version, NULL); + fu_hwids_add_value(self, FU_HWIDS_KEY_BIOS_VERSION, version); + } + + /* success */ + return TRUE; +} diff --git a/libfwupdplugin/fu-hwids-kenv.c b/libfwupdplugin/fu-hwids-kenv.c new file mode 100644 index 000000000..4d426c87f --- /dev/null +++ b/libfwupdplugin/fu-hwids-kenv.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2021 Richard Hughes + * + * 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-kenv.h" + +gboolean +fu_hwids_kenv_setup(FuContext *ctx, FuHwids *self, GError **error) +{ +#ifdef HAVE_KENV_H + struct { + const gchar *hwid; + const gchar *key; + } map[] = {{FU_HWIDS_KEY_BASEBOARD_MANUFACTURER, "smbios.planar.maker"}, + {FU_HWIDS_KEY_BASEBOARD_PRODUCT, "smbios.planar.product"}, + {FU_HWIDS_KEY_BIOS_VENDOR, "smbios.bios.vendor"}, + {FU_HWIDS_KEY_BIOS_VERSION, "smbios.bios.version"}, + {FU_HWIDS_KEY_FAMILY, "smbios.system.family"}, + {FU_HWIDS_KEY_MANUFACTURER, "smbios.system.maker"}, + {FU_HWIDS_KEY_PRODUCT_NAME, "smbios.system.product"}, + {FU_HWIDS_KEY_PRODUCT_SKU, "smbios.system.sku"}, + {{NULL, NULL}}}; + for (guint i = 0; map[i].key != NULL; i++) { + g_autoptr(GError) error_local = NULL; + g_autofree gchar *value = fu_kenv_get_string(map[i].key, error_local); + if (value == NULL) { + g_debug("ignoring: %s", error_local->message); + continue; + } + fu_hwids_add_value(self, map[i].hwid, value); + } +#endif + + /* success */ + return TRUE; +} diff --git a/libfwupdplugin/fu-hwids-private.h b/libfwupdplugin/fu-hwids-private.h new file mode 100644 index 000000000..be2e28d1d --- /dev/null +++ b/libfwupdplugin/fu-hwids-private.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2023 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#pragma once + +#include "fu-context.h" +#include "fu-hwids.h" + +FuHwids * +fu_hwids_new(void); +gboolean +fu_hwids_setup(FuHwids *self, GError **error) G_GNUC_WARN_UNUSED_RESULT; +gboolean +fu_hwids_config_setup(FuContext *ctx, FuHwids *self, GError **error); +gboolean +fu_hwids_dmi_setup(FuContext *ctx, FuHwids *self, GError **error); +gboolean +fu_hwids_fdt_setup(FuContext *ctx, FuHwids *self, GError **error); +gboolean +fu_hwids_kenv_setup(FuContext *ctx, FuHwids *self, GError **error); +gboolean +fu_hwids_smbios_setup(FuContext *ctx, FuHwids *self, GError **error); diff --git a/libfwupdplugin/fu-hwids-smbios.c b/libfwupdplugin/fu-hwids-smbios.c new file mode 100644 index 000000000..130aee7e8 --- /dev/null +++ b/libfwupdplugin/fu-hwids-smbios.c @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2021 Richard Hughes + * + * 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-smbios-private.h" +#include "fu-string.h" + +typedef gchar *(*FuContextHwidConvertFunc)(FuSmbios *smbios, + guint8 type, + guint8 offset, + GError **error); + +static gchar * +fu_hwids_smbios_convert_string_table_cb(FuSmbios *smbios, + guint8 type, + guint8 offset, + GError **error) +{ + const gchar *tmp = fu_smbios_get_string(smbios, type, offset, error); + if (tmp == NULL) + return NULL; + /* ComputerHardwareIds.exe seems to strip spaces */ + return fu_strstrip(tmp); +} + +static gchar * +fu_hwids_smbios_convert_padded_integer_cb(FuSmbios *smbios, + guint8 type, + guint8 offset, + GError **error) +{ + guint tmp = fu_smbios_get_integer(smbios, type, offset, error); + if (tmp == G_MAXUINT) + return NULL; + return g_strdup_printf("%02x", tmp); +} + +static gchar * +fu_hwids_smbios_convert_integer_cb(FuSmbios *smbios, guint8 type, guint8 offset, GError **error) +{ + guint tmp = fu_smbios_get_integer(smbios, type, offset, error); + if (tmp == G_MAXUINT) + return NULL; + return g_strdup_printf("%x", tmp); +} + +gboolean +fu_hwids_smbios_setup(FuContext *ctx, FuHwids *self, GError **error) +{ + FuSmbios *smbios = fu_context_get_smbios(ctx); + struct { + const gchar *key; + guint8 type; + guint8 offset; + FuContextHwidConvertFunc func; + } map[] = {{FU_HWIDS_KEY_MANUFACTURER, + FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, + 0x04, + fu_hwids_smbios_convert_string_table_cb}, + {FU_HWIDS_KEY_ENCLOSURE_KIND, + FU_SMBIOS_STRUCTURE_TYPE_CHASSIS, + 0x05, + fu_hwids_smbios_convert_integer_cb}, + {FU_HWIDS_KEY_FAMILY, + FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, + 0x1a, + fu_hwids_smbios_convert_string_table_cb}, + {FU_HWIDS_KEY_PRODUCT_NAME, + FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, + 0x05, + fu_hwids_smbios_convert_string_table_cb}, + {FU_HWIDS_KEY_PRODUCT_SKU, + FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, + 0x19, + fu_hwids_smbios_convert_string_table_cb}, + {FU_HWIDS_KEY_BIOS_VENDOR, + FU_SMBIOS_STRUCTURE_TYPE_BIOS, + 0x04, + fu_hwids_smbios_convert_string_table_cb}, + {FU_HWIDS_KEY_BIOS_VERSION, + FU_SMBIOS_STRUCTURE_TYPE_BIOS, + 0x05, + fu_hwids_smbios_convert_string_table_cb}, + {FU_HWIDS_KEY_BIOS_MAJOR_RELEASE, + FU_SMBIOS_STRUCTURE_TYPE_BIOS, + 0x14, + fu_hwids_smbios_convert_padded_integer_cb}, + {FU_HWIDS_KEY_BIOS_MINOR_RELEASE, + FU_SMBIOS_STRUCTURE_TYPE_BIOS, + 0x15, + fu_hwids_smbios_convert_padded_integer_cb}, + {FU_HWIDS_KEY_FIRMWARE_MAJOR_RELEASE, + FU_SMBIOS_STRUCTURE_TYPE_BIOS, + 0x16, + fu_hwids_smbios_convert_padded_integer_cb}, + {FU_HWIDS_KEY_FIRMWARE_MINOR_RELEASE, + FU_SMBIOS_STRUCTURE_TYPE_BIOS, + 0x17, + fu_hwids_smbios_convert_padded_integer_cb}, + {FU_HWIDS_KEY_BASEBOARD_MANUFACTURER, + FU_SMBIOS_STRUCTURE_TYPE_BASEBOARD, + 0x04, + fu_hwids_smbios_convert_string_table_cb}, + {FU_HWIDS_KEY_BASEBOARD_PRODUCT, + FU_SMBIOS_STRUCTURE_TYPE_BASEBOARD, + 0x05, + fu_hwids_smbios_convert_string_table_cb}, + {NULL, 0x00, 0x00, NULL}}; + + if (!fu_smbios_setup(smbios, error)) + return FALSE; + + /* get all DMI data from SMBIOS */ + fu_context_set_chassis_kind( + ctx, + fu_smbios_get_integer(smbios, FU_SMBIOS_STRUCTURE_TYPE_CHASSIS, 0x05, NULL)); + for (guint i = 0; map[i].key != NULL; i++) { + const gchar *contents_hdr = NULL; + g_autofree gchar *contents = NULL; + g_autoptr(GError) error_local = NULL; + + contents = map[i].func(smbios, map[i].type, map[i].offset, &error_local); + if (contents == NULL) { + g_debug("ignoring %s: %s", map[i].key, error_local->message); + continue; + } + g_debug("smbios property %s=%s", map[i].key, contents); + + /* weirdly, remove leading zeros */ + contents_hdr = contents; + while (contents_hdr[0] == '0' && + map[i].func != fu_hwids_smbios_convert_padded_integer_cb) + contents_hdr++; + fu_hwids_add_value(self, map[i].key, contents_hdr); + } + + /* success */ + return TRUE; +} diff --git a/libfwupdplugin/fu-hwids.c b/libfwupdplugin/fu-hwids.c index 94dcfd97a..5192488b3 100644 --- a/libfwupdplugin/fu-hwids.c +++ b/libfwupdplugin/fu-hwids.c @@ -15,7 +15,7 @@ #include "fwupd-error.h" #include "fu-common.h" -#include "fu-hwids.h" +#include "fu-hwids-private.h" #include "fu-path.h" #include "fu-string.h" @@ -32,9 +32,8 @@ struct _FuHwids { GObject parent_instance; - GHashTable *hash_dmi_hw; /* BiosVersion->"1.2.3 " */ - GHashTable *hash_dmi_display; /* BiosVersion->"1.2.3" */ - GHashTable *hash_smbios_override; /* BiosVersion->"1.2.3" */ + GHashTable *hash_values; /* BiosVersion->"1.2.3 " */ + GHashTable *hash_values_display; /* BiosVersion->"1.2.3" */ GHashTable *hash_guid; /* a-c-b-d->1 */ GPtrArray *array_guids; /* a-c-b-d */ }; @@ -56,7 +55,7 @@ G_DEFINE_TYPE(FuHwids, fu_hwids, G_TYPE_OBJECT) const gchar * fu_hwids_get_value(FuHwids *self, const gchar *key) { - return g_hash_table_lookup(self->hash_dmi_display, key); + return g_hash_table_lookup(self->hash_values_display, key); } /** @@ -121,6 +120,7 @@ fu_hwids_get_keys(FuHwids *self) FU_HWIDS_KEY_BASEBOARD_MANUFACTURER, FU_HWIDS_KEY_BASEBOARD_PRODUCT, NULL}; + g_return_val_if_fail(FU_IS_HWIDS(self), NULL); for (guint i = 0; keys[i] != NULL; i++) g_ptr_array_add(array, (gpointer)keys[i]); return array; @@ -219,6 +219,9 @@ fu_hwids_get_replace_keys(FuHwids *self, const gchar *key) {"HardwareID-14", FU_HWIDS_KEY_MANUFACTURER}, {NULL, NULL}}; + g_return_val_if_fail(FU_IS_HWIDS(self), NULL); + g_return_val_if_fail(key != NULL, NULL); + /* defined for Windows 10 */ for (guint i = 0; msdefined[i].search != NULL; i++) { if (g_strcmp0(msdefined[i].search, key) == 0) { @@ -231,23 +234,39 @@ fu_hwids_get_replace_keys(FuHwids *self, const gchar *key) } /** - * fu_hwids_add_smbios_override: + * fu_hwids_add_value: * @self: a #FuHwids * @key: a key, e.g. %FU_HWIDS_KEY_PRODUCT_SKU * @value: (nullable): a new value, e.g. `ExampleModel` * - * Sets SMBIOS override values so you can emulate another system. + * Sets override values so you can emulate another system. * * This function has no effect if called after fu_hwids_setup() * - * Since: 1.5.6 + * Since: 1.8.10 **/ void -fu_hwids_add_smbios_override(FuHwids *self, const gchar *key, const gchar *value) +fu_hwids_add_value(FuHwids *self, const gchar *key, const gchar *value) { g_return_if_fail(FU_IS_HWIDS(self)); g_return_if_fail(key != NULL); - g_hash_table_insert(self->hash_smbios_override, g_strdup(key), g_strdup(value)); + + /* does not replace; first value set wins */ + if (g_hash_table_contains(self->hash_values, key)) + return; + g_hash_table_insert(self->hash_values, g_strdup(key), g_strdup(value)); + + /* make suitable for display */ + if (value != NULL) { + g_autofree gchar *value_safe = g_str_to_ascii(value, "C"); + g_strdelimit(value_safe, "\n\r", '\0'); + g_strchomp(value_safe); + g_hash_table_insert(self->hash_values_display, + g_strdup(key), + g_steal_pointer(&value_safe)); + } else { + g_hash_table_insert(self->hash_values_display, g_strdup(key), NULL); + } } /** @@ -278,7 +297,7 @@ fu_hwids_get_replace_values(FuHwids *self, const gchar *keys, GError **error) /* get each part of the HWID */ split = g_strsplit(keys, "&", -1); for (guint j = 0; split[j] != NULL; j++) { - const gchar *tmp = g_hash_table_lookup(self->hash_dmi_hw, split[j]); + const gchar *tmp = g_hash_table_lookup(self->hash_values, split[j]); if (tmp == NULL) { g_set_error(error, G_IO_ERROR, @@ -321,199 +340,41 @@ fu_hwids_get_guid(FuHwids *self, const gchar *keys, GError **error) return fu_hwids_get_guid_for_str(tmp, error); } -typedef gchar *(*FuHwidsConvertFunc)(FuSmbios *smbios, guint8 type, guint8 offset, GError **error); - -static gchar * -fu_hwids_convert_string_table_cb(FuSmbios *smbios, guint8 type, guint8 offset, GError **error) +/** + * fu_hwids_add_guid: + * @self: a #FuHwids + * @guid: a GUID + * + * Adds a HWID GUID value. + * + * Since: 1.8.10 + **/ +void +fu_hwids_add_guid(FuHwids *self, const gchar *guid) { - const gchar *tmp; - tmp = fu_smbios_get_string(smbios, type, offset, error); - if (tmp == NULL) - return NULL; - /* ComputerHardwareIds.exe seems to strip spaces */ - return fu_strstrip(tmp); -} - -static gchar * -fu_hwids_convert_padded_integer_cb(FuSmbios *smbios, guint8 type, guint8 offset, GError **error) -{ - guint tmp = fu_smbios_get_integer(smbios, type, offset, error); - if (tmp == G_MAXUINT) - return NULL; - return g_strdup_printf("%02x", tmp); -} - -static gchar * -fu_hwids_convert_integer_cb(FuSmbios *smbios, guint8 type, guint8 offset, GError **error) -{ - guint tmp = fu_smbios_get_integer(smbios, type, offset, error); - if (tmp == G_MAXUINT) - return NULL; - return g_strdup_printf("%x", tmp); -} - -static gboolean -fu_hwids_setup_overrides(FuHwids *self, GError **error) -{ - g_autofree gchar *localstatedir = fu_path_from_kind(FU_PATH_KIND_LOCALSTATEDIR_PKG); - g_autofree gchar *sysconfigdir = fu_path_from_kind(FU_PATH_KIND_SYSCONFDIR_PKG); - g_autoptr(GKeyFile) kf = g_key_file_new(); - g_autoptr(GPtrArray) fns = g_ptr_array_new_with_free_func(g_free); - g_autoptr(GPtrArray) keys = fu_hwids_get_keys(self); - - /* per-system configuration and optional overrides */ - g_ptr_array_add(fns, g_build_filename(sysconfigdir, "daemon.conf", NULL)); - g_ptr_array_add(fns, g_build_filename(localstatedir, "daemon.conf", NULL)); - for (guint i = 0; i < fns->len; i++) { - const gchar *fn = g_ptr_array_index(fns, i); - if (g_file_test(fn, G_FILE_TEST_EXISTS)) { - g_debug("loading HwId overrides from %s", fn); - if (!g_key_file_load_from_file(kf, fn, G_KEY_FILE_NONE, error)) - return FALSE; - } else { - g_debug("not loading HwId overrides from %s", fn); - } - } - - /* all keys are optional */ - for (guint i = 0; i < keys->len; i++) { - const gchar *key = g_ptr_array_index(keys, i); - g_autofree gchar *value = g_key_file_get_string(kf, "fwupd", key, NULL); - if (value != NULL) - fu_hwids_add_smbios_override(self, key, value); - } - - /* success */ - return TRUE; + g_return_if_fail(FU_IS_HWIDS(self)); + g_return_if_fail(guid != NULL); + g_hash_table_insert(self->hash_guid, g_strdup(guid), GUINT_TO_POINTER(1)); + g_ptr_array_add(self->array_guids, g_strdup(guid)); } /** * fu_hwids_setup: * @self: a #FuHwids - * @smbios: (nullable): a #FuSmbios * @error: (nullable): optional return location for an error * - * Reads all the SMBIOS values from the hardware. + * Adds all the `HardwareID` GUIDs from the previously supplied data. * * Returns: %TRUE for success * * Since: 0.9.3 **/ gboolean -fu_hwids_setup(FuHwids *self, FuSmbios *smbios, GError **error) +fu_hwids_setup(FuHwids *self, GError **error) { - struct { - const gchar *key; - guint8 type; - guint8 offset; - FuHwidsConvertFunc func; - } map[] = {{FU_HWIDS_KEY_MANUFACTURER, - FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, - 0x04, - fu_hwids_convert_string_table_cb}, - {FU_HWIDS_KEY_ENCLOSURE_KIND, - FU_SMBIOS_STRUCTURE_TYPE_CHASSIS, - 0x05, - fu_hwids_convert_integer_cb}, - {FU_HWIDS_KEY_FAMILY, - FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, - 0x1a, - fu_hwids_convert_string_table_cb}, - {FU_HWIDS_KEY_PRODUCT_NAME, - FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, - 0x05, - fu_hwids_convert_string_table_cb}, - {FU_HWIDS_KEY_PRODUCT_SKU, - FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, - 0x19, - fu_hwids_convert_string_table_cb}, - {FU_HWIDS_KEY_BIOS_VENDOR, - FU_SMBIOS_STRUCTURE_TYPE_BIOS, - 0x04, - fu_hwids_convert_string_table_cb}, - {FU_HWIDS_KEY_BIOS_VERSION, - FU_SMBIOS_STRUCTURE_TYPE_BIOS, - 0x05, - fu_hwids_convert_string_table_cb}, - {FU_HWIDS_KEY_BIOS_MAJOR_RELEASE, - FU_SMBIOS_STRUCTURE_TYPE_BIOS, - 0x14, - fu_hwids_convert_padded_integer_cb}, - {FU_HWIDS_KEY_BIOS_MINOR_RELEASE, - FU_SMBIOS_STRUCTURE_TYPE_BIOS, - 0x15, - fu_hwids_convert_padded_integer_cb}, - {FU_HWIDS_KEY_FIRMWARE_MAJOR_RELEASE, - FU_SMBIOS_STRUCTURE_TYPE_BIOS, - 0x16, - fu_hwids_convert_padded_integer_cb}, - {FU_HWIDS_KEY_FIRMWARE_MINOR_RELEASE, - FU_SMBIOS_STRUCTURE_TYPE_BIOS, - 0x17, - fu_hwids_convert_padded_integer_cb}, - {FU_HWIDS_KEY_BASEBOARD_MANUFACTURER, - FU_SMBIOS_STRUCTURE_TYPE_BASEBOARD, - 0x04, - fu_hwids_convert_string_table_cb}, - {FU_HWIDS_KEY_BASEBOARD_PRODUCT, - FU_SMBIOS_STRUCTURE_TYPE_BASEBOARD, - 0x05, - fu_hwids_convert_string_table_cb}, - {NULL, 0x00, 0x00, NULL}}; - g_return_val_if_fail(FU_IS_HWIDS(self), FALSE); - g_return_val_if_fail(FU_IS_SMBIOS(smbios) || smbios == NULL, FALSE); g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - /* override using a config file */ - if (!fu_hwids_setup_overrides(self, error)) - return FALSE; - - /* get all DMI data */ - for (guint i = 0; map[i].key != NULL; i++) { - const gchar *contents_hdr = NULL; - g_autofree gchar *contents = NULL; - g_autofree gchar *contents_safe = NULL; - g_autoptr(GError) error_local = NULL; - - /* get the data from a SMBIOS table unless an override exists */ - if (g_hash_table_lookup_extended(self->hash_smbios_override, - map[i].key, - NULL, - (gpointer *)&contents_hdr)) { - if (contents_hdr == NULL) { - g_debug("ignoring %s", map[i].key); - continue; - } - } else if (smbios != NULL) { - contents = map[i].func(smbios, map[i].type, map[i].offset, &error_local); - if (contents == NULL) { - g_debug("ignoring %s: %s", map[i].key, error_local->message); - continue; - } - contents_hdr = contents; - } else { - g_debug("ignoring %s", map[i].key); - continue; - } - g_debug("smbios property %s=%s", map[i].key, contents_hdr); - - /* weirdly, remove leading zeros */ - while (contents_hdr[0] == '0' && map[i].func != fu_hwids_convert_padded_integer_cb) - contents_hdr++; - g_hash_table_insert(self->hash_dmi_hw, - g_strdup(map[i].key), - g_strdup(contents_hdr)); - - /* make suitable for display */ - contents_safe = g_str_to_ascii(contents_hdr, "C"); - g_strdelimit(contents_safe, "\n\r", '\0'); - g_strchomp(contents_safe); - g_hash_table_insert(self->hash_dmi_display, - g_strdup(map[i].key), - g_steal_pointer(&contents_safe)); - } - /* add GUIDs */ for (guint i = 0; i < 15; i++) { g_autofree gchar *guid = NULL; @@ -527,8 +388,7 @@ fu_hwids_setup(FuHwids *self, FuSmbios *smbios, GError **error) g_debug("%s is not available, %s", key, error_local->message); continue; } - g_hash_table_insert(self->hash_guid, g_strdup(guid), GUINT_TO_POINTER(1)); - g_ptr_array_add(self->array_guids, g_steal_pointer(&guid)); + fu_hwids_add_guid(self, guid); } return TRUE; @@ -541,9 +401,8 @@ fu_hwids_finalize(GObject *object) g_return_if_fail(FU_IS_HWIDS(object)); self = FU_HWIDS(object); - g_hash_table_unref(self->hash_dmi_hw); - g_hash_table_unref(self->hash_dmi_display); - g_hash_table_unref(self->hash_smbios_override); + g_hash_table_unref(self->hash_values); + g_hash_table_unref(self->hash_values_display); g_hash_table_unref(self->hash_guid); g_ptr_array_unref(self->array_guids); @@ -560,9 +419,8 @@ fu_hwids_class_init(FuHwidsClass *klass) static void fu_hwids_init(FuHwids *self) { - self->hash_dmi_hw = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - self->hash_dmi_display = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); - self->hash_smbios_override = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + self->hash_values = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + self->hash_values_display = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); self->hash_guid = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); self->array_guids = g_ptr_array_new_with_free_func(g_free); } diff --git a/libfwupdplugin/fu-hwids.h b/libfwupdplugin/fu-hwids.h index eb82efaf2..990931d2f 100644 --- a/libfwupdplugin/fu-hwids.h +++ b/libfwupdplugin/fu-hwids.h @@ -117,14 +117,12 @@ G_DECLARE_FINAL_TYPE(FuHwids, fu_hwids, FU, HWIDS, GObject) **/ #define FU_HWIDS_KEY_PRODUCT_SKU "ProductSku" -FuHwids * -fu_hwids_new(void); GPtrArray * fu_hwids_get_keys(FuHwids *self); const gchar * fu_hwids_get_value(FuHwids *self, const gchar *key); void -fu_hwids_add_smbios_override(FuHwids *self, const gchar *key, const gchar *value); +fu_hwids_add_value(FuHwids *self, const gchar *key, const gchar *value); const gchar * fu_hwids_get_replace_keys(FuHwids *self, const gchar *key); gchar * @@ -135,7 +133,7 @@ gchar * fu_hwids_get_guid(FuHwids *self, const gchar *keys, GError **error) G_GNUC_WARN_UNUSED_RESULT; GPtrArray * fu_hwids_get_guids(FuHwids *self); +void +fu_hwids_add_guid(FuHwids *self, const gchar *guid); gboolean fu_hwids_has_guid(FuHwids *self, const gchar *guid); -gboolean -fu_hwids_setup(FuHwids *self, FuSmbios *smbios, GError **error) G_GNUC_WARN_UNUSED_RESULT; diff --git a/libfwupdplugin/fu-i2c-device.h b/libfwupdplugin/fu-i2c-device.h index 29562e93f..9c8b5a47f 100644 --- a/libfwupdplugin/fu-i2c-device.h +++ b/libfwupdplugin/fu-i2c-device.h @@ -13,7 +13,6 @@ G_DECLARE_DERIVABLE_TYPE(FuI2cDevice, fu_i2c_device, FU, I2C_DEVICE, FuUdevDevic struct _FuI2cDeviceClass { FuUdevDeviceClass parent_class; - gpointer __reserved[31]; }; guint diff --git a/libfwupdplugin/fu-mei-device.h b/libfwupdplugin/fu-mei-device.h index 5ec749527..3b73b996d 100644 --- a/libfwupdplugin/fu-mei-device.h +++ b/libfwupdplugin/fu-mei-device.h @@ -13,7 +13,6 @@ G_DECLARE_DERIVABLE_TYPE(FuMeiDevice, fu_mei_device, FU, MEI_DEVICE, FuUdevDevic struct _FuMeiDeviceClass { FuUdevDeviceClass parent_class; - gpointer __reserved[31]; }; gboolean diff --git a/libfwupdplugin/fu-path.c b/libfwupdplugin/fu-path.c index 859a6cd09..0df8144cf 100644 --- a/libfwupdplugin/fu-path.c +++ b/libfwupdplugin/fu-path.c @@ -292,6 +292,12 @@ fu_path_from_kind(FuPathKind path_kind) if (tmp != NULL) return g_strdup(tmp); return g_strdup("/sys/kernel/security"); + /* /sys/class/dmi/id */ + case FU_PATH_KIND_SYSFSDIR_DMI: + tmp = g_getenv("FWUPD_SYSFSDMIDIR"); + if (tmp != NULL) + return g_strdup(tmp); + return g_strdup("/sys/class/dmi/id"); /* /sys/firmware/acpi/tables */ case FU_PATH_KIND_ACPI_TABLES: tmp = g_getenv("FWUPD_ACPITABLESDIR"); diff --git a/libfwupdplugin/fu-path.h b/libfwupdplugin/fu-path.h index 6329cc982..7c4a50767 100644 --- a/libfwupdplugin/fu-path.h +++ b/libfwupdplugin/fu-path.h @@ -44,6 +44,7 @@ * /var/lib/fwupd/remotes.d) * @FU_PATH_KIND_WIN32_BASEDIR: The root of the install directory on Windows * @FU_PATH_KIND_LOCALCONFDIR_PKG: The package configuration override (IE /var/etc/fwupd) + * @FU_PATH_KIND_SYSFSDIR_DMI: The sysfs DMI location, (IE /sys/class/dmi/id) * * Path types to use when dynamically determining a path at runtime **/ @@ -73,6 +74,7 @@ typedef enum { FU_PATH_KIND_LOCALSTATEDIR_REMOTES, FU_PATH_KIND_WIN32_BASEDIR, FU_PATH_KIND_LOCALCONFDIR_PKG, + FU_PATH_KIND_SYSFSDIR_DMI, /*< private >*/ FU_PATH_KIND_LAST } FuPathKind; diff --git a/libfwupdplugin/fu-pefile-firmware.c b/libfwupdplugin/fu-pefile-firmware.c new file mode 100644 index 000000000..021b379ec --- /dev/null +++ b/libfwupdplugin/fu-pefile-firmware.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2023 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#define G_LOG_DOMAIN "FuFirmware" + +#include "config.h" + +#include "fu-bytes.h" +#include "fu-coswid-firmware.h" +#include "fu-dump.h" +#include "fu-mem.h" +#include "fu-pefile-firmware.h" +#include "fu-string.h" + +/** + * FuPefileFirmware: + * + * A PE file consists of a Microsoft MS-DOS stub, the PE signature, the COFF file header, and an + * optional header, followed by section data. + * + * Documented: + * https://learn.microsoft.com/en-gb/windows/win32/debug/pe-format + */ + +G_DEFINE_TYPE(FuPefileFirmware, fu_pefile_firmware, FU_TYPE_FIRMWARE) + +static gboolean +fu_pefile_firmware_check_magic(FuFirmware *firmware, GBytes *fw, gsize offset, GError **error) +{ + guint16 magic = 0x0; + + if (!fu_memread_uint16_safe(g_bytes_get_data(fw, NULL), + g_bytes_get_size(fw), + offset, + &magic, + G_LITTLE_ENDIAN, + error)) { + g_prefix_error(error, "failed to read magic: "); + return FALSE; + } + if (magic != 0x5A4D) { + g_set_error_literal(error, + FWUPD_ERROR, + FWUPD_ERROR_INVALID_FILE, + "invalid magic for file"); + return FALSE; + } + + /* success */ + return TRUE; +} + +static gboolean +fu_pefile_firmware_parse(FuFirmware *firmware, + GBytes *fw, + gsize offset, + FwupdInstallFlags flags, + GError **error) +{ + gsize bufsz = 0; + gsize hdr_offset = offset; + guint16 opt_hdrsz = 0x0; + guint32 nr_sections = 0x0; + guint32 offset_sig = 0x0; + guint32 signature = 0x0; + const guint8 *buf = g_bytes_get_data(fw, &bufsz); + + /* we already checked the MS-DOS magic, check the signature now */ + if (!fu_memread_uint32_safe(buf, + bufsz, + hdr_offset + 0x3C, + &offset_sig, + G_LITTLE_ENDIAN, + error)) + return FALSE; + hdr_offset += offset_sig; + if (!fu_memread_uint32_safe(buf, bufsz, hdr_offset, &signature, G_LITTLE_ENDIAN, error)) + return FALSE; + if (signature != 0x4550) { + g_set_error_literal(error, + FWUPD_ERROR, + FWUPD_ERROR_INVALID_FILE, + "invalid signature for file"); + return FALSE; + } + hdr_offset += 4; + + /* read number of sections */ + if (!fu_memread_uint32_safe(buf, + bufsz, + hdr_offset + 0x02, + &nr_sections, + G_LITTLE_ENDIAN, + error)) + return FALSE; + if (nr_sections == 0) { + g_set_error_literal(error, + FWUPD_ERROR, + FWUPD_ERROR_INVALID_FILE, + "invalid number of sections"); + return FALSE; + } + + /* read optional extra header size */ + if (!fu_memread_uint16_safe(buf, + bufsz, + hdr_offset + 0x10, + &opt_hdrsz, + G_LITTLE_ENDIAN, + error)) + return FALSE; + hdr_offset += 0x14 + opt_hdrsz; + + /* read out COFF header */ + for (guint idx = 0; idx < nr_sections; idx++) { + guint32 sect_length = 0x0; + guint32 sect_offset = 0x0; + guint8 name[8] = {0x0}; + g_autofree gchar *sect_id = NULL; + g_autoptr(FuFirmware) fw_sect = NULL; + g_autoptr(GBytes) sect_blob = NULL; + + /* read the section name */ + if (!fu_memcpy_safe(name, + sizeof(name), + 0x0, + buf, + bufsz, + hdr_offset, + sizeof(name), + error)) + return FALSE; + sect_id = fu_strsafe((const gchar *)name, sizeof(name)); + if (sect_id == NULL) { + g_set_error_literal(error, + FWUPD_ERROR, + FWUPD_ERROR_INVALID_FILE, + "no section name"); + return FALSE; + } + + /* create new firmware */ + if (g_strcmp0(sect_id, ".sbom") == 0) { + fw_sect = fu_coswid_firmware_new(); + } else { + fw_sect = fu_firmware_new(); + } + fu_firmware_set_idx(fw_sect, idx); + fu_firmware_set_id(fw_sect, sect_id); + + /* add data */ + if (!fu_memread_uint32_safe(buf, + bufsz, + hdr_offset + 0x08, + §_length, + G_LITTLE_ENDIAN, + error)) + return FALSE; + fu_firmware_set_size(fw_sect, sect_length); + if (!fu_memread_uint32_safe(buf, + bufsz, + hdr_offset + 0x14, + §_offset, + G_LITTLE_ENDIAN, + error)) + return FALSE; + fu_firmware_set_offset(fw_sect, sect_offset); + sect_blob = fu_bytes_new_offset(fw, sect_offset, sect_length, error); + if (sect_blob == NULL) { + g_prefix_error(error, "failed to get raw data for %s: ", sect_id); + return FALSE; + } + if (!fu_firmware_parse(fw_sect, sect_blob, flags, error)) + return FALSE; + fu_firmware_add_image(firmware, fw_sect); + + /* next! */ + hdr_offset += 0x28; + } + + /* success */ + return TRUE; +} + +static void +fu_pefile_firmware_init(FuPefileFirmware *self) +{ +} + +static void +fu_pefile_firmware_class_init(FuPefileFirmwareClass *klass) +{ + FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS(klass); + klass_firmware->check_magic = fu_pefile_firmware_check_magic; + klass_firmware->parse = fu_pefile_firmware_parse; +} + +/** + * fu_pefile_firmware_new: + * + * Creates a new #FuPefileFirmware + * + * Since: 1.8.10 + **/ +FuFirmware * +fu_pefile_firmware_new(void) +{ + return FU_FIRMWARE(g_object_new(FU_TYPE_PEFILE_FIRMWARE, NULL)); +} diff --git a/libfwupdplugin/fu-pefile-firmware.h b/libfwupdplugin/fu-pefile-firmware.h new file mode 100644 index 000000000..ab3e58b37 --- /dev/null +++ b/libfwupdplugin/fu-pefile-firmware.h @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2023 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#pragma once + +#include "fu-firmware.h" + +#define FU_TYPE_PEFILE_FIRMWARE (fu_pefile_firmware_get_type()) +G_DECLARE_DERIVABLE_TYPE(FuPefileFirmware, fu_pefile_firmware, FU, PEFILE_FIRMWARE, FuFirmware) + +struct _FuPefileFirmwareClass { + FuFirmwareClass parent_class; +}; + +FuFirmware * +fu_pefile_firmware_new(void); diff --git a/libfwupdplugin/fu-plugin.c b/libfwupdplugin/fu-plugin.c index c77158d13..633f0c044 100644 --- a/libfwupdplugin/fu-plugin.c +++ b/libfwupdplugin/fu-plugin.c @@ -891,16 +891,33 @@ fu_plugin_runner_startup(FuPlugin *self, FuProgress *progress, GError **error) /* ensure the configure file is set to the correct permission */ if (fu_plugin_has_flag(self, FWUPD_PLUGIN_FLAG_SECURE_CONFIG)) { if (g_file_test(config_filename, G_FILE_TEST_EXISTS)) { - gint rc = g_chmod(config_filename, FU_PLUGIN_FILE_MODE_SECURE); + GStatBuf st = {0x0}; + gint rc = g_stat(config_filename, &st); if (rc != 0) { g_set_error(error, G_IO_ERROR, G_IO_ERROR_FAILED, - "failed to change permission of %s", + "failed to get permission of %s", config_filename); fu_plugin_add_flag(self, FWUPD_PLUGIN_FLAG_FAILED_OPEN); return FALSE; } + st.st_mode &= 0777; + if (st.st_mode != FU_PLUGIN_FILE_MODE_SECURE) { + g_debug("mode was 0%o, and needs to be 0%o", + st.st_mode, + (guint)FU_PLUGIN_FILE_MODE_SECURE); + rc = g_chmod(config_filename, FU_PLUGIN_FILE_MODE_SECURE); + if (rc != 0) { + g_set_error(error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "failed to change permission of %s", + config_filename); + fu_plugin_add_flag(self, FWUPD_PLUGIN_FLAG_FAILED_OPEN); + return FALSE; + } + } } } diff --git a/libfwupdplugin/fu-plugin.h b/libfwupdplugin/fu-plugin.h index 03267391b..e34caeaff 100644 --- a/libfwupdplugin/fu-plugin.h +++ b/libfwupdplugin/fu-plugin.h @@ -17,7 +17,6 @@ #include "fu-context.h" #include "fu-device-locker.h" #include "fu-device.h" -#include "fu-hwids.h" #include "fu-plugin.h" #include "fu-quirks.h" #include "fu-security-attrs.h" diff --git a/libfwupdplugin/fu-self-test.c b/libfwupdplugin/fu-self-test.c index ec070d28c..3969ba5b2 100644 --- a/libfwupdplugin/fu-self-test.c +++ b/libfwupdplugin/fu-self-test.c @@ -416,84 +416,39 @@ fu_smbios3_func(void) } static void -fu_smbios_dt_func(void) +fu_context_flags_func(void) { - const gchar *str; - gboolean ret; - g_autofree gchar *path = NULL; - g_autoptr(FuSmbios) smbios = NULL; - g_autoptr(GError) error = NULL; + g_autoptr(FuContext) ctx = fu_context_new(); - path = g_test_build_filename(G_TEST_DIST, "tests", "devicetree", "base", NULL); - smbios = fu_smbios_new(); - ret = fu_smbios_setup_from_path(smbios, path, &error); - g_assert_no_error(error); - g_assert_true(ret); - if (g_getenv("FWUPD_VERBOSE") != NULL) { - g_autofree gchar *dump = fu_firmware_to_string(FU_FIRMWARE(smbios)); - g_debug("%s", dump); - } - - /* get vendor */ - str = fu_smbios_get_string(smbios, FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, 0x04, &error); - g_assert_no_error(error); - g_assert_cmpstr(str, ==, "Hughski Limited"); + g_assert_false(fu_context_has_flag(ctx, FU_CONTEXT_FLAG_SAVE_EVENTS)); + fu_context_add_flag(ctx, FU_CONTEXT_FLAG_SAVE_EVENTS); + g_assert_true(fu_context_has_flag(ctx, FU_CONTEXT_FLAG_SAVE_EVENTS)); + fu_context_remove_flag(ctx, FU_CONTEXT_FLAG_SAVE_EVENTS); + fu_context_remove_flag(ctx, FU_CONTEXT_FLAG_SAVE_EVENTS); + g_assert_false(fu_context_has_flag(ctx, FU_CONTEXT_FLAG_SAVE_EVENTS)); + fu_context_add_flag(ctx, FU_CONTEXT_FLAG_SAVE_EVENTS); + fu_context_add_flag(ctx, FU_CONTEXT_FLAG_SAVE_EVENTS); + g_assert_true(fu_context_has_flag(ctx, FU_CONTEXT_FLAG_SAVE_EVENTS)); } static void -fu_smbios_dt_fallback_func(void) +fu_context_hwids_dmi_func(void) { - const gchar *str; - gboolean ret; - g_autofree gchar *path = NULL; - g_autoptr(FuSmbios) smbios = fu_smbios_new(); + g_autoptr(FuContext) ctx = fu_context_new(); g_autoptr(GError) error = NULL; + gboolean ret; - path = g_test_build_filename(G_TEST_DIST, "tests", "devicetree-fallback", "base", NULL); - ret = fu_smbios_setup_from_path(smbios, path, &error); + ret = fu_context_load_hwinfo(ctx, FU_CONTEXT_HWID_FLAG_LOAD_DMI, &error); g_assert_no_error(error); g_assert_true(ret); if (g_getenv("FWUPD_VERBOSE") != NULL) { - g_autofree gchar *dump = fu_firmware_to_string(FU_FIRMWARE(smbios)); + g_autofree gchar *dump = + fu_firmware_to_string(FU_FIRMWARE(fu_context_get_smbios(ctx))); g_debug("%s", dump); } - /* get vendor */ - str = fu_smbios_get_string(smbios, FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, 0x04, &error); - g_assert_no_error(error); - g_assert_cmpstr(str, ==, "solidrun"); - - /* get model */ - str = fu_smbios_get_string(smbios, FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, 0x05, &error); - g_assert_no_error(error); - g_assert_cmpstr(str, ==, "honeycomb"); -} - -static void -fu_smbios_class_func(void) -{ - g_autofree gchar *path = g_test_build_filename(G_TEST_DIST, "tests", "dmi", "class", NULL); - g_autoptr(FuSmbios) smbios = fu_smbios_new(); - g_autoptr(GError) error = NULL; - gboolean ret; - const gchar *str; - guint8 byte; - - ret = fu_smbios_setup_from_kernel(smbios, path, &error); - g_assert_no_error(error); - g_assert_true(ret); - if (g_getenv("FWUPD_VERBOSE") != NULL) { - g_autofree gchar *dump = fu_firmware_to_string(FU_FIRMWARE(smbios)); - g_debug("%s", dump); - } - - str = fu_smbios_get_string(smbios, FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, 4, &error); - g_assert_no_error(error); - g_assert_cmpstr(str, ==, "FwupdTest"); - - byte = fu_smbios_get_integer(smbios, FU_SMBIOS_STRUCTURE_TYPE_CHASSIS, 5, &error); - g_assert_no_error(error); - g_assert_cmpuint(byte, ==, 16); + g_assert_cmpstr(fu_context_get_hwid_value(ctx, FU_HWIDS_KEY_MANUFACTURER), ==, "FwupdTest"); + g_assert_cmpuint(fu_context_get_chassis_kind(ctx), ==, 16); } static gboolean @@ -603,8 +558,7 @@ static void fu_hwids_func(void) { g_autofree gchar *testdatadir = NULL; - g_autoptr(FuHwids) hwids = NULL; - g_autoptr(FuSmbios) smbios = NULL; + g_autoptr(FuContext) context = NULL; g_autoptr(GError) error = NULL; gboolean ret; @@ -638,36 +592,42 @@ fu_hwids_func(void) testdatadir = g_test_build_filename(G_TEST_DIST, "tests", NULL); (void)g_setenv("FWUPD_SYSFSFWDIR", testdatadir, TRUE); - smbios = fu_smbios_new(); - ret = fu_smbios_setup(smbios, &error); + context = fu_context_new(); + ret = fu_context_load_hwinfo(context, FU_CONTEXT_HWID_FLAG_LOAD_SMBIOS, &error); g_assert_no_error(error); g_assert_true(ret); - hwids = fu_hwids_new(); - ret = fu_hwids_setup(hwids, smbios, &error); - g_assert_no_error(error); - g_assert_true(ret); - - g_assert_cmpstr(fu_hwids_get_value(hwids, FU_HWIDS_KEY_MANUFACTURER), ==, "LENOVO"); - g_assert_cmpstr(fu_hwids_get_value(hwids, FU_HWIDS_KEY_ENCLOSURE_KIND), ==, "a"); - g_assert_cmpstr(fu_hwids_get_value(hwids, FU_HWIDS_KEY_FAMILY), ==, "ThinkPad T440s"); - g_assert_cmpstr(fu_hwids_get_value(hwids, FU_HWIDS_KEY_PRODUCT_NAME), ==, "20ARS19C0C"); - g_assert_cmpstr(fu_hwids_get_value(hwids, FU_HWIDS_KEY_BIOS_VENDOR), ==, "LENOVO"); - g_assert_cmpstr(fu_hwids_get_value(hwids, FU_HWIDS_KEY_BIOS_VERSION), + g_assert_cmpstr(fu_context_get_hwid_value(context, FU_HWIDS_KEY_MANUFACTURER), + ==, + "LENOVO"); + g_assert_cmpstr(fu_context_get_hwid_value(context, FU_HWIDS_KEY_ENCLOSURE_KIND), ==, "a"); + g_assert_cmpstr(fu_context_get_hwid_value(context, FU_HWIDS_KEY_FAMILY), + ==, + "ThinkPad T440s"); + g_assert_cmpstr(fu_context_get_hwid_value(context, FU_HWIDS_KEY_PRODUCT_NAME), + ==, + "20ARS19C0C"); + g_assert_cmpstr(fu_context_get_hwid_value(context, FU_HWIDS_KEY_BIOS_VENDOR), ==, "LENOVO"); + g_assert_cmpstr(fu_context_get_hwid_value(context, FU_HWIDS_KEY_BIOS_VERSION), ==, "GJET75WW (2.25 )"); - g_assert_cmpstr(fu_hwids_get_value(hwids, FU_HWIDS_KEY_BIOS_MAJOR_RELEASE), ==, "02"); - g_assert_cmpstr(fu_hwids_get_value(hwids, FU_HWIDS_KEY_BIOS_MINOR_RELEASE), ==, "19"); - g_assert_cmpstr(fu_hwids_get_value(hwids, FU_HWIDS_KEY_PRODUCT_SKU), + g_assert_cmpstr(fu_context_get_hwid_value(context, FU_HWIDS_KEY_BIOS_MAJOR_RELEASE), + ==, + "02"); + g_assert_cmpstr(fu_context_get_hwid_value(context, FU_HWIDS_KEY_BIOS_MINOR_RELEASE), + ==, + "19"); + g_assert_cmpstr(fu_context_get_hwid_value(context, FU_HWIDS_KEY_PRODUCT_SKU), ==, "LENOVO_MT_20AR_BU_Think_FM_ThinkPad T440s"); for (guint i = 0; guids[i].key != NULL; i++) { + FuHwids *hwids = fu_context_get_hwids(context); g_autofree gchar *guid = fu_hwids_get_guid(hwids, guids[i].key, &error); g_assert_no_error(error); g_assert_cmpstr(guid, ==, guids[i].value); } for (guint i = 0; guids[i].key != NULL; i++) - g_assert_true(fu_hwids_has_guid(hwids, guids[i].value)); + g_assert_true(fu_context_has_hwid_guid(context, guids[i].value)); } static void @@ -838,6 +798,47 @@ fu_plugin_delay_func(void) g_clear_object(&device_tmp); } +static void +fu_plugin_fdt_func(void) +{ + gboolean ret; + g_autofree gchar *compatible = NULL; + g_autoptr(FuContext) ctx = fu_context_new(); + g_autoptr(FuFirmware) fdt = NULL; + g_autoptr(FuFirmware) fdt_root = NULL; + g_autoptr(FuFirmware) fdt_tmp = fu_fdt_firmware_new(); + g_autoptr(GError) error = NULL; + g_autoptr(GFile) file = + g_file_new_for_path("/tmp/fwupd-self-test/var/lib/fwupd/system.dtb"); + + /* write file */ + ret = fu_firmware_build_from_xml( + FU_FIRMWARE(fdt_tmp), + "\n" + " \n" + " pine64,rockpro64-v2.1\n" + " \n" + "\n", + &error); + g_assert_no_error(error); + g_assert_true(ret); + ret = fu_firmware_write_file(FU_FIRMWARE(fdt_tmp), file, &error); + g_assert_no_error(error); + g_assert_true(ret); + + /* get compatible from the context */ + fdt = fu_context_get_fdt(ctx, &error); + g_assert_no_error(error); + g_assert_nonnull(fdt); + fdt_root = fu_firmware_get_image_by_id(fdt, NULL, &error); + g_assert_no_error(error); + g_assert_nonnull(fdt_root); + ret = fu_fdt_image_get_attr_str(FU_FDT_IMAGE(fdt_root), "compatible", &compatible, &error); + g_assert_no_error(error); + g_assert_true(ret); + g_assert_cmpstr(compatible, ==, "pine64,rockpro64-v2.1"); +} + static void fu_plugin_quirks_func(void) { @@ -3759,6 +3760,8 @@ main(int argc, char **argv) (void)g_setenv("FWUPD_LIBDIR_PKG", testdatadir, TRUE); (void)g_setenv("FWUPD_SYSCONFDIR", testdatadir, TRUE); (void)g_setenv("FWUPD_SYSFSFWATTRIBDIR", testdatadir, TRUE); + (void)g_setenv("FWUPD_SYSFSDMIDIR", testdatadir, TRUE); + (void)g_setenv("FWUPD_LOCALSTATEDIR", testdatadir, TRUE); (void)g_setenv("FWUPD_OFFLINE_TRIGGER", "/tmp/fwupd-self-test/system-update", TRUE); (void)g_setenv("FWUPD_LOCALSTATEDIR", "/tmp/fwupd-self-test/var", TRUE); (void)g_setenv("FWUPD_PROFILE", "1", TRUE); @@ -3780,6 +3783,7 @@ main(int argc, char **argv) fu_plugin_device_inhibit_children_func); g_test_add_func("/fwupd/plugin{delay}", fu_plugin_delay_func); g_test_add_func("/fwupd/plugin{quirks}", fu_plugin_quirks_func); + g_test_add_func("/fwupd/plugin{fdt}", fu_plugin_fdt_func); g_test_add_func("/fwupd/plugin{quirks-performance}", fu_plugin_quirks_performance_func); g_test_add_func("/fwupd/plugin{quirks-device}", fu_plugin_quirks_device_func); g_test_add_func("/fwupd/backend", fu_backend_func); @@ -3802,11 +3806,10 @@ main(int argc, char **argv) g_test_add_func("/fwupd/common{strsafe}", fu_strsafe_func); g_test_add_func("/fwupd/efivar", fu_efivar_func); g_test_add_func("/fwupd/hwids", fu_hwids_func); + g_test_add_func("/fwupd/context{flags}", fu_context_flags_func); + g_test_add_func("/fwupd/context{hwids-dmi}", fu_context_hwids_dmi_func); g_test_add_func("/fwupd/smbios", fu_smbios_func); g_test_add_func("/fwupd/smbios3", fu_smbios3_func); - g_test_add_func("/fwupd/smbios{dt}", fu_smbios_dt_func); - g_test_add_func("/fwupd/smbios{dt-fallback}", fu_smbios_dt_fallback_func); - g_test_add_func("/fwupd/smbios{class}", fu_smbios_class_func); g_test_add_func("/fwupd/firmware", fu_firmware_func); g_test_add_func("/fwupd/firmware{common}", fu_firmware_common_func); g_test_add_func("/fwupd/firmware{archive}", fu_firmware_archive_func); diff --git a/libfwupdplugin/fu-smbios-private.h b/libfwupdplugin/fu-smbios-private.h index 8e5cb2488..cd42ae052 100644 --- a/libfwupdplugin/fu-smbios-private.h +++ b/libfwupdplugin/fu-smbios-private.h @@ -18,7 +18,3 @@ gboolean fu_smbios_setup_from_file(FuSmbios *self, const gchar *filename, GError **error) G_GNUC_WARN_UNUSED_RESULT; -gboolean -fu_smbios_setup_from_kernel(FuSmbios *self, - const gchar *path, - GError **error) G_GNUC_WARN_UNUSED_RESULT; diff --git a/libfwupdplugin/fu-smbios.c b/libfwupdplugin/fu-smbios.c index f387aaeb3..229b3c7ca 100644 --- a/libfwupdplugin/fu-smbios.c +++ b/libfwupdplugin/fu-smbios.c @@ -20,7 +20,6 @@ #include "fu-byte-array.h" #include "fu-common.h" -#include "fu-kenv.h" #include "fu-mem.h" #include "fu-path.h" #include "fu-smbios-private.h" @@ -29,7 +28,7 @@ /** * FuSmbios: * - * Enumerate the SMBIOS data on the system, either using DMI or Device Tree. + * Enumerate the SMBIOS data on the system. * * See also: [class@FuHwids] */ @@ -81,274 +80,6 @@ typedef struct { G_DEFINE_TYPE(FuSmbios, fu_smbios, FU_TYPE_FIRMWARE) -static void -fu_smbios_set_integer(FuSmbios *self, guint8 type, guint8 offset, guint8 value) -{ - FuSmbiosItem *item = g_ptr_array_index(self->items, type); - for (guint i = item->buf->len; i < (guint)offset + 1; i++) - fu_byte_array_append_uint8(item->buf, 0x0); - item->buf->data[offset] = value; -} - -static void -fu_smbios_set_string(FuSmbios *self, guint8 type, guint8 offset, const gchar *buf, gssize bufsz) -{ - FuSmbiosItem *item = g_ptr_array_index(self->items, type); - - /* NUL terminated UTF-8 */ - if (bufsz < 0) - bufsz = strlen(buf); - - /* add value to string table */ - g_ptr_array_add(item->strings, g_strndup(buf, (gsize)bufsz)); - fu_smbios_set_integer(self, type, offset, item->strings->len); -} - -static gboolean -fu_smbios_convert_dt_string(FuSmbios *self, - guint8 type, - guint8 offset, - const gchar *path, - const gchar *subpath) -{ - gsize bufsz = 0; - g_autofree gchar *fn = g_build_filename(path, subpath, NULL); - g_autofree gchar *buf = NULL; - - /* not found */ - if (!g_file_get_contents(fn, &buf, &bufsz, NULL)) - return FALSE; - if (bufsz == 0) - return FALSE; - fu_smbios_set_string(self, type, offset, buf, (gssize)bufsz); - return TRUE; -} - -static gchar ** -fu_smbios_convert_dt_string_array(FuSmbios *self, const gchar *path, const gchar *subpath) -{ - gsize bufsz = 0; - g_autofree gchar *fn = g_build_filename(path, subpath, NULL); - g_autofree gchar *buf = NULL; - g_auto(GStrv) split = NULL; - - /* not found */ - if (!g_file_get_contents(fn, &buf, &bufsz, NULL)) - return NULL; - if (bufsz == 0) - return NULL; - - /* return only if valid */ - split = g_strsplit(buf, ",", -1); - if (g_strv_length(split) == 0) - return NULL; - - /* success */ - return g_steal_pointer(&split); -} - -#ifdef HAVE_KENV_H - -static gboolean -fu_smbios_convert_kenv_string(FuSmbios *self, - guint8 type, - guint8 offset, - const gchar *sminfo, - GError **error) -{ - g_autofree gchar *value = fu_kenv_get_string(sminfo, error); - if (value == NULL) - return FALSE; - fu_smbios_set_string(self, type, offset, value, -1); - return TRUE; -} - -static gboolean -fu_smbios_setup_from_kenv(FuSmbios *self, GError **error) -{ - gboolean is_valid = FALSE; - g_autoptr(GError) error_local = NULL; - - /* add all four faked structures */ - for (guint i = 0; i < FU_SMBIOS_STRUCTURE_TYPE_LAST; i++) { - FuSmbiosItem *item = g_new0(FuSmbiosItem, 1); - item->type = i; - item->buf = g_byte_array_new(); - item->strings = g_ptr_array_new_with_free_func(g_free); - g_ptr_array_add(self->items, item); - } - - /* DMI:Manufacturer */ - if (!fu_smbios_convert_kenv_string(self, - FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, - 0x04, - "smbios.bios.vendor", - &error_local)) { - g_debug("ignoring: %s", error_local->message); - g_clear_error(&error_local); - } else { - is_valid = TRUE; - } - - /* DMI:BiosVersion */ - if (!fu_smbios_convert_kenv_string(self, - FU_SMBIOS_STRUCTURE_TYPE_BIOS, - 0x05, - "smbios.bios.version", - &error_local)) { - g_debug("ignoring: %s", error_local->message); - g_clear_error(&error_local); - } else { - is_valid = TRUE; - } - - /* DMI:Family */ - if (!fu_smbios_convert_kenv_string(self, - FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, - 0x1a, - "smbios.system.family", - &error_local)) { - g_debug("ignoring: %s", error_local->message); - g_clear_error(&error_local); - } else { - is_valid = TRUE; - } - - /* DMI:ProductName */ - if (!fu_smbios_convert_kenv_string(self, - FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, - 0x05, - "smbios.planar.product", - &error_local)) { - g_debug("ignoring: %s", error_local->message); - g_clear_error(&error_local); - } else { - is_valid = TRUE; - } - - /* DMI:BaseboardManufacturer */ - if (!fu_smbios_convert_kenv_string(self, - FU_SMBIOS_STRUCTURE_TYPE_BASEBOARD, - 0x04, - "smbios.planar.maker", - &error_local)) { - g_debug("ignoring: %s", error_local->message); - g_clear_error(&error_local); - } else { - is_valid = TRUE; - } - - /* we got no data */ - if (!is_valid) { - g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_READ, "no SMBIOS information provided"); - return FALSE; - } - - /* success */ - return TRUE; -} -#endif - -static gboolean -fu_smbios_setup_from_path_dt(FuSmbios *self, const gchar *path, GError **error) -{ - gboolean has_family; - gboolean has_model; - gboolean has_vendor; - g_autofree gchar *fn_battery = NULL; - - /* add all four faked structures */ - for (guint i = 0; i < FU_SMBIOS_STRUCTURE_TYPE_LAST; i++) { - FuSmbiosItem *item = g_new0(FuSmbiosItem, 1); - item->type = i; - item->buf = g_byte_array_new(); - item->strings = g_ptr_array_new_with_free_func(g_free); - g_ptr_array_add(self->items, item); - } - - /* if it has a battery it is portable (probably a laptop) */ - fn_battery = g_build_filename(path, "battery", NULL); - if (g_file_test(fn_battery, G_FILE_TEST_EXISTS)) { - fu_smbios_set_integer(self, - FU_SMBIOS_STRUCTURE_TYPE_CHASSIS, - 0x05, - FU_SMBIOS_CHASSIS_KIND_PORTABLE); - } - - /* DMI:Manufacturer */ - has_vendor = fu_smbios_convert_dt_string(self, - FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, - 0x04, - path, - "vendor"); - - /* DMI:Family */ - has_family = fu_smbios_convert_dt_string(self, - FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, - 0x1a, - path, - "model-name"); - - /* DMI:ProductName */ - has_model = - fu_smbios_convert_dt_string(self, FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, 0x05, path, "model"); - - /* fall back to the first compatible string if required */ - if (!has_vendor || !has_model || !has_family) { - g_auto(GStrv) parts = NULL; - - /* NULL if invalid, otherwise we're sure this has size of exactly 3 */ - parts = fu_smbios_convert_dt_string_array(self, path, "compatible"); - if (parts != NULL) { - if (!has_vendor && g_strv_length(parts) > 0) { - fu_smbios_set_string(self, - FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, - 0x4, - parts[0], - -1); - } - if (!has_model && g_strv_length(parts) > 1) { - fu_smbios_set_string(self, - FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, - 0x05, - parts[1], - -1); - } - if (!has_family && g_strv_length(parts) > 2) { - fu_smbios_set_string(self, - FU_SMBIOS_STRUCTURE_TYPE_SYSTEM, - 0x1a, - parts[2], - -1); - } - } - } - - /* DMI:BiosVersion */ - fu_smbios_convert_dt_string(self, - FU_SMBIOS_STRUCTURE_TYPE_BIOS, - 0x05, - path, - "ibm,firmware-versions/version"); - - /* DMI:BaseboardManufacturer */ - fu_smbios_convert_dt_string(self, - FU_SMBIOS_STRUCTURE_TYPE_BASEBOARD, - 0x04, - path, - "vpd/root-node-vpd@a000/enclosure@1e00/backplane@800/vendor"); - - /* DMI:BaseboardProduct */ - fu_smbios_convert_dt_string( - self, - FU_SMBIOS_STRUCTURE_TYPE_BASEBOARD, - 0x05, - path, - "vpd/root-node-vpd@a000/enclosure@1e00/backplane@800/part-number"); - - return TRUE; -} - static gboolean fu_smbios_setup_from_data(FuSmbios *self, const guint8 *buf, gsize sz, GError **error) { @@ -425,172 +156,17 @@ fu_smbios_setup_from_file(FuSmbios *self, const gchar *filename, GError **error) { gsize sz = 0; g_autofree gchar *buf = NULL; - g_autofree gchar *basename = NULL; g_return_val_if_fail(FU_IS_SMBIOS(self), FALSE); g_return_val_if_fail(filename != NULL, FALSE); g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - /* use a heuristic */ - basename = g_path_get_basename(filename); - if (g_strcmp0(basename, "base") == 0) - return fu_smbios_setup_from_path_dt(self, filename, error); - /* DMI blob */ if (!g_file_get_contents(filename, &buf, &sz, error)) return FALSE; return fu_smbios_setup_from_data(self, (guint8 *)buf, sz, error); } -static gboolean -fu_smbios_encode_string_from_kernel(FuSmbios *self, - const gchar *file_contents, - guint8 type, - guint8 offset, - GError **error) -{ - fu_smbios_set_string(self, type, offset, file_contents, -1); - return TRUE; -} - -static gboolean -fu_smbios_encode_byte_from_kernel(FuSmbios *self, - const gchar *file_contents, - guint8 type, - guint8 offset, - GError **error) -{ - gchar *endp; - gint64 value = g_ascii_strtoll(file_contents, &endp, 10); - - if (*endp != 0) { - g_set_error(error, - FWUPD_ERROR, - FWUPD_ERROR_NOT_SUPPORTED, - "non-numeric values in numeric string: %s", - endp); - return FALSE; - } - if (value < 0 || value > G_MAXUINT8) { - g_set_error(error, - FWUPD_ERROR, - FWUPD_ERROR_NOT_SUPPORTED, - "value \"%s\" is not representable in a byte", - file_contents); - return FALSE; - } - - fu_smbios_set_integer(self, type, offset, value); - return TRUE; -} - -/* - * The mapping from SMBIOS field to sysfs name can be found by mapping - * the field to a kernel property name in dmi_decode() - * (drivers/firmware/dmi_scan.c), then the property name to sysfs entry - * in dmi_id_init_attr_table() (drivers/firmware/dmi-id.c). This table - * lists each attribute exposed in /sys/class/dmi when CONFIG_DMIID is - * enabled, mapping to the SMBIOS field and a function that can convert - * the textual version of the field back into the raw SMBIOS table - * representation. - */ -#define SYSFS_DMI_FIELD(_name, _type, offset_ignored, kind) \ - { \ - .name = _name, .type = _type, .offset = offset_ignored, \ - .encode = fu_smbios_encode_##kind##_from_kernel \ - } -const struct kernel_dmi_field { - const gchar *name; - gboolean (*encode)(FuSmbios *, const gchar *, guint8, guint8, GError **); - guint8 type; - guint8 offset; -} KERNEL_DMI_FIELDS[] = { - SYSFS_DMI_FIELD("bios_vendor", 0, 4, string), - SYSFS_DMI_FIELD("bios_version", 0, 5, string), - SYSFS_DMI_FIELD("bios_date", 0, 8, string), - SYSFS_DMI_FIELD("sys_vendor", 1, 4, string), - SYSFS_DMI_FIELD("product_name", 1, 5, string), - SYSFS_DMI_FIELD("product_version", 1, 6, string), - SYSFS_DMI_FIELD("product_serial", 1, 7, string), - /* SYSFS_DMI_FIELD("product_uuid", 1, 8, uuid) */ - SYSFS_DMI_FIELD("product_family", 1, 26, string), - SYSFS_DMI_FIELD("product_sku", 1, 25, string), - SYSFS_DMI_FIELD("board_vendor", 2, 4, string), - SYSFS_DMI_FIELD("board_name", 2, 5, string), - SYSFS_DMI_FIELD("board_version", 2, 6, string), - SYSFS_DMI_FIELD("board_serial", 2, 7, string), - SYSFS_DMI_FIELD("board_asset_tag", 2, 8, string), - SYSFS_DMI_FIELD("chassis_vendor", 3, 4, string), - SYSFS_DMI_FIELD("chassis_type", 3, 5, byte), - SYSFS_DMI_FIELD("chassis_version", 3, 6, string), - SYSFS_DMI_FIELD("chassis_serial", 3, 7, string), - SYSFS_DMI_FIELD("chassis_asset_tag", 3, 8, string), -}; - -/** - * fu_smbios_setup_from_kernel: - * @self: a #FuSmbios - * @path: a directory path - * @error: (nullable): optional return location for an error - * - * Reads SMBIOS value from DMI values provided by the kernel, such as in - * /sys/class/dmi on Linux. - * - * Returns: %TRUE for success - * - * Since: 1.6.2 - **/ -gboolean -fu_smbios_setup_from_kernel(FuSmbios *self, const gchar *path, GError **error) -{ - gboolean any_success = FALSE; - - /* add fake structures */ - for (guint i = 0; i < FU_SMBIOS_STRUCTURE_TYPE_LAST; i++) { - FuSmbiosItem *item = g_new0(FuSmbiosItem, 1); - item->type = i; - item->buf = g_byte_array_new(); - item->strings = g_ptr_array_new_with_free_func(g_free); - g_ptr_array_add(self->items, item); - } - - /* parse every known field from the corresponding file */ - for (gsize i = 0; i < G_N_ELEMENTS(KERNEL_DMI_FIELDS); i++) { - const struct kernel_dmi_field *field = &KERNEL_DMI_FIELDS[i]; - gsize bufsz = 0; - g_autofree gchar *buf = NULL; - g_autofree gchar *fn = g_build_filename(path, field->name, NULL); - g_autoptr(GError) local_error = NULL; - - if (!g_file_get_contents(fn, &buf, &bufsz, &local_error)) { - g_debug("unable to read SMBIOS data from %s: %s", fn, local_error->message); - continue; - } - - /* trim trailing newline added by kernel */ - if (buf[bufsz - 1] == '\n') - buf[bufsz - 1] = 0; - - if (!field->encode(self, buf, field->type, field->offset, &local_error)) { - g_warning("failed to parse SMBIOS data from %s: %s", - fn, - local_error->message); - continue; - } - - any_success = TRUE; - } - if (!any_success) { - g_set_error(error, - FWUPD_ERROR, - FWUPD_ERROR_NOT_SUPPORTED, - "failed to read any SMBIOS values from %s", - path); - return FALSE; - } - return TRUE; -} - static gboolean fu_smbios_parse_ep32(FuSmbios *self, const gchar *buf, gsize sz, GError **error) { @@ -685,8 +261,20 @@ fu_smbios_parse_ep64(FuSmbios *self, const gchar *buf, gsize sz, GError **error) return TRUE; } -static gboolean -fu_smbios_setup_from_path_dmi(FuSmbios *self, const gchar *path, GError **error) +/** + * fu_smbios_setup_from_path: + * @self: a #FuSmbios + * @path: a path, e.g. `/sys/firmware/dmi/tables` + * @error: (nullable): optional return location for an error + * + * Reads all the SMBIOS values from a specific path. + * + * Returns: %TRUE for success + * + * Since: 1.0.0 + **/ +gboolean +fu_smbios_setup_from_path(FuSmbios *self, const gchar *path, GError **error) { gsize sz = 0; g_autofree gchar *dmi_fn = NULL; @@ -695,6 +283,8 @@ fu_smbios_setup_from_path_dmi(FuSmbios *self, const gchar *path, GError **error) g_autofree gchar *ep_raw = NULL; g_return_val_if_fail(FU_IS_SMBIOS(self), FALSE); + g_return_val_if_fail(path != NULL, FALSE); + g_return_val_if_fail(error == NULL || *error == NULL, FALSE); /* get the smbios entry point */ ep_fn = g_build_filename(path, "smbios_entry_point", NULL); @@ -763,34 +353,6 @@ fu_smbios_parse(FuFirmware *firmware, return fu_smbios_setup_from_data(self, buf, bufsz, error); } -/** - * fu_smbios_setup_from_path: - * @self: a #FuSmbios - * @path: a path, e.g. `/sys/firmware/dmi/tables` - * @error: (nullable): optional return location for an error - * - * Reads all the SMBIOS values from a specific path. - * - * Returns: %TRUE for success - * - * Since: 1.0.0 - **/ -gboolean -fu_smbios_setup_from_path(FuSmbios *self, const gchar *path, GError **error) -{ - g_autofree gchar *basename = NULL; - - g_return_val_if_fail(FU_IS_SMBIOS(self), FALSE); - g_return_val_if_fail(path != NULL, FALSE); - g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - - /* use a heuristic */ - basename = g_path_get_basename(path); - if (g_strcmp0(basename, "base") == 0) - return fu_smbios_setup_from_path_dt(self, path, error); - return fu_smbios_setup_from_path_dmi(self, path, error); -} - #ifdef _WIN32 #define FU_SMBIOS_FT_SIG_ACPI 0x41435049 #define FU_SMBIOS_FT_SIG_FIRM 0x4649524D @@ -850,51 +412,33 @@ fu_smbios_setup(FuSmbios *self, GError **error) error); #else g_autofree gchar *path = NULL; - g_autofree gchar *path_dt = NULL; g_autofree gchar *sysfsfwdir = NULL; - const gchar *path_dmi_class = "/sys/class/dmi/id"; + g_autoptr(GError) error_local = NULL; g_return_val_if_fail(FU_IS_SMBIOS(self), FALSE); g_return_val_if_fail(error == NULL || *error == NULL, FALSE); - sysfsfwdir = fu_path_from_kind(FU_PATH_KIND_SYSFSDIR_FW); - /* DMI */ + sysfsfwdir = fu_path_from_kind(FU_PATH_KIND_SYSFSDIR_FW); path = g_build_filename(sysfsfwdir, "dmi", "tables", NULL); - if (g_file_test(path, G_FILE_TEST_EXISTS)) { - g_autoptr(GError) error_local = NULL; - if (!fu_smbios_setup_from_path(self, path, &error_local)) { - if (!g_error_matches(error_local, G_FILE_ERROR, G_FILE_ERROR_ACCES)) { - g_propagate_error(error, g_steal_pointer(&error_local)); - return FALSE; - } - g_debug("ignoring %s", error_local->message); - } else - return TRUE; - } - - /* the values the kernel parsed; these are world-readable */ - if (g_file_test(path_dmi_class, G_FILE_TEST_IS_DIR)) { - g_debug("trying to read %s", path_dmi_class); - return fu_smbios_setup_from_kernel(self, path_dmi_class, error); - } - - /* DT */ - path_dt = g_build_filename(sysfsfwdir, "devicetree", "base", NULL); - if (g_file_test(path_dt, G_FILE_TEST_EXISTS)) - return fu_smbios_setup_from_path(self, path_dt, error); - -#ifdef HAVE_KENV_H - /* kenv */ - return fu_smbios_setup_from_kenv(self, error); -#endif - - /* neither found */ - g_set_error_literal(error, + if (!g_file_test(path, G_FILE_TEST_EXISTS)) { + g_set_error(error, FWUPD_ERROR, - FWUPD_ERROR_INVALID_FILE, - "neither SMBIOS or DT found"); - return FALSE; + FWUPD_ERROR_NOT_SUPPORTED, + "SMBIOS tables not found at %s", + path); + return FALSE; + } + if (!fu_smbios_setup_from_path(self, path, &error_local)) { + if (!g_error_matches(error_local, G_FILE_ERROR, G_FILE_ERROR_ACCES)) { + g_propagate_error(error, g_steal_pointer(&error_local)); + return FALSE; + } + g_debug("ignoring %s", error_local->message); + } + + /* success */ + return TRUE; #endif } diff --git a/libfwupdplugin/fu-udev-device.h b/libfwupdplugin/fu-udev-device.h index 5c78aeff1..05cf1ecb5 100644 --- a/libfwupdplugin/fu-udev-device.h +++ b/libfwupdplugin/fu-udev-device.h @@ -27,7 +27,6 @@ G_DECLARE_DERIVABLE_TYPE(FuUdevDevice, fu_udev_device, FU, UDEV_DEVICE, FuDevice struct _FuUdevDeviceClass { FuDeviceClass parent_class; - gpointer __reserved[31]; }; /** diff --git a/libfwupdplugin/fu-usb-device.h b/libfwupdplugin/fu-usb-device.h index e56489a2f..38b3e144c 100644 --- a/libfwupdplugin/fu-usb-device.h +++ b/libfwupdplugin/fu-usb-device.h @@ -24,7 +24,6 @@ G_DECLARE_DERIVABLE_TYPE(FuUsbDevice, fu_usb_device, FU, USB_DEVICE, FuDevice) struct _FuUsbDeviceClass { FuDeviceClass parent_class; - gpointer __reserved[31]; }; FuUsbDevice * diff --git a/libfwupdplugin/fu-uswid-firmware.c b/libfwupdplugin/fu-uswid-firmware.c index c0d2948af..c77992b56 100644 --- a/libfwupdplugin/fu-uswid-firmware.c +++ b/libfwupdplugin/fu-uswid-firmware.c @@ -319,6 +319,7 @@ fu_uswid_firmware_init(FuUswidFirmware *self) priv->hdrver = USWID_HEADER_VERSION_V1; priv->compressed = FALSE; fu_firmware_add_flag(FU_FIRMWARE(self), FU_FIRMWARE_FLAG_HAS_STORED_SIZE); + fu_firmware_add_flag(FU_FIRMWARE(self), FU_FIRMWARE_FLAG_ALWAYS_SEARCH); } static void diff --git a/libfwupdplugin/fu-volume.c b/libfwupdplugin/fu-volume.c index a6c4e4b0c..80b154b61 100644 --- a/libfwupdplugin/fu-volume.c +++ b/libfwupdplugin/fu-volume.c @@ -725,6 +725,10 @@ fu_volume_new_esp_for_path(const gchar *esp_path, GError **error) if (g_strcmp0(basename, vol_basename) == 0) return g_object_ref(vol); } + if (g_file_test(esp_path, G_FILE_TEST_IS_DIR)) { + g_debug("Using user requested path %s for ESP", esp_path); + return fu_volume_new_from_mount_path(esp_path); + } g_set_error(error, G_IO_ERROR, G_IO_ERROR_INVALID_FILENAME, diff --git a/libfwupdplugin/fwupdplugin.h b/libfwupdplugin/fwupdplugin.h index 9a8074853..721810d3e 100644 --- a/libfwupdplugin/fwupdplugin.h +++ b/libfwupdplugin/fwupdplugin.h @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -61,11 +62,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include diff --git a/libfwupdplugin/fwupdplugin.map b/libfwupdplugin/fwupdplugin.map index 46f2f991e..f18158527 100644 --- a/libfwupdplugin/fwupdplugin.map +++ b/libfwupdplugin/fwupdplugin.map @@ -63,8 +63,6 @@ LIBFWUPDPLUGIN_0.9.3 { fu_hwids_get_type; fu_hwids_get_value; fu_hwids_has_guid; - fu_hwids_new; - fu_hwids_setup; local: *; } LIBFWUPDPLUGIN_0.8.0; @@ -540,7 +538,6 @@ LIBFWUPDPLUGIN_1.5.6 { fu_firmware_strparse_uint32_safe; fu_firmware_strparse_uint4_safe; fu_firmware_strparse_uint8_safe; - fu_hwids_add_smbios_override; fu_hwids_get_keys; fu_plugin_get_devices; fu_plugin_runner_backend_device_added; @@ -603,7 +600,6 @@ LIBFWUPDPLUGIN_1.6.0 { fu_context_get_type; fu_context_get_udev_subsystems; fu_context_has_hwid_guid; - fu_context_load_hwinfo; fu_context_load_quirks; fu_context_lookup_quirk_by_id; fu_context_lookup_quirk_by_id_iter; @@ -720,7 +716,6 @@ LIBFWUPDPLUGIN_1.6.2 { fu_ifd_region_to_name; fu_ifd_region_to_string; fu_plugin_add_udev_subsystem; - fu_smbios_setup_from_kernel; fu_udev_device_get_children_with_subsystem; fu_udev_device_set_dev; local: *; @@ -1151,3 +1146,19 @@ LIBFWUPDPLUGIN_1.8.9 { fu_version_from_uint24; local: *; } LIBFWUPDPLUGIN_1.8.7; + +LIBFWUPDPLUGIN_1.8.10 { + global: + fu_context_get_chassis_kind; + fu_context_get_fdt; + fu_context_get_hwids; + fu_context_get_smbios; + fu_context_load_hwinfo; + fu_context_remove_flag; + fu_context_set_chassis_kind; + fu_hwids_add_guid; + fu_hwids_add_value; + fu_pefile_firmware_get_type; + fu_pefile_firmware_new; + local: *; +} LIBFWUPDPLUGIN_1.8.9; diff --git a/libfwupdplugin/meson.build b/libfwupdplugin/meson.build index db6b234a1..ac8c15ea5 100644 --- a/libfwupdplugin/meson.build +++ b/libfwupdplugin/meson.build @@ -48,6 +48,11 @@ fwupdplugin_src = [ 'fu-dfuse-firmware.c', # fuzzing 'fu-fmap-firmware.c', # fuzzing 'fu-hwids.c', # fuzzing + 'fu-hwids-config.c', # fuzzing + 'fu-hwids-dmi.c', # fuzzing + 'fu-hwids-fdt.c', # fuzzing + 'fu-hwids-kenv.c', # fuzzing + 'fu-hwids-smbios.c', # fuzzing 'fu-ihex-firmware.c', # fuzzing 'fu-io-channel.c', # fuzzing 'fu-plugin.c', @@ -74,6 +79,7 @@ fwupdplugin_src = [ 'fu-uswid-firmware.c', # fuzzing 'fu-coswid-common.c', # fuzzing 'fu-coswid-firmware.c', # fuzzing + 'fu-pefile-firmware.c', # fuzzing 'fu-efivar.c', 'fu-udev-device.c', 'fu-i2c-device.c', @@ -149,6 +155,7 @@ fwupdplugin_headers = [ 'fu-ifd-firmware.h', 'fu-uswid-firmware.h', 'fu-coswid-firmware.h', + 'fu-pefile-firmware.h', 'fu-ifd-image.h', 'fu-linear-firmware.h', 'fu-volume.h', @@ -359,6 +366,25 @@ if get_option('tests') ], ) test('fwupdplugin-self-test', e, is_parallel: false, timeout: 180, env: env) + + install_data([ + 'tests/chassis_type', + 'tests/sys_vendor', + ], + install_dir: installed_test_datadir, + ) + install_data([ + 'tests/dmi/tables/DMI', + 'tests/dmi/tables/smbios_entry_point', + ], + install_dir: join_paths(installed_test_datadir, 'tests/dmi/tables'), + ) + install_data([ + 'tests/dmi/tables64/DMI', + 'tests/dmi/tables64/smbios_entry_point', + ], + install_dir: join_paths(installed_test_datadir, 'tests/dmi/tables64'), + ) endif fwupdplugin_incdir = include_directories('.') diff --git a/libfwupdplugin/tests/dmi/class/chassis_type b/libfwupdplugin/tests/chassis_type similarity index 100% rename from libfwupdplugin/tests/dmi/class/chassis_type rename to libfwupdplugin/tests/chassis_type diff --git a/libfwupdplugin/tests/devicetree-fallback/base/compatible b/libfwupdplugin/tests/devicetree-fallback/base/compatible deleted file mode 120000 index abcb73dbb..000000000 --- a/libfwupdplugin/tests/devicetree-fallback/base/compatible +++ /dev/null @@ -1 +0,0 @@ -../../devicetree/base/compatible \ No newline at end of file diff --git a/libfwupdplugin/tests/devicetree/base/compatible b/libfwupdplugin/tests/devicetree/base/compatible deleted file mode 100644 index 33529460d..000000000 Binary files a/libfwupdplugin/tests/devicetree/base/compatible and /dev/null differ diff --git a/libfwupdplugin/tests/devicetree/base/ibm,firmware-versions/version b/libfwupdplugin/tests/devicetree/base/ibm,firmware-versions/version deleted file mode 100644 index 94b2bd66d..000000000 --- a/libfwupdplugin/tests/devicetree/base/ibm,firmware-versions/version +++ /dev/null @@ -1 +0,0 @@ -1.2.3-4 \ No newline at end of file diff --git a/libfwupdplugin/tests/devicetree/base/model b/libfwupdplugin/tests/devicetree/base/model deleted file mode 100644 index 86c8a128b..000000000 --- a/libfwupdplugin/tests/devicetree/base/model +++ /dev/null @@ -1 +0,0 @@ -ColorHug \ No newline at end of file diff --git a/libfwupdplugin/tests/devicetree/base/model-name b/libfwupdplugin/tests/devicetree/base/model-name deleted file mode 100644 index 9d37fc1ac..000000000 --- a/libfwupdplugin/tests/devicetree/base/model-name +++ /dev/null @@ -1 +0,0 @@ -To Be Filled By O.E.M. \ No newline at end of file diff --git a/libfwupdplugin/tests/devicetree/base/name b/libfwupdplugin/tests/devicetree/base/name deleted file mode 100644 index f76dd238a..000000000 Binary files a/libfwupdplugin/tests/devicetree/base/name and /dev/null differ diff --git a/libfwupdplugin/tests/devicetree/base/vendor b/libfwupdplugin/tests/devicetree/base/vendor deleted file mode 100644 index 1555d1a5c..000000000 --- a/libfwupdplugin/tests/devicetree/base/vendor +++ /dev/null @@ -1 +0,0 @@ -Hughski Limited \ No newline at end of file diff --git a/libfwupdplugin/tests/devicetree/base/vpd/name b/libfwupdplugin/tests/devicetree/base/vpd/name deleted file mode 100644 index b8acbc9ee..000000000 Binary files a/libfwupdplugin/tests/devicetree/base/vpd/name and /dev/null differ diff --git a/libfwupdplugin/tests/devicetree/base/vpd/root-node-vpd@a000/enclosure@1e00/backplane@800/name b/libfwupdplugin/tests/devicetree/base/vpd/root-node-vpd@a000/enclosure@1e00/backplane@800/name deleted file mode 100644 index 1f22cb8d6..000000000 Binary files a/libfwupdplugin/tests/devicetree/base/vpd/root-node-vpd@a000/enclosure@1e00/backplane@800/name and /dev/null differ diff --git a/libfwupdplugin/tests/devicetree/base/vpd/root-node-vpd@a000/enclosure@1e00/backplane@800/part-number b/libfwupdplugin/tests/devicetree/base/vpd/root-node-vpd@a000/enclosure@1e00/backplane@800/part-number deleted file mode 100644 index e00c9e144..000000000 --- a/libfwupdplugin/tests/devicetree/base/vpd/root-node-vpd@a000/enclosure@1e00/backplane@800/part-number +++ /dev/null @@ -1 +0,0 @@ -PCB-CH001 \ No newline at end of file diff --git a/libfwupdplugin/tests/devicetree/base/vpd/root-node-vpd@a000/enclosure@1e00/backplane@800/vendor b/libfwupdplugin/tests/devicetree/base/vpd/root-node-vpd@a000/enclosure@1e00/backplane@800/vendor deleted file mode 100644 index ffbb9e015..000000000 --- a/libfwupdplugin/tests/devicetree/base/vpd/root-node-vpd@a000/enclosure@1e00/backplane@800/vendor +++ /dev/null @@ -1 +0,0 @@ -Richard Hughes \ No newline at end of file diff --git a/libfwupdplugin/tests/devicetree/base/vpd/root-node-vpd@a000/enclosure@1e00/name b/libfwupdplugin/tests/devicetree/base/vpd/root-node-vpd@a000/enclosure@1e00/name deleted file mode 100644 index 88600030b..000000000 Binary files a/libfwupdplugin/tests/devicetree/base/vpd/root-node-vpd@a000/enclosure@1e00/name and /dev/null differ diff --git a/libfwupdplugin/tests/devicetree/base/vpd/root-node-vpd@a000/name b/libfwupdplugin/tests/devicetree/base/vpd/root-node-vpd@a000/name deleted file mode 100644 index c6f7bd989..000000000 Binary files a/libfwupdplugin/tests/devicetree/base/vpd/root-node-vpd@a000/name and /dev/null differ diff --git a/libfwupdplugin/tests/dmi/class/sys_vendor b/libfwupdplugin/tests/sys_vendor similarity index 100% rename from libfwupdplugin/tests/dmi/class/sys_vendor rename to libfwupdplugin/tests/sys_vendor diff --git a/meson.build b/meson.build index 032fd7e11..9ae278b66 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project('fwupd', 'c', - version: '1.8.9', + version: '1.8.10', license: 'LGPL-2.1+', meson_version: '>=0.61.0', default_options: ['warning_level=2', 'c_std=c11'], @@ -219,7 +219,7 @@ hsi = get_option('hsi').disable_auto_if(host_machine.system() != 'linux').disabl if hsi conf.set('HAVE_HSI', '1') endif -libxmlb = dependency('xmlb', version: '>= 0.1.13', fallback: ['libxmlb', 'libxmlb_dep']) +libxmlb = dependency('xmlb', version: '>= 0.1.15', fallback: ['libxmlb', 'libxmlb_dep']) gusb = dependency('gusb', version: '>= 0.3.0', fallback: ['gusb', 'gusb_dep'], required: get_option('gusb')) if gusb.found() conf.set('HAVE_GUSB', '1') @@ -267,8 +267,13 @@ if build_daemon endif libm = cc.find_library('m', required: false) libgcab = dependency('libgcab-1.0', version: '>= 1.0', fallback: ['gcab', 'gcab_dep']) -if libgcab.type_name() == 'pkgconfig' and cc.has_function('gcab_file_set_bytes', dependencies: libgcab) - conf.set('HAVE_GCAB_FILE_SET_BYTES', '1') +if libgcab.type_name() == 'pkgconfig' + if cc.has_function('gcab_file_set_bytes', dependencies: libgcab) + conf.set('HAVE_GCAB_FILE_SET_BYTES', '1') + endif + if cc.has_function('gcab_cabinet_add_allowed_compression', dependencies: libgcab) + conf.set('HAVE_GCAB_CABINET_ADD_ALLOWED_COMPRESSION', '1') + endif endif bashcomp = dependency('bash-completion', required: false) @@ -608,7 +613,7 @@ custom_target('builtin-quirk-gz', install_dir: join_paths(datadir, 'fwupd', 'quirks.d'), ) -if build_daemon and libsystemd.found() +if build_daemon and libsystemd.found() and offline.allowed() install_symlink('fwupd-offline-update.service', install_dir: join_paths(systemdunitdir, 'system-update.target.wants'), pointing_to: join_paths('..', 'fwupd-offline-update.service') diff --git a/plugins/acpi-dmar/README.md b/plugins/acpi-dmar/README.md index f4c606c89..f2d40b289 100644 --- a/plugins/acpi-dmar/README.md +++ b/plugins/acpi-dmar/README.md @@ -1,4 +1,6 @@ -# DMA Protection +--- +title: Plugin: ACPI DMAR — DMA Protection +--- ## Introduction diff --git a/plugins/acpi-facp/README.md b/plugins/acpi-facp/README.md index 59a56ea0d..19820c31f 100644 --- a/plugins/acpi-facp/README.md +++ b/plugins/acpi-facp/README.md @@ -1,4 +1,6 @@ -# ACPI FACP +--- +title: Plugin: ACPI FACP — Fixed ACPI Description Table +--- ## Introduction diff --git a/plugins/acpi-ivrs/README.md b/plugins/acpi-ivrs/README.md index d0fba374a..303cb214b 100644 --- a/plugins/acpi-ivrs/README.md +++ b/plugins/acpi-ivrs/README.md @@ -1,4 +1,6 @@ -# DMA Protection +--- +title: Plugin: ACPI IVRS — DMA Protection +--- ## Introduction diff --git a/plugins/acpi-phat/README.md b/plugins/acpi-phat/README.md index 75c9f2aae..42a160126 100644 --- a/plugins/acpi-phat/README.md +++ b/plugins/acpi-phat/README.md @@ -1,4 +1,6 @@ -# Platform Health Assessment Table +--- +title: Plugin: ACPI PHAT — Platform Health Assessment Table +--- ## Introduction diff --git a/plugins/amd-pmc/README.md b/plugins/amd-pmc/README.md index 7ed53d3cb..f60e67d29 100644 --- a/plugins/amd-pmc/README.md +++ b/plugins/amd-pmc/README.md @@ -1,4 +1,6 @@ -# AMD PMC +--- +title: Plugin: AMD PMC +--- ## Introduction diff --git a/plugins/analogix/README.md b/plugins/analogix/README.md index 9b5cff988..0d38deb13 100644 --- a/plugins/analogix/README.md +++ b/plugins/analogix/README.md @@ -1,4 +1,6 @@ -# Analogix +--- +title: Plugin: Analogix +--- ## Introduction @@ -15,7 +17,7 @@ a Intel Hex file format. The resulting binary image is either: This plugin supports the following protocol ID: -* com.analogix.bb +* `com.analogix.bb` ## GUID Generation diff --git a/plugins/android-boot/README.md b/plugins/android-boot/README.md index 12c8262d2..6287ccdad 100644 --- a/plugins/android-boot/README.md +++ b/plugins/android-boot/README.md @@ -1,4 +1,6 @@ -# Android Bootloaders +--- +title: Plugin: Android Boot +--- ## Introduction @@ -13,7 +15,7 @@ to flash from the device itself rather than external device. This plugin supports the following protocol ID: -* com.google.android_boot +* `com.google.android_boot` ## GUID Generation diff --git a/plugins/ata/README.md b/plugins/ata/README.md index a459dfccc..dfb8c7c89 100644 --- a/plugins/ata/README.md +++ b/plugins/ata/README.md @@ -1,4 +1,6 @@ -# ATA +--- +title: Plugin: ATA +--- ## Introduction @@ -18,7 +20,7 @@ an unspecified binary file format. This plugin supports the following protocol ID: -* org.t13.ata +* `org.t13.ata` ## GUID Generation diff --git a/plugins/bcm57xx/README.md b/plugins/bcm57xx/README.md index e5639fb24..195ffaa49 100644 --- a/plugins/bcm57xx/README.md +++ b/plugins/bcm57xx/README.md @@ -1,4 +1,6 @@ -# BCM57xx +--- +title: Plugin: BCM57xx +--- ## Introduction diff --git a/plugins/bios/README.md b/plugins/bios/README.md new file mode 100644 index 000000000..7df46696f --- /dev/null +++ b/plugins/bios/README.md @@ -0,0 +1,11 @@ +--- +title: Plugin: BIOS +--- + +## Introduction + +This plugin checks UEFI capsules are available, and if missing a HSI failure is reported. + +## External Interface Access + +This plugin requires read only access to attributes located within `/sys/firmware/efi/esrt`. diff --git a/plugins/ccgx/README.md b/plugins/ccgx/README.md index 3c6070d41..6079161a3 100644 --- a/plugins/ccgx/README.md +++ b/plugins/ccgx/README.md @@ -1,4 +1,6 @@ -# Infineon Technologies +--- +title: Plugin: CCGX +--- ## Introduction @@ -9,10 +11,10 @@ controller family of devices used in docks. This plugin supports the following protocol IDs: -* com.cypress.ccgx -* com.cypress.ccgx.dmc -* com.infineon.ccgx -* com.infineon.ccgx.dmc +* `com.cypress.ccgx` (deprecated) +* `com.cypress.ccgx.dmc` (deprecated) +* `com.infineon.ccgx` +* `com.infineon.ccgx.dmc` ## Device Flash @@ -101,7 +103,7 @@ The vendor ID is set from the USB vendor, for example set to `USB:0x04B4` This plugin uses the following plugin-specific quirks: -### Trigger Code +### CcgxDmcTriggerCode DMC devices need a specified trigger code to request the device to update the firmware and the trigger code depends on the devices. diff --git a/plugins/cfu/README.md b/plugins/cfu/README.md index 53446267b..bbb51f834 100644 --- a/plugins/cfu/README.md +++ b/plugins/cfu/README.md @@ -1,4 +1,6 @@ -# Component Firmware update +--- +title: Plugin: CFU - Component Firmware Update +--- ## Introduction @@ -13,7 +15,7 @@ details. This plugin supports the following protocol ID: -* com.microsoft.cfu +* `com.microsoft.cfu` ## GUID Generation diff --git a/plugins/ch341a/README.md b/plugins/ch341a/README.md index 9b873feee..07216ea75 100644 --- a/plugins/ch341a/README.md +++ b/plugins/ch341a/README.md @@ -1,4 +1,6 @@ -# CH341A +--- +title: Plugin: CH341A +--- ## Introduction @@ -22,7 +24,7 @@ The daemon will decompress the cabinet archive and extract a firmware blob of un This plugin supports the following protocol ID: -- com.winchiphead.ch341a +- `com.winchiphead.ch341a` ## GUID Generation diff --git a/plugins/ch341a/fu-ch341a-cfi-device.c b/plugins/ch341a/fu-ch341a-cfi-device.c index d22653374..da4477626 100644 --- a/plugins/ch341a/fu-ch341a-cfi-device.c +++ b/plugins/ch341a/fu-ch341a-cfi-device.c @@ -106,14 +106,17 @@ fu_ch341a_cfi_device_read_jedec(FuCh341aCfiDevice *self, GError **error) g_set_error_literal(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, - "flash ID non-valid"); + "flash ID non-valid, got 0x000000"); return FALSE; } if (buf[1] == 0xFF && buf[2] == 0xFF && buf[3] == 0xFF) { - g_set_error_literal(error, - FWUPD_ERROR, - FWUPD_ERROR_NOT_SUPPORTED, - "device not detected"); + g_set_error(error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_SUPPORTED, + "device not detected, flash ID 0x%02X%02X%02X", + buf[1], + buf[2], + buf[3]); return FALSE; } g_string_append_printf(flash_id, "%02X", buf[1]); @@ -426,6 +429,7 @@ fu_ch341a_cfi_device_init(FuCh341aCfiDevice *self) fu_device_add_protocol(FU_DEVICE(self), "org.jedec.cfi"); fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_UPDATABLE); fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_UNSIGNED_PAYLOAD); + fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE); } static void diff --git a/plugins/colorhug/README.md b/plugins/colorhug/README.md index 5431abca7..947ac0798 100644 --- a/plugins/colorhug/README.md +++ b/plugins/colorhug/README.md @@ -1,4 +1,6 @@ -# ColorHug +--- +title: Plugin: ColorHug +--- ## Introduction @@ -16,7 +18,7 @@ a packed binary file format. This plugin supports the following protocol ID: -* com.hughski.colorhug +* `com.hughski.colorhug` ## GUID Generation diff --git a/plugins/corsair/README.md b/plugins/corsair/README.md index 8875265c1..b345263e5 100644 --- a/plugins/corsair/README.md +++ b/plugins/corsair/README.md @@ -1,4 +1,6 @@ -# Corsair +--- +title: Plugin: Corsair +--- ## Introduction diff --git a/plugins/cpu/README.md b/plugins/cpu/README.md index e5e1e5cbf..786f1ade3 100644 --- a/plugins/cpu/README.md +++ b/plugins/cpu/README.md @@ -1,4 +1,6 @@ -# CPU Microcode +--- +title: Plugin: CPU Microcode +--- ## Introduction diff --git a/plugins/cros-ec/README.md b/plugins/cros-ec/README.md index 00f768127..36f6a23c9 100644 --- a/plugins/cros-ec/README.md +++ b/plugins/cros-ec/README.md @@ -1,4 +1,6 @@ -# Chrome OS EC +--- +title: Plugin: Chrome OS EC +--- ## Introduction @@ -19,7 +21,7 @@ the Google [fmap file format](https://www.chromium.org/chromium-os/firmware-port This plugin supports the following protocol ID: -* com.google.usb.crosec +* `com.google.usb.crosec` ## GUID Generation diff --git a/plugins/dell-dock/README.md b/plugins/dell-dock/README.md index 07a89067f..9a0df4a86 100644 --- a/plugins/dell-dock/README.md +++ b/plugins/dell-dock/README.md @@ -1,4 +1,6 @@ -# Dell USB-C Dock +--- +title: Plugin: Dell USB-C Dock +--- ## Dell System @@ -35,8 +37,8 @@ blobs with an unspecified binary file format. This plugin supports the following protocol ID: -* com.dell.dock -* com.synaptics.mst +* `com.dell.dock` +* `com.synaptics.mst` ## GUID Generation diff --git a/plugins/dell-esrt/README.md b/plugins/dell-esrt/README.md index e95220b3b..649ea0363 100644 --- a/plugins/dell-esrt/README.md +++ b/plugins/dell-esrt/README.md @@ -1,4 +1,6 @@ -# Dell ESRT Support +--- +title: Plugin: Dell ESRT +--- ## Introduction diff --git a/plugins/dell/README.md b/plugins/dell/README.md index 4d1402af5..909c3e572 100644 --- a/plugins/dell/README.md +++ b/plugins/dell/README.md @@ -1,4 +1,6 @@ -# Dell Support +--- +title: Plugin: Dell +--- ## Introduction diff --git a/plugins/dell/fu-dell-plugin.c b/plugins/dell/fu-dell-plugin.c index f1f6dcd17..154e15fdf 100644 --- a/plugins/dell/fu-dell-plugin.c +++ b/plugins/dell/fu-dell-plugin.c @@ -147,9 +147,9 @@ static gboolean fu_dell_supported(FuPlugin *plugin, GError **error) { FuContext *ctx = fu_plugin_get_context(plugin); + FuSmbiosChassisKind chassis_kind = fu_context_get_chassis_kind(ctx); g_autoptr(GBytes) de_table = NULL; g_autoptr(GBytes) da_table = NULL; - g_autoptr(GBytes) enclosure = NULL; guint8 value = 0; struct da_structure da_values = {0x0}; @@ -194,19 +194,8 @@ fu_dell_supported(FuPlugin *plugin, GError **error) } /* only run on intended Dell hw types */ - enclosure = fu_context_get_smbios_data(ctx, FU_SMBIOS_STRUCTURE_TYPE_CHASSIS, error); - if (enclosure == NULL) - return FALSE; - if (!fu_memread_uint8_safe(g_bytes_get_data(enclosure, NULL), - g_bytes_get_size(enclosure), - 0x0, - &value, - error)) { - g_prefix_error(error, "invalid enclosure data: "); - return FALSE; - } for (guint i = 0; i < G_N_ELEMENTS(enclosure_allowlist); i++) { - if (enclosure_allowlist[i] == value) + if (enclosure_allowlist[i] == chassis_kind) return TRUE; } diff --git a/plugins/dfu-csr/README.md b/plugins/dfu-csr/README.md index 5335719f0..ee5646280 100644 --- a/plugins/dfu-csr/README.md +++ b/plugins/dfu-csr/README.md @@ -1,4 +1,6 @@ -# DFU CSR +--- +title: Plugin: DFU CSR — Cambridge Silicon Radio +--- ## Introduction @@ -21,7 +23,7 @@ DFU file format. This plugin supports the following protocol ID: -* com.qualcomm.dfu +* `com.qualcomm.dfu` ## GUID Generation diff --git a/plugins/dfu/README.md b/plugins/dfu/README.md index d020230d2..d0ef82ecd 100644 --- a/plugins/dfu/README.md +++ b/plugins/dfu/README.md @@ -1,4 +1,6 @@ -# DFU +--- +title: Plugin: DFU +--- ## Introduction @@ -12,8 +14,8 @@ DFU or DfuSe file format. This plugin supports the following protocol IDs: -* org.usb.dfu -* com.st.dfuse +* `org.usb.dfu` +* `com.st.dfuse` ## GUID Generation @@ -32,6 +34,42 @@ the device again re-enumerates back to the runtime mode. For this reason the `REPLUG_MATCH_GUID` internal device flag is used so that the bootloader and runtime modes are treated as the same device. +## Implementation Notes + +The runtime mode is just as important as the DFU mode from the point of view of +fwupd and should be included if firmware updates are to "just work". Without a +DFU runtime interface we can match the device with `Flags = no-dfu-runtime` but +will need a suitably new fwupd version before the device is recognized. + +The USB interface revision (`REV`) is used as the BCD version number, as DFU has +no way of representing a firmware version number. A new firmware version should +always increment the USB REV of the *runtime* interface as fwupd will **not** switch +the device into *DFU mode* during enumeration to read the version number. +The version number of the DFU mode should represent the *bootloader version* and +this should not change as the firmware is updated. + +The runtime USB interface should have a unique vendor ID and product ID for the +specific firmware stream. A different version of software should have a unique +VID/PID USB descriptor pair. The microcontroller example VID/PID should **never** +be used in the runtime mode otherwise fwupd would not know what firmware to match. + +Ideally, the bootloader should also have a unique USB vendor ID and product ID. +This allows fwupd to more easily recognize the runtime interface *going away* and +the DFU interface *coming back*. If the VID/PID is the same in runtime and DFU +modes then the quirk `Flags = no-pid-change` is required. + +If the bootloader VID/PID is not customized (as might be the default for the supplied +MCU) then fwupd can match the runtime VID/PID to the bootloader VID/PID. Where this +fails is when the device is *stuck* in the DFU mode, perhaps because the user removed +the USB cable before the device had completed updating. +With a unique VID/PID fwupd can *recover* the device stuck in DFU mode, reflashing the +device with the latest matching firmware and then attaching it back into runtime mode. + +Using a *generic* VID/PID for the bootloader means fwupd does not know how to recover +the device back into runtime mode as the client does not know what firmware to choose +and the user is forced to either RMA the device, or to download the correct file manually +from the vendor vebsite and use low-level commands like `sudo fwupdtool install-blob`. + ## Vendor ID Security The vendor ID is set from the USB vendor, for example `USB:0x0A12` diff --git a/plugins/ebitdo/README.md b/plugins/ebitdo/README.md index 63473bf90..43d3f7c9e 100644 --- a/plugins/ebitdo/README.md +++ b/plugins/ebitdo/README.md @@ -1,4 +1,6 @@ -# 8BitDo +--- +title: Plugin: 8BitDo +--- ## Introduction @@ -18,7 +20,7 @@ that is used when flashing the image. This plugin supports the following protocol ID: -* com.8bitdo +* `com.8bitdo` ## GUID Generation diff --git a/plugins/elanfp/README.md b/plugins/elanfp/README.md index f74613eab..30bb93899 100644 --- a/plugins/elanfp/README.md +++ b/plugins/elanfp/README.md @@ -1,23 +1,21 @@ -Elan Fingerprint Sensor Support -================================= +--- +title: Plugin: Elan Fingerprint Sensor +--- -Introduction ------------- +## Introduction The plugin used for update firmware for fingerprint sensors from Elan. -Firmware Format ---------------- +## Firmware Format The daemon will decompress the cabinet archive and extract a firmware blob in a packed binary file format. This plugin supports the following protocol ID: -* tw.com.emc.elanfp +* `tw.com.emc.elanfp` -GUID Generation ---------------- +## GUID Generation These devices use the standard USB DeviceInstanceId values, e.g. @@ -25,7 +23,6 @@ These devices use the standard USB DeviceInstanceId values, e.g. * `USB\VID_04F3&PID_0C7E` * `USB\VID_04F3` -Vendor ID Security ------------------- +## Vendor ID Security The vendor ID is set from the USB vendor, in this instance set to `USB:0x04F3` diff --git a/plugins/elantp/README.md b/plugins/elantp/README.md index f92ff675e..e817a55b0 100644 --- a/plugins/elantp/README.md +++ b/plugins/elantp/README.md @@ -1,4 +1,6 @@ -# Elan TouchPad +--- +title: Plugin: Elan TouchPad +--- ## Introduction @@ -13,7 +15,7 @@ an unspecified binary file format. This plugin supports the following protocol ID: -* tw.com.emc.elantp +* `tw.com.emc.elantp` ## GUID Generation diff --git a/plugins/emmc/README.md b/plugins/emmc/README.md index 6f511b23d..3088863a8 100644 --- a/plugins/emmc/README.md +++ b/plugins/emmc/README.md @@ -1,4 +1,6 @@ -# eMMC +--- +title: Plugin: eMMC +--- ## Introduction @@ -13,12 +15,16 @@ eMMC devices support the `org.jedec.mmc` protocol. These devices use the following instance values: -* `EMMC\%NAME%` -* `EMMC\%NAME%&%REV%` -* `EMMC\%MANFID%&%OEMID%` -* `EMMC\%MANFID%&%OEMID%&%NAME%` -* `EMMC\%MANFID%&%NAME%&%REV%` -* `EMMC\%MANFID%&%OEMID%&%NAME%&%REV%` +* `EMMC\NAME_%name%` +* `EMMC\NAME_%name%&REV_%rev%` +* `EMMC\MAN_%manfid%&OEM_%oemid%` +* `EMMC\MAN_%manfid%&OEM_%oemid%&NAME_%name%` +* `EMMC\MAN_%manfid%&NAME_%name%&REV_%rev%` +* `EMMC\MAN_%manfid%&OEM_%oemid%&NAME_%name%&REV_%rev%` + +One deprecated instance ID is also added; new firmware should not use this. + +* `EMMC\%manfid%&%oemid%&%name%` ## Update Behavior diff --git a/plugins/emmc/fu-emmc-device.c b/plugins/emmc/fu-emmc-device.c index 59da03ac8..a950ce1d9 100644 --- a/plugins/emmc/fu-emmc-device.c +++ b/plugins/emmc/fu-emmc-device.c @@ -136,6 +136,7 @@ fu_emmc_device_probe(FuDevice *device, GError **error) guint64 manfid = 0; const gchar *tmp; g_autoptr(GUdevDevice) udev_parent = NULL; + g_autofree gchar *man_oem_name = NULL; g_autofree gchar *vendor_id = NULL; g_autoptr(GRegex) dev_regex = NULL; @@ -221,6 +222,13 @@ fu_emmc_device_probe(FuDevice *device, GError **error) fu_device_build_instance_id(device, NULL, "EMMC", "MAN", "NAME", "REV", NULL); fu_device_build_instance_id(device, NULL, "EMMC", "MAN", "OEM", "NAME", "REV", NULL); + /* this is a (invalid!) instance ID added for legacy compatibility */ + man_oem_name = g_strdup_printf("EMMC\\%04" G_GUINT64_FORMAT "&%04" G_GUINT64_FORMAT "&%s", + manfid, + oemid, + fu_device_get_name(device)); + fu_device_add_instance_id(device, man_oem_name); + /* set the vendor */ tmp = g_udev_device_get_sysfs_attr(udev_parent, "manfid"); vendor_id = g_strdup_printf("EMMC:%s", tmp); diff --git a/plugins/ep963x/README.md b/plugins/ep963x/README.md index f54c2fcfe..eb0e2be3c 100644 --- a/plugins/ep963x/README.md +++ b/plugins/ep963x/README.md @@ -1,4 +1,6 @@ -# Explore EP963x +--- +title: Plugin: EP963x +--- ## Introduction @@ -11,7 +13,7 @@ a packed binary file format. This plugin supports the following protocol ID: -* tw.com.exploretech.ep963x +* `tw.com.exploretech.ep963x` ## GUID Generation diff --git a/plugins/fastboot/README.md b/plugins/fastboot/README.md index 2f277822b..61958eda5 100644 --- a/plugins/fastboot/README.md +++ b/plugins/fastboot/README.md @@ -1,4 +1,6 @@ -# Fastboot +--- +title: Plugin: Fastboot +--- ## Introduction @@ -17,7 +19,7 @@ be updated. This plugin supports the following protocol ID: -* com.google.fastboot +* `com.google.fastboot` ## GUID Generation diff --git a/plugins/flashrom/README.md b/plugins/flashrom/README.md index 14f580f16..c372137ec 100644 --- a/plugins/flashrom/README.md +++ b/plugins/flashrom/README.md @@ -1,4 +1,6 @@ -# Flashrom +--- +title: Plugin: Flashrom +--- ## Introduction @@ -15,7 +17,7 @@ EEPROM programmer. This plugin supports the following protocol ID: -* org.flashrom +* `org.flashrom` ## Coreboot Version String diff --git a/plugins/flashrom/flashrom.quirk b/plugins/flashrom/flashrom.quirk index d245598fe..6b8861318 100644 --- a/plugins/flashrom/flashrom.quirk +++ b/plugins/flashrom/flashrom.quirk @@ -99,11 +99,16 @@ Branch = coreboot Flags = reset-cmos PciBcrAddr = 0x0 +# StarBook Mk VI - Intel (AMI GUID) +[1292e166-a66f-5e11-b2bb-53265a8f53d9] +FirmwareSizeMax = 0x2000000 + # StarBook Mk VI - Intel (coreboot GUID) [8c994a92-7ef8-5d68-80b5-99ead7cf4686] Branch = coreboot Flags = reset-cmos PciBcrAddr = 0x0 +FirmwareSizeMax = 0x2000000 # NovaCustom NV4x (HwId) [25b6ea34-8f52-598e-a27a-31e03014dbe3] diff --git a/plugins/focalfp/README.md b/plugins/focalfp/README.md index b70b5058e..ca1945d44 100644 --- a/plugins/focalfp/README.md +++ b/plugins/focalfp/README.md @@ -1,4 +1,6 @@ -# Focal TouchPad +--- +title: Plugin: Focal TouchPad +--- ## Introduction @@ -12,7 +14,7 @@ an unspecified binary file format. This plugin supports the following protocol ID: -* tw.com.focalfp +* `tw.com.focalfp` ## GUID Generation diff --git a/plugins/fpc/README.md b/plugins/fpc/README.md index 995b62dec..e289f9c0b 100644 --- a/plugins/fpc/README.md +++ b/plugins/fpc/README.md @@ -1,4 +1,6 @@ -# FPC Fingerprint Sensor +--- +title: Plugin: FPC Fingerprint Sensor +--- ## Introduction @@ -11,7 +13,7 @@ a packed binary file format. This plugin supports the following protocol ID: -* com.fingerprints.dfupc +* `com.fingerprints.dfupc` ## GUID Generation diff --git a/plugins/fresco-pd/README.md b/plugins/fresco-pd/README.md index 274f3505c..ec49a1d07 100644 --- a/plugins/fresco-pd/README.md +++ b/plugins/fresco-pd/README.md @@ -1,4 +1,6 @@ -# Fresco PD +--- +title: Plugin: Fresco PD +--- ## Introduction @@ -11,7 +13,7 @@ an unspecified binary format. This plugin supports the following protocol ID: -* com.frescologic.pd +* `com.frescologic.pd` ## GUID Generation diff --git a/plugins/genesys/README.md b/plugins/genesys/README.md index 0227db208..f3ee73b65 100644 --- a/plugins/genesys/README.md +++ b/plugins/genesys/README.md @@ -1,4 +1,6 @@ -# Genesys Logic +--- +title: Plugin: Genesys Logic +--- ## Introduction @@ -18,8 +20,8 @@ The daemon will decompress the cabinet archives and extract the firmware blob in This plugin supports the following protocol IDs: -* com.genesys.usbhub -* com.mstarsemi.scaler +* `com.genesys.usbhub` +* `com.mstarsemi.scaler` ## GUID Generation diff --git a/plugins/goodix-moc/README.md b/plugins/goodix-moc/README.md index a150a6644..c761f4875 100644 --- a/plugins/goodix-moc/README.md +++ b/plugins/goodix-moc/README.md @@ -1,4 +1,6 @@ -# Goodix Fingerprint Sensor +--- +title: Plugin: Goodix Fingerprint Sensor +--- ## Introduction @@ -11,7 +13,7 @@ a packed binary file format. This plugin supports the following protocol ID: -* com.goodix.goodixmoc +* `com.goodix.goodixmoc` ## GUID Generation diff --git a/plugins/gpio/README.md b/plugins/gpio/README.md index e10bdfff6..d776002ef 100644 --- a/plugins/gpio/README.md +++ b/plugins/gpio/README.md @@ -1,4 +1,6 @@ -# GPIO +--- +title: Plugin: GPIO +--- ## Introduction diff --git a/plugins/hailuck/README.md b/plugins/hailuck/README.md index cc09ad57f..e1a2b5a44 100644 --- a/plugins/hailuck/README.md +++ b/plugins/hailuck/README.md @@ -1,4 +1,6 @@ -# Hailuck +--- +title: Plugin: Hailuck +--- ## Introduction @@ -12,8 +14,8 @@ a packed binary file format. This plugin supports the following protocol ID: -* com.hailuck.kbd -* com.hailuck.tp +* `com.hailuck.kbd` +* `com.hailuck.tp` ## GUID Generation diff --git a/plugins/intel-gsc/README.md b/plugins/intel-gsc/README.md index 3a065d91d..d9c1be041 100644 --- a/plugins/intel-gsc/README.md +++ b/plugins/intel-gsc/README.md @@ -1,4 +1,6 @@ -# Intel Graphics System Controller +--- +title: Plugin: Intel GSC — Graphics System Controller +--- ## Introduction @@ -13,7 +15,7 @@ There are two firmware formats in use: This plugin supports the following protocol ID: -* com.intel.gsc +* `com.intel.gsc` ## GUID Generation diff --git a/plugins/intel-me/README.md b/plugins/intel-me/README.md index a0675f4b6..6018e962f 100644 --- a/plugins/intel-me/README.md +++ b/plugins/intel-me/README.md @@ -1,4 +1,6 @@ -# Intel ME +--- +title: Plugin: Intel ME +--- ## Introduction diff --git a/plugins/intel-spi/README.md b/plugins/intel-spi/README.md index 516b135b0..468056c4d 100644 --- a/plugins/intel-spi/README.md +++ b/plugins/intel-spi/README.md @@ -1,4 +1,6 @@ -# Intel SPI +--- +title: Plugin: Intel SPI +--- ## Introduction diff --git a/plugins/intel-usb4/README.md b/plugins/intel-usb4/README.md index 27757fbf7..cb0b715c8 100644 --- a/plugins/intel-usb4/README.md +++ b/plugins/intel-usb4/README.md @@ -1,4 +1,6 @@ -# Intel USB4 +--- +title: Plugin: Intel USB4 +--- ## Introduction @@ -12,7 +14,7 @@ an unspecified binary file format, with vendor specific header. This plugin supports the following protocol ID: -* com.intel.thunderbolt +* `com.intel.thunderbolt` ## GUID Generation diff --git a/plugins/iommu/README.md b/plugins/iommu/README.md index 2ee57793c..b593cd538 100644 --- a/plugins/iommu/README.md +++ b/plugins/iommu/README.md @@ -1,4 +1,6 @@ -# Linux IOMMU +--- +title: Plugin: IOMMU +--- ## Introduction diff --git a/plugins/jabra/README.md b/plugins/jabra/README.md index 6e3d81d48..55ceba080 100644 --- a/plugins/jabra/README.md +++ b/plugins/jabra/README.md @@ -1,4 +1,6 @@ -# Jabra +--- +title: Plugin: Jabra +--- ## Introduction diff --git a/plugins/lenovo-thinklmi/README.md b/plugins/lenovo-thinklmi/README.md index 030f7cbf7..0cb5dfc5b 100644 --- a/plugins/lenovo-thinklmi/README.md +++ b/plugins/lenovo-thinklmi/README.md @@ -1,4 +1,6 @@ -# Lenovo ThinkLMI +--- +title: Plugin: Lenovo ThinkLMI +--- ## Introduction diff --git a/plugins/lenovo-thinklmi/fu-self-test.c b/plugins/lenovo-thinklmi/fu-self-test.c index 55635d1b4..1ddc7b6b1 100644 --- a/plugins/lenovo-thinklmi/fu-self-test.c +++ b/plugins/lenovo-thinklmi/fu-self-test.c @@ -46,7 +46,7 @@ fu_test_self_init(FuTest *self, GError **error_global) &error); g_assert_no_error(error); g_assert_true(ret); - ret = fu_context_load_hwinfo(ctx, &error); + ret = fu_context_load_hwinfo(ctx, FU_CONTEXT_HWID_FLAG_LOAD_CONFIG, &error); g_assert_no_error(error); g_assert_true(ret); ret = fu_context_reload_bios_settings(ctx, &error); diff --git a/plugins/linux-lockdown/README.md b/plugins/linux-lockdown/README.md index adefa49a8..3e32d79cb 100644 --- a/plugins/linux-lockdown/README.md +++ b/plugins/linux-lockdown/README.md @@ -1,4 +1,6 @@ -# Linux Kernel Lockdown +--- +title: Plugin: Linux Kernel Lockdown +--- ## Introduction diff --git a/plugins/linux-sleep/README.md b/plugins/linux-sleep/README.md index 828e8e842..ff2fe3772 100644 --- a/plugins/linux-sleep/README.md +++ b/plugins/linux-sleep/README.md @@ -1,4 +1,6 @@ -# Linux Kernel Sleep +--- +title: Plugin: Linux Kernel Sleep +--- ## Introduction diff --git a/plugins/linux-swap/README.md b/plugins/linux-swap/README.md index e840370b7..d11c2b43a 100644 --- a/plugins/linux-swap/README.md +++ b/plugins/linux-swap/README.md @@ -1,4 +1,6 @@ -# Linux Swap +--- +title: Plugin: Linux Swap +--- ## Introduction diff --git a/plugins/linux-swap/fu-self-test.c b/plugins/linux-swap/fu-self-test.c index 97a4f671c..ea6c6b177 100644 --- a/plugins/linux-swap/fu-self-test.c +++ b/plugins/linux-swap/fu-self-test.c @@ -35,6 +35,7 @@ fu_linux_swap_plain_func(void) 0, &error); if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) || + g_error_matches(error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY) || g_error_matches(error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT)) { g_test_skip(error->message); return; diff --git a/plugins/linux-swap/meson.build b/plugins/linux-swap/meson.build index a01184176..93f8a6238 100644 --- a/plugins/linux-swap/meson.build +++ b/plugins/linux-swap/meson.build @@ -14,6 +14,9 @@ plugin_builtin_linux_swap = static_library('fu_plugin_linux_swap', plugin_builtins += plugin_builtin_linux_swap if get_option('tests') + env = environment() + env.set('G_TEST_SRCDIR', meson.current_source_dir()) + env.set('G_TEST_BUILDDIR', meson.current_build_dir()) e = executable( 'linux-swap-self-test', sources: [ @@ -29,6 +32,6 @@ if get_option('tests') install_rpath: libdir_pkg, install_dir: installed_test_bindir, ) - test('linux-swap-self-test', e) # added to installed-tests + test('linux-swap-self-test', e, env: env) # added to installed-tests endif endif diff --git a/plugins/linux-tainted/README.md b/plugins/linux-tainted/README.md index 641626bc3..488456c8f 100644 --- a/plugins/linux-tainted/README.md +++ b/plugins/linux-tainted/README.md @@ -1,4 +1,6 @@ -# Linux Kernel Tainted +--- +title: Plugin: Linux Kernel Tainted +--- ## Introduction diff --git a/plugins/logind/README.md b/plugins/logind/README.md index 602d65e06..ac79b6883 100644 --- a/plugins/logind/README.md +++ b/plugins/logind/README.md @@ -1,4 +1,6 @@ -# logind +--- +title: Plugin: logind +--- ## Introduction diff --git a/plugins/logitech-bulkcontroller/README.md b/plugins/logitech-bulkcontroller/README.md index 67df69a59..9bf165797 100644 --- a/plugins/logitech-bulkcontroller/README.md +++ b/plugins/logitech-bulkcontroller/README.md @@ -1,8 +1,11 @@ -# Logitech Video Collaboration +--- +title: Plugin: Logitech Bulk Controller — Video Collaboration +--- ## Introduction -This plugin can upgrade the firmware on Logitech Video Collaboration products (Rally Bar and Rally Bar Mini), using USB bulk transfer. +This plugin can upgrade the firmware on Logitech Video Collaboration products +(Rally Bar and RallyBar Mini), using USB bulk transfer. ## Firmware Format @@ -11,7 +14,7 @@ a packed binary file format. This plugin supports the following protocol ID: -* com.logitech.vc.proto +* `com.logitech.vc.proto` ## GUID Generation diff --git a/plugins/logitech-hidpp/README.md b/plugins/logitech-hidpp/README.md index 6fea2427c..a1f8908fa 100644 --- a/plugins/logitech-hidpp/README.md +++ b/plugins/logitech-hidpp/README.md @@ -1,4 +1,6 @@ -# Logitech HID +--- +title: Plugin: Logitech HID++ +--- ## Introduction @@ -26,8 +28,8 @@ a vendor-specific format that appears to be a subset of the Intel HEX format. This plugin supports the following protocol IDs: -* com.logitech.unifying -* com.logitech.unifyingsigned +* `com.logitech.unifying` +* `com.logitech.unifyingsigned` ## GUID Generation diff --git a/plugins/logitech-hidpp/meson.build b/plugins/logitech-hidpp/meson.build index 7b47afd5e..f4de1b082 100644 --- a/plugins/logitech-hidpp/meson.build +++ b/plugins/logitech-hidpp/meson.build @@ -25,6 +25,9 @@ plugin_builtin_logitech_hidpp = static_library('fu_plugin_logitech_hidpp', plugin_builtins += plugin_builtin_logitech_hidpp if get_option('tests') + env = environment() + env.set('G_TEST_SRCDIR', meson.current_source_dir()) + env.set('G_TEST_BUILDDIR', meson.current_build_dir()) e = executable( 'logitech-hidpp-self-test', sources: [ @@ -38,6 +41,6 @@ if get_option('tests') ], c_args: cargs, ) - test('logitech-hidpp-self-test', e) + test('logitech-hidpp-self-test', e, env: env) endif endif diff --git a/plugins/logitech-scribe/README.md b/plugins/logitech-scribe/README.md index d6251424f..cd912836c 100644 --- a/plugins/logitech-scribe/README.md +++ b/plugins/logitech-scribe/README.md @@ -1,8 +1,11 @@ -# Logitech Video Collaboration +--- +title: Plugin: Logitech Scribe +--- ## Introduction -This plugin can upgrade the firmware on Logitech Video Collaboration products (Scribe), using USB bulk transfer. +This plugin can upgrade the firmware on Logitech Video Collaboration products +(Scribe), using USB bulk transfer. ## Firmware Format @@ -11,7 +14,7 @@ a packed binary file format. This plugin supports the following protocol ID: -* com.logitech.vc.scribe +* `com.logitech.vc.scribe` ## GUID Generation diff --git a/plugins/meson.build b/plugins/meson.build index 719dc7c56..169444b2f 100644 --- a/plugins/meson.build +++ b/plugins/meson.build @@ -12,100 +12,104 @@ plugin_deps = [ protobufc, ] -# this is used by lenovo-thinklmi and dell -subdir('uefi-capsule') +plugins = [ + 'uefi-capsule', + 'acpi-dmar', + 'acpi-facp', + 'acpi-ivrs', + 'acpi-phat', + 'amd-pmc', + 'analogix', + 'android-boot', + 'ata', + 'bcm57xx', + 'bios', + 'ccgx', + 'cfu', + 'ch341a', + 'colorhug', + 'corsair', + 'cpu', + 'cros-ec', + 'dell', + 'dell-dock', + 'dell-esrt', + 'dfu', + 'dfu-csr', + 'ebitdo', + 'elantp', + 'elanfp', + 'emmc', + 'ep963x', + 'fastboot', + 'flashrom', + 'focalfp', + 'fpc', + 'fresco-pd', + 'genesys', + 'goodix-moc', + 'gpio', + 'hailuck', + 'intel-gsc', + 'intel-me', + 'intel-spi', + 'intel-usb4', + 'iommu', + 'jabra', + 'lenovo-thinklmi', + 'linux-lockdown', + 'linux-sleep', + 'linux-swap', + 'linux-tainted', + 'logind', + 'logitech-hidpp', + 'logitech-bulkcontroller', + 'logitech-scribe', + 'modem-manager', + 'msr', + 'mtd', + 'nitrokey', + 'nordic-hid', + 'nvme', + 'optionrom', + 'parade-lspcon', + 'pci-bcr', + 'pci-mei', + 'pci-psp', + 'pixart-rf', + 'powerd', + 'qsi-dock', + 'realtek-mst', + 'redfish', + 'rts54hid', + 'rts54hub', + 'steelseries', + 'scsi', + 'superio', + 'synaptics-cape', + 'synaptics-cxaudio', + 'synaptics-mst', + 'synaptics-prometheus', + 'synaptics-rmi', + 'system76-launch', + 'test', + 'thelio-io', + 'thunderbolt', + 'ti-tps6598x', + 'tpm', + 'uefi-dbx', + 'uefi-pk', + 'uefi-recovery', + 'uf2', + 'upower', + 'usi-dock', + 'vbe', + 'vli', + 'wacom-raw', + 'wacom-usb', + 'wistron-dock', +] -subdir('acpi-dmar') -subdir('acpi-facp') -subdir('acpi-ivrs') -subdir('acpi-phat') -subdir('amd-pmc') -subdir('analogix') -subdir('android-boot') -subdir('ata') -subdir('bcm57xx') -subdir('bios') -subdir('ccgx') -subdir('cfu') -subdir('ch341a') -subdir('colorhug') -subdir('corsair') -subdir('cpu') -subdir('cros-ec') -subdir('dell') -subdir('dell-dock') -subdir('dell-esrt') -subdir('dfu') -subdir('dfu-csr') -subdir('ebitdo') -subdir('elantp') -subdir('elanfp') -subdir('emmc') -subdir('ep963x') -subdir('fastboot') -subdir('flashrom') -subdir('focalfp') -subdir('fpc') -subdir('fresco-pd') -subdir('genesys') -subdir('goodix-moc') -subdir('gpio') -subdir('hailuck') -subdir('intel-gsc') -subdir('intel-me') -subdir('intel-spi') -subdir('intel-usb4') -subdir('iommu') -subdir('jabra') -subdir('lenovo-thinklmi') -subdir('linux-lockdown') -subdir('linux-sleep') -subdir('linux-swap') -subdir('linux-tainted') -subdir('logind') -subdir('logitech-hidpp') -subdir('logitech-bulkcontroller') -subdir('logitech-scribe') -subdir('modem-manager') -subdir('msr') -subdir('mtd') -subdir('nitrokey') -subdir('nordic-hid') -subdir('nvme') -subdir('optionrom') -subdir('parade-lspcon') -subdir('pci-bcr') -subdir('pci-mei') -subdir('pci-psp') -subdir('pixart-rf') -subdir('powerd') -subdir('qsi-dock') -subdir('realtek-mst') -subdir('redfish') -subdir('rts54hid') -subdir('rts54hub') -subdir('steelseries') -subdir('scsi') -subdir('superio') -subdir('synaptics-cape') -subdir('synaptics-cxaudio') -subdir('synaptics-mst') -subdir('synaptics-prometheus') -subdir('synaptics-rmi') -subdir('system76-launch') -subdir('test') -subdir('thelio-io') -subdir('thunderbolt') -subdir('ti-tps6598x') -subdir('tpm') -subdir('uefi-dbx') -subdir('uefi-pk') -subdir('uefi-recovery') -subdir('uf2') -subdir('upower') -subdir('usi-dock') -subdir('vbe') -subdir('vli') -subdir('wacom-raw') -subdir('wacom-usb') -subdir('wistron-dock') +foreach plugin: plugins + subdir(plugin) +endforeach diff --git a/plugins/modem-manager/README.md b/plugins/modem-manager/README.md index 26ff4e8ea..a64b6850d 100644 --- a/plugins/modem-manager/README.md +++ b/plugins/modem-manager/README.md @@ -1,4 +1,6 @@ -# ModemManager +--- +title: Plugin: ModemManager +--- ## Introduction @@ -30,6 +32,12 @@ AT command to execute to determine the firmware branch currently installed on th Since: 1.7.4 +### ModemManagerFirehoseProgFile + +Firehose program file to use during the switch to EDL (Emergency Download) mode. + +Since: 1.8.10 + ## Vendor ID Security The vendor ID is set from the USB or PCI vendor, for example `USB:0x413C` `PCI:0x105B` diff --git a/plugins/modem-manager/fu-mm-device.c b/plugins/modem-manager/fu-mm-device.c index 90627cfde..87c0fcda1 100644 --- a/plugins/modem-manager/fu-mm-device.c +++ b/plugins/modem-manager/fu-mm-device.c @@ -88,10 +88,12 @@ struct _FuMmDevice { /* firehose update handling */ gchar *port_qcdm; gchar *port_edl; + gchar *firehose_prog_file; FuSaharaLoader *sahara_loader; #if MM_CHECK_VERSION(1, 17, 2) FuFirehoseUpdater *firehose_updater; #endif + /* for sahara */ FuUsbDevice *usb_device; @@ -1473,11 +1475,19 @@ fu_mm_copy_firehose_prog(FuMmDevice *self, GBytes *prog, GError **error) g_autofree gchar *qcom_fw_dir = NULL; g_autofree gchar *firehose_file_path = NULL; + if (self->firehose_prog_file == NULL) { + g_set_error(error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_FOUND, + "Firehose prog filename is not set for the device"); + return FALSE; + } + qcom_fw_dir = g_build_filename(self->firmware_path, "qcom", NULL); if (!fu_path_mkdir_parent(qcom_fw_dir, error)) return FALSE; - firehose_file_path = g_build_filename(qcom_fw_dir, "prog_firehose_sdx24.mbn", NULL); + firehose_file_path = g_build_filename(qcom_fw_dir, self->firehose_prog_file, NULL); if (!fu_bytes_set_contents(firehose_file_path, prog, error)) return FALSE; @@ -1681,6 +1691,11 @@ fu_mm_device_set_quirk_kv(FuDevice *device, const gchar *key, const gchar *value return TRUE; } + if (g_strcmp0(key, "ModemManagerFirehoseProgFile") == 0) { + self->firehose_prog_file = g_strdup(value); + return TRUE; + } + /* failed */ g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "quirk key not supported"); return FALSE; @@ -1947,6 +1962,7 @@ fu_mm_device_finalize(GObject *object) g_free(self->inhibition_uid); g_free(self->firmware_path); g_free(self->restore_firmware_path); + g_free(self->firehose_prog_file); G_OBJECT_CLASS(fu_mm_device_parent_class)->finalize(object); } diff --git a/plugins/modem-manager/modem-manager.quirk b/plugins/modem-manager/modem-manager.quirk index 4e45861f3..7c49470e0 100644 --- a/plugins/modem-manager/modem-manager.quirk +++ b/plugins/modem-manager/modem-manager.quirk @@ -58,3 +58,18 @@ ModemManagerBranchAtCommand = AT+GETFWBRANCH [USB\VID_05C6&PID_9008] Summary = Qualcomm based modems in EDL (sahara) Plugin = modem_manager + +# Quectel EM120 firehose prog file +[PCI\VID_1EAC&PID_1001] +Summary = Quectel EM120 firehose prog file +ModemManagerFirehoseProgFile = prog_firehose_sdx24.mbn + +# Quectel EM160 firehose prog file +[PCI\VID_1EAC&PID_1002] +Summary = Quectel EM160 firehose prog file +ModemManagerFirehoseProgFile = prog_firehose_sdx24.mbn + +# Quectel RM520 firehose prog file +[PCI\VID_1EAC&PID_1004] +Summary = Quectel RM520 firehose prog file +ModemManagerFirehoseProgFile = prog_firehose_sdx6x.elf diff --git a/plugins/msr/README.md b/plugins/msr/README.md index 39323a351..04070ebd6 100644 --- a/plugins/msr/README.md +++ b/plugins/msr/README.md @@ -1,4 +1,6 @@ -# MSR +--- +title: Plugin: MSR +--- ## Introduction diff --git a/plugins/msr/fu-msr-plugin.c b/plugins/msr/fu-msr-plugin.c index 8949d7591..1529a3e23 100644 --- a/plugins/msr/fu-msr-plugin.c +++ b/plugins/msr/fu-msr-plugin.c @@ -207,7 +207,7 @@ fu_msr_plugin_backend_device_added(FuPlugin *plugin, FuDevice *device, GError ** buf, sizeof(buf), error)) { - g_prefix_error(error, "could not read IA32_DEBUG_INTERFACE: "); + g_prefix_error(error, "could not read IA32_TME_ACTIVATION: "); return FALSE; } if (!fu_memread_uint64_safe(buf, diff --git a/plugins/mtd/README.md b/plugins/mtd/README.md index 6eefb8849..e666789f9 100644 --- a/plugins/mtd/README.md +++ b/plugins/mtd/README.md @@ -1,4 +1,6 @@ -# MTD +--- +title: Plugin: MTD +--- ## Introduction @@ -9,7 +11,7 @@ See for more details. This plugin supports the following protocol ID: -* org.infradead.mtd +* `org.infradead.mtd` ## GUID Generation diff --git a/plugins/mtd/fu-self-test.c b/plugins/mtd/fu-self-test.c index 73b8ed6df..d68eb6c22 100644 --- a/plugins/mtd/fu-self-test.c +++ b/plugins/mtd/fu-self-test.c @@ -32,7 +32,7 @@ fu_test_mtd_device_func(void) ret = fu_context_load_quirks(ctx, FU_QUIRKS_LOAD_FLAG_NO_CACHE, &error); g_assert_no_error(error); g_assert_true(ret); - ret = fu_context_load_hwinfo(ctx, &error); + ret = fu_context_load_hwinfo(ctx, FU_CONTEXT_HWID_FLAG_LOAD_SMBIOS, &error); g_assert_no_error(error); g_assert_true(ret); @@ -103,6 +103,7 @@ main(int argc, char **argv) g_test_init(&argc, &argv, NULL); (void)g_setenv("FWUPD_MTD_VERBOSE", "1", TRUE); testdatadir = g_test_build_filename(G_TEST_DIST, "tests", NULL); + (void)g_setenv("FWUPD_SYSFSFWDIR", testdatadir, TRUE); (void)g_setenv("FWUPD_SYSFSFWATTRIBDIR", testdatadir, TRUE); g_log_set_fatal_mask(NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL); diff --git a/plugins/mtd/meson.build b/plugins/mtd/meson.build index 316948e85..442f5f3da 100644 --- a/plugins/mtd/meson.build +++ b/plugins/mtd/meson.build @@ -15,6 +15,9 @@ plugin_builtin_mtd = static_library('fu_plugin_mtd', plugin_builtins += plugin_builtin_mtd if get_option('tests') + env = environment() + env.set('G_TEST_SRCDIR', meson.current_source_dir()) + env.set('G_TEST_BUILDDIR', meson.current_build_dir()) e = executable( 'mtd-self-test', sources: [ @@ -31,6 +34,6 @@ if get_option('tests') install_rpath: libdir_pkg, install_dir: installed_test_bindir, ) - test('mtd-self-test', e) # added to installed-tests + test('mtd-self-test', e, env: env) # added to installed-tests endif endif diff --git a/plugins/mtd/tests/dmi b/plugins/mtd/tests/dmi new file mode 120000 index 000000000..545fadeaf --- /dev/null +++ b/plugins/mtd/tests/dmi @@ -0,0 +1 @@ +../../../libfwupdplugin/tests/dmi/ \ No newline at end of file diff --git a/plugins/nitrokey/README.md b/plugins/nitrokey/README.md index 937733904..60d8f6fd9 100644 --- a/plugins/nitrokey/README.md +++ b/plugins/nitrokey/README.md @@ -1,4 +1,6 @@ -# Nitrokey +--- +title: Plugin: Nitrokey +--- ## Introduction diff --git a/plugins/nitrokey/meson.build b/plugins/nitrokey/meson.build index d3e9908f0..a16c60b46 100644 --- a/plugins/nitrokey/meson.build +++ b/plugins/nitrokey/meson.build @@ -16,6 +16,9 @@ plugin_builtin_nitrokey = static_library('fu_plugin_nitrokey', plugin_builtins += plugin_builtin_nitrokey if get_option('tests') + env = environment() + env.set('G_TEST_SRCDIR', meson.current_source_dir()) + env.set('G_TEST_BUILDDIR', meson.current_build_dir()) e = executable( 'nitrokey-self-test', sources: [ @@ -34,6 +37,6 @@ if get_option('tests') install_rpath: libdir_pkg, install_dir: installed_test_bindir, ) - test('nitrokey-self-test', e) # added to installed-tests + test('nitrokey-self-test', e, env: env) # added to installed-tests endif endif diff --git a/plugins/nordic-hid/README.md b/plugins/nordic-hid/README.md index 9f49f34a3..3c19e16e3 100644 --- a/plugins/nordic-hid/README.md +++ b/plugins/nordic-hid/README.md @@ -1,4 +1,6 @@ -# Nordic Semiconductor HID +--- +title: Plugin: Nordic HID +--- ## Introduction @@ -24,7 +26,7 @@ aka "B0" is supported and tested. This plugin supports the following protocol ID: -* Nordic HID Config Channel: com.nordic.hidcfgchannel +* Nordic HID Config Channel: `com.nordic.hidcfgchannel` ## GUID Generation diff --git a/plugins/nvme/README.md b/plugins/nvme/README.md index ff951e248..0c50bbc6f 100644 --- a/plugins/nvme/README.md +++ b/plugins/nvme/README.md @@ -1,4 +1,6 @@ -# NVMe +--- +title: Plugin: NVMe +--- ## Introduction @@ -16,7 +18,7 @@ an unspecified binary file format. This plugin supports the following protocol ID: -* org.nvmexpress +* `org.nvmexpress` ## GUID Generation diff --git a/plugins/optionrom/README.md b/plugins/optionrom/README.md index ae0a29475..e12ed736c 100644 --- a/plugins/optionrom/README.md +++ b/plugins/optionrom/README.md @@ -1,4 +1,6 @@ -# OptionROM +--- +title: Plugin: OptionROM +--- ## Introduction diff --git a/plugins/parade-lspcon/README.md b/plugins/parade-lspcon/README.md index 6372f941a..5dde6997b 100644 --- a/plugins/parade-lspcon/README.md +++ b/plugins/parade-lspcon/README.md @@ -1,4 +1,6 @@ -# Parade LSPCON +--- +title: Plugin: Parade LSPCON +--- ## Introduction @@ -22,7 +24,7 @@ to an inactive partition of the Flash attached to the device. This plugin supports the following protocol ID: -* com.paradetech.ps176 +* `com.paradetech.ps176` ## GUID Generation diff --git a/plugins/pci-bcr/README.md b/plugins/pci-bcr/README.md index 32770f8e7..37c3eba9e 100644 --- a/plugins/pci-bcr/README.md +++ b/plugins/pci-bcr/README.md @@ -1,4 +1,6 @@ -# PCI BIOS Control Register +--- +title: Plugin: PCI BCR — BIOS Control Register +--- ## Introduction diff --git a/plugins/pci-mei/README.md b/plugins/pci-mei/README.md index 359fe4e6b..ae650ee7c 100644 --- a/plugins/pci-mei/README.md +++ b/plugins/pci-mei/README.md @@ -1,4 +1,6 @@ -# PCI MEI +--- +title: Plugin: PCI MEI +--- ## Introduction diff --git a/plugins/pci-psp/README.md b/plugins/pci-psp/README.md index c4d474e07..89c5dc0b5 100644 --- a/plugins/pci-psp/README.md +++ b/plugins/pci-psp/README.md @@ -1,4 +1,6 @@ -# PCI PSP +--- +title: Plugin: PCI PSP — Platform Secure Processor +--- ## Introduction diff --git a/plugins/pci-psp/fu-pci-psp-device.c b/plugins/pci-psp/fu-pci-psp-device.c index 5d3726fbe..45c8d5783 100644 --- a/plugins/pci-psp/fu-pci-psp-device.c +++ b/plugins/pci-psp/fu-pci-psp-device.c @@ -149,6 +149,7 @@ fu_pci_psp_device_add_security_attrs_rollback_protection(FuDevice *device, g_debug("rollback protection not enforced"); fwupd_security_attr_set_result(attr, FWUPD_SECURITY_ATTR_RESULT_NOT_ENABLED); fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_ACTION_CONTACT_OEM); + fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_ACTION_CONFIG_FW); return; } diff --git a/plugins/pixart-rf/README.md b/plugins/pixart-rf/README.md index 82e67df94..bef862f0e 100644 --- a/plugins/pixart-rf/README.md +++ b/plugins/pixart-rf/README.md @@ -1,4 +1,6 @@ -# PixArt RF Devices +--- +title: Plugin: PixArt RF +--- ## Introduction @@ -12,7 +14,7 @@ an unspecified binary file format. This plugin supports the following protocol ID: -* com.pixart.rf +* `com.pixart.rf` ## GUID Generation diff --git a/plugins/powerd/README.md b/plugins/powerd/README.md index 8d4015bd0..78b33eb49 100644 --- a/plugins/powerd/README.md +++ b/plugins/powerd/README.md @@ -1,18 +1,16 @@ -Powerd Support -============== +--- +title: Plugin: Powerd +--- -Introduction ------------- +## Introduction This plugin is used to ensure that some updates are not done on battery power and that there is sufficient battery power for certain updates that are. -Vendor ID Security ------------------- +## Vendor ID Security This protocol does not create a device and thus requires no vendor ID set. -External interface access -------------------------- +## External interface access This plugin requires access to the `org.chromium.PowerManager` DBus interface. diff --git a/plugins/qsi-dock/README.md b/plugins/qsi-dock/README.md index 9a2699e56..7f2325c23 100644 --- a/plugins/qsi-dock/README.md +++ b/plugins/qsi-dock/README.md @@ -1,4 +1,6 @@ -# QSI Dock +--- +title: Plugin: QSI Dock +--- ## Introduction @@ -7,7 +9,7 @@ is provided by the DMC bcdDevice. This plugin supports the following protocol ID: -* com.qsi.dock +* `com.qsi.dock` ## GUID Generation diff --git a/plugins/realtek-mst/README.md b/plugins/realtek-mst/README.md index 6e1751b88..9a86b4228 100644 --- a/plugins/realtek-mst/README.md +++ b/plugins/realtek-mst/README.md @@ -1,4 +1,6 @@ -# Realtek MST +--- +title: Plugin: Realtek MST +--- ## Introduction @@ -25,7 +27,7 @@ device flash that is not currently running. This plugin supports the following protocol ID: -* com.realtek.rtd2142 +* `com.realtek.rtd2142` ## GUID Generation diff --git a/plugins/redfish/README.md b/plugins/redfish/README.md index b7de25d2e..0fb69b7d9 100644 --- a/plugins/redfish/README.md +++ b/plugins/redfish/README.md @@ -1,4 +1,6 @@ -# Redfish +--- +title: Plugin: Redfish +--- ## Introduction @@ -15,7 +17,7 @@ an unspecified binary file format. This plugin supports the following protocol ID: -* org.dmtf.redfish +* `org.dmtf.redfish` ## GUID Generation diff --git a/plugins/redfish/fu-redfish-network.c b/plugins/redfish/fu-redfish-network.c index 6566cc4e6..806948a80 100644 --- a/plugins/redfish/fu-redfish-network.c +++ b/plugins/redfish/fu-redfish-network.c @@ -118,6 +118,7 @@ fu_redfish_network_device_match(FuRedfishNetworkMatchHelper *helper, GError **er &error_local); if (proxy == NULL) { if (g_error_matches(error_local, G_IO_ERROR, G_IO_ERROR_DBUS_ERROR) || + g_error_matches(error_local, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY) || g_error_matches(error_local, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) { g_set_error_literal(error, FWUPD_ERROR, diff --git a/plugins/redfish/meson.build b/plugins/redfish/meson.build index 1e35b6ce9..2fd39786a 100644 --- a/plugins/redfish/meson.build +++ b/plugins/redfish/meson.build @@ -43,7 +43,9 @@ if get_option('tests') install_data(['tests/redfish-smbios.bin'], install_dir: join_paths(installed_test_datadir, 'tests')) install_data(['tests/redfish.conf'], - install_dir: join_paths(installed_test_datadir, 'tests')) + install_dir: join_paths(installed_test_datadir, 'tests'), + install_mode: 'rw-r-----', + ) install_data(['tests/efi/efivars/RedfishIndications-16faa37e-4b6a-4891-9028-242de65a3b70'], install_dir: join_paths(installed_test_datadir, 'tests', 'efi', 'efivars')) install_data(['tests/efi/efivars/RedfishOSCredentials-16faa37e-4b6a-4891-9028-242de65a3b70'], diff --git a/plugins/rts54hid/README.md b/plugins/rts54hid/README.md index 2f395a52e..d5f1c6502 100644 --- a/plugins/rts54hid/README.md +++ b/plugins/rts54hid/README.md @@ -1,4 +1,6 @@ -# Realtek RTS54HID +--- +title: Plugin: RTS54HID +--- ## Introduction @@ -15,7 +17,7 @@ an unspecified binary file format. This plugin supports the following protocol ID: -* com.realtek.rts54 +* `com.realtek.rts54` ## GUID Generation diff --git a/plugins/rts54hub/README.md b/plugins/rts54hub/README.md index 50b39409d..49f685b44 100644 --- a/plugins/rts54hub/README.md +++ b/plugins/rts54hub/README.md @@ -1,4 +1,6 @@ -# Realtek RTS54 HUB +--- +title: Plugin: RTS54HUB +--- ## Introduction @@ -15,8 +17,8 @@ an unspecified binary file format. This plugin supports the following protocol IDs: -* com.realtek.rts54 -* com.realtek.rts54.i2c +* `com.realtek.rts54` +* `com.realtek.rts54.i2c` ## GUID Generation diff --git a/plugins/scsi/README.md b/plugins/scsi/README.md index 9227d8a1b..7d57578e4 100644 --- a/plugins/scsi/README.md +++ b/plugins/scsi/README.md @@ -1,4 +1,6 @@ -# SCSI +--- +title: Plugin: SCSI +--- ## Introduction @@ -14,7 +16,7 @@ an unspecified binary file format. This plugin supports the following protocol ID: -* org.jedec.ufs +* `org.jedec.ufs` ## GUID Generation diff --git a/plugins/steelseries/README.md b/plugins/steelseries/README.md index 347068be4..a6e2b7f18 100644 --- a/plugins/steelseries/README.md +++ b/plugins/steelseries/README.md @@ -1,4 +1,6 @@ -# SteelSeries +--- +title: Plugin: SteelSeries +--- ## Introduction @@ -16,9 +18,9 @@ available from the vendor. This plugin supports the following protocol IDs: -* com.steelseries.fizz -* com.steelseries.gamepad -* com.steelseries.sonic +* `com.steelseries.fizz` +* `com.steelseries.gamepad` +* `com.steelseries.sonic` ## GUID Generation diff --git a/plugins/superio/README.md b/plugins/superio/README.md index e5b77d15d..3bf6ce827 100644 --- a/plugins/superio/README.md +++ b/plugins/superio/README.md @@ -1,4 +1,8 @@ -# SuperIO +--- +title: Plugin: SuperIO +--- + +## Introduction This plugin enumerates the various ITE85* SuperIO embedded controller ICs found in many laptops. Vendors wanting to expose the SuperIO functionality will need diff --git a/plugins/synaptics-cape/README.md b/plugins/synaptics-cape/README.md index 70bde599d..b591c768e 100644 --- a/plugins/synaptics-cape/README.md +++ b/plugins/synaptics-cape/README.md @@ -1,4 +1,6 @@ -# Synaptics CAPE devices +--- +title: Plugin: Synaptics CAPE +--- ## Introduction @@ -10,7 +12,7 @@ The daemon will decompress the cabinet archive and extract a firmware blob. This plugin supports the following protocol ID: -* com.synaptics.cape +* `com.synaptics.cape` ## GUID Generation diff --git a/plugins/synaptics-cxaudio/README.md b/plugins/synaptics-cxaudio/README.md index 7fecee865..00991761b 100644 --- a/plugins/synaptics-cxaudio/README.md +++ b/plugins/synaptics-cxaudio/README.md @@ -1,4 +1,6 @@ -# Conexant Audio +--- +title: Plugin: Synaptics CxAudio — Conexant Audio +--- ## Introduction @@ -12,7 +14,7 @@ a modified SREC file format. This plugin supports the following protocol ID: -* com.synaptics.synaptics-cxaudio +* `com.synaptics.synaptics-cxaudio` ## GUID Generation diff --git a/plugins/synaptics-mst/README.md b/plugins/synaptics-mst/README.md index f3208ab7f..930f6c91b 100644 --- a/plugins/synaptics-mst/README.md +++ b/plugins/synaptics-mst/README.md @@ -1,4 +1,8 @@ -# Synaptics MST +--- +title: Plugin: Synaptics MST +--- + +## Introduction This plugin supports querying and flashing Synaptics MST hubs used in Dell systems and docks. @@ -10,7 +14,7 @@ an unspecified binary file format. This plugin supports the following protocol ID: -* com.synaptics.mst +* `com.synaptics.mst` ## GUID Generation diff --git a/plugins/synaptics-mst/fu-self-test.c b/plugins/synaptics-mst/fu-self-test.c index 7c810b980..be868d668 100644 --- a/plugins/synaptics-mst/fu-self-test.c +++ b/plugins/synaptics-mst/fu-self-test.c @@ -37,7 +37,7 @@ _test_add_fake_devices_from_dir(FuPlugin *plugin, const gchar *path) ret = fu_context_load_quirks(ctx, FU_QUIRKS_LOAD_FLAG_NO_CACHE, &error); g_assert_no_error(error); g_assert_true(ret); - ret = fu_context_load_hwinfo(ctx, &error); + ret = fu_context_load_hwinfo(ctx, FU_CONTEXT_HWID_FLAG_NONE, &error); g_assert_no_error(error); g_assert_true(ret); @@ -84,7 +84,7 @@ fu_plugin_synaptics_mst_none_func(void) ret = fu_context_load_quirks(ctx, FU_QUIRKS_LOAD_FLAG_NO_CACHE, &error); g_assert_no_error(error); g_assert_true(ret); - ret = fu_context_load_hwinfo(ctx, &error); + ret = fu_context_load_hwinfo(ctx, FU_CONTEXT_HWID_FLAG_NONE, &error); g_assert_no_error(error); g_assert_true(ret); @@ -127,7 +127,7 @@ fu_plugin_synaptics_mst_tb16_func(void) ret = fu_context_load_quirks(ctx, FU_QUIRKS_LOAD_FLAG_NO_CACHE, &error); g_assert_no_error(error); g_assert_true(ret); - ret = fu_context_load_hwinfo(ctx, &error); + ret = fu_context_load_hwinfo(ctx, FU_CONTEXT_HWID_FLAG_NONE, &error); g_assert_no_error(error); g_assert_true(ret); diff --git a/plugins/synaptics-prometheus/README.md b/plugins/synaptics-prometheus/README.md index b452f3195..f714cd363 100644 --- a/plugins/synaptics-prometheus/README.md +++ b/plugins/synaptics-prometheus/README.md @@ -1,4 +1,6 @@ -# Synaptics Prometheus +--- +title: Plugin: Synaptics Prometheus +--- ## Introduction @@ -12,7 +14,7 @@ that is used when flashing the image. This plugin supports the following protocol ID: -* com.synaptics.prometheus +* `com.synaptics.prometheus` ## GUID Generation diff --git a/plugins/synaptics-rmi/README.md b/plugins/synaptics-rmi/README.md index a06bd8bf1..2ced3068b 100644 --- a/plugins/synaptics-rmi/README.md +++ b/plugins/synaptics-rmi/README.md @@ -1,4 +1,6 @@ -# Synaptics RMI4 +--- +title: Plugin: Synaptics RMI4 +--- ## Introduction @@ -31,7 +33,7 @@ a proprietary (but documented) file format. This plugin supports the following protocol ID: -* com.synaptics.rmi +* `com.synaptics.rmi` ## External Interface Access diff --git a/plugins/synaptics-rmi/fu-synaptics-rmi-device.h b/plugins/synaptics-rmi/fu-synaptics-rmi-device.h index 1bfc683e5..83dc07c01 100644 --- a/plugins/synaptics-rmi/fu-synaptics-rmi-device.h +++ b/plugins/synaptics-rmi/fu-synaptics-rmi-device.h @@ -60,6 +60,7 @@ typedef struct { guint32 build_id; guint8 bootloader_id[2]; guint8 status_addr; + gboolean has_pubkey; } FuSynapticsRmiFlash; #define RMI_F34_HAS_NEW_REG_MAP (1 << 0) @@ -69,11 +70,13 @@ typedef struct { #define RMI_F34_BLOCK_DATA_V1_OFFSET 1 #define RMI_F34_ENABLE_WAIT_MS 300 /* ms */ -#define RMI_F34_IDLE_WAIT_MS 20 /* ms */ +#define RMI_F34_IDLE_WAIT_MS 500 /* ms */ #define RMI_DEVICE_PAGE_SELECT_REGISTER 0xff #define RMI_DEVICE_BUS_SELECT_REGISTER 0xfe +#define RMI_KEY_SIZE_2K 0x100 + typedef enum { RMI_DEVICE_WAIT_FOR_IDLE_FLAG_NONE = 0, RMI_DEVICE_WAIT_FOR_IDLE_FLAG_REFRESH_F34 = (1 << 0), diff --git a/plugins/synaptics-rmi/fu-synaptics-rmi-firmware.c b/plugins/synaptics-rmi/fu-synaptics-rmi-firmware.c index 7f47f68bc..ddf7e1143 100644 --- a/plugins/synaptics-rmi/fu-synaptics-rmi-firmware.c +++ b/plugins/synaptics-rmi/fu-synaptics-rmi-firmware.c @@ -57,10 +57,7 @@ typedef struct __attribute__((packed)) { guint16 container_id; guint8 minor_version; guint8 major_version; - guint8 reserved_08; - guint8 reserved_09; - guint8 reserved_0a; - guint8 reserved_0b; + guint32 signature_size; guint32 container_option_flags; guint32 content_options_length; guint32 content_options_address; @@ -93,6 +90,7 @@ typedef enum { RMI_FIRMWARE_CONTAINER_ID_EXTERNAL_TOUCH_AFE_CONFIG, RMI_FIRMWARE_CONTAINER_ID_UTILITY, RMI_FIRMWARE_CONTAINER_ID_UTILITY_PARAMETER, + RMI_FIRMWARE_CONTAINER_ID_FIXED_LOCATION_DATA = 27, } RmiFirmwareContainerId; static const gchar * @@ -146,6 +144,8 @@ rmi_firmware_container_id_to_string(RmiFirmwareContainerId container_id) return "utility"; if (container_id == RMI_FIRMWARE_CONTAINER_ID_UTILITY_PARAMETER) return "utility-parameter"; + if (container_id == RMI_FIRMWARE_CONTAINER_ID_FIXED_LOCATION_DATA) + return "fixed-location-data"; return NULL; } @@ -169,6 +169,33 @@ fu_synaptics_rmi_firmware_add_image(FuFirmware *firmware, return TRUE; } +static gboolean +fu_synaptics_rmi_firmware_add_image_v10(FuFirmware *firmware, + const gchar *id, + GBytes *fw, + gsize offset, + gsize sz, + gsize sig_sz, + GError **error) +{ + g_autoptr(GBytes) bytes = NULL; + g_autoptr(FuFirmware) img = NULL; + g_autofree gchar *sig_id = NULL; + + if (!fu_synaptics_rmi_firmware_add_image(firmware, id, fw, offset, sz, error)) + return FALSE; + if (sig_sz != 0) { + bytes = fu_bytes_new_offset(fw, offset + sz, sig_sz, error); + if (bytes == NULL) + return FALSE; + img = fu_firmware_new_from_bytes(bytes); + sig_id = g_strdup_printf("%s-signature", id); + fu_firmware_set_id(img, sig_id); + fu_firmware_add_image(firmware, img); + } + return TRUE; +} + static void fu_synaptics_rmi_firmware_export(FuFirmware *firmware, FuFirmwareExportFlags flags, @@ -200,6 +227,7 @@ fu_synaptics_rmi_firmware_parse_v10(FuFirmware *firmware, GBytes *fw, GError **e guint8 product_id[RMI_PRODUCT_ID_LENGTH] = {0x0}; gsize sz = 0; const guint8 *data = g_bytes_get_data(fw, &sz); + guint32 signature_size; if (!fu_memread_uint32_safe(data, sz, @@ -271,10 +299,12 @@ fu_synaptics_rmi_firmware_parse_v10(FuFirmware *firmware, GBytes *fw, GError **e container_id = GUINT16_FROM_LE(desc.container_id); content_addr = GUINT32_FROM_LE(desc.content_address); length = GUINT32_FROM_LE(desc.content_length); - g_debug("RmiFirmwareContainerDescriptor 0x%02x @ 0x%x (len 0x%x)", + signature_size = GUINT32_FROM_LE(desc.signature_size); + g_debug("RmiFirmwareContainerDescriptor 0x%02x @ 0x%x (len 0x%x) sig_size 0x%x", container_id, content_addr, - length); + length, + signature_size); if (length == 0 || length > sz) { g_set_error(error, FWUPD_ERROR, @@ -305,31 +335,64 @@ fu_synaptics_rmi_firmware_parse_v10(FuFirmware *firmware, GBytes *fw, GError **e break; case RMI_FIRMWARE_CONTAINER_ID_UI: case RMI_FIRMWARE_CONTAINER_ID_CORE_CODE: - if (!fu_synaptics_rmi_firmware_add_image(firmware, - "ui", - fw, - content_addr, - length, - error)) + if (!fu_synaptics_rmi_firmware_add_image_v10(firmware, + "ui", + fw, + content_addr, + length, + signature_size, + error)) return FALSE; break; case RMI_FIRMWARE_CONTAINER_ID_FLASH_CONFIG: - if (!fu_synaptics_rmi_firmware_add_image(firmware, - "flash-config", - fw, - content_addr, - length, - error)) + if (!fu_synaptics_rmi_firmware_add_image_v10(firmware, + "flash-config", + fw, + content_addr, + length, + signature_size, + error)) return FALSE; break; case RMI_FIRMWARE_CONTAINER_ID_UI_CONFIG: case RMI_FIRMWARE_CONTAINER_ID_CORE_CONFIG: - if (!fu_synaptics_rmi_firmware_add_image(firmware, - "config", - fw, - content_addr, - length, - error)) + if (!fu_synaptics_rmi_firmware_add_image_v10(firmware, + "config", + fw, + content_addr, + length, + signature_size, + error)) + return FALSE; + break; + case RMI_FIRMWARE_CONTAINER_ID_FIXED_LOCATION_DATA: + if (!fu_synaptics_rmi_firmware_add_image_v10(firmware, + "fixed-location-data", + fw, + content_addr, + length, + signature_size, + error)) + return FALSE; + break; + case RMI_FIRMWARE_CONTAINER_ID_EXTERNAL_TOUCH_AFE_CONFIG: + if (!fu_synaptics_rmi_firmware_add_image_v10(firmware, + "afe-config", + fw, + content_addr, + length, + signature_size, + error)) + return FALSE; + break; + case RMI_FIRMWARE_CONTAINER_ID_DISPLAY_CONFIG: + if (!fu_synaptics_rmi_firmware_add_image_v10(firmware, + "display-config", + fw, + content_addr, + length, + signature_size, + error)) return FALSE; break; case RMI_FIRMWARE_CONTAINER_ID_GENERAL_INFORMATION: @@ -551,6 +614,7 @@ fu_synaptics_rmi_firmware_parse(FuFirmware *firmware, self->kind = RMI_FIRMWARE_KIND_0X; break; case 16: + case 17: if (!fu_synaptics_rmi_firmware_parse_v10(firmware, fw, error)) return FALSE; self->kind = RMI_FIRMWARE_KIND_10; diff --git a/plugins/synaptics-rmi/fu-synaptics-rmi-hid-device.c b/plugins/synaptics-rmi/fu-synaptics-rmi-hid-device.c index abc4a3ac3..3c84bd62d 100644 --- a/plugins/synaptics-rmi/fu-synaptics-rmi-hid-device.c +++ b/plugins/synaptics-rmi/fu-synaptics-rmi-hid-device.c @@ -32,17 +32,17 @@ G_DEFINE_TYPE(FuSynapticsRmiHidDevice, fu_synaptics_rmi_hid_device, FU_TYPE_SYNA #define RMI_DEVICE_DEFAULT_TIMEOUT 2000 -#define HID_RMI4_REPORT_ID 0 -#define HID_RMI4_READ_INPUT_COUNT 1 -#define HID_RMI4_READ_INPUT_DATA 2 -#define HID_RMI4_READ_OUTPUT_ADDR 2 -#define HID_RMI4_READ_OUTPUT_COUNT 4 -#define HID_RMI4_WRITE_OUTPUT_COUNT 1 -#define HID_RMI4_WRITE_OUTPUT_ADDR 2 -#define HID_RMI4_WRITE_OUTPUT_DATA 4 -#define HID_RMI4_FEATURE_MODE 1 +#define HID_RMI4_REPORT_ID 0 +#define HID_RMI4_READ_INPUT_COUNT 1 +#define HID_RMI4_READ_INPUT_DATA 2 +#define HID_RMI4_READ_OUTPUT_ADDR 2 +#define HID_RMI4_READ_OUTPUT_COUNT 4 +#define HID_RMI4_WRITE_OUTPUT_COUNT 1 +#define HID_RMI4_WRITE_OUTPUT_ADDR 2 +#define HID_RMI4_WRITE_OUTPUT_DATA 4 +#define HID_RMI4_FEATURE_MODE 1 #define HID_RMI4_ATTN_INTERRUPT_SOURCES 1 -#define HID_RMI4_ATTN_DATA 2 +#define HID_RMI4_ATTN_DATA 2 /* * This bit disables whatever sleep mode may be selected by the sleep_mode @@ -379,7 +379,8 @@ fu_synaptics_rmi_hid_device_rebind_driver(FuSynapticsRmiDevice *self, GError **e g_autofree gchar *fn_rebind = NULL; g_autofree gchar *fn_unbind = NULL; g_autoptr(GUdevDevice) parent_hid = NULL; - g_autoptr(GUdevDevice) parent_i2c = NULL; + g_autoptr(GUdevDevice) parent_phys = NULL; + g_auto(GStrv) hid_strs = NULL; /* get actual HID node */ parent_hid = g_udev_device_get_parent_with_subsystem(udev_device, "hid", NULL); @@ -392,30 +393,36 @@ fu_synaptics_rmi_hid_device_rebind_driver(FuSynapticsRmiDevice *self, GError **e return FALSE; } + /* build paths */ + parent_phys = g_udev_device_get_parent_with_subsystem(udev_device, "i2c", NULL); + if (parent_phys == NULL) { + parent_phys = g_udev_device_get_parent_with_subsystem(udev_device, "usb", NULL); + if (parent_phys == NULL) { + g_set_error(error, + FWUPD_ERROR, + FWUPD_ERROR_INVALID_FILE, + "no parent device for %s", + g_udev_device_get_sysfs_path(parent_hid)); + return FALSE; + } + } + /* find the physical ID to use for the rebind */ - hid_id = g_udev_device_get_property(parent_hid, "HID_PHYS"); + hid_strs = g_strsplit(g_udev_device_get_sysfs_path(parent_phys), "/", -1); + hid_id = hid_strs[g_strv_length(hid_strs) - 1]; if (hid_id == NULL) { g_set_error(error, FWUPD_ERROR, FWUPD_ERROR_INVALID_FILE, "no HID_PHYS in %s", - g_udev_device_get_sysfs_path(parent_hid)); + g_udev_device_get_sysfs_path(parent_phys)); return FALSE; } + g_debug("HID_PHYS: %s", hid_id); - /* build paths */ - parent_i2c = g_udev_device_get_parent_with_subsystem(udev_device, "i2c", NULL); - if (parent_i2c == NULL) { - g_set_error(error, - FWUPD_ERROR, - FWUPD_ERROR_INVALID_FILE, - "no I2C parent device for %s", - g_udev_device_get_sysfs_path(udev_device)); - return FALSE; - } - driver = g_udev_device_get_driver(parent_i2c); - subsystem = g_udev_device_get_subsystem(parent_i2c); + driver = g_udev_device_get_driver(parent_phys); + subsystem = g_udev_device_get_subsystem(parent_phys); fn_rebind = g_build_filename("/sys/bus/", subsystem, "drivers", driver, "bind", NULL); fn_unbind = g_build_filename("/sys/bus/", subsystem, "drivers", driver, "unbind", NULL); @@ -552,10 +559,9 @@ static void fu_synaptics_rmi_hid_device_set_progress(FuDevice *self, FuProgress *progress) { fu_progress_set_id(progress, G_STRLOC); - fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED); - fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2, "detach"); - fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 94, "write"); - fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 2, "attach"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 3, "detach"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 88, "write"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_RESTART, 7, "attach"); fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 2, "reload"); } diff --git a/plugins/synaptics-rmi/fu-synaptics-rmi-v7-device.c b/plugins/synaptics-rmi/fu-synaptics-rmi-v7-device.c index 3d86bd2c7..b734a674f 100644 --- a/plugins/synaptics-rmi/fu-synaptics-rmi-v7-device.c +++ b/plugins/synaptics-rmi/fu-synaptics-rmi-v7-device.c @@ -22,6 +22,7 @@ typedef enum { RMI_FLASH_CMD_ERASE, RMI_FLASH_CMD_ERASE_AP, RMI_FLASH_CMD_SENSOR_ID, + RMI_FLASH_CMD_SIGNATURE, } RmiFlashCommand; typedef enum { @@ -38,6 +39,8 @@ typedef enum { RMI_PARTITION_ID_DISPLAY_CONFIG, RMI_PARTITION_ID_EXTERNAL_TOUCH_AFE_CONFIG, RMI_PARTITION_ID_UTILITY_PARAMETER, + RMI_PARTITION_ID_PUBKEY, + RMI_PARTITION_ID_FIXED_LOCATION_DATA = 0x0E, } RmiPartitionId; static const gchar * @@ -69,6 +72,10 @@ rmi_firmware_partition_id_to_string(RmiPartitionId partition_id) return "external-touch-afe-config"; if (partition_id == RMI_PARTITION_ID_UTILITY_PARAMETER) return "utility-parameter"; + if (partition_id == RMI_PARTITION_ID_PUBKEY) + return "pubkey"; + if (partition_id == RMI_PARTITION_ID_FIXED_LOCATION_DATA) + return "fixed-location-data"; return NULL; } @@ -116,6 +123,53 @@ fu_synaptics_rmi_v7_device_detach(FuDevice *device, FuProgress *progress, GError return TRUE; } +static gboolean +fu_synaptics_rmi_v7_device_erase_partition(FuSynapticsRmiDevice *self, + guint8 partition_id, + GError **error) +{ + FuSynapticsRmiFunction *f34; + FuSynapticsRmiFlash *flash = fu_synaptics_rmi_device_get_flash(self); + g_autoptr(GByteArray) erase_cmd = g_byte_array_new(); + + /* f34 */ + f34 = fu_synaptics_rmi_device_get_function(self, 0x34, error); + if (f34 == NULL) + return FALSE; + fu_byte_array_append_uint8(erase_cmd, partition_id); + fu_byte_array_append_uint32(erase_cmd, 0x0, G_LITTLE_ENDIAN); + fu_byte_array_append_uint8(erase_cmd, RMI_FLASH_CMD_ERASE); + + fu_byte_array_append_uint8(erase_cmd, flash->bootloader_id[0]); + fu_byte_array_append_uint8(erase_cmd, flash->bootloader_id[1]); + + g_usleep(1000 * 1000); + if (!fu_synaptics_rmi_device_write(self, + f34->data_base + 1, + erase_cmd, + FU_SYNAPTICS_RMI_DEVICE_FLAG_NONE, + error)) { + g_prefix_error(error, "failed to unlock erasing: "); + return FALSE; + } + g_usleep(1000 * 100); + + /* wait for ATTN */ + if (!fu_synaptics_rmi_device_wait_for_idle(self, + RMI_F34_ERASE_WAIT_MS, + RMI_DEVICE_WAIT_FOR_IDLE_FLAG_NONE, + error)) { + g_prefix_error(error, "failed to wait for idle: "); + return FALSE; + } + + if (!fu_synaptics_rmi_device_poll_wait(self, error)) { + g_prefix_error(error, "failed to get flash success: "); + return FALSE; + } + return TRUE; +} + static gboolean fu_synaptics_rmi_v7_device_erase_all(FuSynapticsRmiDevice *self, GError **error) { @@ -130,7 +184,7 @@ fu_synaptics_rmi_v7_device_erase_all(FuSynapticsRmiDevice *self, GError **error) fu_byte_array_append_uint8(erase_cmd, RMI_PARTITION_ID_CORE_CODE); fu_byte_array_append_uint32(erase_cmd, 0x0, G_LITTLE_ENDIAN); - if (flash->bootloader_id[1] == 8) { + if (flash->bootloader_id[1] >= 8) { /* For bootloader v8 */ fu_byte_array_append_uint8(erase_cmd, RMI_FLASH_CMD_ERASE_AP); } else { @@ -141,7 +195,7 @@ fu_synaptics_rmi_v7_device_erase_all(FuSynapticsRmiDevice *self, GError **error) fu_byte_array_append_uint8(erase_cmd, flash->bootloader_id[1]); /* for BL8 device, we need hold 1 seconds after querying F34 status to * avoid not get attention by following giving erase command */ - if (flash->bootloader_id[1] == 8) + if (flash->bootloader_id[1] >= 8) g_usleep(1000 * 1000); if (!fu_synaptics_rmi_device_write(self, f34->data_base + 1, @@ -152,7 +206,7 @@ fu_synaptics_rmi_v7_device_erase_all(FuSynapticsRmiDevice *self, GError **error) return FALSE; } g_usleep(1000 * 100); - if (flash->bootloader_id[1] == 8) { + if (flash->bootloader_id[1] >= 8) { /* wait for ATTN */ if (!fu_synaptics_rmi_device_wait_for_idle(self, RMI_F34_ERASE_WAIT_MS, @@ -249,8 +303,88 @@ fu_synaptics_rmi_v7_device_write_blocks(FuSynapticsRmiDevice *self, return TRUE; } +static gboolean +fu_synaptics_rmi_v7_device_write_partition_signature(FuSynapticsRmiDevice *self, + FuFirmware *firmware, + const gchar *id, + RmiPartitionId partition_id, + GError **error) +{ + FuSynapticsRmiFunction *f34; + FuSynapticsRmiFlash *flash = fu_synaptics_rmi_device_get_flash(self); + g_autoptr(GByteArray) req_offset = g_byte_array_new(); + g_autoptr(GPtrArray) chunks = NULL; + g_autoptr(GBytes) bytes = NULL; + + /* f34 */ + f34 = fu_synaptics_rmi_device_get_function(self, 0x34, error); + if (f34 == NULL) + return FALSE; + + /*check if signature exists */ + bytes = + fu_firmware_get_image_by_id_bytes(firmware, g_strdup_printf("%s-signature", id), NULL); + if (bytes == NULL) { + return TRUE; + } + + /* write partition signature */ + g_debug("writing partition signature %s…", + rmi_firmware_partition_id_to_string(partition_id)); + + fu_byte_array_append_uint16(req_offset, 0x0, G_LITTLE_ENDIAN); + if (!fu_synaptics_rmi_device_write(self, + f34->data_base + 0x2, + req_offset, + FU_SYNAPTICS_RMI_DEVICE_FLAG_NONE, + error)) { + g_prefix_error(error, "failed to write offset: "); + return FALSE; + } + + chunks = + fu_chunk_array_new_from_bytes(bytes, + 0x00, /* start addr */ + 0x00, /* page_sz */ + (gsize)flash->payload_length * (gsize)flash->block_size); + for (guint i = 0; i < chunks->len; i++) { + FuChunk *chk = g_ptr_array_index(chunks, i); + g_autoptr(GByteArray) req_trans_sz = g_byte_array_new(); + g_autoptr(GByteArray) req_cmd = g_byte_array_new(); + fu_byte_array_append_uint16(req_trans_sz, + fu_chunk_get_data_sz(chk) / flash->block_size, + G_LITTLE_ENDIAN); + if (!fu_synaptics_rmi_device_write(self, + f34->data_base + 0x3, + req_trans_sz, + FU_SYNAPTICS_RMI_DEVICE_FLAG_NONE, + error)) { + g_prefix_error(error, "failed to write transfer length: "); + return FALSE; + } + fu_byte_array_append_uint8(req_cmd, RMI_FLASH_CMD_SIGNATURE); + if (!fu_synaptics_rmi_device_write(self, + f34->data_base + 0x4, + req_cmd, + FU_SYNAPTICS_RMI_DEVICE_FLAG_NONE, + error)) { + g_prefix_error(error, "failed to write signature command: "); + return FALSE; + } + if (!fu_synaptics_rmi_v7_device_write_blocks(self, + f34->data_base + 0x5, + fu_chunk_get_data(chk), + fu_chunk_get_data_sz(chk), + error)) + return FALSE; + } + return TRUE; +} + static gboolean fu_synaptics_rmi_v7_device_write_partition(FuSynapticsRmiDevice *self, + FuFirmware *firmware, + const gchar *id, RmiPartitionId partition_id, GBytes *bytes, FuProgress *progress, @@ -295,7 +429,7 @@ fu_synaptics_rmi_v7_device_write_partition(FuSynapticsRmiDevice *self, 0x00, /* page_sz */ (gsize)flash->payload_length * (gsize)flash->block_size); fu_progress_set_id(progress, G_STRLOC); - fu_progress_set_steps(progress, chunks->len); + fu_progress_set_steps(progress, chunks->len + 1); for (guint i = 0; i < chunks->len; i++) { FuChunk *chk = g_ptr_array_index(chunks, i); g_autoptr(GByteArray) req_trans_sz = g_byte_array_new(); @@ -328,6 +462,140 @@ fu_synaptics_rmi_v7_device_write_partition(FuSynapticsRmiDevice *self, return FALSE; fu_progress_step_done(progress); } + if (!fu_synaptics_rmi_v7_device_write_partition_signature(self, + firmware, + id, + partition_id, + error)) + return FALSE; + fu_progress_step_done(progress); + return TRUE; +} + +GBytes * +fu_synaptics_rmi_v7_device_get_pubkey(FuSynapticsRmiDevice *self, GError **error) +{ + FuSynapticsRmiFlash *flash = fu_synaptics_rmi_device_get_flash(self); + FuSynapticsRmiFunction *f34; + const gsize key_size = RMI_KEY_SIZE_2K; + g_autoptr(GByteArray) req_addr_zero = g_byte_array_new(); + g_autoptr(GByteArray) req_cmd = g_byte_array_new(); + g_autoptr(GByteArray) req_partition_id = g_byte_array_new(); + g_autoptr(GByteArray) req_transfer_length = g_byte_array_new(); + g_autoptr(GByteArray) res = NULL; + g_autoptr(GByteArray) pubkey = g_byte_array_new(); + + /* f34 */ + f34 = fu_synaptics_rmi_device_get_function(self, 0x34, error); + if (f34 == NULL) + return NULL; + + /* set partition id for bootloader 7 */ + fu_byte_array_append_uint8(req_partition_id, RMI_PARTITION_ID_PUBKEY); + if (!fu_synaptics_rmi_device_write(self, + f34->data_base + 0x1, + req_partition_id, + FU_SYNAPTICS_RMI_DEVICE_FLAG_NONE, + error)) { + g_prefix_error(error, "failed to write flash partition id: "); + return NULL; + } + fu_byte_array_append_uint16(req_addr_zero, 0x0, G_LITTLE_ENDIAN); + if (!fu_synaptics_rmi_device_write(self, + f34->data_base + 0x2, + req_addr_zero, + FU_SYNAPTICS_RMI_DEVICE_FLAG_NONE, + error)) { + g_prefix_error(error, "failed to write flash config address: "); + return NULL; + } + + /* set transfer length */ + fu_byte_array_append_uint16(req_transfer_length, + key_size / flash->block_size, + G_LITTLE_ENDIAN); + if (!fu_synaptics_rmi_device_write(self, + f34->data_base + 0x3, + req_transfer_length, + FU_SYNAPTICS_RMI_DEVICE_FLAG_NONE, + error)) { + g_prefix_error(error, "failed to set transfer length: "); + return NULL; + } + + /* set command to read */ + fu_byte_array_append_uint8(req_cmd, RMI_FLASH_CMD_READ); + if (!fu_synaptics_rmi_device_write(self, + f34->data_base + 0x4, + req_cmd, + FU_SYNAPTICS_RMI_DEVICE_FLAG_NONE, + error)) { + g_prefix_error(error, "failed to write command to read: "); + return NULL; + } + if (!fu_synaptics_rmi_device_poll_wait(self, error)) { + g_prefix_error(error, "failed to wait: "); + return NULL; + } + + /* read back entire buffer in blocks */ + res = fu_synaptics_rmi_device_read(self, f34->data_base + 0x5, (guint32)key_size, error); + if (res == NULL) { + g_prefix_error(error, "failed to read: "); + return NULL; + } + + for (guint i = 0; i < res->len; i++) + fu_byte_array_append_uint8(pubkey, res->data[res->len - i - 1]); + + /* success */ + return g_byte_array_free_to_bytes(g_steal_pointer(&pubkey)); +} + +gboolean +fu_synaptics_rmi_v7_device_secure_check(FuSynapticsRmiDevice *self, + FuFirmware *firmware, + GError **error) +{ + FuSynapticsRmiFlash *flash = fu_synaptics_rmi_device_get_flash(self); + g_autoptr(GBytes) pubkey = NULL; + g_autoptr(GPtrArray) imgs = NULL; + + if (flash->bootloader_id[1] >= 10 || flash->has_pubkey == FALSE) + return TRUE; + + pubkey = fu_synaptics_rmi_v7_device_get_pubkey(self, error); + if (pubkey == NULL) { + g_prefix_error(error, "get pubkey failed: "); + return FALSE; + } + + imgs = fu_firmware_get_images(firmware); + for (guint i = 0; i < imgs->len; i++) { + FuFirmware *img = g_ptr_array_index(imgs, i); + const gchar *id = fu_firmware_get_id(img); + g_autoptr(GBytes) byte_payload = NULL; + g_autoptr(GBytes) byte_signature = NULL; + g_autofree gchar *id_signature = NULL; + + if (g_str_has_suffix(id, "-signature")) + continue; + id_signature = g_strdup_printf("%s-signature", id); + byte_signature = fu_firmware_get_image_by_id_bytes(firmware, id_signature, NULL); + if (byte_signature == NULL) + continue; + byte_payload = fu_firmware_get_bytes(img, error); + if (byte_payload == NULL) + return FALSE; + if (!fu_synaptics_verify_sha256_signature(byte_payload, + pubkey, + byte_signature, + error)) { + g_prefix_error(error, "%s secure check failed: ", id); + return FALSE; + } + g_debug("%s signature verified successfully", id); + } return TRUE; } @@ -344,15 +612,52 @@ fu_synaptics_rmi_v7_device_write_firmware(FuDevice *device, g_autoptr(GBytes) bytes_bin = NULL; g_autoptr(GBytes) bytes_cfg = NULL; g_autoptr(GBytes) bytes_flashcfg = NULL; + g_autoptr(GBytes) bytes_fld = NULL; + g_autoptr(GBytes) bytes_afe = NULL; + g_autoptr(GBytes) bytes_displayconfig = NULL; /* progress */ fu_progress_set_id(progress, G_STRLOC); - fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED); - fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1, "disable-sleep"); - fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 10, NULL); - fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 20, "flash-config"); - fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 20, "core-code"); - fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 20, "core-config"); + if (flash->bootloader_id[1] > 8) { + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0, "disable-sleep"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_READ, 0, "verify-signature"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 1, "fixed-location-data"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 8, "flash-config"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 9, NULL); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 81, "core-code"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 1, "core-config"); + fu_progress_add_step(progress, + FWUPD_STATUS_DEVICE_WRITE, + 0, + "external-touch-afe-config"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 0, "display-config"); + } else if (flash->bootloader_id[1] == 8) { + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0, "disable-sleep"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_READ, 0, "verify-signature"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 0, "fixed-location-data"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 16, NULL); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 0, "flash-config"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 81, "core-code"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 1, "core-config"); + fu_progress_add_step(progress, + FWUPD_STATUS_DEVICE_WRITE, + 0, + "external-touch-afe-config"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 0, "display-config"); + } else { + fu_progress_add_flag(progress, FU_PROGRESS_FLAG_GUESSED); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 0, "disable-sleep"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_READ, 2, "verify-signature"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 2, "fixed-location-data"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_ERASE, 3, NULL); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 89, "core-code"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 2, "core-config"); + fu_progress_add_step(progress, + FWUPD_STATUS_DEVICE_WRITE, + 2, + "external-touch-afe-config"); + fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_WRITE, 2, "display-config"); + } /* we should be in bootloader mode now, but check anyway */ if (!fu_device_has_flag(device, FWUPD_DEVICE_FLAG_IS_BOOTLOADER)) { @@ -375,17 +680,56 @@ fu_synaptics_rmi_v7_device_write_firmware(FuDevice *device, bytes_cfg = fu_firmware_get_image_by_id_bytes(firmware, "config", error); if (bytes_cfg == NULL) return FALSE; - if (flash->bootloader_id[1] == 8) { + if (flash->bootloader_id[1] >= 8) { bytes_flashcfg = fu_firmware_get_image_by_id_bytes(firmware, "flash-config", error); if (bytes_flashcfg == NULL) return FALSE; } + bytes_fld = fu_firmware_get_image_by_id_bytes(firmware, "fixed-location-data", NULL); + bytes_afe = fu_firmware_get_image_by_id_bytes(firmware, "afe-config", NULL); + bytes_displayconfig = fu_firmware_get_image_by_id_bytes(firmware, "display-config", NULL); /* disable powersaving */ if (!fu_synaptics_rmi_device_disable_sleep(self, error)) return FALSE; fu_progress_step_done(progress); + /* verify signature */ + if (!fu_synaptics_rmi_v7_device_secure_check(self, firmware, error)) + return FALSE; + fu_progress_step_done(progress); + + /* write fld before erase if exists */ + if (bytes_fld != NULL) { + if (!fu_synaptics_rmi_v7_device_write_partition( + self, + firmware, + "fixed-location-data", + RMI_PARTITION_ID_FIXED_LOCATION_DATA, + bytes_fld, + fu_progress_get_child(progress), + error)) + return FALSE; + } + fu_progress_step_done(progress); + + /* write flash config for BL > v8 */ + if (flash->bootloader_id[1] > 8) { + if (!fu_synaptics_rmi_v7_device_erase_partition(self, + RMI_PARTITION_ID_FLASH_CONFIG, + error)) + return FALSE; + if (!fu_synaptics_rmi_v7_device_write_partition(self, + firmware, + "flash-config", + RMI_PARTITION_ID_FLASH_CONFIG, + bytes_flashcfg, + fu_progress_get_child(progress), + error)) + return FALSE; + fu_progress_step_done(progress); + } + /* erase all */ if (!fu_synaptics_rmi_v7_device_erase_all(self, error)) { g_prefix_error(error, "failed to erase all: "); @@ -394,18 +738,22 @@ fu_synaptics_rmi_v7_device_write_firmware(FuDevice *device, fu_progress_step_done(progress); /* write flash config for v8 */ - if (bytes_flashcfg != NULL) { + if (flash->bootloader_id[1] == 8) { if (!fu_synaptics_rmi_v7_device_write_partition(self, + firmware, + "flash-config", RMI_PARTITION_ID_FLASH_CONFIG, bytes_flashcfg, fu_progress_get_child(progress), error)) return FALSE; + fu_progress_step_done(progress); } - fu_progress_step_done(progress); /* write core code */ if (!fu_synaptics_rmi_v7_device_write_partition(self, + firmware, + "ui", RMI_PARTITION_ID_CORE_CODE, bytes_bin, fu_progress_get_child(progress), @@ -415,6 +763,8 @@ fu_synaptics_rmi_v7_device_write_firmware(FuDevice *device, /* write core config */ if (!fu_synaptics_rmi_v7_device_write_partition(self, + firmware, + "config", RMI_PARTITION_ID_CORE_CONFIG, bytes_cfg, fu_progress_get_child(progress), @@ -422,6 +772,33 @@ fu_synaptics_rmi_v7_device_write_firmware(FuDevice *device, return FALSE; fu_progress_step_done(progress); + /* write afe-config if exists */ + if (bytes_afe != NULL) { + if (!fu_synaptics_rmi_v7_device_write_partition( + self, + firmware, + "afe-config", + RMI_PARTITION_ID_EXTERNAL_TOUCH_AFE_CONFIG, + bytes_afe, + fu_progress_get_child(progress), + error)) + return FALSE; + } + fu_progress_step_done(progress); + + /* write display config if exists */ + if (bytes_displayconfig != NULL) { + if (!fu_synaptics_rmi_v7_device_write_partition(self, + firmware, + "display-config", + RMI_PARTITION_ID_DISPLAY_CONFIG, + bytes_displayconfig, + fu_progress_get_child(progress), + error)) + return FALSE; + } + fu_progress_step_done(progress); + /* success */ return TRUE; } @@ -445,6 +822,7 @@ fu_synaptics_rmi_device_read_flash_config_v7(FuSynapticsRmiDevice *self, GError g_autoptr(GByteArray) req_partition_id = g_byte_array_new(); g_autoptr(GByteArray) req_transfer_length = g_byte_array_new(); g_autoptr(GByteArray) res = NULL; + gsize partition_size = sizeof(RmiPartitionTbl); /* f34 */ f34 = fu_synaptics_rmi_device_get_function(self, 0x34, error); @@ -518,8 +896,11 @@ fu_synaptics_rmi_device_read_flash_config_v7(FuSynapticsRmiDevice *self, GError FU_DUMP_FLAGS_NONE); } + if ((res->data[0] & 0x0f) == 1) + partition_size = sizeof(RmiPartitionTbl) + 2; + /* parse the config length */ - for (guint i = 0x2; i < res->len; i += sizeof(RmiPartitionTbl)) { + for (guint i = 0x2; i < res->len; i += partition_size) { RmiPartitionTbl tbl; if (!fu_memcpy_safe((guint8 *)&tbl, sizeof(tbl), @@ -541,6 +922,10 @@ fu_synaptics_rmi_device_read_flash_config_v7(FuSynapticsRmiDevice *self, GError flash->block_count_fw = tbl.partition_len; continue; } + if (tbl.partition_id == RMI_PARTITION_ID_PUBKEY) { + flash->has_pubkey = TRUE; + continue; + } if (tbl.partition_id == RMI_PARTITION_ID_NONE) break; } diff --git a/plugins/synaptics-rmi/fu-synaptics-rmi-v7-device.h b/plugins/synaptics-rmi/fu-synaptics-rmi-v7-device.h index 05ed59597..88ddb211c 100644 --- a/plugins/synaptics-rmi/fu-synaptics-rmi-v7-device.h +++ b/plugins/synaptics-rmi/fu-synaptics-rmi-v7-device.h @@ -20,3 +20,9 @@ gboolean fu_synaptics_rmi_v7_device_setup(FuSynapticsRmiDevice *self, GError **error); gboolean fu_synaptics_rmi_v7_device_query_status(FuSynapticsRmiDevice *self, GError **error); +gboolean +fu_synaptics_rmi_v7_device_secure_check(FuSynapticsRmiDevice *self, + FuFirmware *firmware, + GError **error); +GBytes * +fu_synaptics_rmi_v7_device_get_pubkey(FuSynapticsRmiDevice *self, GError **error); diff --git a/plugins/system76-launch/README.md b/plugins/system76-launch/README.md index 4e971e849..1829d656a 100644 --- a/plugins/system76-launch/README.md +++ b/plugins/system76-launch/README.md @@ -1,4 +1,6 @@ -# System76 Launch +--- +title: Plugin: System76 Launch +--- ## Introduction @@ -14,6 +16,7 @@ These devices use the standard USB DeviceInstanceId values, e.g. * `USB\VID_3384&PID_0001&REV_0001` * `USB\VID_3384&PID_0005&REV_0001` * `USB\VID_3384&PID_0006&REV_0001` +* `USB\VID_3384&PID_0007&REV_0001` ## Update Behavior diff --git a/plugins/system76-launch/system76-launch.quirk b/plugins/system76-launch/system76-launch.quirk index a5bc2ef70..971480ded 100644 --- a/plugins/system76-launch/system76-launch.quirk +++ b/plugins/system76-launch/system76-launch.quirk @@ -12,3 +12,8 @@ CounterpartGuid = USB\VID_03EB&PID_2FF9 [USB\VID_3384&PID_0006&REV_0001] Plugin = system76_launch CounterpartGuid = USB\VID_03EB&PID_2FF9 + +# System76 launch_heavy_1 +[USB\VID_3384&PID_0007&REV_0001] +Plugin = system76_launch +CounterpartGuid = USB\VID_03EB&PID_2FF9 diff --git a/plugins/test/README.md b/plugins/test/README.md index a2125918e..513ca397f 100644 --- a/plugins/test/README.md +++ b/plugins/test/README.md @@ -1,4 +1,6 @@ -# Test +--- +title: Plugin: Test +--- ## Introduction diff --git a/plugins/thelio-io/README.md b/plugins/thelio-io/README.md index 866e89369..298c9ce6c 100644 --- a/plugins/thelio-io/README.md +++ b/plugins/thelio-io/README.md @@ -1,4 +1,6 @@ -# Thelio IO +--- +title: Plugin: Thelio IO +--- ## Introduction diff --git a/plugins/thunderbolt/README.md b/plugins/thunderbolt/README.md index 9952a4911..3bce4164e 100644 --- a/plugins/thunderbolt/README.md +++ b/plugins/thunderbolt/README.md @@ -1,4 +1,6 @@ -# Thunderbolt™ +--- +title: Plugin: Thunderbolt +--- ## Introduction @@ -14,7 +16,7 @@ an unspecified binary file format, with vendor specific header. This plugin supports the following protocol ID: -* com.intel.thunderbolt +* `com.intel.thunderbolt` ## GUID Generation diff --git a/plugins/ti-tps6598x/README.md b/plugins/ti-tps6598x/README.md index 3420a848c..ab7f03f6b 100644 --- a/plugins/ti-tps6598x/README.md +++ b/plugins/ti-tps6598x/README.md @@ -1,4 +1,6 @@ -# Texas Instruments TPS6598x +--- +title: Plugin: TI TPS6598x +--- ## Introduction @@ -13,7 +15,7 @@ signed binary file. This plugin supports the following protocol ID: -* com.ti.tps6598x +* `com.ti.tps6598x` ## GUID Generation @@ -25,8 +27,8 @@ These devices use the standard USB DeviceInstanceId values, e.g. Child devices also have an additional instance IDs which corresponds to the index, e.g. -* `USB\VID_2188&PID_5988&REV_0714&PD_00 -* `USB\VID_2188&PID_5988&PD_00 +* `USB\VID_2188&PID_5988&REV_0714&PD_00` +* `USB\VID_2188&PID_5988&PD_00` ## Update Behavior diff --git a/plugins/tpm/README.md b/plugins/tpm/README.md index 9b8d7357f..30371ba68 100644 --- a/plugins/tpm/README.md +++ b/plugins/tpm/README.md @@ -1,4 +1,6 @@ -# TPM +--- +title: Plugin: TPM +--- ## Introduction diff --git a/plugins/uefi-capsule/README.md b/plugins/uefi-capsule/README.md index 311650f5f..915d38712 100644 --- a/plugins/uefi-capsule/README.md +++ b/plugins/uefi-capsule/README.md @@ -1,4 +1,6 @@ -# UEFI Capsule +--- +title: Plugin: UEFI Capsule +--- ## Introduction @@ -37,7 +39,7 @@ for details. This plugin supports the following protocol ID: -* org.uefi.capsule +* `org.uefi.capsule` ## Update Behavior diff --git a/plugins/uefi-capsule/fu-uefi-tool.c b/plugins/uefi-capsule/fu-uefi-tool.c index 55dc42389..162db57d3 100644 --- a/plugins/uefi-capsule/fu-uefi-tool.c +++ b/plugins/uefi-capsule/fu-uefi-tool.c @@ -336,7 +336,7 @@ main(int argc, char *argv[]) g_autoptr(GError) error_local = NULL; /* load SMBIOS */ - if (!fu_context_load_hwinfo(ctx, &error_local)) { + if (!fu_context_load_hwinfo(ctx, FU_CONTEXT_HWID_FLAG_LOAD_ALL, &error_local)) { g_printerr("failed: %s\n", error_local->message); return EXIT_FAILURE; } @@ -464,7 +464,7 @@ main(int argc, char *argv[]) fu_progress_add_step(progress, FWUPD_STATUS_DEVICE_BUSY, 1, "cleanup"); /* load SMBIOS */ - if (!fu_context_load_hwinfo(ctx, &error_local)) { + if (!fu_context_load_hwinfo(ctx, FU_CONTEXT_HWID_FLAG_LOAD_ALL, &error_local)) { g_printerr("failed: %s\n", error_local->message); return EXIT_FAILURE; } diff --git a/plugins/uefi-capsule/fwupd.grub.conf.in b/plugins/uefi-capsule/fwupd.grub.conf.in index 9c3a22f23..6d17fc3cc 100755 --- a/plugins/uefi-capsule/fwupd.grub.conf.in +++ b/plugins/uefi-capsule/fwupd.grub.conf.in @@ -14,8 +14,8 @@ if [ -f @localstatedir@/lib/fwupd/uefi_capsule.conf ] && cat << EOF menuentry 'Linux Firmware Updater' \$menuentry_id_option 'fwupd' { EOF - ${grub_probe:?} - prepare_grub_to_access_device '`${grub_probe} --target=device \${ESP}` | sed -e "s/^/\t/"' + ${grub_probe:?} --version > /dev/null + prepare_grub_to_access_device "$(${grub_probe} --target=device ${ESP})" | sed -e "s/^/\t/" cat << EOF chainloader ${EFI_PATH} } diff --git a/plugins/uefi-dbx/README.md b/plugins/uefi-dbx/README.md index 324f4f302..01ff0f939 100644 --- a/plugins/uefi-dbx/README.md +++ b/plugins/uefi-dbx/README.md @@ -1,4 +1,6 @@ -# UEFI dbx +--- +title: Plugin: UEFI dbx +--- ## Introduction @@ -19,7 +21,7 @@ for details. This plugin supports the following protocol ID: -* org.uefi.dbx +* `org.uefi.dbx` ## GUID Generation diff --git a/plugins/uefi-pk/README.md b/plugins/uefi-pk/README.md index 8dc93566c..f515f55dc 100644 --- a/plugins/uefi-pk/README.md +++ b/plugins/uefi-pk/README.md @@ -1,4 +1,6 @@ -# UEFI PK +--- +title: Plugin: UEFI PK +--- ## Introduction diff --git a/plugins/uefi-recovery/README.md b/plugins/uefi-recovery/README.md index fa535c7e7..55e0e242c 100644 --- a/plugins/uefi-recovery/README.md +++ b/plugins/uefi-recovery/README.md @@ -1,4 +1,6 @@ -# UEFI +--- +title: Plugin: UEFI Recovery +--- ## Introduction diff --git a/plugins/uf2/README.md b/plugins/uf2/README.md index 35ef10e6d..187b7ab1f 100644 --- a/plugins/uf2/README.md +++ b/plugins/uf2/README.md @@ -1,4 +1,6 @@ -# UF2 Devices +--- +title: Plugin: UF2 +--- ## Introduction diff --git a/plugins/upower/README.md b/plugins/upower/README.md index e3ebb5f65..2ed543a91 100644 --- a/plugins/upower/README.md +++ b/plugins/upower/README.md @@ -1,4 +1,6 @@ -# UPower +--- +title: Plugin: UPower +--- ## Introduction diff --git a/plugins/usi-dock/README.md b/plugins/usi-dock/README.md index 0cf1a70cb..98b584a55 100644 --- a/plugins/usi-dock/README.md +++ b/plugins/usi-dock/README.md @@ -1,4 +1,6 @@ -# USI Dock +--- +title: Plugin: USI Dock +--- ## Introduction @@ -7,7 +9,7 @@ is provided by the DMC bcdDevice. This plugin supports the following protocol ID: -* com.usi.dock +* `com.usi.dock` ## GUID Generation diff --git a/plugins/vbe/README.md b/plugins/vbe/README.md index 6b6d3366a..96f6439a7 100644 --- a/plugins/vbe/README.md +++ b/plugins/vbe/README.md @@ -1,4 +1,6 @@ -# Verified Boot for Embedded (VBE) +--- +title: Plugin: VBE — Verified Boot for Embedded +--- ## Introduction diff --git a/plugins/vbe/fu-vbe-device.c b/plugins/vbe/fu-vbe-device.c index 8688a95e9..e739cf0a1 100644 --- a/plugins/vbe/fu-vbe-device.c +++ b/plugins/vbe/fu-vbe-device.c @@ -10,13 +10,12 @@ #include "fu-vbe-device.h" -enum { PROP_0, PROP_VBE_METHOD, PROP_FDT_ROOT, PROP_FDT_NODE, PROP_VBE_DIR, PROP_LAST }; +enum { PROP_0, PROP_VBE_METHOD, PROP_FDT_ROOT, PROP_FDT_NODE, PROP_LAST }; typedef struct { FuFdtImage *fdt_root; FuFdtImage *fdt_node; gchar **compatible; - gchar *vbe_dir; } FuVbeDevicePrivate; G_DEFINE_TYPE_WITH_PRIVATE(FuVbeDevice, fu_vbe_device, FU_TYPE_DEVICE) @@ -28,7 +27,6 @@ fu_vbe_device_to_string(FuDevice *device, guint idt, GString *str) FuVbeDevice *self = FU_VBE_DEVICE(device); FuVbeDevicePrivate *priv = GET_PRIVATE(self); - fu_string_append(str, idt, "VbeDir", priv->vbe_dir); if (priv->compatible != NULL) { g_autofree gchar *tmp = g_strjoinv(":", priv->compatible); fu_string_append(str, idt, "Compatible", tmp); @@ -59,14 +57,6 @@ fu_vbe_device_get_compatible(FuVbeDevice *self) return priv->compatible; } -const gchar * -fu_vbe_device_get_dir(FuVbeDevice *self) -{ - FuVbeDevicePrivate *priv = GET_PRIVATE(self); - g_return_val_if_fail(FU_IS_VBE_DEVICE(self), NULL); - return priv->vbe_dir; -} - static void fu_vbe_device_init(FuVbeDevice *self) { @@ -131,9 +121,6 @@ fu_vbe_device_get_property(GObject *obj, guint prop_id, GValue *value, GParamSpe case PROP_FDT_NODE: g_value_set_object(value, priv->fdt_node); break; - case PROP_VBE_DIR: - g_value_set_string(value, priv->vbe_dir); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec); break; @@ -152,10 +139,6 @@ fu_vbe_device_set_property(GObject *obj, guint prop_id, const GValue *value, GPa case PROP_FDT_NODE: g_set_object(&priv->fdt_node, g_value_get_object(value)); break; - case PROP_VBE_DIR: - g_free(priv->vbe_dir); - priv->vbe_dir = g_strdup(g_value_get_string(value)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec); break; @@ -167,7 +150,6 @@ fu_vbe_device_finalize(GObject *obj) { FuVbeDevice *self = FU_VBE_DEVICE(obj); FuVbeDevicePrivate *priv = GET_PRIVATE(self); - g_free(priv->vbe_dir); g_strfreev(priv->compatible); if (priv->fdt_root != NULL) g_object_unref(priv->fdt_root); @@ -202,14 +184,6 @@ fu_vbe_device_class_init(FuVbeDeviceClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME); g_object_class_install_property(object_class, PROP_FDT_NODE, pspec); - pspec = - g_param_spec_string("vbe-dir", - NULL, - "Directory containing state file for each VBE method", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME); - g_object_class_install_property(object_class, PROP_VBE_DIR, pspec); - object_class->constructed = fu_vbe_device_constructed; object_class->finalize = fu_vbe_device_finalize; klass_device->to_string = fu_vbe_device_to_string; diff --git a/plugins/vbe/fu-vbe-device.h b/plugins/vbe/fu-vbe-device.h index 049c96a3e..7c0398ca7 100644 --- a/plugins/vbe/fu-vbe-device.h +++ b/plugins/vbe/fu-vbe-device.h @@ -21,5 +21,3 @@ FuFdtImage * fu_vbe_device_get_fdt_node(FuVbeDevice *self); gchar ** fu_vbe_device_get_compatible(FuVbeDevice *self); -const gchar * -fu_vbe_device_get_dir(FuVbeDevice *self); diff --git a/plugins/vbe/fu-vbe-plugin.c b/plugins/vbe/fu-vbe-plugin.c index aba93bd27..88674a4f6 100644 --- a/plugins/vbe/fu-vbe-plugin.c +++ b/plugins/vbe/fu-vbe-plugin.c @@ -13,8 +13,6 @@ struct _FuVbePlugin { FuPlugin parent_instance; - FuFirmware *fdt; - gchar *vbe_dir; }; G_DEFINE_TYPE(FuVbePlugin, fu_vbe_plugin, FU_TYPE_PLUGIN) @@ -25,7 +23,6 @@ fu_vbe_plugin_coldplug_img(FuPlugin *plugin, FuFdtImage *fdt_node, GError **error) { - FuVbePlugin *self = FU_VBE_PLUGIN(plugin); GType device_gtype = G_TYPE_INVALID; g_autofree gchar *compatible = NULL; g_auto(GStrv) split = NULL; @@ -85,8 +82,6 @@ fu_vbe_plugin_coldplug_img(FuPlugin *plugin, fdt_root, "fdt-node", fdt_node, - "vbe-dir", - self->vbe_dir, NULL); fu_plugin_device_add(plugin, dev); return TRUE; @@ -95,13 +90,15 @@ fu_vbe_plugin_coldplug_img(FuPlugin *plugin, static gboolean fu_vbe_plugin_coldplug(FuPlugin *plugin, FuProgress *progress, GError **error) { - FuVbePlugin *self = FU_VBE_PLUGIN(plugin); + g_autoptr(FuFirmware) fdt = NULL; g_autoptr(FuFdtImage) fdt_root = NULL; g_autoptr(GPtrArray) fdt_imgs = NULL; /* get compatible from root node */ - fdt_root = - fu_fdt_firmware_get_image_by_path(FU_FDT_FIRMWARE(self->fdt), "/chosen/fwupd", error); + fdt = fu_context_get_fdt(fu_plugin_get_context(plugin), error); + if (fdt == NULL) + return FALSE; + fdt_root = fu_fdt_firmware_get_image_by_path(FU_FDT_FIRMWARE(fdt), "/chosen/fwupd", error); if (fdt_root == NULL) return FALSE; fdt_imgs = fu_firmware_get_images(FU_FIRMWARE(fdt_root)); @@ -127,77 +124,14 @@ fu_vbe_plugin_coldplug(FuPlugin *plugin, FuProgress *progress, GError **error) return TRUE; } -static GFile * -fu_vbe_plugin_get_bfname(FuPlugin *plugin) -{ - FuVbePlugin *self = FU_VBE_PLUGIN(plugin); - g_autofree gchar *bfname_local = NULL; - g_autofree gchar *bfname_sys = NULL; - g_autofree gchar *sysfsdir = NULL; - - /* look for override first, fall back to system value */ - bfname_local = g_build_filename(self->vbe_dir, "system.dtb", NULL); - if (g_file_test(bfname_local, G_FILE_TEST_EXISTS)) - return g_file_new_for_path(bfname_local); - - /* actual hardware value */ - sysfsdir = fu_path_from_kind(FU_PATH_KIND_SYSFSDIR_FW); - bfname_sys = g_build_filename(sysfsdir, "fdt", NULL); - return g_file_new_for_path(bfname_sys); -} - -static gboolean -fu_vbe_plugin_startup(FuPlugin *plugin, FuProgress *progress, GError **error) -{ - FuVbePlugin *self = FU_VBE_PLUGIN(plugin); - g_autoptr(GFile) file = NULL; - - /* look for override first, fall back to system value */ - file = fu_vbe_plugin_get_bfname(plugin); - if (!fu_firmware_parse_file(self->fdt, file, FWUPD_INSTALL_FLAG_NO_SEARCH, error)) { - g_prefix_error(error, "failed to parse FDT: "); - return FALSE; - } - - /* success */ - return TRUE; -} - -static void -fu_vbe_plugin_to_string(FuPlugin *plugin, guint idt, GString *str) -{ - FuVbePlugin *self = FU_VBE_PLUGIN(plugin); - fu_string_append(str, idt, "VbeDir", self->vbe_dir); -} - static void fu_vbe_plugin_init(FuVbePlugin *self) { - g_autofree gchar *localstatedir_pkg = NULL; - - /* where we can store the override and also image state */ - localstatedir_pkg = fu_path_from_kind(FU_PATH_KIND_LOCALSTATEDIR_PKG); - self->vbe_dir = g_build_filename(localstatedir_pkg, "vbe", NULL); - self->fdt = fu_fdt_firmware_new(); -} - -static void -fu_vbe_finalize(GObject *obj) -{ - FuVbePlugin *self = FU_VBE_PLUGIN(obj); - g_free(self->vbe_dir); - g_object_unref(self->fdt); - G_OBJECT_CLASS(fu_vbe_plugin_parent_class)->finalize(obj); } static void fu_vbe_plugin_class_init(FuVbePluginClass *klass) { FuPluginClass *plugin_class = FU_PLUGIN_CLASS(klass); - GObjectClass *object_class = G_OBJECT_CLASS(klass); - - object_class->finalize = fu_vbe_finalize; - plugin_class->to_string = fu_vbe_plugin_to_string; - plugin_class->startup = fu_vbe_plugin_startup; plugin_class->coldplug = fu_vbe_plugin_coldplug; } diff --git a/plugins/vli/README.md b/plugins/vli/README.md index 4a79a53c5..552cbb47a 100644 --- a/plugins/vli/README.md +++ b/plugins/vli/README.md @@ -1,4 +1,6 @@ -# VIA +--- +title: Plugin: VIA +--- ## Introduction @@ -11,9 +13,9 @@ an undisclosed binary file format. This plugin supports the following protocol ID: -* com.vli.i2c -* com.vli.pd -* com.vli.usbhub +* `com.vli.i2c` +* `com.vli.pd` +* `com.vli.usbhub` ## GUID Generation diff --git a/plugins/vli/meson.build b/plugins/vli/meson.build index 1a9305a19..ad5f1a762 100644 --- a/plugins/vli/meson.build +++ b/plugins/vli/meson.build @@ -34,6 +34,9 @@ plugin_builtin_vli = static_library('fu_plugin_vli', plugin_builtins += plugin_builtin_vli if get_option('tests') + env = environment() + env.set('G_TEST_SRCDIR', meson.current_source_dir()) + env.set('G_TEST_BUILDDIR', meson.current_build_dir()) e = executable( 'vli-self-test', sources: [ @@ -50,6 +53,6 @@ if get_option('tests') install_rpath: libdir_pkg, install_dir: installed_test_bindir, ) - test('vli-self-test', e) # added to installed-tests + test('vli-self-test', e, env: env) # added to installed-tests endif endif diff --git a/plugins/wacom-raw/README.md b/plugins/wacom-raw/README.md index 45a20df34..fd4d71563 100644 --- a/plugins/wacom-raw/README.md +++ b/plugins/wacom-raw/README.md @@ -1,4 +1,6 @@ -# Wacom RAW +--- +title: Plugin: Wacom RAW +--- ## Introduction @@ -16,7 +18,7 @@ Intel HEX file format. This plugin supports the following protocol ID: -* com.wacom.raw +* `com.wacom.raw` ## Quirk Use diff --git a/plugins/wacom-usb/README.md b/plugins/wacom-usb/README.md index 8bf4f8fb8..fec277533 100644 --- a/plugins/wacom-usb/README.md +++ b/plugins/wacom-usb/README.md @@ -1,4 +1,6 @@ -# Wacom USB +--- +title: Plugin: Wacom USB +--- ## Introduction @@ -26,7 +28,7 @@ the following formats: This plugin supports the following protocol ID: -* com.wacom.usb +* `com.wacom.usb` ## GUID Generation diff --git a/plugins/wacom-usb/fu-wac-module-bluetooth-id6.c b/plugins/wacom-usb/fu-wac-module-bluetooth-id6.c index 84a8a315a..dd0bb9c37 100644 --- a/plugins/wacom-usb/fu-wac-module-bluetooth-id6.c +++ b/plugins/wacom-usb/fu-wac-module-bluetooth-id6.c @@ -111,14 +111,18 @@ fu_wac_module_bluetooth_id6_write_firmware(FuDevice *device, /* get default image */ fw = fu_firmware_get_bytes(firmware, error); - if (fw == NULL) + if (fw == NULL) { + g_prefix_error(error, "wacom bluetooth-id6 module failed to get bytes: "); return FALSE; + } /* build each data packet */ data = g_bytes_get_data(fw, &len); blocks = fu_wac_module_bluetooth_id6_parse_blocks(data, len, error); - if (blocks == NULL) + if (blocks == NULL) { + g_prefix_error(error, "wacom bluetooth-id6 module failed to parse blocks: "); return FALSE; + } /* start, which will erase the module */ if (!fu_wac_module_set_feature(self, @@ -126,8 +130,10 @@ fu_wac_module_bluetooth_id6_write_firmware(FuDevice *device, blob_start, fu_progress_get_child(progress), FU_WAC_MODULE_ERASE_TIMEOUT, - error)) + error)) { + g_prefix_error(error, "wacom bluetooth-id6 module failed to erase: "); return FALSE; + } fu_progress_step_done(progress); /* data */ @@ -148,8 +154,10 @@ fu_wac_module_bluetooth_id6_write_firmware(FuDevice *device, blob_chunk, fu_progress_get_child(progress), FU_WAC_MODULE_WRITE_TIMEOUT, - error)) + error)) { + g_prefix_error(error, "wacom bluetooth-id6 module failed to write: "); return FALSE; + } /* update progress */ fu_progress_set_percentage_full(fu_progress_get_child(progress), @@ -164,8 +172,10 @@ fu_wac_module_bluetooth_id6_write_firmware(FuDevice *device, NULL, fu_progress_get_child(progress), FU_WAC_MODULE_COMMIT_TIMEOUT, - error)) + error)) { + g_prefix_error(error, "wacom bluetooth-id6 module failed to end: "); return FALSE; + } fu_progress_step_done(progress); /* success */ diff --git a/plugins/wacom-usb/fu-wac-module-bluetooth.c b/plugins/wacom-usb/fu-wac-module-bluetooth.c index d839d1292..3f3fb3741 100644 --- a/plugins/wacom-usb/fu-wac-module-bluetooth.c +++ b/plugins/wacom-usb/fu-wac-module-bluetooth.c @@ -136,14 +136,18 @@ fu_wac_module_bluetooth_write_firmware(FuDevice *device, /* get default image */ fw = fu_firmware_get_bytes(firmware, error); - if (fw == NULL) + if (fw == NULL) { + g_prefix_error(error, "wacom bluetooth module failed to get bytes: "); return FALSE; + } /* build each data packet */ data = g_bytes_get_data(fw, &len); blocks = fu_wac_module_bluetooth_parse_blocks(data, len, TRUE, error); - if (blocks == NULL) + if (blocks == NULL) { + g_prefix_error(error, "wacom bluetooth module failed to parse: "); return FALSE; + } /* start, which will erase the module */ if (!fu_wac_module_set_feature(self, @@ -151,8 +155,10 @@ fu_wac_module_bluetooth_write_firmware(FuDevice *device, blob_start, fu_progress_get_child(progress), FU_WAC_MODULE_ERASE_TIMEOUT, - error)) + error)) { + g_prefix_error(error, "wacom bluetooth module failed to erase: "); return FALSE; + } fu_progress_step_done(progress); /* data */ @@ -173,8 +179,10 @@ fu_wac_module_bluetooth_write_firmware(FuDevice *device, blob_chunk, fu_progress_get_child(progress), FU_WAC_MODULE_WRITE_TIMEOUT, - error)) + error)) { + g_prefix_error(error, "wacom bluetooth module failed to write: "); return FALSE; + } /* update progress */ fu_progress_set_percentage_full(fu_progress_get_child(progress), @@ -189,8 +197,10 @@ fu_wac_module_bluetooth_write_firmware(FuDevice *device, NULL, fu_progress_get_child(progress), FU_WAC_MODULE_FINISH_TIMEOUT, - error)) + error)) { + g_prefix_error(error, "wacom bluetooth module failed to end: "); return FALSE; + } fu_progress_step_done(progress); /* success */ diff --git a/plugins/wacom-usb/fu-wac-module-scaler.c b/plugins/wacom-usb/fu-wac-module-scaler.c index a65cfbf7b..bd953507d 100644 --- a/plugins/wacom-usb/fu-wac-module-scaler.c +++ b/plugins/wacom-usb/fu-wac-module-scaler.c @@ -84,14 +84,18 @@ fu_wac_module_scaler_write_firmware(FuDevice *device, /* get default image */ fw = fu_firmware_get_bytes(firmware, error); - if (fw == NULL) + if (fw == NULL) { + g_prefix_error(error, "wacom scaler module failed to get bytes: "); return FALSE; + } /* build each data packet */ data = g_bytes_get_data(fw, &len); blocks = fu_wac_module_scaler_parse_blocks(data, len, error); - if (blocks == NULL) + if (blocks == NULL) { + g_prefix_error(error, "wacom scaler module failed to parse blocks: "); return FALSE; + } /* start, which will erase the module */ if (!fu_wac_module_set_feature(self, @@ -99,8 +103,10 @@ fu_wac_module_scaler_write_firmware(FuDevice *device, blob_start, fu_progress_get_child(progress), FU_WAC_MODULE_ERASE_TIMEOUT, - error)) + error)) { + g_prefix_error(error, "wacom scaler module failed to erase: "); return FALSE; + } fu_progress_step_done(progress); @@ -122,8 +128,10 @@ fu_wac_module_scaler_write_firmware(FuDevice *device, blob_chunk, fu_progress_get_child(progress), FU_WAC_MODULE_WRITE_TIMEOUT, - error)) + error)) { + g_prefix_error(error, "wacom scaler module failed to write: "); return FALSE; + } /* update progress */ fu_progress_set_percentage_full(fu_progress_get_child(progress), i + 1, @@ -137,8 +145,10 @@ fu_wac_module_scaler_write_firmware(FuDevice *device, NULL, fu_progress_get_child(progress), FU_WAC_MODULE_COMMIT_TIMEOUT, - error)) + error)) { + g_prefix_error(error, "wacom scaler module failed to end: "); return FALSE; + } fu_progress_step_done(progress); /* success */ diff --git a/plugins/wacom-usb/fu-wac-module-touch.c b/plugins/wacom-usb/fu-wac-module-touch.c index 47b9964b5..a49449e93 100644 --- a/plugins/wacom-usb/fu-wac-module-touch.c +++ b/plugins/wacom-usb/fu-wac-module-touch.c @@ -41,8 +41,10 @@ fu_wac_module_touch_write_firmware(FuDevice *device, /* build each data packet */ fw = fu_firmware_get_bytes(firmware, error); - if (fw == NULL) + if (fw == NULL) { + g_prefix_error(error, "wacom touch module failed to get bytes: "); return FALSE; + } chunks = fu_chunk_array_new_from_bytes(fw, fu_firmware_get_addr(firmware), 0x0, /* page_sz */ @@ -54,8 +56,10 @@ fu_wac_module_touch_write_firmware(FuDevice *device, NULL, fu_progress_get_child(progress), FU_WAC_MODULE_ERASE_TIMEOUT, - error)) + error)) { + g_prefix_error(error, "wacom touch module failed to erase: "); return FALSE; + } fu_progress_step_done(progress); /* data */ @@ -77,8 +81,10 @@ fu_wac_module_touch_write_firmware(FuDevice *device, fu_chunk_get_data_sz(chk), 0x0, /* src */ fu_chunk_get_data_sz(chk), - error)) + error)) { + g_prefix_error(error, "wacom touch module failed to memcpy: "); return FALSE; + } blob_chunk = g_bytes_new(buf, sizeof(buf)); if (!fu_wac_module_set_feature(self, FU_WAC_MODULE_COMMAND_DATA, @@ -103,8 +109,10 @@ fu_wac_module_touch_write_firmware(FuDevice *device, NULL, fu_progress_get_child(progress), FU_WAC_MODULE_FINISH_TIMEOUT, - error)) + error)) { + g_prefix_error(error, "wacom touch module failed to end: "); return FALSE; + } fu_progress_step_done(progress); /* success */ diff --git a/plugins/wistron-dock/README.md b/plugins/wistron-dock/README.md index 39ab0a435..f0b4ee9bf 100644 --- a/plugins/wistron-dock/README.md +++ b/plugins/wistron-dock/README.md @@ -1,4 +1,6 @@ -# Wistron Dock +--- +title: Plugin: Wistron Dock +--- ## Introduction @@ -16,7 +18,7 @@ The archive must contain exactly one file with each of these extensions: This plugin supports the following protocol ID: -* com.wistron.dock +* `com.wistron.dock` ## GUID Generation diff --git a/po/ca.po b/po/ca.po index 0e5239d46..e0a13a8d6 100644 --- a/po/ca.po +++ b/po/ca.po @@ -3,7 +3,7 @@ # This file is distributed under the same license as the fwupd package. # # Translators: -# Antoni Bella Pérez , 2017-2022 +# Antoni Bella Pérez , 2017-2023 # Robert Antoni Buj i Gelonch , 2017 msgid "" msgstr "" @@ -83,6 +83,12 @@ msgstr "Actualització del dispositiu %s" msgid "%s Display Update" msgstr "Actualitza la pantalla %s" +#. TRANSLATORS: Dock refers to the port replicator hardware laptops are +#. * cradled in, or lowered onto +#, c-format +msgid "%s Dock Update" +msgstr "Actualització el moll %s" + #. TRANSLATORS: drive refers to a storage device, e.g. SATA disk #, c-format msgid "%s Drive Update" @@ -94,6 +100,11 @@ msgstr "Actualització del controlador %s" msgid "%s Embedded Controller Update" msgstr "Actualització del controlador incrustat %s" +#. TRANSLATORS: a device that can read your fingerprint pattern +#, c-format +msgid "%s Fingerprint Reader Update" +msgstr "%s actualització del lector d'empremtes" + #. TRANSLATORS: flash refers to solid state storage, e.g. UFS or eMMC #, c-format msgid "%s Flash Drive Update" @@ -105,6 +116,12 @@ msgstr "Actualització de la unitat flaix %s" msgid "%s GPU Update" msgstr "%s Actualització de la GPU" +#. TRANSLATORS: a large pressure-sensitive drawing area typically used +#. * by artists and digital artists +#, c-format +msgid "%s Graphics Tablet Update" +msgstr "%s Actualització de la tauleta gràfica" + #. TRANSLATORS: Keyboard refers to an input device for typing #, c-format msgid "%s Keyboard Update" @@ -161,6 +178,12 @@ msgstr "Actualització del controlador Thunderbolt %s" msgid "%s Touchpad Update" msgstr "%s Actualització del ratolí tàctil" +#. TRANSLATORS: Dock refers to the port replicator device connected +#. * by plugging in a USB cable -- which may or may not also provide power +#, c-format +msgid "%s USB Dock Update" +msgstr "%s actualització del moll USB" + #. TRANSLATORS: Receiver refers to a radio device, e.g. a tiny Bluetooth #. * device that stays in the USB port so the wireless peripheral works #, c-format @@ -1343,6 +1366,10 @@ msgstr "Obté tots els dispositius que admeten actualitzacions de microprogramar msgid "Get all enabled plugins registered with the system" msgstr "Obté tots els connectors habilitats registrats amb el sistema." +#. TRANSLATORS: command description +msgid "Get device report metadata" +msgstr "Obtén les metadades de l'informe del dispositiu" + #. TRANSLATORS: command description msgid "Gets details about a firmware file" msgstr "Obté la informació sobre un fitxer de microprogramari." @@ -2713,6 +2740,10 @@ msgstr "El microprogramari des de %s no és proporcionat per %s, el proveïdor d msgid "The system clock has not been set correctly and downloading files may fail." msgstr "El rellotge del sistema no s'ha configurat correctament i pot fallar la descàrrega de fitxers." +#. TRANSLATORS: warning message shown after update has been scheduled +msgid "The update will continue when the device USB cable has been re-inserted." +msgstr "L'actualització continuarà quan s'hagi tornat a endollar el cable USB del dispositiu." + #. TRANSLATORS: warning message shown after update has been scheduled msgid "The update will continue when the device USB cable has been unplugged and then re-inserted." msgstr "L'actualització continuarà quan el cable USB del dispositiu s'hagi desconnectat i es torni a inserir." diff --git a/po/en_GB.po b/po/en_GB.po index 073394a95..9f9f60ce3 100644 --- a/po/en_GB.po +++ b/po/en_GB.po @@ -4,7 +4,7 @@ # # Translators: # Andi Chandler , 2019-2020,2022 -# Richard Hughes , 2015,2017-2022 +# Richard Hughes , 2015,2017-2023 msgid "" msgstr "" "Project-Id-Version: fwupd\n" @@ -83,6 +83,12 @@ msgstr "%s Device Update" msgid "%s Display Update" msgstr "%s Display Update" +#. TRANSLATORS: Dock refers to the port replicator hardware laptops are +#. * cradled in, or lowered onto +#, c-format +msgid "%s Dock Update" +msgstr "%s Dock Update" + #. TRANSLATORS: drive refers to a storage device, e.g. SATA disk #, c-format msgid "%s Drive Update" @@ -94,11 +100,28 @@ msgstr "%s Drive Update" msgid "%s Embedded Controller Update" msgstr "%s Embedded Controller Update" +#. TRANSLATORS: a device that can read your fingerprint pattern +#, c-format +msgid "%s Fingerprint Reader Update" +msgstr "%s Fingerprint Reader Update" + #. TRANSLATORS: flash refers to solid state storage, e.g. UFS or eMMC #, c-format msgid "%s Flash Drive Update" msgstr "%s Flash Drive Update" +#. TRANSLATORS: GPU refers to a Graphics Processing Unit, e.g. +#. * the "video card" +#, c-format +msgid "%s GPU Update" +msgstr "%s GPU Update" + +#. TRANSLATORS: a large pressure-sensitive drawing area typically used +#. * by artists and digital artists +#, c-format +msgid "%s Graphics Tablet Update" +msgstr "%s Graphics Tablet Update" + #. TRANSLATORS: Keyboard refers to an input device for typing #, c-format msgid "%s Keyboard Update" @@ -155,6 +178,12 @@ msgstr "%s Thunderbolt Controller Update" msgid "%s Touchpad Update" msgstr "%s Touchpad Update" +#. TRANSLATORS: Dock refers to the port replicator device connected +#. * by plugging in a USB cable -- which may or may not also provide power +#, c-format +msgid "%s USB Dock Update" +msgstr "%s USB Dock Update" + #. TRANSLATORS: Receiver refers to a radio device, e.g. a tiny Bluetooth #. * device that stays in the USB port so the wireless peripheral works #, c-format @@ -826,6 +855,10 @@ msgstr "Disables a given remote" msgid "Display version" msgstr "Display version" +#. TRANSLATORS: the OS the release was tested on +msgid "Distribution" +msgstr "Distribution" + #. TRANSLATORS: command line option msgid "Do not check for old metadata" msgstr "Do not check for old metadata" @@ -1333,6 +1366,10 @@ msgstr "Get all devices that support firmware updates" msgid "Get all enabled plugins registered with the system" msgstr "Get all enabled plugins registered with the system" +#. TRANSLATORS: command description +msgid "Get device report metadata" +msgstr "Get device report metadata" + #. TRANSLATORS: command description msgid "Gets details about a firmware file" msgstr "Gets details about a firmware file" @@ -1921,6 +1958,10 @@ msgstr "OK" msgid "OK!" msgstr "OK!" +#. TRANSLATORS: the firmware old version +msgid "Old version" +msgstr "Old version" + #. TRANSLATORS: command line option msgid "Only show single PCR value" msgstr "Only show single PCR value" @@ -2643,6 +2684,15 @@ msgstr "Target" msgid "Test a device using a JSON manifest" msgstr "Test a device using a JSON manifest" +#. TRANSLATORS: when the release was tested +msgid "Tested" +msgstr "Tested" + +#. TRANSLATORS: the %s is a vendor name, e.g. Lenovo +#, c-format +msgid "Tested by %s" +msgstr "Tested by %s" + #. TRANSLATORS: longer description msgid "The Intel Management Engine Key Manifest must be valid so that the device firmware can be trusted by the CPU." msgstr "The Intel Management Engine Key Manifest must be valid so that the device firmware can be trusted by the CPU." @@ -2690,6 +2740,10 @@ msgstr "The firmware from %s is not supplied by %s, the hardware vendor." msgid "The system clock has not been set correctly and downloading files may fail." msgstr "The system clock has not been set correctly and downloading files may fail." +#. TRANSLATORS: warning message shown after update has been scheduled +msgid "The update will continue when the device USB cable has been re-inserted." +msgstr "The update will continue when the device USB cable has been re-inserted." + #. TRANSLATORS: warning message shown after update has been scheduled msgid "The update will continue when the device USB cable has been unplugged and then re-inserted." msgstr "The update will continue when the device USB cable has been unplugged and then re-inserted." @@ -3036,6 +3090,10 @@ msgstr "Verifying…" msgid "Version" msgstr "Version" +#. TRANSLATORS: the fwupd version the release was tested on +msgid "Version[fwupd]" +msgstr "Version[fwupd]" + #. TRANSLATORS: this is a prefix on the console msgid "WARNING:" msgstr "WARNING:" diff --git a/po/fur.po b/po/fur.po index 492ae35ed..3e9957e70 100644 --- a/po/fur.po +++ b/po/fur.po @@ -3,7 +3,7 @@ # This file is distributed under the same license as the fwupd package. # # Translators: -# Fabio Tomat , 2017-2018,2020 +# Fabio Tomat , 2017-2018,2020,2023 msgid "" msgstr "" "Project-Id-Version: fwupd\n" @@ -22,6 +22,41 @@ msgid_plural "%.0f minutes remaining" msgstr[0] "Al mancjie %.0f minût" msgstr[1] "A mancjin %.0f minûts" +#. TRANSLATORS: a specific part of hardware, +#. * the first %s is the device name, e.g. 'Unifying Receiver` +#, c-format +msgid "%s Device Update" +msgstr "Inzornament dispositîf %s" + +#. TRANSLATORS: this is the fallback where we don't know if the release +#. * is updating the system, the device, or a device class, or something else +#. -- +#. * the first %s is the device name, e.g. 'ThinkPad P50` +#, c-format +msgid "%s Update" +msgstr "Inzornament di %s" + +#. TRANSLATORS: the device has a reason it can't update, e.g. laptop lid +#. closed +#, c-format +msgid "%s is not currently updatable" +msgstr "Pal moment nol è pussibil inzornâ %s" + +#. TRANSLATORS: Title: %s is ME kind, e.g. CSME/TXT +#, c-format +msgid "%s manufacturing mode" +msgstr "Modalitât costrutôr %s" + +#. TRANSLATORS: Title: %s is ME kind, e.g. CSME/TXT +#, c-format +msgid "%s override" +msgstr "Override %s" + +#. TRANSLATORS: Title: %s is ME kind, e.g. CSME/TXT +#, c-format +msgid "%s version" +msgstr "Version di %s" + #. TRANSLATORS: this is shown in the MOTD #, c-format msgid "%u device has a firmware upgrade available." @@ -29,6 +64,13 @@ msgid_plural "%u devices have a firmware upgrade available." msgstr[0] "%u dispositîf al à un inzornament firmware disponibil." msgstr[1] "%u dispositîfs a àn un inzornament firmware disponibil." +#. TRANSLATORS: this is shown in the MOTD +#, c-format +msgid "%u device is not the best known configuration." +msgid_plural "%u devices are not the best known configuration." +msgstr[0] "%u dispositîf no e la miôr configurazion cognossude." +msgstr[1] "%u dispositîfs no son la miôr configurazion cognossude." + #. TRANSLATORS: how many local devices can expect updates now #, c-format msgid "%u local device supported" @@ -36,6 +78,18 @@ msgid_plural "%u local devices supported" msgstr[0] "%u dispositîf locâl supuartât" msgstr[1] "%u dispositîfs locâi supuartâts" +#. TRANSLATORS: Title: if hardware enforces control of SPI writes +msgid "AMD Firmware Write Protection" +msgstr "Protezion de scriture dal firmware AMD" + +#. TRANSLATORS: command description +msgid "Activate devices" +msgstr "Ative dispositîfs" + +#. TRANSLATORS: command description +msgid "Activate pending devices" +msgstr "Ative dispositîfs in spiete" + msgid "Activate the new firmware on the device" msgstr "Ative il gnûf firmware sul dispositîf" @@ -43,13 +97,17 @@ msgstr "Ative il gnûf firmware sul dispositîf" msgid "Activating firmware update" msgstr "Ativazion inzornament firmware" +#. TRANSLATORS: shown when shutting down to switch to the new version +msgid "Activating firmware update for" +msgstr "Ativazion dal inzornament firmware par" + #. TRANSLATORS: the age of the metadata msgid "Age" msgstr "Etât" #. TRANSLATORS: should the remote still be enabled msgid "Agree and enable the remote?" -msgstr "Acetâ e abilitâ il rimot?" +msgstr "Acetâ e abilitâ la sorzint esterne?" #. TRANSLATORS: this is a command alias, e.g. 'get-devices' #, c-format @@ -64,6 +122,10 @@ msgstr "Permet di tornâ indaûr aes versions di firmware precedentis" msgid "Allow reinstalling existing firmware versions" msgstr "Permet di tornâ a instalâ lis versions dal firmware esistentis" +#. TRANSLATORS: command line option +msgid "Allow switching firmware branch" +msgstr "Permet di cambiâ ram dal firmware" + #. TRANSLATORS: explain why we want to reboot msgid "An update requires a reboot to complete." msgstr "Un inzornament al à bisugne che si torni a inviâ il computer par finî." @@ -80,6 +142,18 @@ msgstr "Rispuint di sì a dutis lis domandis" msgid "Apply firmware updates" msgstr "Apliche i inzornaments firmware" +#. TRANSLATORS: command line option +msgid "Apply update even when not advised" +msgstr "Apliche l'inzornament ancje cuant che nol è conseât" + +#. TRANSLATORS: command line option +msgid "Apply update files" +msgstr "Apliche i files di inzornament" + +#. TRANSLATORS: actually sending the update to the hardware +msgid "Applying update…" +msgstr "Daûr a aplicâ l'inzornament…" + #. TRANSLATORS: approved firmware has been checked by #. * the domain administrator msgid "Approved firmware:" @@ -87,10 +161,18 @@ msgid_plural "Approved firmware:" msgstr[0] "Firmware aprovât:" msgstr[1] "Firmware aprovâts:" +#. TRANSLATORS: command description +msgid "Attach to firmware mode" +msgstr "Zonte ae modalitât firmware" + #. TRANSLATORS: waiting for user to authenticate msgid "Authenticating…" msgstr "Daûr a autenticâ…" +#. TRANSLATORS: user needs to run a command +msgid "Authentication details are required" +msgstr "I detais de autenticazion a son necessaris" + #. TRANSLATORS: this is the PolicyKit modal dialog msgid "Authentication is required to downgrade the firmware on a removable device" msgstr "La autenticazion e je necessarie par tornâ indaûr ae version precedente dal firmware suntun dispositîf estraibil " @@ -99,14 +181,22 @@ msgstr "La autenticazion e je necessarie par tornâ indaûr ae version precedent msgid "Authentication is required to downgrade the firmware on this machine" msgstr "La autenticazion e je necessarie par tornâ indaûr ae version precedente dal firmware su cheste machine" +#. TRANSLATORS: this is the PolicyKit modal dialog +msgid "Authentication is required to modify BIOS settings" +msgstr "La autenticazion e je necessarie par modificâ lis impostazions dal BIOS" + #. TRANSLATORS: this is the PolicyKit modal dialog msgid "Authentication is required to modify a configured remote used for firmware updates" -msgstr "La autenticazion e je necessarie par modificâ un rimot configurât, doprât pai inzornaments dal firmware" +msgstr "La autenticazion e je necessarie par modificâ une sorzint esterne configurade, doprade pai inzornaments dal firmware" #. TRANSLATORS: this is the PolicyKit modal dialog msgid "Authentication is required to modify daemon configuration" msgstr "La autenticazion e je necessarie par modificâ la configurazion dal demoni" +#. TRANSLATORS: this is the PolicyKit modal dialog +msgid "Authentication is required to read BIOS settings" +msgstr "La autenticazion e je necessarie par lei lis impostazions BIOS" + #. TRANSLATORS: this is the PolicyKit modal dialog msgid "Authentication is required to set the list of approved firmware" msgstr "La autenticazion e je necessarie par stabilî la liste dai firmware aprovâts" @@ -135,6 +225,25 @@ msgstr "La autenticazion e je necessarie par inzornâ il firmware su cheste mach msgid "Authentication is required to update the stored checksums for the device" msgstr "La autenticazion e je necessarie par inzornâ i checksum archiviâts pal dispositîf" +#. TRANSLATORS: description of a BIOS setting +msgid "BIOS updates delivered via LVFS or Windows Update" +msgstr "Inzornaments BIOS dâts fûr vie LVFS o Windows Update" + +msgid "BYTES" +msgstr "BYTES" + +#. TRANSLATORS: there follows a list of hashes +msgid "Blocked firmware files:" +msgstr "Files di firmware blocâts:" + +#. TRANSLATORS: we will not offer this firmware to the user +msgid "Blocking firmware:" +msgstr "Firmware blocât:" + +#. TRANSLATORS: command description +msgid "Build a firmware file" +msgstr "Compile un file di firmware" + #. TRANSLATORS: this is to abort the interactive prompt msgid "Cancel" msgstr "Anule" @@ -143,6 +252,14 @@ msgstr "Anule" msgid "Cancelled" msgstr "Anulât" +#. TRANSLATORS: same or newer update already applied +msgid "Cannot apply as dbx update has already been applied." +msgstr "Impussibil aplicâ viodût che l'inzornament dbx al è za stât aplicât." + +#. TRANSLATORS: the user is using a LiveCD or LiveUSB install disk +msgid "Cannot apply updates on live media" +msgstr "Impussibil aplicâ i inzornaments su supuarts “live”" + #. TRANSLATORS: this is when the daemon state changes msgid "Changed" msgstr "Modificât" @@ -151,6 +268,11 @@ msgstr "Modificât" msgid "Checksum" msgstr "Checksum" +#. TRANSLATORS: get interactive prompt, where branch is the +#. * supplier of the firmware, e.g. "non-free" or "free" +msgid "Choose a branch:" +msgstr "Sielç un ram:" + #. TRANSLATORS: get interactive prompt msgid "Choose a device:" msgstr "Sielç un dispositîf:" @@ -163,6 +285,14 @@ msgstr "Sielç un gjenar di firmware:" msgid "Choose a release:" msgstr "Sielç une publicazion:" +#. TRANSLATORS: get interactive prompt +msgid "Choose a volume:" +msgstr "Sielç un volum:" + +#. TRANSLATORS: get interactive prompt +msgid "Choose the ESP:" +msgstr "Sielç l'ESP:" + #. TRANSLATORS: command description msgid "Clears the results from the last update" msgstr "Al nete i risultâts dal ultin inzornament" @@ -171,6 +301,10 @@ msgstr "Al nete i risultâts dal ultin inzornament" msgid "Command not found" msgstr "Comant no cjatât" +#. TRANSLATORS: command description +msgid "Convert a firmware file" +msgstr "Convertìs un file di firmware" + #. TRANSLATORS: DFU stands for device firmware update msgid "DFU Utility" msgstr "Utilitât DFU" @@ -188,6 +322,14 @@ msgstr "Daûr a decomprimi…" msgid "Description" msgstr "Descrizion" +#. TRANSLATORS: description of device ability +msgid "Device Flags" +msgstr "Variabilis/flags dispositîf" + +#. TRANSLATORS: ID for hardware, typically a SHA1 sum +msgid "Device ID" +msgstr "ID dispositîf" + #. TRANSLATORS: this is when a device is hotplugged msgid "Device added:" msgstr "Dispositîf zontât:" @@ -196,10 +338,36 @@ msgstr "Dispositîf zontât:" msgid "Device changed:" msgstr "Dispositîf modificât:" +#. TRANSLATORS: emulated means we are pretending to be a different model +msgid "Device is emulated" +msgstr "Il dispositîf al è emulât" + +#. TRANSLATORS: Is locked and can be unlocked +msgid "Device is locked" +msgstr "Il dispositîf al è blocât" + +#. TRANSLATORS: currently unreachable, perhaps because it is in a lower power +#. state +#. * or is out of wireless range +msgid "Device is unreachable" +msgstr "Impussibil rivâ al dispositîf" + #. TRANSLATORS: this is when a device is hotplugged msgid "Device removed:" msgstr "Dispositîf gjavât:" +#. TRANSLATORS: longer description +msgid "Device software updates are provided for this device." +msgstr "Su chest dispositîf a son dâts fûr inzornaments." + +#. TRANSLATORS: Device supports a safety mechanism for flashing +msgid "Device stages updates" +msgstr "Il dispositîf al apliche i inzornaments a tapis" + +#. TRANSLATORS: command line option +msgid "Device update method" +msgstr "Metodi di inzornament dal dispositîf" + #. TRANSLATORS: a list of successful updates msgid "Devices that have been updated successfully:" msgstr "Dispositîfs che a son stâts inzornâts cun sucès:" @@ -208,9 +376,41 @@ msgstr "Dispositîfs che a son stâts inzornâts cun sucès:" msgid "Devices that were not updated correctly:" msgstr "Dispositîfs che no son stâts inzornâts ben:" +#. TRANSLATORS: message letting the user know no device upgrade +#. * available due to missing on LVFS +#. TRANSLATORS: message letting the user know no device +#. * upgrade available due to missing on LVFS +#. TRANSLATORS: message letting the user know no device upgrade +#. * available due to missing on LVFS +#. TRANSLATORS: message letting the user know no device +#. * upgrade available due to missing on LVFS +msgid "Devices with no available firmware updates: " +msgstr "Dispositîfs cence inzornaments firmware disponibii:" + +#. TRANSLATORS: Suffix: the HSI result +#. TRANSLATORS: Plugin is inactive and not used +msgid "Disabled" +msgstr "Disabilitât" + msgid "Disabled fwupdate debugging" msgstr "Disabilite il debug di fwupdate" +#. TRANSLATORS: command description +msgid "Disables a given remote" +msgstr "Al disabilite une sorzint esterne indicade" + +#. TRANSLATORS: command line option +msgid "Display version" +msgstr "Visualize la version" + +#. TRANSLATORS: the OS the release was tested on +msgid "Distribution" +msgstr "Distribuzion" + +#. TRANSLATORS: command line option +msgid "Do not check if download remotes should be enabled" +msgstr "No sta controlâ se lis sorzint esternis dal discjariament a àn di sei abilitadis" + #. TRANSLATORS: turn on all debugging msgid "Do not include log domain prefix" msgstr "No sta includi il prefìs il domini dal regjistri" @@ -223,11 +423,25 @@ msgstr "No sta includi il prefìs date/ore" msgid "Do not perform device safety checks" msgstr "No sta eseguî i controi di sigurece dal dispositîf" +#. TRANSLATORS: command line option +msgid "Do not prompt for devices" +msgstr "No sta domandâ dispositîfs" + +#. TRANSLATORS: ask the user if we can update the metadata +msgid "Do you want to refresh this remote now?" +msgstr "Desideristu inzornâ cheste sorzint esterne cumò?" + #. TRANSLATORS: success #. success msgid "Done!" msgstr "Fat!" +#. TRANSLATORS: message letting the user know an downgrade is available +#. * %1 is the device name and %2 and %3 are version strings +#, c-format +msgid "Downgrade %s from %s to %s?" +msgstr "Puartâ indaûr %s de version %s ae %s?" + #. TRANSLATORS: command description msgid "Downgrades the firmware on a device" msgstr "Al torne indaûr ae version precedente dal firmware suntun dispositîf" @@ -244,6 +458,10 @@ msgstr "Daûr a tornâ indaûr ae version precedente di %s de %s ae %s... " msgid "Downgrading %s…" msgstr "Daûr a degradâ di version %s…" +#. TRANSLATORS: command description +msgid "Download a file" +msgstr "Discjame un file" + #. TRANSLATORS: downloading from a remote server msgid "Downloading…" msgstr "Daûr a discjariâ…" @@ -252,17 +470,32 @@ msgstr "Daûr a discjariâ…" msgid "Dump SMBIOS data from a file" msgstr "Scrîf jù i dâts SMBIOS di un file" +#. TRANSLATORS: length of time the update takes to apply +msgid "Duration" +msgstr "Durade" + #. TRANSLATORS: ESP is EFI System Partition msgid "ESP specified was not valid" msgstr "L'ESP specificât nol jere valit" +#. TRANSLATORS: Title: if we are emulating a different host +msgid "Emulated host" +msgstr "Host emulât" + +msgid "Enable" +msgstr "Abilite" + #. TRANSLATORS: command line option msgid "Enable firmware update support on supported systems" msgstr "Abilite il supuart dal inzornament dal firmware sui sistemis supuartâts" +#. TRANSLATORS: a remote here is like a 'repo' or software source +msgid "Enable new remote?" +msgstr "Abilitâ gnove sorzint esterne?" + #. TRANSLATORS: Turn on the remote msgid "Enable this remote?" -msgstr "Abilitâ chest rimot?" +msgstr "Abilitâ cheste sorzint esterne?" #. TRANSLATORS: Suffix: the HSI result #. TRANSLATORS: Plugin is active and in use @@ -273,12 +506,27 @@ msgstr "Abilitât" msgid "Enabled fwupdate debugging" msgstr "Abilite il debug di fwupdate" +#. TRANSLATORS: Plugin is active only if hardware is found +msgid "Enabled if hardware matches" +msgstr "Abilitât se l'hardware al corispuint" + +#. TRANSLATORS: command description +msgid "Enables a given remote" +msgstr "Al abilite une sorzint esterne indicade" + msgid "Enabling this functionality is done at your own risk, which means you have to contact your original equipment manufacturer regarding any problems caused by these updates. Only problems with the update process itself should be filed at $OS_RELEASE:BUG_REPORT_URL$." msgstr "Si abilite cheste funzionalitât a propri pericul, che al significhe che, par ogni probleme causât di chescj inzornaments, si à di contatâ il produtôr origjinâl dal imprest. Dome i problemis che si àn cul sôl procès di inzornament a àn di sei inviâts a $OS_RELEASE:BUG_REPORT_URL$." #. TRANSLATORS: show the user a warning msgid "Enabling this remote is done at your own risk." -msgstr "La abilitazion di chest rimot e ven fate a to pericul." +msgstr "La abilitazion di cheste sorzint esterne e ven fate a to pericul." + +#. TRANSLATORS: Title: Memory contents are encrypted, e.g. Intel TME +msgid "Encrypted RAM" +msgstr "RAM cifrade" + +msgid "Encrypted RAM makes it impossible for information that is stored in device memory to be read if the memory chip is removed and accessed." +msgstr "La RAM cifrade e fâs in mût che al sedi impussibil lei lis informazions archiviadis te memorie dal dispositîf, se il banc di memorie al ven gjavât e doprât." #. TRANSLATORS: command description msgid "Erase all firmware update history" @@ -296,6 +544,15 @@ msgstr "Jes dopo un piçul ritart" msgid "Exit after the engine has loaded" msgstr "Jes dopo che il motôr al à cjariât" +#. TRANSLATORS: command argument: uppercase, spaces->dashes +#. TRANSLATORS: filename argument with path +msgid "FILENAME" +msgstr "NONFILE" + +#. TRANSLATORS: dbx file failed to be applied as an update +msgid "Failed to apply update" +msgstr "Impussibil aplicâ l'inzornament" + #. TRANSLATORS: we could not talk to the fwupd daemon msgid "Failed to connect to daemon" msgstr "No si è rivâts a conetisi al demoni" @@ -308,6 +565,23 @@ msgstr "No si è rivâts a otignî i dispositîfs in spiete" msgid "Failed to install firmware update" msgstr "No si è rivâts a instalâ l'inzornament dal firmware" +#. TRANSLATORS: could not read existing system data +#. TRANSLATORS: could not read file +msgid "Failed to load local dbx" +msgstr "Impussibil cjariâ il dbx locâl" + +#. TRANSLATORS: quirks are device-specific workarounds +msgid "Failed to load quirks" +msgstr "Impussibil cjariâ lis soluzions alternativis" + +#. TRANSLATORS: could not read existing system data +msgid "Failed to load system dbx" +msgstr "Impussibil cjariâ il dbx di sisteme" + +#. TRANSLATORS: another fwupdtool instance is already running +msgid "Failed to lock" +msgstr " Impussibil blocâ" + #. TRANSLATORS: the user didn't read the man page msgid "Failed to parse arguments" msgstr "No si è rivâts a analizâ i argoments" @@ -316,6 +590,14 @@ msgstr "No si è rivâts a analizâ i argoments" msgid "Failed to parse file" msgstr "No si è rivâts a analizâ il file" +#. TRANSLATORS: the user didn't read the man page +msgid "Failed to parse flags for --filter" +msgstr "Impussibil analizâ lis variabilis/flags par --filter" + +#. TRANSLATORS: could not parse file +msgid "Failed to parse local dbx" +msgstr "Impussibil analizâ il dbx locâl" + #. TRANSLATORS: we could not reboot for some reason msgid "Failed to reboot" msgstr " No si è rivâts a tornâ a inviâ il sisteme" @@ -324,6 +606,11 @@ msgstr " No si è rivâts a tornâ a inviâ il sisteme" msgid "Failed to set splash mode" msgstr "No si è rivâts a stabilî la modalitât splash" +#. TRANSLATORS: something with a blocked hash exists +#. * in the users ESP -- which would be bad! +msgid "Failed to validate ESP contents" +msgstr "Impussibil convalidâ i contignûts ESP" + #. TRANSLATORS: filename of the local file msgid "Filename" msgstr "Non file" @@ -332,6 +619,34 @@ msgstr "Non file" msgid "Filename Signature" msgstr "Firme non file" +#. TRANSLATORS: full path of the remote.conf file +msgid "Filename Source" +msgstr "Sorzint dal non di file" + +#. TRANSLATORS: user did not include a filename parameter +msgid "Filename required" +msgstr "Non di file necessari" + +#. TRANSLATORS: Title: if we can verify the firmware checksums +msgid "Firmware Attestation" +msgstr "Attestazion firmware" + +#. TRANSLATORS: Title: firmware refers to the flash chip in the computer +msgid "Firmware BIOS Descriptor" +msgstr "Descritôr BIOS dal firmware" + +#. TRANSLATORS: longer description +msgid "Firmware BIOS Descriptor protects device firmware memory from being tampered with." +msgstr "Il Descritôr BIOS dal firmware al protêç des modifichis la memorie firmware dal dispositîf." + +#. TRANSLATORS: Title: SPI refers to the flash chip in the computer +msgid "Firmware BIOS Region" +msgstr "Regjon BIOS dal firmware" + +#. TRANSLATORS: longer description +msgid "Firmware BIOS Region protects device firmware memory from being tampered with." +msgstr "La Regjon BIOS dal firmware e protêç des modifichis la memorie firmware dal dispositîf ." + #. TRANSLATORS: remote URI msgid "Firmware Base URI" msgstr "URI de base dal firmware" @@ -344,10 +659,34 @@ msgstr "Servizi D-Bus inzornament firmware" msgid "Firmware Update Daemon" msgstr "Demoni di inzornament firmware" +#. TRANSLATORS: Title: if the fwupd plugins are all present and correct +msgid "Firmware Updater Verification" +msgstr "Verifiche dal inzornadôr dal firmware" + +#. TRANSLATORS: Title: if firmware updates are available +msgid "Firmware Updates" +msgstr "Inzornaments firmware" + #. TRANSLATORS: program name msgid "Firmware Utility" msgstr "Utilitât firmware" +#. TRANSLATORS: Title: firmware refers to the flash chip in the computer +msgid "Firmware Write Protection" +msgstr "Protezion di scriture dal firmware" + +#. TRANSLATORS: Title: firmware refers to the flash chip in the computer +msgid "Firmware Write Protection Lock" +msgstr "Bloc di protezion de scriture dal firmware" + +#. TRANSLATORS: longer description +msgid "Firmware Write Protection protects device firmware memory from being tampered with." +msgstr "La protezion de scriture dal firmware e protêç des modifichis la memorie dal firmware dai dispositîfs." + +#. TRANSLATORS: Title: if we can verify the firmware checksums +msgid "Firmware attestation" +msgstr "Attestazion firmware" + #. TRANSLATORS: the metadata is very out of date; %u is a number > 1 #, c-format msgid "Firmware metadata has not been updated for %u day and may not be up to date." @@ -355,12 +694,20 @@ msgid_plural "Firmware metadata has not been updated for %u days and may not be msgstr[0] "I metadâts dal firmware no son stâts inzornâts par %u zornade e a podaressin jessi vielis." msgstr[1] "I metadâts dal firmware no son stâts inzornâts par %u dîs e a podaressin jessi vielis." +#. TRANSLATORS: Title: if firmware updates are available +msgid "Firmware updates" +msgstr "Inzornaments firmware" + msgid "Firmware updates are not supported on this machine." msgstr "Su cheste machine no son supuartâts i inzornaments firmware." msgid "Firmware updates are supported on this machine." msgstr "Su cheste machine a son supuartâts i inzornaments firmware." +#. TRANSLATORS: command line option +msgid "Force the action by relaxing some runtime checks" +msgstr "Sfuarce la azion smolant cualchi control in timp di esecuzion" + msgid "Force the action ignoring all warnings" msgstr "Sfuarce la azion ignorant ducj i avertiments" @@ -368,11 +715,24 @@ msgstr "Sfuarce la azion ignorant ducj i avertiments" msgid "Found" msgstr "Cjatât" +#. TRANSLATORS: global ID common to all similar hardware +msgid "GUID" +msgid_plural "GUIDs" +msgstr[0] "GUID" +msgstr[1] "GUIDs" + #. TRANSLATORS: command argument: uppercase, spaces->dashes msgctxt "A single GUID" msgid "GUID" msgstr "GUID" +msgid "Get BIOS settings" +msgstr "Oten impostazions BIOS" + +#. TRANSLATORS: command description +msgid "Get all device flags supported by fwupd" +msgstr "Oten dutis lis variabilis/flags supuartadis di fwupd" + #. TRANSLATORS: command description msgid "Get all devices that support firmware updates" msgstr "Oten ducj i dispositîfs che a supuartin i inzornaments dal firmware" @@ -383,7 +743,15 @@ msgstr "Al oten detais su un file di firmware" #. TRANSLATORS: command description msgid "Gets the configured remotes" -msgstr "Al oten i rimots configurâts" +msgstr "Al oten lis sorzint esternis configuradis" + +#. TRANSLATORS: firmware approved by the admin +msgid "Gets the list of approved firmware" +msgstr "Al oten la liste dai firmware aprovâts" + +#. TRANSLATORS: command description +msgid "Gets the list of blocked firmware" +msgstr "Al oten la liste dai firmware blocâts" #. TRANSLATORS: command description msgid "Gets the list of updates for connected hardware" @@ -397,20 +765,52 @@ msgstr "Al oten lis publicazions par un dispositîf" msgid "Gets the results from the last update" msgstr "Al oten i risultâts dal ultin inzornament" +#. TRANSLATORS: Title: +#. * https://en.wikipedia.org/wiki/Input%E2%80%93output_memory_management_unit +msgid "IOMMU" +msgstr "IOMMU" + +#. TRANSLATORS: Title: +#. * https://en.wikipedia.org/wiki/Input%E2%80%93output_memory_management_unit +msgid "IOMMU Protection" +msgstr "Protezion IOMMU" + +#. TRANSLATORS: longer description +msgid "IOMMU Protection prevents connected devices from accessing unauthorized parts of system memory." +msgstr "La Protezion IOMMU e impedìs ai dispositîfs colegâts di acedi a parts no autorizadis de memorie dal sisteme." + #. TRANSLATORS: daemon is inactive msgid "Idle…" msgstr "In polse…" +#. TRANSLATORS: Ignore validation safety checks when flashing this device +msgid "Ignore validation safety checks" +msgstr "Ignore la covalide dai controi di sigurece" + +#. TRANSLATORS: command description +msgid "Install a firmware blob on a device" +msgstr "Instale un binari firmware suntun dispositîf" + #. TRANSLATORS: command description msgid "Install a firmware file on this hardware" msgstr "Instale un file firmware su chest hardware" +msgid "Install old version of signed system firmware" +msgstr "Instale la version vecje dal firmware di sisteme firmât" + +msgid "Install old version of unsigned system firmware" +msgstr "Instale la version vecje dal firmware di sisteme cence firme" + msgid "Install signed device firmware" msgstr "Instasle firmware di dispositîf firmât" msgid "Install signed system firmware" msgstr "Instale firmware di sisteme firmât" +#. TRANSLATORS: Install composite firmware on the parent before the child +msgid "Install to parent device first" +msgstr "Instale prime sul dispositîf gjenitôr" + msgid "Install unsigned device firmware" msgstr "Instale firmware di dispositîf cence firme" @@ -430,6 +830,106 @@ msgstr "Daûr a instalâ l'inzornament dal firmware…" msgid "Installing on %s…" msgstr "Daûr a instalâ su %s…" +#. TRANSLATORS: Title: BootGuard is a trademark from Intel +msgid "Intel BootGuard" +msgstr "Intel BootGuard" + +#. TRANSLATORS: Title: BootGuard is a trademark from Intel, +#. * ACM means to verify the integrity of Initial Boot Block +msgid "Intel BootGuard ACM Protected" +msgstr "ACM protet di Intel BootGuard" + +#. TRANSLATORS: Title: BootGuard is a trademark from Intel, +#. * ACM means to verify the integrity of Initial Boot Block +msgid "Intel BootGuard ACM protected" +msgstr "ACM protet di Intel BootGuard" + +#. TRANSLATORS: Title: BootGuard is a trademark from Intel, +#. * error policy is what to do on failure +msgid "Intel BootGuard Error Policy" +msgstr "Politiche sui erôrs di Intel BootGuard" + +msgid "Intel BootGuard Error Policy ensures the device does not continue to start if its device software has been tampered with." +msgstr "La Politiche sui erôrs di Intel BootGuard e garantìs che il dispositîf nol continui a inviâsi se il software dal dispositîf al è stât modificât." + +#. TRANSLATORS: Title: BootGuard is a trademark from Intel, +#. * OTP = one time programmable +msgid "Intel BootGuard OTP fuse" +msgstr "Fusibil OTP di Intel BootGuard" + +#. TRANSLATORS: Title: BootGuard is a trademark from Intel, +#. * verified boot refers to the way the boot process is verified +msgid "Intel BootGuard Verified Boot" +msgstr "Inviament verificât di Intel BootGuard" + +#. TRANSLATORS: Title: BootGuard is a trademark from Intel, +#. * error policy is what to do on failure +msgid "Intel BootGuard error policy" +msgstr "Politiche di erôr di Intel BootGuard" + +#. TRANSLATORS: longer description +msgid "Intel BootGuard prevents unauthorized device software from operating when the device is started." +msgstr "Intel BootGuard al impedìs al software di dispositîfs no-autorizâts dal operâ cuant che il dispositîf al è inviât." + +#. TRANSLATORS: Title: BootGuard is a trademark from Intel, +#. * verified boot refers to the way the boot process is verified +msgid "Intel BootGuard verified boot" +msgstr "Inviament verificât di Intel BootGuard" + +#. TRANSLATORS: Title: CET = Control-flow Enforcement Technology +msgid "Intel CET" +msgstr "Intel CET" + +#. TRANSLATORS: Title: CET = Control-flow Enforcement Technology, +#. * active means being used by the OS +msgid "Intel CET Active" +msgstr "Intel CET atîf" + +#. TRANSLATORS: Title: CET = Control-flow Enforcement Technology, +#. * enabled means supported by the processor +msgid "Intel CET Enabled" +msgstr "Intel CET abilitât" + +#. TRANSLATORS: longer description +msgid "Intel Control-Flow Enforcement Technology detects and prevents certain methods for running malicious software on the device." +msgstr "Intel Control-Flow Enforcement Technology al rileve e al impedìs cierts metodis di esecuzion di software malevul sul dispositîf." + +#. TRANSLATORS: Title: MEI = Intel Management Engine +msgid "Intel Management Engine Manufacturing Mode" +msgstr "Modalitât di produzion dal Intel Management Engine" + +#. TRANSLATORS: Title: MEI = Intel Management Engine, and the "override" is +#. enabled +#. * with a jumper -- luckily it is probably not accessible to end users on +#. consumer +#. * boards +msgid "Intel Management Engine Override" +msgstr "Intel Management Engine Override" + +#. TRANSLATORS: Title: MEI = Intel Management Engine +msgid "Intel Management Engine Version" +msgstr "Version dal Intel Management Engine" + +#. TRANSLATORS: Title: SMAP = Supervisor Mode Access Prevention +msgid "Intel SMAP" +msgstr "Intel SMAP" + +#. TRANSLATORS: longer description +msgid "Intel Supervisor Mode Access Prevention ensures critical parts of device memory are not accessed by less secure programs." +msgstr "Intel Supervisor Mode Access Prevention al garantìs che i programs mancul sigûrs no podedin doprâ ciertis parts critichis de memorie dal dispositîf." + +#. TRANSLATORS: Device cannot be removed easily +msgid "Internal device" +msgstr "Dispositîf interni" + +#. TRANSLATORS: error message +msgid "Invalid arguments" +msgstr "Argoments no valits" + +#. TRANSLATORS: version is older +msgid "Is downgrade" +msgstr "Al è pussibil puartâ indaûr di version" + #. TRANSLATORS: keyring type, e.g. GPG or PKCS7 msgid "Keyring" msgstr "Puarteclâfs" @@ -438,30 +938,98 @@ msgstr "Puarteclâfs" msgid "Less than one minute remaining" msgstr "Al mancje mancul di un minût" +#. TRANSLATORS: Title: lockdown is a security mode of the kernel +msgid "Linux Kernel Lockdown" +msgstr "Lockdown dal kernel Linux" + +#. TRANSLATORS: longer description +msgid "Linux Kernel Lockdown mode prevents administrator (root) accounts from accessing and changing critical parts of system software." +msgstr "La modalitât Lokdown dal Kernel Linux e impedìs ai accounts dai aministradôrs (root) di acedi e cambiâ parts critichis dal software di sisteme." + +msgid "Linux Kernel Swap temporarily saves information to disk as you work. If the information is not protected, it could be accessed by someone if they obtained the disk." +msgstr "Il Swap dal kernel Linux, vâl a dî la memorie di scambi, e salve in mût temporani informazions su disc intant che tu lavoris. Se lis informazions no son protetis, cualchidun al podarès acedi a chestis informazions se al oten il disc." + +#. TRANSLATORS: Title: if it's tainted or not +msgid "Linux Kernel Verification" +msgstr "Verifiche dal kernel Linux" + +msgid "Linux Kernel Verification makes sure that critical system software has not been tampered with. Using device drivers which are not provided with the system can prevent this security feature from working correctly." +msgstr "La verifiche dal kernel Linux e garantìs che il software critic di sisteme nol sedi modificât. Se a vegnin doprâts dirvers di dispositîf che no son stâts dâts fûr cul sisteme, al è pussibil impedî di lavorâ ben a cheste funzionalitât di sigurece." + +#. TRANSLATORS: Title: swap space or swap partition +msgid "Linux Swap" +msgstr "Swap di Linux" + msgid "Linux Vendor Firmware Service (stable firmware)" msgstr "Servizi Firmware dal vendidôr di Linux (firmware stabil)" msgid "Linux Vendor Firmware Service (testing firmware)" msgstr "Servizi Firmware dal vendidôr di Linux (firmware di prove)" +#. TRANSLATORS: Title: if it's tainted or not +msgid "Linux kernel" +msgstr "Kernel Linux" + +#. TRANSLATORS: Title: lockdown is a security mode of the kernel +msgid "Linux kernel lockdown" +msgstr "Lockdown dal kernel Linux" + +#. TRANSLATORS: Title: swap space or swap partition +msgid "Linux swap" +msgstr "Swap di Linux" + +#. TRANSLATORS: command line option +msgid "List entries in dbx" +msgstr "Vôs de liste in dbx" + #. TRANSLATORS: command line option msgid "List supported firmware updates" msgstr "Liste dai inzornaments di firmware supuartâts" +#. TRANSLATORS: command description +msgid "List the available firmware types" +msgstr "Liste i gjenars di firmware disponibii" + #. TRANSLATORS: parsing the firmware information msgid "Loading…" msgstr "Daûr a cjariâ…" +#. TRANSLATORS: Title: MEI = Intel Management Engine +msgid "MEI manufacturing mode" +msgstr "Modalitât costrutôr MEI" + +#. TRANSLATORS: Title: MEI = Intel Management Engine, and the +#. * "override" is the physical PIN that can be driven to +#. * logic high -- luckily it is probably not accessible to +#. * end users on consumer boards +msgid "MEI override" +msgstr "Override MEI" + +msgid "MEI version" +msgstr "Version MEI" + +#. TRANSLATORS: remote URI +msgid "Metadata Signature" +msgstr "Firme metadâts" + #. TRANSLATORS: remote URI msgid "Metadata URI" msgstr "URI metadata" +#. TRANSLATORS: smallest version number installable on device +msgid "Minimum Version" +msgstr "Version minime" + +#. TRANSLATORS: sets something in daemon.conf +msgid "Modifies a daemon configuration value" +msgstr "Al modifiche un valôr di configurazion dal demoni" + #. TRANSLATORS: command description msgid "Modifies a given remote" -msgstr "Al modifiche un rimot furnît" +msgstr "Al modifiche une sorzint esterne indicade" msgid "Modify a configured remote" -msgstr "Modifiche un rimot configurât" +msgstr "Modifiche une sorzint esterne configurade" msgid "Modify daemon configuration" msgstr "Modifiche la configurazion dal demoni" @@ -470,6 +1038,18 @@ msgstr "Modifiche la configurazion dal demoni" msgid "Monitor the daemon for events" msgstr "Monitore il demoni pai events" +#. TRANSLATORS: we're poking around as a power user +msgid "NOTE: This program may only work correctly as root" +msgstr "NOTE: Chest program al pues lavorâ ben dome come root" + +#. TRANSLATORS: the update state of the specific device +msgid "Needs reboot" +msgstr " Al necessite di tornâ a inviâ il sisteme" + +#. TRANSLATORS: version number of new firmware +msgid "New version" +msgstr "Gnove version" + #. TRANSLATORS: user did not tell the tool what to do msgid "No action specified!" msgstr "Nissune azion specificade!" @@ -496,18 +1076,42 @@ msgstr "Nissun plugin cjatât" msgid "No releases available" msgstr "Nissune publicazion disponibile" +#. TRANSLATORS: explain why no metadata available +msgid "No remotes are currently enabled so no metadata is available." +msgstr "In chest moment no je abilitade nissune sorzint esterne duncje nissun metadât al è disponibil." + #. TRANSLATORS: no repositories to download from msgid "No remotes available" -msgstr "Nissun rimot disponibil" +msgstr "Nissune sorzint esterne disponibile" + +#. TRANSLATORS: this is an error string +msgid "No updatable devices" +msgstr "Nissun dispositîf che si pues inzornâ" + +#. TRANSLATORS: this is an error string +msgid "No updates available" +msgstr "Nissun inzornament disponibil" #. TRANSLATORS: nothing was updated offline msgid "No updates were applied" msgstr "Nol è stât aplicât nissun inzornament" +#. TRANSLATORS: Suffix: the HSI result +msgid "Not found" +msgstr "No cjatât" + #. TRANSLATORS: Suffix: the HSI result msgid "OK" msgstr "Va ben" +#. TRANSLATORS: this is for the device tests +msgid "OK!" +msgstr "Va ben!" + +#. TRANSLATORS: the firmware old version +msgid "Old version" +msgstr "Version vecje" + #. TRANSLATORS: command line option msgid "Only show single PCR value" msgstr "Mostre dome il valôr PCR" @@ -516,6 +1120,22 @@ msgstr "Mostre dome il valôr PCR" msgid "Override the default ESP path" msgstr "Passe parsore al valôr dal percors ESP predefinît" +#. TRANSLATORS: command argument: uppercase, spaces->dashes +msgid "PATH" +msgstr "PERCORS" + +#. TRANSLATORS: command description +msgid "Parse and show details about a firmware file" +msgstr "Analize e mostre i detais in merit a un file di firmware" + +#. TRANSLATORS: reading new dbx from the update +msgid "Parsing dbx update…" +msgstr "Daûr a analizâ l'inzornament di dbx…" + +#. TRANSLATORS: reading existing dbx from the system +msgid "Parsing system dbx…" +msgstr "Daûr a analizâ il dbx di sisteme…" + #. TRANSLATORS: remote filename base msgid "Password" msgstr "Password" @@ -524,11 +1144,31 @@ msgstr "Password" msgid "Percentage complete" msgstr "Percentuâl di completament" +#. TRANSLATORS: Title: Allows debugging of parts using proprietary hardware +msgid "Platform Debugging" +msgstr "Debug de plateforme" + +#. TRANSLATORS: Title: Allows debugging of parts using proprietary hardware +msgid "Platform debugging" +msgstr "Debug de plateforme" + #. TRANSLATORS: the user isn't reading the question #, c-format msgid "Please enter a number from 0 to %u: " msgstr "Inserìs un numar di 0 a %u: " +#. TRANSLATORS: Title: DMA as in https://en.wikipedia.org/wiki/DMA_attack +msgid "Pre-boot DMA Protection" +msgstr "Protezion DMA di pre-inviament" + +#. TRANSLATORS: Title: DMA as in https://en.wikipedia.org/wiki/DMA_attack +msgid "Pre-boot DMA protection" +msgstr "Protezion DMA pre-inviament" + +#. TRANSLATORS: longer description +msgid "Pre-boot DMA protection prevents devices from accessing system memory after being connected to the computer." +msgstr "La protezion DMA di pre-inviament e impedìs ai dispositîfs di acedi ae memorie di sisteme dopo che si son colegâts al computer." + msgid "Print the version number" msgstr "Stampe il numar de version" @@ -542,10 +1182,22 @@ msgstr "Prioritât" msgid "Proceed with upload?" msgstr "Procedi cul inviament?" +#. TRANSLATORS: Title: if fwupd supports HSI on this chip +msgid "Processor Security Checks" +msgstr "Controi di sigurece dal processôr" + #. TRANSLATORS: command line option msgid "Query for firmware update support" msgstr "Interogazion pal supuart dai inzornaments firmware" +#. TRANSLATORS: command description +msgid "Read a firmware blob from a device" +msgstr "Lei di un dispositîf un file binari di firmware" + +#. TRANSLATORS: command description +msgid "Read a firmware from a device" +msgstr "Lei di un dispositîf un firmware" + #. TRANSLATORS: command description msgid "Read firmware from device into a file" msgstr "Lei il firmware dal dispositîf intun file" @@ -569,7 +1221,21 @@ msgstr "Daûr a tornâ a inviâ il sisteme…" #. TRANSLATORS: command description msgid "Refresh metadata from remote server" -msgstr "Inzorne i metadâts dal servidôr rimot" +msgstr "Inzorne i metadâts dal servidôr esterni" + +#. TRANSLATORS: message letting the user know an upgrade is available +#. * %1 is the device name and %2 is a version string +#, c-format +msgid "Reinstall %s to %s?" +msgstr "Tornâ a instalâ %s %s? " + +#. TRANSLATORS: command description +msgid "Reinstall current firmware on the device" +msgstr "Torne instale il firmware atuâl sul dispositîf" + +#. TRANSLATORS: command description +msgid "Reinstall firmware on a device" +msgstr "Torne instale un firmware suntun dispositîf" #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second is a version number @@ -578,10 +1244,14 @@ msgstr "Inzorne i metadâts dal servidôr rimot" msgid "Reinstalling %s with %s... " msgstr "Daûr a tornâ a instalâ %s cun %s... " +#. TRANSLATORS: the exact component on the server +msgid "Release ID" +msgstr "ID publicazion" + #. TRANSLATORS: the server the file is coming from #. TRANSLATORS: remote identifier, e.g. lvfs-testing msgid "Remote ID" -msgstr "ID rimot" +msgstr "ID esterni" #. TRANSLATORS: command description msgid "Replace data in an existing firmware file" @@ -591,6 +1261,14 @@ msgstr "Sostituìs i dâts intun file di firmware esistent" msgid "Report URI" msgstr "URI segnalazion" +#. TRANSLATORS: Has been reported to a metadata server +msgid "Reported to remote server" +msgstr "Segnalât su servidôr esterni" + +#. TRANSLATORS: we asked the user to choose an option and they declined +msgid "Request canceled" +msgstr "Richieste anulade" + #. TRANSLATORS: metadata is downloaded from the Internet msgid "Requires internet connection" msgstr "Al à bisugne de conession a internet" @@ -615,6 +1293,30 @@ msgstr "Torne ducj i ID dal hardware pe machine" msgid "Run `fwupdmgr get-upgrades` for more information." msgstr "Eseguìs `fwupdmgr get-upgrades` par vê plui informazions." +#. TRANSLATORS: this is shown in the MOTD +msgid "Run `fwupdmgr sync-bkc` to complete this action." +msgstr "Eseguìs `fwupdmgr sync-bkc` par completâ cheste azion." + +#. TRANSLATORS: Title: SPI refers to the flash chip in the computer +msgid "SPI BIOS Descriptor" +msgstr "Descritôr dal BIOS SPI" + +#. TRANSLATORS: Title: SPI refers to the flash chip in the computer +msgid "SPI BIOS region" +msgstr "Regjon BIOS SPI" + +#. TRANSLATORS: Title: SPI refers to the flash chip in the computer +msgid "SPI lock" +msgstr "Bloc SPI" + +#. TRANSLATORS: Title: SPI refers to the flash chip in the computer +msgid "SPI write" +msgstr "Scriture SPI" + +#. TRANSLATORS: Title: if hardware enforces control of SPI writes +msgid "SPI write protection" +msgstr "Protezion de scriture SPI" + #. TRANSLATORS: command line option msgid "Schedule installation for next reboot when possible" msgstr "Planifiche la instalazion pe volte sucessive che si torne a inviâ cuant che al è pussibil" @@ -623,10 +1325,22 @@ msgstr "Planifiche la instalazion pe volte sucessive che si torne a inviâ cuant msgid "Scheduling…" msgstr "Daûr a planificâ…" +#. TRANSLATORS: %s is a link to a website +#, c-format +msgid "See %s for more information." +msgstr "Viôt %s par vê plui informazions." + #. TRANSLATORS: device has been chosen by the daemon for the user msgid "Selected device" msgstr "Dispositîf selezionât" +#. TRANSLATORS: Volume has been chosen by the user +msgid "Selected volume" +msgstr "Volum selezionât" + +msgid "Set one or more BIOS settings" +msgstr "Configure une o plui impostazion BIOS" + #. TRANSLATORS: command line option msgid "Set the debugging flag during update" msgstr "Stabilìs la opzion di debug dilunc l'inzornament" @@ -635,6 +1349,10 @@ msgstr "Stabilìs la opzion di debug dilunc l'inzornament" msgid "Sets the list of approved firmware" msgstr "Al stabilìs la liste dai firmware aprovâts" +#. TRANSLATORS: description of a BIOS setting +msgid "Settings will apply after system reboots" +msgstr "Lis impostazions a vignaran aplicadis daspò che il sisteme si tornarà a inviâ" + #. TRANSLATORS: command description msgid "Share firmware history with the developers" msgstr "Condivît la conologjie dai firmware cui svilupadôrs" @@ -671,6 +1389,10 @@ msgstr "Mostre la cronologjie dai inzoronaments dal firmware" msgid "Show plugin verbose information" msgstr "Mostre lis informazions prolissis dai plugin" +#. TRANSLATORS: command line option +msgid "Show the calculated version of the dbx" +msgstr "Mostre la version calcolade dal dbx" + #. TRANSLATORS: command line option msgid "Show the debug log from the last attempted update" msgstr "Mostre il regjistri dal debug dal ultin tentatîf di inzornament" @@ -691,27 +1413,48 @@ msgctxt "command-description" msgid "Sign data using the client certificate" msgstr "Firme i dâts doprant il certificât dal client" +#. TRANSLATORS: command line option +msgid "Sign the uploaded data with the client certificate" +msgstr "Firme i dâts cjamâts in rêt cul certificât dal client" + msgid "Signature" msgstr "Firme" msgid "Specify Vendor/Product ID(s) of DFU device" msgstr "Specifiche Vendidôr/ID prodot dal dispositîf DFU" +#. TRANSLATORS: command line option +msgid "Specify the dbx database file" +msgstr "Specifiche il file de base di dâts dal dbx" + msgid "Specify the number of bytes per USB transfer" msgstr "Specifiche il numar di byte par trasferiment USB" +#. TRANSLATORS: The BIOS setting accepts strings +msgid "String" +msgstr "Stringhe" + +#. TRANSLATORS: success message -- where activation is making the new +#. * firmware take effect, usually after updating offline +msgid "Successfully activated all devices" +msgstr "Ducj i dispositîfs a son stâts ativâts cun sucès" + #. TRANSLATORS: success message msgid "Successfully disabled remote" -msgstr "Rimot disabilitât cun sucès" +msgstr "Sorzint esterne disabilitade cun sucès" #. TRANSLATORS: success message -- where 'metadata' is information #. * about available firmware on the remote server msgid "Successfully downloaded new metadata: " msgstr "Gnûf metadât discjariât cun sucès:" +#. TRANSLATORS: success message +msgid "Successfully enabled and refreshed remote" +msgstr "Sorzint esterne inzornade e abilitade cun sucès" + #. TRANSLATORS: success message msgid "Successfully enabled remote" -msgstr "Rimot abilitât cun sucès" +msgstr "Sorzint esterne abilitade cun sucès" #. TRANSLATORS: success message msgid "Successfully installed firmware" @@ -723,12 +1466,16 @@ msgstr "Valôr di configurazion modificât cun sucès" #. TRANSLATORS: success message for a per-remote setting change msgid "Successfully modified remote" -msgstr "Rimot modificât cun sucès" +msgstr "Sorzint modificade cun sucès" #. TRANSLATORS: success message -- the user can do this by-hand too msgid "Successfully refreshed metadata manually" msgstr "Metadât inzornât a man cun sucès" +#. TRANSLATORS: success message when user refreshes device checksums +msgid "Successfully updated device checksums" +msgstr "Sumis di control dai dispositîfs inzornadis cun sucès" + #. TRANSLATORS: success message -- where the user has uploaded #. * success and/or failure reports to the remote server #, c-format @@ -737,10 +1484,84 @@ msgid_plural "Successfully uploaded %u reports" msgstr[0] "%u rapuart inviât cun sucès" msgstr[1] "%u rapuarts inviâts cun sucès" +#. TRANSLATORS: success message when user verified device checksums +msgid "Successfully verified device checksums" +msgstr "Sumis di control dai dispositîfs verificadis cun sucès" + #. TRANSLATORS: one line summary of device msgid "Summary" msgstr "Sintesi" +#. TRANSLATORS: Title: if fwupd supports HSI on this chip +msgid "Supported CPU" +msgstr "CPU supuartade" + +#. TRANSLATORS: Is found in current metadata +msgid "Supported on remote server" +msgstr "Supuartât su servidôr esterni" + +#. TRANSLATORS: Title: a better sleep state +msgid "Suspend To Idle" +msgstr "Sospension su inativitât" + +#. TRANSLATORS: Title: sleep state +msgid "Suspend To RAM" +msgstr "Sospension su RAM" + +#. TRANSLATORS: longer description +msgid "Suspend to Idle allows the device to quickly go to sleep in order to save power. While the device has been suspended, its memory could be physically removed and its information accessed." +msgstr "Sospension su inativitât al permet al dispositîf di lâ in polse subite, cussì di sparagnâ energjie. Intant che il dispositîf al è sospindût, al è pussibil gjavâ in mût fisic il banc di memorie, e chest doprât par acedi aes informazions." + +#. TRANSLATORS: longer description +msgid "Suspend to RAM allows the device to quickly go to sleep in order to save power. While the device has been suspended, its memory could be physically removed and its information accessed." +msgstr "La sospension su RAM e permet al dispositîf di lâ in polse subite, cussì di sparagnâ energjie. Intant che il dispositîf al è sospindût, al è pussibil gjavâ in mût fisic il banc di memorie, e chest doprât par acedi aes informazions." + +#. TRANSLATORS: Title: a better sleep state +msgid "Suspend-to-idle" +msgstr "Suspend-to-idle" + +#. TRANSLATORS: Title: sleep state +msgid "Suspend-to-ram" +msgstr "Suspend-to-ram" + +#. TRANSLATORS: show and ask user to confirm -- +#. * %1 is the old branch name, %2 is the new branch name +#, c-format +msgid "Switch branch from %s to %s?" +msgstr "Cambiâ ram di %s a %s? " + +#. TRANSLATORS: command description +msgid "Switch the firmware branch on the device" +msgstr "Cambie il ram dal firmware sul dispositîf" + +#. TRANSLATORS: Title: the PCR is rebuilt from the TPM event log +msgid "TPM PCR0 reconstruction" +msgstr "Ricostruzion di PCR0 dal TPM" + +#. TRANSLATORS: Title: PCRs (Platform Configuration Registers) shouldn't be +#. empty +msgid "TPM Platform Configuration" +msgstr "Configurazion de plateforme TPM" + +#. TRANSLATORS: Title: the PCR is rebuilt from the TPM event log +msgid "TPM Reconstruction" +msgstr "Ricostruzion dal TPM" + +#. TRANSLATORS: Title: PCRs (Platform Configuration Registers) shouldn't be +#. empty +msgid "TPM empty PCRs" +msgstr "PCRs vueits di TPM" + +#. TRANSLATORS: Title: TPM = Trusted Platform Module +msgid "TPM v2.0" +msgstr "TPM v2.0" + +#. TRANSLATORS: release tag set for release, e.g. lenovo-2021q3 +msgid "Tag" +msgid_plural "Tags" +msgstr[0] "Etichete" +msgstr[1] "Etichetis" + msgid "Target" msgstr "Destinazion" @@ -748,6 +1569,14 @@ msgstr "Destinazion" msgid "The LVFS is a free service that operates as an independent legal entity and has no connection with $OS_RELEASE:NAME$. Your distributor may not have verified any of the firmware updates for compatibility with your system or connected devices. All firmware is provided only by the original equipment manufacturer." msgstr "Il LVFS — Servizi firmware dal vendidôr di linux — al è un servizi gratuit che al opere come entitât legâl indipendente e no à conession cun $OS_RELEASE:NAME$. Il to distributôr al podarès no vê verificât la compatibilitât di nissun dai inzornaments firmware cul vuestri sisteme o cui dispositîfs tacâts. Ducj i firmware a son furnîts dome dal produtôr origjinâl dal imprest." +#. TRANSLATORS: longer description +msgid "The UEFI Platform Key is used to determine if device software comes from a trusted source." +msgstr "La clâf de plateforme UEFI e ven doprade par determinâ se il software dal dispositîf al rive di une sorzint afidabile." + +#. TRANSLATORS: nothing to show +msgid "There are no blocked firmware files" +msgstr "No'nd è nissun file di firmware blocât" + #. TRANSLATORS: approved firmware has been checked by #. * the domain administrator msgid "There is no approved firmware." @@ -758,12 +1587,28 @@ msgid "This program may only work correctly as root" msgstr "Chest program al pues lavorâ in maniere juste dome come root" msgid "This remote contains firmware which is not embargoed, but is still being tested by the hardware vendor. You should ensure you have a way to manually downgrade the firmware if the firmware update fails." -msgstr "Chest rimot al conten firmware che no son sot di embargo, ma a son ancjemò in prove dal vendidôr dal hardware. Si à di sigurâsi di vê une maniere par puartâ indaûr a man il firmware ae version precedente, se l'inzornament al falìs." +msgstr "Cheste sorzint esterne e conten firmware che no son sot di embargo, ma a son ancjemò in prove dal vendidôr dal hardware. Tu varessis di sigurâti di vê une maniere par puartâ indaûr a man il firmware ae version precedente, se l'inzornament al falìs." + +#. TRANSLATORS: error message +msgid "This system doesn't support firmware settings" +msgstr "Chest sisteme nol supuarte lis configurazions dai firmwares" + +#. TRANSLATORS: description of dbxtool +msgid "This tool allows an administrator to apply UEFI dbx updates." +msgstr "Chest imprest al permet a un aministradôr di aplicâ i inzornaments dbx UEFI." + +#. TRANSLATORS: CLI description +msgid "This tool allows an administrator to debug UpdateCapsule operation." +msgstr "Chest imprest al permet a un aministradôr di fâ il debug de operazion UpdateCapsule ." #. TRANSLATORS: the user needs to stop playing with stuff msgid "This tool can only be used by the root user" msgstr "Chest strument al pues jessi doprât dome dal utent root" +#. TRANSLATORS: CLI description +msgid "This tool will read and parse the TPM event log from the system firmware." +msgstr "Chest strument al leiarà e al analizarà il regjistri events TPM dal firmware di sisteme." + #. TRANSLATORS: remote type, e.g. remote or local msgid "Type" msgstr "Gjenar" @@ -772,12 +1617,44 @@ msgstr "Gjenar" msgid "UEFI Firmware Utility" msgstr "Utilitât Firmware UEFI" +#. TRANSLATORS: Title: PK is the 'platform key' for the machine +msgid "UEFI Platform Key" +msgstr "Clâf de plateforme UEFI" + +#. TRANSLATORS: Title: SB is a way of locking down UEFI +msgid "UEFI Secure Boot" +msgstr "Inviament sigûr di UEFI" + +#. TRANSLATORS: program name +msgid "UEFI dbx Utility" +msgstr "Utilitât dbx di UEFI" + +#. TRANSLATORS: Title: PK is the 'platform key' for the machine +msgid "UEFI platform key" +msgstr "Clâf de plateforme UEFI" + +#. TRANSLATORS: Title: SB is a way of locking down UEFI +msgid "UEFI secure boot" +msgstr "Inviament sigûr di UEFI" + +#. TRANSLATORS: error message +msgid "Unable to connect to service" +msgstr "Impussibil conetisi al servizi" + +#. TRANSLATORS: we will now offer this firmware to the user +msgid "Unblocking firmware:" +msgstr "Firmware sblocât:" + #. TRANSLATORS: current daemon status is unknown #. TRANSLATORS: we don't know the license of the update #. TRANSLATORS: unknown release urgency msgid "Unknown" msgstr "No cognossût" +#. TRANSLATORS: Name of hardware +msgid "Unknown Device" +msgstr "Dispositîf no cognossût" + msgid "Unlock the device to allow access" msgstr "Sbloche il dispositîf par permeti l'acès" @@ -794,6 +1671,22 @@ msgstr "Gjave la opzion di debug dilunc l'inzornament" msgid "Unsupported daemon version %s, client version is %s" msgstr "Version %s dal demoni no supuartade, la version dal client e je la %s" +#. TRANSLATORS: Device is updatable in this or any other mode +msgid "Updatable" +msgstr "Si pues inzornâ" + +#. TRANSLATORS: error message from last update attempt +msgid "Update Error" +msgstr "Erôr inzornament" + +#. TRANSLATORS: helpful image for the update +msgid "Update Image" +msgstr "Imagjin di inzornament" + +#. TRANSLATORS: hardware state, e.g. "pending" +msgid "Update State" +msgstr "Stât inzornament" + #. TRANSLATORS: the server sent the user a small message msgid "Update failure is a known issue, visit this URL for more information:" msgstr "Il faliment dal inzornament al è un probleme cognossût, visite chest URL par vê plui informazions:" @@ -802,9 +1695,16 @@ msgstr "Il faliment dal inzornament al è un probleme cognossût, visite chest U msgid "Update now?" msgstr "Inzornâ cumò?" +#. TRANSLATORS: Update can only be done from offline mode +msgid "Update requires a reboot" +msgstr "Pal inzornament al è necessari tornâ a inviâ il computer" + msgid "Update the stored device verification information" msgstr "Inzorne lis informazions di verifiche dal dispositîf archiviadis" +msgid "Updating" +msgstr "Daûr a inzornâ" + #. TRANSLATORS: the first replacement is a display name #. * e.g. "ColorHugALS" and the second and third are #. * version numbers e.g. "1.2.3" @@ -817,6 +1717,12 @@ msgstr "Daûr a inzornâ %s di %s a %s... " msgid "Updating %s…" msgstr "Daûr a inzornâ %s…" +#. TRANSLATORS: message letting the user know an upgrade is available +#. * %1 is the device name and %2 and %3 are version strings +#, c-format +msgid "Upgrade %s from %s to %s?" +msgstr "Inzornâ %s de version %s ae %s?" + #. TRANSLATORS: ask the user to upload msgid "Upload report now?" msgstr "Inviâ il rapuart cumò?" @@ -825,10 +1731,18 @@ msgstr "Inviâ il rapuart cumò?" msgid "Uploading firmware reports helps hardware vendors to quickly identify failing and successful updates on real devices." msgstr "Inviâ i rapuarts dal firmware al jude i vendidôrs di hardware a identificâ subite i inzornaments bogns e falimentârs sui dispositîfs reâi." +#. TRANSLATORS: command line option +msgid "Use quirk flags when installing firmware" +msgstr "Dopre variabilis/flags di soluzions alternativis cuant che si instale il firmware" + #. TRANSLATORS: remote filename base msgid "Username" msgstr "Non utent" +#. TRANSLATORS: ESP refers to the EFI System Partition +msgid "Validating ESP contents…" +msgstr "Daûr a convalidâ i contignûts ESP…" + #. TRANSLATORS: verifying we wrote the firmware correctly msgid "Verifying…" msgstr "Daûr a verificâ…" @@ -837,6 +1751,10 @@ msgstr "Daûr a verificâ…" msgid "Version" msgstr "Version" +#. TRANSLATORS: the fwupd version the release was tested on +msgid "Version[fwupd]" +msgstr "Version[fwupd]" + #. TRANSLATORS: waiting for device to do something msgid "Waiting…" msgstr "In spiete…" @@ -849,6 +1767,10 @@ msgstr "Scrîf il firmware dal file intal dispositîf" msgid "Write firmware from file into one partition" msgstr "Scrîf il firmware dal file intune partizion" +#. TRANSLATORS: decompressing images from a container firmware +msgid "Writing file:" +msgstr "Daûr a scrivi il file:" + #. TRANSLATORS: writing to the flash chips msgid "Writing…" msgstr "Daûr a scrivi…" @@ -856,3 +1778,11 @@ msgstr "Daûr a scrivi…" #. TRANSLATORS: show the user a warning msgid "Your distributor may not have verified any of the firmware updates for compatibility with your system or connected devices." msgstr "Il to distributôr al podarès no vê verificât nissun dai inzornaments firmware pe compatibilitât cui dispositîfs tacâts o cul to sisteme." + +#. TRANSLATORS: program name +msgid "fwupd TPM event log utility" +msgstr "Utilitât di regjistrazion events TPM di fwupd" + +#. TRANSLATORS: Title: if the fwupd plugins are all present and correct +msgid "fwupd plugins" +msgstr "plugins di fwupd" diff --git a/po/hr.po b/po/hr.po index 1c8ad8c47..a98211ad9 100644 --- a/po/hr.po +++ b/po/hr.po @@ -7,7 +7,7 @@ # gogo , 2016 # Milo Ivir , 2020-2021 # Milo Ivir , 2021 -# gogo , 2016-2022 +# gogo , 2016-2023 msgid "" msgstr "" "Project-Id-Version: fwupd\n" @@ -87,6 +87,12 @@ msgstr "%s nadopuna uređaja" msgid "%s Display Update" msgstr "%s nadopuna zaslona" +#. TRANSLATORS: Dock refers to the port replicator hardware laptops are +#. * cradled in, or lowered onto +#, c-format +msgid "%s Dock Update" +msgstr "%s nadopuna doka" + #. TRANSLATORS: drive refers to a storage device, e.g. SATA disk #, c-format msgid "%s Drive Update" @@ -98,11 +104,28 @@ msgstr "%s nadopuna diska" msgid "%s Embedded Controller Update" msgstr "%s nadopuna ugrađenog upravljača" +#. TRANSLATORS: a device that can read your fingerprint pattern +#, c-format +msgid "%s Fingerprint Reader Update" +msgstr "%s nadopuna čitača otisaka prsta" + #. TRANSLATORS: flash refers to solid state storage, e.g. UFS or eMMC #, c-format msgid "%s Flash Drive Update" msgstr "%s nadopuna flash memorije" +#. TRANSLATORS: GPU refers to a Graphics Processing Unit, e.g. +#. * the "video card" +#, c-format +msgid "%s GPU Update" +msgstr "%s GPU nadopuna" + +#. TRANSLATORS: a large pressure-sensitive drawing area typically used +#. * by artists and digital artists +#, c-format +msgid "%s Graphics Tablet Update" +msgstr "%s nadopuna grafičkog tableta" + #. TRANSLATORS: Keyboard refers to an input device for typing #, c-format msgid "%s Keyboard Update" @@ -159,6 +182,12 @@ msgstr "%s nadopuna Thunderbolt kontrolera" msgid "%s Touchpad Update" msgstr "%s touchpad nadopuna" +#. TRANSLATORS: Dock refers to the port replicator device connected +#. * by plugging in a USB cable -- which may or may not also provide power +#, c-format +msgid "%s USB Dock Update" +msgstr "%s nadopuna USB doka" + #. TRANSLATORS: Receiver refers to a radio device, e.g. a tiny Bluetooth #. * device that stays in the USB port so the wireless peripheral works #, c-format @@ -314,6 +343,10 @@ msgstr "AMD firmver zaštita ponavljanja" msgid "AMD Firmware Write Protection" msgstr "AMD firmver zaštita zpisivanja" +#. TRANSLATORS: Title: if firmware enforces rollback protection +msgid "AMD Secure Processor Rollback Protection" +msgstr "Zaštita od vraćanja na stariju inačicu AMD sigurnog procesora" + #. TRANSLATORS: the user needs to do something, e.g. remove the device msgid "Action Required:" msgstr "Radnja je potrebna:" @@ -492,6 +525,14 @@ msgstr "Automatsko izvještavanje" msgid "Automatically upload every time?" msgstr "Automatski pošalji svaki put?" +#. TRANSLATORS: Title: if firmware enforces rollback protection +msgid "BIOS Rollback Protection" +msgstr "Zaštita od vraćanja na stariju inačicu BIOS-a" + +#. TRANSLATORS: Title: if firmware enforces rollback protection +msgid "BIOS rollback protection" +msgstr "Zaštita od vraćanja na stariju inačicu BIOS-a" + #. TRANSLATORS: description of a BIOS setting msgid "BIOS updates delivered via LVFS or Windows Update" msgstr "BIOS nadopune isporučene putem LVFS-a ili Windows ažuriranja" @@ -826,6 +867,10 @@ msgstr "Onemogućuje zadane udaljene lokacije" msgid "Display version" msgstr "Prikaži inačicu" +#. TRANSLATORS: the OS the release was tested on +msgid "Distribution" +msgstr "Distribucija" + #. TRANSLATORS: command line option msgid "Do not check for old metadata" msgstr "Ne provjeravaj stare metapodatke" @@ -858,6 +903,10 @@ msgstr "Nemoj izvoditi provjere sigurnosti uređaja" msgid "Do not prompt for devices" msgstr "Ne upitaj za uređaje" +#. TRANSLATORS: command line option +msgid "Do not search the firmware when parsing" +msgstr "Ne pretražuj firmver pri obradi" + #. TRANSLATORS: warning message shown after update has been scheduled msgid "Do not turn off your computer or remove the AC adaptor while the update is in progress." msgstr "Ne isključujte svoje računalo ili AC adapter tijekom procesa nadopune." @@ -1331,6 +1380,10 @@ msgstr "Prikaži sve uređaje koji podržavaju nadopunu firmvera" msgid "Get all enabled plugins registered with the system" msgstr "Prikaži sve omogućene priključke registrirane sa sustavom" +#. TRANSLATORS: command description +msgid "Get device report metadata" +msgstr "Preuzmi metapodatke izvještaja uređaja" + #. TRANSLATORS: command description msgid "Gets details about a firmware file" msgstr "Prikaži pojedinosti datoteke firmvera" @@ -1732,6 +1785,16 @@ msgstr "Zaključano" msgid "Low" msgstr "Niska" +#. TRANSLATORS: Title: MEI = Intel Management Engine, and key refers +#. * to the private/public key used to secure loading of firmware +msgid "MEI Key Manifest" +msgstr "Manifest MEI ključa" + +#. TRANSLATORS: Title: MEI = Intel Management Engine, and key refer +#. * to the private/public key used to secure loading of firmware +msgid "MEI key manifest" +msgstr "Manifest MEI ključa" + #. TRANSLATORS: Title: MEI = Intel Management Engine msgid "MEI manufacturing mode" msgstr "MEI način rada za proizvođače" @@ -1910,6 +1973,10 @@ msgstr "U redu" msgid "OK!" msgstr "U redu!" +#. TRANSLATORS: the firmware old version +msgid "Old version" +msgstr "Stara inačica" + #. TRANSLATORS: command line option msgid "Only show single PCR value" msgstr "Prikaži samo jednu PRC vrijednost" @@ -1978,6 +2045,10 @@ msgstr "Otklanjanje grešaka platforme" msgid "Platform Debugging allows device security features to be disabled. This should only be used by hardware manufacturers." msgstr "Otklanjanje grešaka platforme dopušta onemogućavanje sigurnosnih značajki uređaja. Ovo bi trebali koristit samo proizvođači hardvera." +#. TRANSLATORS: Title: Allows debugging of parts using proprietary hardware +msgid "Platform debugging" +msgstr "Otklanjanje grešaka platforme" + #. TRANSLATORS: 'recovery key' here refers to a code, rather than a physical #. metal thing msgid "Please ensure you have the volume recovery key before continuing." @@ -2045,6 +2116,10 @@ msgstr "Nastavi sa slanjem?" msgid "Processor Security Checks" msgstr "Sigurnosna provjera procesora" +#. TRANSLATORS: Title: if firmware enforces rollback protection +msgid "Processor rollback protection" +msgstr "Zaštita od vraćanja na stariju inačicu procesora" + #. TRANSLATORS: a non-free software license msgid "Proprietary" msgstr "Vlasnički" @@ -2055,7 +2130,7 @@ msgstr "Zatraži podršku nadopune firmvera" #. TRANSLATORS: command argument: uppercase, spaces->dashes msgid "REMOTE-ID" -msgstr "UDALJENA_LOKACIJA" +msgstr "UDALJENI-ID" #. TRANSLATORS: command argument: uppercase, spaces->dashes msgid "REMOTE-ID KEY VALUE" @@ -2188,6 +2263,10 @@ msgstr "Preuzmi BIOS postavke. Ako se argumenati ne proslijede, postavke su nep msgid "Return all the hardware IDs for the machine" msgstr "Vrati sve ID-ove hardvera za uređaj" +#. TRANSLATORS: longer description +msgid "Rollback Protection prevents device software from being downgraded to an older version that has security problems." +msgstr "Zaštita od vraćanja na stariju inačicu sprječava softver uređaja da ga vrati na stariju inačicu koja ima sigurnosne probleme." + #. TRANSLATORS: this is shown in the MOTD msgid "Run `fwupdmgr get-upgrades` for more information." msgstr "Pokrenite `fwupdmgr get-upgrades` za više informacija." @@ -2622,6 +2701,19 @@ msgstr "Odredište" msgid "Test a device using a JSON manifest" msgstr "Testiraj uređaj koristeći JSON manifest" +#. TRANSLATORS: when the release was tested +msgid "Tested" +msgstr "Testirano" + +#. TRANSLATORS: the %s is a vendor name, e.g. Lenovo +#, c-format +msgid "Tested by %s" +msgstr "Testirao %s" + +#. TRANSLATORS: longer description +msgid "The Intel Management Engine Key Manifest must be valid so that the device firmware can be trusted by the CPU." +msgstr "Manifest ključa Intel pogon upravljanja (Intel Management Engine) mora biti valjan tako da firmver uređaja može vjerovati CPU." + #. TRANSLATORS: longer description msgid "The Intel Management Engine controls device components and needs to have a recent version to avoid security issues." msgstr "Intel pogon upravljanja (Intel Management Engine) upravlja komponentama uređaja i mora biti najnovije inačice kako bi se izbjegli sigurnosni problemi." @@ -2665,6 +2757,10 @@ msgstr "%s firmver nije isporučen od strane %s dobavljača hardvera." msgid "The system clock has not been set correctly and downloading files may fail." msgstr "Sat sustava nije pravilno postavljen i preuzimanje datoteka možda ne uspije." +#. TRANSLATORS: warning message shown after update has been scheduled +msgid "The update will continue when the device USB cable has been re-inserted." +msgstr "Nadopuna će se nastaviti kada se kabel USB uređaja ponovno poveže." + #. TRANSLATORS: warning message shown after update has been scheduled msgid "The update will continue when the device USB cable has been unplugged and then re-inserted." msgstr "Nadopuna će se nastaviti kada se kabel USB uređaja odspoji i ponvno priključi." @@ -3011,6 +3107,10 @@ msgstr "Provjeravanje…" msgid "Version" msgstr "Inačica" +#. TRANSLATORS: the fwupd version the release was tested on +msgid "Version[fwupd]" +msgstr "Inačica[fwupd]" + #. TRANSLATORS: this is a prefix on the console msgid "WARNING:" msgstr "UPOZORENJE:" @@ -3023,6 +3123,11 @@ msgstr "Čekanje…" msgid "Watch for hardware changes" msgstr "Nadgledaj promjene hardvera" +#. TRANSLATORS: check various UEFI and ACPI tables are unchanged after the +#. update +msgid "Will measure elements of system integrity around an update" +msgstr "Mjerit će elemente integriteta sustava oko nadopune" + #. TRANSLATORS: command description msgid "Write firmware from file into device" msgstr "Zapiši firmver iz datoteke u uređaj" diff --git a/po/ko.po b/po/ko.po index 27b25f3dd..c033e5651 100644 --- a/po/ko.po +++ b/po/ko.po @@ -3,7 +3,7 @@ # This file is distributed under the same license as the fwupd package. # # Translators: -# Seong-ho Cho , 2017,2019,2021-2022 +# Seong-ho Cho , 2017,2019,2021-2023 # Shinjo Park , 2018-2021 msgid "" msgstr "" @@ -82,6 +82,12 @@ msgstr "%s 장치 업데이트" msgid "%s Display Update" msgstr "%s 디스플레이 장치 업데이트" +#. TRANSLATORS: Dock refers to the port replicator hardware laptops are +#. * cradled in, or lowered onto +#, c-format +msgid "%s Dock Update" +msgstr "%s 도크 업데이트" + #. TRANSLATORS: drive refers to a storage device, e.g. SATA disk #, c-format msgid "%s Drive Update" @@ -93,6 +99,11 @@ msgstr "%s 드라이브 업데이트" msgid "%s Embedded Controller Update" msgstr "%s 임베디드 컨트롤러 업데이트" +#. TRANSLATORS: a device that can read your fingerprint pattern +#, c-format +msgid "%s Fingerprint Reader Update" +msgstr "%s 지문 스캐너 업데이트" + #. TRANSLATORS: flash refers to solid state storage, e.g. UFS or eMMC #, c-format msgid "%s Flash Drive Update" @@ -104,6 +115,12 @@ msgstr "%s 플래시 드라이브 업데이트" msgid "%s GPU Update" msgstr "%s GPU 장치 업데이트" +#. TRANSLATORS: a large pressure-sensitive drawing area typically used +#. * by artists and digital artists +#, c-format +msgid "%s Graphics Tablet Update" +msgstr "%s 그래픽 태블릿 업데이트" + #. TRANSLATORS: Keyboard refers to an input device for typing #, c-format msgid "%s Keyboard Update" @@ -160,6 +177,12 @@ msgstr "%s Thunderbolt 컨트롤러 업데이트" msgid "%s Touchpad Update" msgstr "%s 터치패드 업데이트" +#. TRANSLATORS: Dock refers to the port replicator device connected +#. * by plugging in a USB cable -- which may or may not also provide power +#, c-format +msgid "%s USB Dock Update" +msgstr "%s USB 도크 업데이트" + #. TRANSLATORS: Receiver refers to a radio device, e.g. a tiny Bluetooth #. * device that stays in the USB port so the wireless peripheral works #, c-format @@ -1332,6 +1355,10 @@ msgstr "펌웨어 업데이트를 지원하는 모든 장치 정보 가져오기 msgid "Get all enabled plugins registered with the system" msgstr "시스템에 등록된 모든 활성 플러그인 가져오기" +#. TRANSLATORS: command description +msgid "Get device report metadata" +msgstr "장치 보고서 메타데이터 가져오기" + #. TRANSLATORS: command description msgid "Gets details about a firmware file" msgstr "펌웨어 파일 세부 정보 가져오기" @@ -2699,6 +2726,10 @@ msgstr "%s의 펌웨어는 하드웨어 제조사 %s에서 제공하지 않았 msgid "The system clock has not been set correctly and downloading files may fail." msgstr "시스템 시계가 올바르게 설정되어 있지 않습니다. 파일 다운로드가 실패할 수도 있습니다." +#. TRANSLATORS: warning message shown after update has been scheduled +msgid "The update will continue when the device USB cable has been re-inserted." +msgstr "장치 USB 케이블을 뽑고난 후 다시 연결하면 업데이트를 계속합니다." + #. TRANSLATORS: warning message shown after update has been scheduled msgid "The update will continue when the device USB cable has been unplugged and then re-inserted." msgstr "장치 USB 케이블을 뽑고난 후 다시 연결하면 업데이트를 계속합니다." diff --git a/po/pl.po b/po/pl.po index 0e641c260..2d40ce67a 100644 --- a/po/pl.po +++ b/po/pl.po @@ -3,7 +3,7 @@ # This file is distributed under the same license as the fwupd package. # # Translators: -# Piotr Drąg , 2015-2022 +# Piotr Drąg , 2015-2023 msgid "" msgstr "" "Project-Id-Version: fwupd\n" @@ -51,7 +51,7 @@ msgstr "Aktualizacja aparatu %s" #. * the first %s is the device name, e.g. 'Secure Boot` #, c-format msgid "%s Configuration Update" -msgstr "Aktualizacja konfiguracji urządzenia %s" +msgstr "Aktualizacja konfiguracji %s" #. TRANSLATORS: ME stands for Management Engine, where #. * the first %s is the device name, e.g. 'ThinkPad P50` @@ -84,6 +84,12 @@ msgstr "Aktualizacja urządzenia %s" msgid "%s Display Update" msgstr "Aktualizacja ekranu %s" +#. TRANSLATORS: Dock refers to the port replicator hardware laptops are +#. * cradled in, or lowered onto +#, c-format +msgid "%s Dock Update" +msgstr "Aktualizacja stacji dokującej %s" + #. TRANSLATORS: drive refers to a storage device, e.g. SATA disk #, c-format msgid "%s Drive Update" @@ -95,6 +101,11 @@ msgstr "Aktualizacja dysku %s" msgid "%s Embedded Controller Update" msgstr "Aktualizacja wbudowanego kontrolera %s" +#. TRANSLATORS: a device that can read your fingerprint pattern +#, c-format +msgid "%s Fingerprint Reader Update" +msgstr "Aktualizacja czytnika odcisków palców %s" + #. TRANSLATORS: flash refers to solid state storage, e.g. UFS or eMMC #, c-format msgid "%s Flash Drive Update" @@ -106,6 +117,12 @@ msgstr "Aktualizacja dysku półprzewodnikowego %s" msgid "%s GPU Update" msgstr "Aktualizacja karty graficznej %s" +#. TRANSLATORS: a large pressure-sensitive drawing area typically used +#. * by artists and digital artists +#, c-format +msgid "%s Graphics Tablet Update" +msgstr "Aktualizacja tabletu graficznego %s" + #. TRANSLATORS: Keyboard refers to an input device for typing #, c-format msgid "%s Keyboard Update" @@ -162,6 +179,12 @@ msgstr "Aktualizacja kontrolera Thunderbolt %s" msgid "%s Touchpad Update" msgstr "Aktualizacja panelu dotykowego %s" +#. TRANSLATORS: Dock refers to the port replicator device connected +#. * by plugging in a USB cable -- which may or may not also provide power +#, c-format +msgid "%s USB Dock Update" +msgstr "Aktualizacja replikatora portów USB %s" + #. TRANSLATORS: Receiver refers to a radio device, e.g. a tiny Bluetooth #. * device that stays in the USB port so the wireless peripheral works #, c-format @@ -1334,6 +1357,10 @@ msgstr "Uzyskuje wszystkie urządzenia obsługujące aktualizacje oprogramowania msgid "Get all enabled plugins registered with the system" msgstr "Uzyskuje wszystkie włączone wtyczki zarejestrowane na komputerze" +#. TRANSLATORS: command description +msgid "Get device report metadata" +msgstr "Uzyskuje metadane zgłoszenia urządzenia" + #. TRANSLATORS: command description msgid "Gets details about a firmware file" msgstr "Uzyskuje informacje o pliku oprogramowania sprzętowego" @@ -2629,6 +2656,10 @@ msgstr "Oprogramowanie sprzętowe od firmy %s nie jest dostarczane przez firmę msgid "The system clock has not been set correctly and downloading files may fail." msgstr "Zegar komputera nie jest poprawnie ustawiony i pobieranie plików może się nie powieść." +#. TRANSLATORS: warning message shown after update has been scheduled +msgid "The update will continue when the device USB cable has been re-inserted." +msgstr "Aktualizacja zostanie kontynuowana po ponownym podłączeniu kabla USB urządzenia." + #. TRANSLATORS: warning message shown after update has been scheduled msgid "The update will continue when the device USB cable has been unplugged and then re-inserted." msgstr "Aktualizacja zostanie kontynuowana po odłączeniu i ponownym podłączeniu kabla USB urządzenia." diff --git a/po/sv.po b/po/sv.po index a656bd1c8..f9d2967d8 100644 --- a/po/sv.po +++ b/po/sv.po @@ -3,7 +3,7 @@ # This file is distributed under the same license as the fwupd package. # # Translators: -# Anders Jonsson , 2017,2019-2022 +# Anders Jonsson , 2017,2019-2023 # Andreas Henriksson , 2017 # Josef Andersson , 2015,2017-2018 # Josef Andersson , 2015,2017 @@ -88,6 +88,12 @@ msgstr "%s-enhetsuppdatering" msgid "%s Display Update" msgstr "%s-skärmuppdatering" +#. TRANSLATORS: Dock refers to the port replicator hardware laptops are +#. * cradled in, or lowered onto +#, c-format +msgid "%s Dock Update" +msgstr "%s-dockuppdatering" + #. TRANSLATORS: drive refers to a storage device, e.g. SATA disk #, c-format msgid "%s Drive Update" @@ -99,6 +105,11 @@ msgstr "%s-enhetsuppdatering" msgid "%s Embedded Controller Update" msgstr "%s inbäddad styrenhetsuppdatering" +#. TRANSLATORS: a device that can read your fingerprint pattern +#, c-format +msgid "%s Fingerprint Reader Update" +msgstr "%s-fingeravtrycksläsaruppdatering" + #. TRANSLATORS: flash refers to solid state storage, e.g. UFS or eMMC #, c-format msgid "%s Flash Drive Update" @@ -110,6 +121,12 @@ msgstr "%s-flashenhetsuppdatering" msgid "%s GPU Update" msgstr "%s GPU-uppdatering" +#. TRANSLATORS: a large pressure-sensitive drawing area typically used +#. * by artists and digital artists +#, c-format +msgid "%s Graphics Tablet Update" +msgstr "%s-ritplatteuppdatering" + #. TRANSLATORS: Keyboard refers to an input device for typing #, c-format msgid "%s Keyboard Update" @@ -166,6 +183,12 @@ msgstr "%s Thunderbolt-styrenhetsuppdatering" msgid "%s Touchpad Update" msgstr "%s-pekplatteuppdatering" +#. TRANSLATORS: Dock refers to the port replicator device connected +#. * by plugging in a USB cable -- which may or may not also provide power +#, c-format +msgid "%s USB Dock Update" +msgstr "%s USB-dockuppdatering" + #. TRANSLATORS: Receiver refers to a radio device, e.g. a tiny Bluetooth #. * device that stays in the USB port so the wireless peripheral works #, c-format @@ -1348,6 +1371,10 @@ msgstr "Hämta alla enheter som stödjer uppdateringar av fast programvara" msgid "Get all enabled plugins registered with the system" msgstr "Erhåll alla aktiverade insticksmoduler som är registrerade i systemet" +#. TRANSLATORS: command description +msgid "Get device report metadata" +msgstr "Hämta rapportmetadata för enhet" + #. TRANSLATORS: command description msgid "Gets details about a firmware file" msgstr "Hämtar detaljer om en fast programvarufil" @@ -2718,6 +2745,10 @@ msgstr "Fast programvara från %s levereras inte av %s, hårdvarutillverkaren." msgid "The system clock has not been set correctly and downloading files may fail." msgstr "Systemklockan har inte ställts in korrekt och hämtning av filer kan misslyckas." +#. TRANSLATORS: warning message shown after update has been scheduled +msgid "The update will continue when the device USB cable has been re-inserted." +msgstr "Uppdateringen kommer fortsätta när enhetens USB-kabel har stoppats in igen." + #. TRANSLATORS: warning message shown after update has been scheduled msgid "The update will continue when the device USB cable has been unplugged and then re-inserted." msgstr "Uppdateringen kommer fortsätta när enhetens USB-kabel har kopplats från och stoppats in igen." diff --git a/src/fu-engine.c b/src/fu-engine.c index a05ca1a5b..9e72616d9 100644 --- a/src/fu-engine.c +++ b/src/fu-engine.c @@ -3773,27 +3773,49 @@ fu_engine_appstream_upgrade_cb(XbBuilderFixup *self, return TRUE; } -static XbBuilderSource * -fu_engine_create_metadata_builder_source(FuEngine *self, const gchar *fn, GError **error) +static GInputStream * +fu_engine_builder_cabinet_adapter_cb(XbBuilderSource *source, + XbBuilderSourceCtx *ctx, + gpointer user_data, + GCancellable *cancellable, + GError **error) { + FuEngine *self = FU_ENGINE(user_data); g_autoptr(GBytes) blob = NULL; g_autoptr(XbSilo) silo = NULL; - g_autoptr(XbBuilderSource) source = xb_builder_source_new(); g_autofree gchar *xml = NULL; - g_debug("building metadata for %s", fn); - blob = fu_bytes_get_contents(fn, error); + /* convert the CAB into metadata XML */ + blob = xb_builder_source_ctx_get_bytes(ctx, cancellable, error); if (blob == NULL) return NULL; - - /* convert the silo for the CAB into a XbBuilderSource */ silo = fu_engine_get_silo_from_blob(self, blob, error); if (silo == NULL) return NULL; xml = xb_silo_export(silo, XB_NODE_EXPORT_FLAG_NONE, error); if (xml == NULL) return NULL; - if (!xb_builder_source_load_xml(source, xml, XB_BUILDER_SOURCE_FLAG_NONE, error)) + return g_memory_input_stream_new_from_data(g_steal_pointer(&xml), -1, g_free); +} + +static XbBuilderSource * +fu_engine_create_metadata_builder_source(FuEngine *self, const gchar *fn, GError **error) +{ + g_autoptr(GFile) file = g_file_new_for_path(fn); + g_autoptr(XbBuilderSource) source = xb_builder_source_new(); + + g_debug("using %s as metadata source", fn); + xb_builder_source_add_simple_adapter(source, + "application/vnd.ms-cab-compressed", + fu_engine_builder_cabinet_adapter_cb, + self, + NULL); + if (!xb_builder_source_load_file(source, + file, + XB_BUILDER_SOURCE_FLAG_WATCH_FILE | + XB_BUILDER_SOURCE_FLAG_WATCH_DIRECTORY, + NULL, + error)) return NULL; return g_steal_pointer(&source); } @@ -4216,7 +4238,7 @@ fu_engine_load_metadata_store(FuEngine *self, FuEngineLoadFlags flags, GError ** /* generate all metadata on demand */ if (fwupd_remote_get_kind(remote) == FWUPD_REMOTE_KIND_DIRECTORY) { - g_debug("building metadata for remote '%s'", fwupd_remote_get_id(remote)); + g_debug("loading metadata for remote '%s'", fwupd_remote_get_id(remote)); if (!fu_engine_create_metadata(self, builder, remote, &error_local)) { g_warning("failed to generate remote %s: %s", fwupd_remote_get_id(remote), @@ -5348,11 +5370,17 @@ fu_engine_add_releases_for_device_component(FuEngine *self, /* invalid */ locations = fwupd_release_get_locations(FWUPD_RELEASE(release)); - if (locations->len == 0) + if (locations->len == 0) { + g_autofree gchar *str = fwupd_release_to_string(FWUPD_RELEASE(release)); + g_debug("no locations for %s", str); continue; + } checksums = fu_release_get_checksums(release); - if (checksums->len == 0) + if (checksums->len == 0) { + g_autofree gchar *str = fwupd_release_to_string(FWUPD_RELEASE(release)); + g_debug("no locations for %s", str); continue; + } /* different branch */ if (g_strcmp0(fu_release_get_branch(release), fu_device_get_branch(device)) != 0) { @@ -6601,17 +6629,16 @@ fu_engine_ensure_security_attrs_tainted(FuEngine *self) static gchar * fu_engine_attrs_calculate_hsi_for_chassis(FuEngine *self) { - guint val = - fu_context_get_smbios_integer(self->ctx, FU_SMBIOS_STRUCTURE_TYPE_CHASSIS, 0x05); + FuSmbiosChassisKind chassis_kind = fu_context_get_chassis_kind(self->ctx); /* if emulating, force the chassis type to be valid */ - if (self->host_emulation && - (val == FU_SMBIOS_CHASSIS_KIND_OTHER || val == FU_SMBIOS_CHASSIS_KIND_UNKNOWN)) { - g_debug("forcing chassis kind [0x%x] to be valid", val); - val = FU_SMBIOS_CHASSIS_KIND_DESKTOP; + if (self->host_emulation && (chassis_kind == FU_SMBIOS_CHASSIS_KIND_OTHER || + chassis_kind == FU_SMBIOS_CHASSIS_KIND_UNKNOWN)) { + g_debug("forcing chassis kind [0x%x] to be valid", chassis_kind); + chassis_kind = FU_SMBIOS_CHASSIS_KIND_DESKTOP; } - switch (val) { + switch (chassis_kind) { case FU_SMBIOS_CHASSIS_KIND_DESKTOP: case FU_SMBIOS_CHASSIS_KIND_LOW_PROFILE_DESKTOP: case FU_SMBIOS_CHASSIS_KIND_MINI_TOWER: @@ -6637,7 +6664,7 @@ fu_engine_attrs_calculate_hsi_for_chassis(FuEngine *self) } return g_strdup_printf("HSI:INVALID:chassis[0x%02x] (v%d.%d.%d)", - val, + chassis_kind, FWUPD_MAJOR_VERSION, FWUPD_MINOR_VERSION, FWUPD_MICRO_VERSION); @@ -7777,11 +7804,20 @@ fu_engine_backends_coldplug(FuEngine *self, FuProgress *progress) backend, fu_progress_get_child(progress), &error_backend)) { - g_warning("failed to coldplug backend %s: %s", - fu_backend_get_name(backend), - error_backend->message); - fu_progress_step_done(progress); - continue; + if (g_error_matches(error_backend, + FWUPD_ERROR, + FWUPD_ERROR_NOT_SUPPORTED)) { + if (g_getenv("FWUPD_PROBE_VERBOSE") != NULL) { + g_debug("ignoring coldplug failure %s: %s", + fu_backend_get_name(backend), + error_backend->message); + } + } else { + g_warning("failed to coldplug backend %s: %s", + fu_backend_get_name(backend), + error_backend->message); + } + fu_progress_finished(fu_progress_get_child(progress)); } fu_progress_step_done(progress); } @@ -7970,7 +8006,7 @@ fu_engine_load(FuEngine *self, FuEngineLoadFlags flags, FuProgress *progress, GE /* load SMBIOS and the hwids */ if (flags & FU_ENGINE_LOAD_FLAG_HWINFO) { - if (!fu_context_load_hwinfo(self->ctx, error)) + if (!fu_context_load_hwinfo(self->ctx, FU_CONTEXT_HWID_FLAG_LOAD_ALL, error)) return FALSE; self->has_hwinfo = TRUE; } @@ -8017,6 +8053,7 @@ fu_engine_load(FuEngine *self, FuEngineLoadFlags flags, FuProgress *progress, GE fu_context_add_firmware_gtype(self->ctx, "cfu-payload", FU_TYPE_CFU_PAYLOAD); fu_context_add_firmware_gtype(self->ctx, "uswid", FU_TYPE_USWID_FIRMWARE); fu_context_add_firmware_gtype(self->ctx, "coswid", FU_TYPE_COSWID_FIRMWARE); + fu_context_add_firmware_gtype(self->ctx, "pefile", FU_TYPE_PEFILE_FIRMWARE); fu_context_add_firmware_gtype(self->ctx, "intel-thunderbolt", FU_TYPE_INTEL_THUNDERBOLT_FIRMWARE); diff --git a/src/fu-release.c b/src/fu-release.c index 7cb0e1c23..24f8e9600 100644 --- a/src/fu-release.c +++ b/src/fu-release.c @@ -858,7 +858,7 @@ fu_release_load(FuRelease *self, if (str->len > 0) fwupd_release_set_description(FWUPD_RELEASE(self), str->str); } - if (artifact == NULL) { + if (fwupd_release_get_locations(FWUPD_RELEASE(self))->len == 0) { tmp = xb_node_query_text(rel, "location", NULL); if (tmp != NULL) { g_autofree gchar *uri = NULL; @@ -879,7 +879,7 @@ fu_release_load(FuRelease *self, fwupd_release_add_location(FWUPD_RELEASE(self), uri); } } - if (artifact == NULL) { + if (fwupd_release_get_filename(FWUPD_RELEASE(self)) == NULL) { tmp = xb_node_query_text(rel, "checksum[@target='content']", NULL); if (tmp != NULL) fwupd_release_set_filename(FWUPD_RELEASE(self), tmp); @@ -890,7 +890,7 @@ fu_release_load(FuRelease *self, tmp = xb_node_query_text(rel, "url[@type='source']", NULL); if (tmp != NULL) fwupd_release_set_source_url(FWUPD_RELEASE(self), tmp); - if (artifact == NULL) { + if (fwupd_release_get_checksums(FWUPD_RELEASE(self))->len == 0) { g_autoptr(GPtrArray) checksums = NULL; checksums = xb_node_query(rel, "checksum[@target='container']", 0, NULL); if (checksums != NULL) { @@ -903,7 +903,7 @@ fu_release_load(FuRelease *self, } } } - if (artifact == NULL) { + if (fwupd_release_get_size(FWUPD_RELEASE(self)) == 0) { tmp64 = xb_node_query_text_as_uint(rel, "size[@type='installed']", NULL); if (tmp64 != G_MAXUINT64) fwupd_release_set_size(FWUPD_RELEASE(self), tmp64); diff --git a/src/fu-tool.c b/src/fu-tool.c index b6116081d..9437571ca 100644 --- a/src/fu-tool.c +++ b/src/fu-tool.c @@ -34,7 +34,6 @@ #include "fu-device-private.h" #include "fu-engine.h" #include "fu-history.h" -#include "fu-hwids.h" #include "fu-plugin-private.h" #include "fu-progressbar.h" #include "fu-security-attr-common.h" @@ -1036,8 +1035,9 @@ fu_util_firmware_dump(FuUtilPrivate *priv, gchar **values, GError **error) /* progress */ fu_progress_set_id(priv->progress, G_STRLOC); - fu_progress_add_step(priv->progress, FWUPD_STATUS_LOADING, 95, "start-engine"); - fu_progress_add_step(priv->progress, FWUPD_STATUS_DEVICE_READ, 5, NULL); + fu_progress_add_flag(priv->progress, FU_PROGRESS_FLAG_NO_PROFILE); + fu_progress_add_step(priv->progress, FWUPD_STATUS_LOADING, 5, "start-engine"); + fu_progress_add_step(priv->progress, FWUPD_STATUS_DEVICE_READ, 95, NULL); /* invalid args */ if (g_strv_length(values) == 0) { @@ -1110,8 +1110,9 @@ fu_util_firmware_read(FuUtilPrivate *priv, gchar **values, GError **error) /* progress */ fu_progress_set_id(priv->progress, G_STRLOC); - fu_progress_add_step(priv->progress, FWUPD_STATUS_LOADING, 95, "start-engine"); - fu_progress_add_step(priv->progress, FWUPD_STATUS_DEVICE_READ, 5, NULL); + fu_progress_add_flag(priv->progress, FU_PROGRESS_FLAG_NO_PROFILE); + fu_progress_add_step(priv->progress, FWUPD_STATUS_LOADING, 5, "start-engine"); + fu_progress_add_step(priv->progress, FWUPD_STATUS_DEVICE_READ, 95, NULL); /* invalid args */ if (g_strv_length(values) == 0) { @@ -1972,8 +1973,8 @@ fu_util_activate(FuUtilPrivate *priv, gchar **values, GError **error) static gboolean fu_util_export_hwids(FuUtilPrivate *priv, gchar **values, GError **error) { - g_autoptr(FuHwids) hwids = fu_hwids_new(); - g_autoptr(FuSmbios) smbios = fu_smbios_new(); + FuContext *ctx = fu_engine_get_context(priv->engine); + FuHwids *hwids = fu_context_get_hwids(ctx); g_autoptr(GKeyFile) kf = g_key_file_new(); g_autoptr(GPtrArray) hwid_keys = NULL; @@ -1987,9 +1988,7 @@ fu_util_export_hwids(FuUtilPrivate *priv, gchar **values, GError **error) } /* setup default hwids */ - if (!fu_smbios_setup(smbios, error)) - return FALSE; - if (!fu_hwids_setup(hwids, smbios, error)) + if (!fu_context_load_hwinfo(ctx, FU_CONTEXT_HWID_FLAG_LOAD_ALL, error)) return FALSE; /* save all keys */ @@ -2007,39 +2006,23 @@ fu_util_export_hwids(FuUtilPrivate *priv, gchar **values, GError **error) static gboolean fu_util_hwids(FuUtilPrivate *priv, gchar **values, GError **error) { - g_autoptr(FuSmbios) smbios = NULL; - g_autoptr(FuHwids) hwids = fu_hwids_new(); + FuContext *ctx = fu_engine_get_context(priv->engine); + FuHwids *hwids = fu_context_get_hwids(ctx); g_autoptr(GPtrArray) hwid_keys = fu_hwids_get_keys(hwids); - /* read DMI data */ - if (g_strv_length(values) == 0) { - smbios = fu_smbios_new(); - if (!fu_smbios_setup(smbios, error)) - return FALSE; - } else if (g_strv_length(values) == 1) { - /* a keyfile with overrides */ + /* a keyfile with overrides */ + if (g_strv_length(values) == 1) { g_autoptr(GKeyFile) kf = g_key_file_new(); - if (g_key_file_load_from_file(kf, values[0], G_KEY_FILE_NONE, NULL)) { - for (guint i = 0; i < hwid_keys->len; i++) { - const gchar *hwid_key = g_ptr_array_index(hwid_keys, i); - g_autofree gchar *tmp = NULL; - tmp = g_key_file_get_string(kf, "HwIds", hwid_key, NULL); - fu_hwids_add_smbios_override(hwids, hwid_key, tmp); - } - /* a DMI blob */ - } else { - smbios = fu_smbios_new(); - if (!fu_smbios_setup_from_file(smbios, values[0], error)) - return FALSE; + if (!g_key_file_load_from_file(kf, values[0], G_KEY_FILE_NONE, error)) + return FALSE; + for (guint i = 0; i < hwid_keys->len; i++) { + const gchar *hwid_key = g_ptr_array_index(hwid_keys, i); + g_autofree gchar *tmp = NULL; + tmp = g_key_file_get_string(kf, "HwIds", hwid_key, NULL); + fu_hwids_add_value(hwids, hwid_key, tmp); } - } else { - g_set_error_literal(error, - FWUPD_ERROR, - FWUPD_ERROR_INVALID_ARGS, - "Invalid arguments"); - return FALSE; } - if (!fu_hwids_setup(hwids, smbios, error)) + if (!fu_context_load_hwinfo(ctx, FU_CONTEXT_HWID_FLAG_LOAD_ALL, error)) return FALSE; /* show debug output */