Add a new internal flag to opt-in to GUID matching

It is far too easy to forget to set FWUPD_DEVICE_FLAG_NO_GUID_MATCHING for new
plugins, and without it it all works really well *until* a user has two devices
of the same type installed at the same time and then one 'disappears' for hard
to explain reasons. Typically we only need it for replug anyway!

Explicitly opt-in to this rarely-required behaviour, with the default to just
use the physical and logical IDs. Also document the update behavior for each
plugin to explain why the flag is being used.

This allows you to have two identical Unifying plugged in without one of them
being hidden from the user, at the same time allowing a HIDRAW<->USB transition
when going to and from bootloader and runtime modes.

This removes the workaround added in 99eb3f06b6.

Fixes https://github.com/fwupd/fwupd/issues/2915
This commit is contained in:
Richard Hughes 2021-02-22 11:20:17 +00:00
parent ae3ad67710
commit 078beafb2d
79 changed files with 404 additions and 195 deletions

View File

@ -12,6 +12,7 @@ deprecated="FWUPD_DEVICE_FLAG_NO_AUTO_INSTANCE_IDS
FWUPD_DEVICE_FLAG_ONLY_SUPPORTED
FWUPD_DEVICE_FLAG_MD_SET_NAME
FWUPD_DEVICE_FLAG_MD_SET_VERFMT
FWUPD_DEVICE_FLAG_NO_GUID_MATCHING
FWUPD_DEVICE_FLAG_MD_SET_ICON"
for val in $deprecated; do
if grep -- $val plugins/*/*.c ; then

View File

@ -123,7 +123,7 @@ typedef enum {
* @FWUPD_DEVICE_FLAG_MD_SET_NAME_CATEGORY: Deprecated, no not use
* @FWUPD_DEVICE_FLAG_MD_SET_VERFMT: Deprecated, no not use
* @FWUPD_DEVICE_FLAG_ADD_COUNTERPART_GUIDS: Add counterpart GUIDs from an alternate mode like bootloader
* @FWUPD_DEVICE_FLAG_NO_GUID_MATCHING: Force an explicit ID match when adding devices to the device list
* @FWUPD_DEVICE_FLAG_NO_GUID_MATCHING: Deprecated, no not use
* @FWUPD_DEVICE_FLAG_UPDATABLE_HIDDEN: Device is updatable but should not be called by the client
* @FWUPD_DEVICE_FLAG_SKIPS_RESTART: Device relies upon activation or power cycle to load firmware
* @FWUPD_DEVICE_FLAG_HAS_MULTIPLE_BRANCHES: Device supports switching to a different stream of firmware
@ -169,7 +169,7 @@ typedef enum {
#define FWUPD_DEVICE_FLAG_MD_SET_NAME_CATEGORY (1llu << 33) /* Since: 1.4.0; Deprecated: 1.5.5 */
#define FWUPD_DEVICE_FLAG_MD_SET_VERFMT (1llu << 34) /* Since: 1.4.0; Deprecated: 1.5.5 */
#define FWUPD_DEVICE_FLAG_ADD_COUNTERPART_GUIDS (1llu << 35) /* Since: 1.4.0 */
#define FWUPD_DEVICE_FLAG_NO_GUID_MATCHING (1llu << 36) /* Since: 1.4.1 */
#define FWUPD_DEVICE_FLAG_NO_GUID_MATCHING (1llu << 36) /* Since: 1.4.1; Deprecated: 1.5.8 */
#define FWUPD_DEVICE_FLAG_UPDATABLE_HIDDEN (1llu << 37) /* Since: 1.4.1 */
#define FWUPD_DEVICE_FLAG_SKIPS_RESTART (1llu << 38) /* Since: 1.5.0 */
#define FWUPD_DEVICE_FLAG_HAS_MULTIPLE_BRANCHES (1llu << 39) /* Since: 1.5.0 */

View File

@ -511,7 +511,6 @@ static void
fu_bluez_device_init (FuBluezDevice *self)
{
FuBluezDevicePrivate *priv = GET_PRIVATE (self);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_NO_GUID_MATCHING);
priv->uuid_paths = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_free);
}

View File

@ -176,6 +176,8 @@ fu_device_internal_flag_to_string (FuDeviceInternalFlags flag)
return "ensure-semver";
if (flag == FU_DEVICE_INTERNAL_FLAG_RETRY_OPEN)
return "retry-open";
if (flag == FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID)
return "replug-match-guid";
return NULL;
}

View File

@ -204,6 +204,7 @@ FuDevice *fu_device_new (void);
* @FU_DEVICE_INTERNAL_FLAG_MD_SET_VERFMT: Set the device version format from the metadata if available
* @FU_DEVICE_INTERNAL_FLAG_MD_SET_ICON: Set the device icon from the metadata if available
* @FU_DEVICE_INTERNAL_FLAG_RETRY_OPEN: Retry the device open up to 5 times if it fails
* @FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID: Match GUIDs on device replug where the physical and logical IDs will be different
*
* The device internal flags.
**/
@ -217,6 +218,7 @@ typedef enum {
FU_DEVICE_INTERNAL_FLAG_MD_SET_VERFMT = (1llu << 5), /* Since: 1.5.5 */
FU_DEVICE_INTERNAL_FLAG_MD_SET_ICON = (1llu << 6), /* Since: 1.5.5 */
FU_DEVICE_INTERNAL_FLAG_RETRY_OPEN = (1llu << 7), /* Since: 1.5.5 */
FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID = (1llu << 8), /* Since: 1.5.8 */
/*< private >*/
FU_DEVICE_INTERNAL_FLAG_UNKNOWN = G_MAXUINT64,
} FuDeviceInternalFlags;

View File

@ -34,6 +34,16 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_1D50&PID_60C6`
* `USB\VID_1D50`
Update Behavior
---------------
The device usually presents in runtime mode, but on detach re-enumerates with a
different USB PID in a bootloader mode. On attach 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.
Vendor ID Security
------------------

View File

@ -556,6 +556,7 @@ static void
fu_altos_device_init (FuAltosDevice *self)
{
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_TRIPLET);
fu_device_set_vendor (FU_DEVICE (self), "altusmetrum.org");
fu_device_set_summary (FU_DEVICE (self), "A USB hardware random number generator");

View File

@ -34,6 +34,14 @@ These device use the Microsoft DeviceInstanceId values, e.g.
See https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-ide-devices
for more details.
Update Behavior
---------------
The firmware is deployed when the device is in normal runtime mode, but it is
only activated when the system is in the final shutdown stages. This is done to
minimize the chance of data loss if the switch to the new firmware is not done
correctly.
Vendor ID Security
------------------

View File

@ -22,6 +22,17 @@ These devices use the standard PCI instance IDs, for example:
* `PCI\VEN_14E4&DEV_1657`
* `PCI\VEN_14E4&DEV_1657&SUBSYS_17AA222E`
Update Behavior
---------------
The device usually presents in runtime mode, and the firmware is written to the
device without disconnecting the working kernel driver. Once complete the APE
is reset which may cause a brief link reconnection.
On flash failure the device is nonfunctional, but is recoverable using direct
BAR writes, which is typically much slower than updating the device using the
kernel driver and the ethtool API.
Vendor ID Security
------------------

View File

@ -612,7 +612,6 @@ fu_bcm57xx_device_close (FuDevice *device, GError **error)
static void
fu_bcm57xx_device_init (FuBcm57xxDevice *self)
{
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_NO_GUID_MATCHING);
fu_device_set_protocol (FU_DEVICE (self), "com.broadcom.bcm57xx");
fu_device_add_icon (FU_DEVICE (self), "network-wired");

View File

@ -719,7 +719,6 @@ fu_bcm57xx_recovery_device_init (FuBcm57xxRecoveryDevice *self)
{
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_NO_GUID_MATCHING);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_NEEDS_REBOOT);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_BACKUP_BEFORE_INSTALL);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_IGNORE_VALIDATION);

View File

@ -93,6 +93,17 @@ application ID and device mode, e.g.
* `USB\VID_1234&PID_5678&SID_9ABC&APP_DEF1`
* `USB\VID_1234&PID_5678&SID_9ABC&APP_DEF1&MODE_FW2`
Update Behavior
---------------
The device usually presents in runtime HID mode, but on detach re-enumerates
with with a DMC or HPI interface. On attach the device again re-enumerates
back to the runtime HID mode.
For this reason the `REPLUG_MATCH_GUID` internal device flag is used so that
the DMC/HPI and runtime modes are treated as the same device.
Vendor ID Security
------------------

View File

@ -652,6 +652,7 @@ fu_ccgx_dmc_device_init (FuCcgxDmcDevice *self)
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_REQUIRE_AC);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_DUAL_IMAGE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_SELF_RECOVERY);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
}
static void

View File

@ -78,6 +78,7 @@ fu_ccgx_hid_device_init (FuCcgxHidDevice *self)
fu_device_set_protocol (FU_DEVICE (self), "com.cypress.ccgx");
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_REQUIRE_AC);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_WILL_DISAPPEAR);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_retry_set_delay (FU_DEVICE (self), FU_CCGX_HID_DEVICE_RETRY_DELAY);
}

View File

@ -1590,6 +1590,7 @@ fu_ccgx_hpi_device_init (FuCcgxHpiDevice *self)
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_REQUIRE_AC);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_DUAL_IMAGE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_SELF_RECOVERY);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_retry_set_delay (FU_DEVICE (self), HPI_CMD_RETRY_DELAY);
/* we can recover the I²C link using reset */

View File

@ -30,6 +30,16 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_273F&PID_1001`
* `USB\VID_273F`
Update Behavior
---------------
The device usually presents in runtime mode, but on detach re-enumerates with a
different USB PID in a bootloader mode. On attach 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.
Vendor ID Security
------------------

View File

@ -484,6 +484,7 @@ fu_colorhug_device_init (FuColorhugDevice *self)
fu_device_set_remove_delay (FU_DEVICE (self),
FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_ADD_COUNTERPART_GUIDS);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
}
static void

View File

@ -30,6 +30,16 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_18D1&PID_501A`
Update Behavior
---------------
The device usually presents in runtime mode, but on detach re-enumerates with
the same USB PID in an unlocked mode. On attach the device again re-enumerates
back to the runtime locked 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.
Vendor ID Security
------------------

View File

@ -952,6 +952,7 @@ fu_cros_ec_usb_device_init (FuCrosEcUsbDevice *device)
{
fu_device_set_protocol (FU_DEVICE (device), "com.google.usb.crosec");
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_internal_flag (FU_DEVICE (device), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_set_version_format (FU_DEVICE (device), FWUPD_VERSION_FORMAT_TRIPLET);
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_DUAL_IMAGE);
}

View File

@ -48,6 +48,12 @@ These devices use several different generation schemes, e.g.
* MST Hub: `MST-panamera-vmm5331-259`
* Thunderbolt Controller: `TBT-00d4b070`
Update Behavior
---------------
For devices implementing "passive flow" the update is deployed at runtime and
then actually written the next time the dock is attached.
Vendor ID Security
------------------

View File

@ -480,6 +480,7 @@ fu_dell_dock_ec_get_dock_info (FuDevice *device,
} else {
g_debug ("not using passive flow (EC: %s Hub2: %s)",
self->ec_version, hub_version);
fu_device_add_internal_flag (device, FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
}
return TRUE;
}

View File

@ -35,6 +35,17 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_0A12&PID_1337`
* `USB\VID_0A12`
Update Behavior
---------------
A DFU device usually presents in runtime mode (or with no interfaces defined),
but if the user puts the device into bootloader mode using a physical button
it then enumerates with a HID descriptor. On attach the device returns to
runtime mode which *may* mean the device "goes away".
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.
Vendor ID Security
------------------

View File

@ -434,6 +434,7 @@ static void
fu_dfu_csr_device_init (FuDfuCsrDevice *self)
{
fu_device_set_protocol (FU_DEVICE (self), "com.qualcomm.dfu");
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
}
static void

View File

@ -27,6 +27,16 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_273F&PID_1003`
* `USB\VID_273F`
Update Behavior
---------------
A DFU device usually presents in runtime mode (with optional DFU runtime), but
on detach re-enumerates with an additional required DFU descriptor. On attach
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.
Vendor ID Security
------------------

View File

@ -1949,5 +1949,6 @@ fu_dfu_device_init (FuDfuDevice *self)
fu_device_add_icon (FU_DEVICE (self), "drive-harddisk-usb");
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_ADD_COUNTERPART_GUIDS);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_set_remove_delay (FU_DEVICE (self), FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE);
}

View File

@ -32,6 +32,16 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_2DC8&PID_AB11`
* `USB\VID_2DC8`
Update Behavior
---------------
The device usually presents in runtime mode, but on detach re-enumerates with a
different USB VID and PID in a bootloader mode. On attach 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.
Vendor ID Security
------------------

View File

@ -598,6 +598,7 @@ fu_ebitdo_device_init (FuEbitdoDevice *self)
{
fu_device_set_protocol (FU_DEVICE (self), "com.8bitdo");
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_ADD_COUNTERPART_GUIDS);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
}
static void

View File

@ -36,6 +36,18 @@ These devices also use custom GUID values for the IC configuration, e.g.
* `ELANTP\ICTYPE_09&MOD_1234`
Update Behavior
---------------
The device usually presents in HID mode, and the firmware is written to the
device by switching to a IAP mode where the touchpad is nonfunctional.
Once complete the device is reset to get out of IAP mode and to load the new
firmware version.
On flash failure the device is nonfunctional, but is recoverable by writing
to the i2c device. This is typically much slower than updating the device
using HID and also requires a model-specific HWID quirk to match.
Vendor ID Security
------------------

View File

@ -20,6 +20,12 @@ These devices use the following instance values:
* `EMMC\%MANFID%&%OEMID%`
* `EMMC\%MANFID%&%OEMID%&%NAME%`
Update Behavior
---------------
The firmware is deployed when the device is in normal runtime mode, but it is
only activated when the device is rebooted.
Vendor ID Security
------------------

View File

@ -25,6 +25,13 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_17EF&PID_7226`
* `USB\VID_17EF`
Update Behavior
---------------
The device usually presents in runtime mode, but on detach re-enumerates with
the same USB PID in an unlocked mode. On attach the device again re-enumerates
back to the runtime locked mode.
Vendor ID Security
------------------

View File

@ -31,6 +31,17 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_18D1&PID_4EE0`
* `USB\VID_18D1`
Update Behavior
---------------
A fastboot device usually presents in runtime mode (or with no interface),
but if the user puts the device into fastboot mode using a physical button
it then enumerates with a USB descriptor. On attach the device reboots to
runtime mode which *may* mean the device "goes away".
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.
Quirk use
---------
This plugin uses the following plugin-specific quirk:

View File

@ -712,6 +712,7 @@ fu_fastboot_device_init (FuFastbootDevice *self)
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_IS_BOOTLOADER);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_ADD_COUNTERPART_GUIDS);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_set_remove_delay (FU_DEVICE (self), FASTBOOT_REMOVE_DELAY_RE_ENUMERATE);
}

View File

@ -51,6 +51,12 @@ These device uses hardware ID values which are derived from SMBIOS. They should
match the values provided by `fwupdtool hwids` or the `ComputerHardwareIds.exe`
Windows utility.
Update Behavior
---------------
The firmware is deployed to the SPI chip when the machine is in normal runtime
mode, but it is only used when the device is rebooted.
Vendor ID Security
------------------

View File

@ -29,6 +29,12 @@ These devices also use custom GUID values, e.g.
* `USB\VID_1D5C&PID_7102&CID_01`
Update Behavior
---------------
The firmware is deployed when the device is in normal runtime mode, and the
device will reset when the new firmware has been written.
Vendor ID Security
------------------

View File

@ -387,6 +387,7 @@ fu_fresco_pd_device_init (FuFrescoPdDevice *self)
{
fu_device_add_icon (FU_DEVICE (self), "audio-card");
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_set_protocol (FU_DEVICE (self), "com.frescologic.pd");
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_QUAD);
fu_device_set_install_duration (FU_DEVICE (self), 15);

View File

@ -25,6 +25,12 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_27C6&PID_6001`
* `USB\VID_27C6`
Update Behavior
---------------
The firmware is deployed when the device is in normal runtime mode, and the
device will reset when the new firmware has been written.
Vendor ID Security
------------------

View File

@ -25,6 +25,19 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_0603&PID_1020`
Update Behavior
---------------
The keyboard device usually presents in runtime mode, but on detach it
re-enumerates with a different USB VID and PID in bootloader mode. On attach
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.
The touchpad firmware is deployed when the device is in normal runtime mode,
and the device will reset when the new firmware has been written.
Vendor ID Security
------------------

View File

@ -270,6 +270,7 @@ fu_hailuck_bl_device_init (FuHailuckBlDevice *self)
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_IS_BOOTLOADER);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_INTERNAL);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_add_icon (FU_DEVICE (self), "input-keyboard");
fu_hid_device_add_flag (FU_HID_DEVICE (self), FU_HID_DEVICE_FLAG_NO_KERNEL_REBIND);
fu_device_set_remove_delay (FU_DEVICE (self),

View File

@ -70,6 +70,7 @@ fu_hailuck_kbd_device_init (FuHailuckKbdDevice *self)
fu_device_set_protocol (FU_DEVICE (self), "com.hailuck.kbd");
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_INTERNAL);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_add_icon (FU_DEVICE (self), "input-keyboard");
fu_hid_device_set_interface (FU_HID_DEVICE (self), 0x1);
fu_device_set_remove_delay (FU_DEVICE (self),

View File

@ -22,6 +22,18 @@ This plugin uses the following plugin-specific quirks:
|---------------|----------------------------------------------|---------------|
|`JabraMagic` | Two magic bytes sent to detach into DFU mode.|1.3.3 |
Update Behavior
---------------
The device usually presents in runtime mode, but on detach re-enumerates with a
different USB VID and PID in DFU APP mode. The device is then further detached
by the `dfu` plugin.
On DFU attach the device again re-enumerates back to the Jabra 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.
Vendor ID Security
------------------

View File

@ -148,6 +148,7 @@ fu_jabra_device_init (FuJabraDevice *self)
{
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_ADD_COUNTERPART_GUIDS);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_set_remove_delay (FU_DEVICE (self), 20000); /* 10+10s! */
fu_device_set_protocol (FU_DEVICE (self), "org.usb.dfu");
}

View File

@ -47,6 +47,20 @@ Vendor ID Security
The vendor ID is set from the vendor ID, in this instance set to `USB:0x046D`
in bootloader and `HIDRAW:0x046D` in runtime mode.
Update Behavior
---------------
The peripheral firmware is deployed when the device is in normal runtime mode,
and the device will reset when the new firmware has been written.
The reciever device presents in runtime mode, but on detach re-enumerates with a
different USB PID in a bootloader mode. On attach the device again re-enumerates
back to the runtime mode. All unifying devices attached to the reciever will not
work for the duration of the update.
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.
Design Notes
------------

View File

@ -457,6 +457,7 @@ fu_logitech_hidpp_bootloader_init (FuLogitechHidPpBootloader *self)
{
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_IS_BOOTLOADER);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_add_icon (FU_DEVICE (self), "preferences-desktop-keyboard");
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_PLAIN);
fu_device_set_name (FU_DEVICE (self), "Unifying Receiver");

View File

@ -327,6 +327,7 @@ static void
fu_logitech_hidpp_runtime_init (FuLogitechHidPpRuntime *self)
{
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_PLAIN);
fu_device_add_icon (FU_DEVICE (self), "preferences-desktop-keyboard");
fu_device_set_name (FU_DEVICE (self), "Unifying Receiver");

View File

@ -34,6 +34,9 @@ the fastboot upgrade procedure.
Update Protocol: com.google.fastboot
For this reason the `REPLUG_MATCH_GUID` internal device flag is used so that
the fastboot and runtime modes are treated as the same device.
Update method: qmi-pdc
----------------------
@ -49,6 +52,9 @@ the new ones.
Update protocol: com.qualcomm.qmi_pdc
For this reason the `REPLUG_MATCH_GUID` internal device flag is used so that
the fastboot and runtime modes are treated as the same device.
External interface access
-------------------------
This plugin requires read/write access to `/dev/bus/usb`.

View File

@ -761,6 +761,7 @@ fu_mm_device_init (FuMmDevice *self)
{
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_USE_RUNTIME_VERSION);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_PLAIN);
fu_device_set_summary (FU_DEVICE (self), "Mobile broadband device");
fu_device_add_icon (FU_DEVICE (self), "network-modem");

View File

@ -20,6 +20,18 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_20A0&PID_4109`
* `USB\VID_20A0`
Update Behavior
---------------
The device usually presents in runtime mode, but on detach re-enumerates with a
different USB VID and PID in DFU mode. The device is then handled by the `dfu`
plugin.
On DFU attach 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.
Vendor ID Security
------------------

View File

@ -130,14 +130,15 @@ fu_nitrokey_device_setup (FuDevice *device, GError **error)
}
static void
fu_nitrokey_device_init (FuNitrokeyDevice *device)
fu_nitrokey_device_init (FuNitrokeyDevice *self)
{
fu_device_set_remove_delay (FU_DEVICE (device), FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE);
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_ADD_COUNTERPART_GUIDS);
fu_device_set_version_format (FU_DEVICE (device), FWUPD_VERSION_FORMAT_PAIR);
fu_device_set_protocol (FU_DEVICE (device), "org.usb.dfu");
fu_device_retry_set_delay (FU_DEVICE (device), 100);
fu_device_set_remove_delay (FU_DEVICE (self), FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_ADD_COUNTERPART_GUIDS);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_PAIR);
fu_device_set_protocol (FU_DEVICE (self), "org.usb.dfu");
fu_device_retry_set_delay (FU_DEVICE (self), 100);
}
static void

View File

@ -41,6 +41,12 @@ added:
and any optional GUID saved in the vendor extension block.
Update Behavior
---------------
The firmware is deployed when the device is in normal runtime mode, but it is
only activated when the system is either restarted or in some cases shutdown.
Quirk use
---------
This plugin uses the following plugin-specific quirks:

View File

@ -396,7 +396,6 @@ fu_nvme_device_init (FuNvmeDevice *self)
{
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_REQUIRE_AC);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_NO_GUID_MATCHING);
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_PLAIN);
fu_device_set_summary (FU_DEVICE (self), "NVM Express Solid State Drive");
fu_device_add_icon (FU_DEVICE (self), "drive-harddisk");

View File

@ -29,6 +29,12 @@ Pixart Imaging, Inc and Primax Electronics, Ltd, e.g.
Additionaly, a custom GUID values including the name is used, e.g.
Update Behavior
---------------
The firmware is deployed when the device is in normal runtime mode, and the
device will reset when the new firmware has been written.
Vendor ID Security
------------------

View File

@ -26,6 +26,12 @@ GUID Generation
These devices use the provided GUID provided in the `SoftwareId` parameter
without modification. Devices without GUIDs are not supported.
Update Behavior
---------------
The firmware willl be deployed as appropriate. The Redfish API does not specify
when the firmware will actually be written to the SPI device.
Vendor ID Security
------------------

View File

@ -33,6 +33,12 @@ Child I²C devices are created using the device number as a suffix, for instance
* `USB\VID_0BDA&PID_1100&I2C_01`
Update Behavior
---------------
The firmware is deployed when the device is in normal runtime mode, and the
device will reset when the new firmware has been written.
Vendor ID Security
------------------

View File

@ -30,6 +30,12 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_0BDA&PID_5423`
* `USB\VID_0BDA`
Update Behavior
---------------
The firmware is deployed when the device is in normal runtime mode, and the
device will reset when the new firmware has been written.
Vendor ID Security
------------------

View File

@ -575,7 +575,6 @@ fu_rts54hub_rtd21xx_device_init (FuRts54hubRtd21xxDevice *self)
fu_device_add_icon (FU_DEVICE (self), "video-display");
fu_device_set_protocol (FU_DEVICE (self), "com.realtek.rts54.i2c");
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_NO_GUID_MATCHING);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_DUAL_IMAGE);
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_PAIR);
fu_device_set_install_duration (FU_DEVICE (self), 100); /* seconds */

View File

@ -27,6 +27,12 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_0483&PID_A2CA&REV_0001`
* `USB\VID_0483&PID_A2CA`
Update Behavior
---------------
The firmware is deployed when the device is in normal runtime mode, and the
device will reset when the new firmware has been written.
Vendor ID Security
------------------

View File

@ -23,6 +23,14 @@ These devices use a custom GUID generated using the SuperIO chipset name:
* `SuperIO-$(chipset)`, for example `SuperIO-IT8512`
Update Behavior
---------------
The firmware is deployed when the device is in normal runtime mode, but it is
only activated on machine reboot. The firware write is normally scheduled to be
done very early in the boot process to minimize the chance the EC chip locking
up if the user is actually using the kerboard controller.
Vendor ID Security
------------------

View File

@ -31,6 +31,12 @@ These devices also use custom GUID values, e.g.
* `SYNAPTICS_CXAUDIO\CX2198X`
* `SYNAPTICS_CXAUDIO\CX21985`
Update Behavior
---------------
The firmware is deployed when the device is in normal runtime mode, and the
device will reset when the new firmware has been written.
Vendor ID Security
------------------

View File

@ -25,6 +25,13 @@ These devices use custom GUID values, e.g.
Please refer to the plugin source for more details about how the GUID is
constructed for specific hardware.
Update Behavior
---------------
The firmware is deployed when the device is in normal runtime mode, and the
device will reset when the new firmware has been written. On some hardware the
MST device may not enumerate if there is no monitor actually plugged in.
Vendor ID Security
------------------

View File

@ -27,6 +27,13 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_06CB&PID_00A9-cfg`
* `USB\VID_06CB&PID_00A9&CFG1_3483&CFG2_500`
Update Behavior
---------------
The device usually presents in runtime mode, but on detach re-enumerates with
the same USB PID in an unlocked mode. On attach the device again re-enumerates
back to the runtime locked mode.
Vendor ID Security
------------------

View File

@ -16,6 +16,13 @@ These devices also use custom GUID values constructed using the board ID, e.g.
* `SYNAPTICS_RMI\TM3038-002`
* `SYNAPTICS_RMI\TM3038`
Update Behavior
---------------
The device usually presents in HID mode, and the firmware is written to the
device by switching to a SERIO mode where the touchpad is nonfunctional.
Once complete the device is reset to get out of SERIO mode and to load the new
firmware version.
Vendor ID Security
------------------

View File

@ -16,6 +16,18 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_3384&PID_0001&REV_0001`
Update Behavior
---------------
The device usually presents in runtime mode, but on detach re-enumerates with a
different USB VID and PID in DFU mode. The device is then handled by the `dfu`
plugin.
On DFU attach 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.
Vendor ID Security
------------------

View File

@ -145,14 +145,15 @@ fu_system76_launch_device_close (FuDevice *device, GError **error)
}
static void
fu_system76_launch_device_init (FuSystem76LaunchDevice *device)
fu_system76_launch_device_init (FuSystem76LaunchDevice *self)
{
fu_device_set_remove_delay (FU_DEVICE (device), FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE);
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (device), FWUPD_DEVICE_FLAG_ADD_COUNTERPART_GUIDS);
fu_device_set_version_format (FU_DEVICE (device), FWUPD_VERSION_FORMAT_PLAIN);
fu_device_set_protocol (FU_DEVICE (device), "org.usb.dfu");
fu_device_retry_set_delay (FU_DEVICE (device), 100);
fu_device_set_remove_delay (FU_DEVICE (self), FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_ADD_COUNTERPART_GUIDS);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_PLAIN);
fu_device_set_protocol (FU_DEVICE (self), "org.usb.dfu");
fu_device_retry_set_delay (FU_DEVICE (self), 100);
}
static void

View File

@ -16,6 +16,18 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_1209&PID_1776&REV_0001`
Update Behavior
---------------
The device usually presents in runtime mode, but on detach re-enumerates with a
different USB VID and PID in DFU mode. The device is then handled by the `dfu`
plugin.
On DFU attach 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.
Vendor ID Security
------------------

View File

@ -96,6 +96,7 @@ static void
fu_thelio_io_device_init (FuThelioIoDevice *self)
{
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_set_remove_delay (FU_DEVICE (self), FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE);
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_TRIPLET);
fu_device_set_protocol (FU_DEVICE (self), "org.usb.dfu");

View File

@ -44,6 +44,21 @@ The retimer index is oriented around the physical connection within
the machine. It is important as multiple controllers may otherwise
identify identically.
Update Behavior
---------------
For most devices the firmware is written to the device at runtime and the
update is applied immediately. Once complete the controller may reboot
which may cause all connected USB and TBT devices to be reenumerated.
For some devices and circumstances (such as the Dell WD19 with a new enough
kernel) the device will remain functional for the duration of the update.
The update will complete on unplug.
If a user sets `DelayedActivation` configuration option then the update will
be staged but not completed until `activate` is separately called such as at
logout or shutdown.
Vendor ID Security
------------------

View File

@ -68,6 +68,7 @@ fu_plugin_device_registered (FuPlugin *plugin, FuDevice *device)
fu_device_get_name (device));
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_USABLE_DURING_UPDATE);
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_SKIPS_RESTART);
fu_device_remove_internal_flag (device, FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
}
}

View File

@ -429,6 +429,8 @@ fu_thunderbolt_device_setup_controller (FuDevice *device, GError **error)
fu_device_remove_flag (device, FWUPD_DEVICE_FLAG_SKIPS_RESTART);
/* control the order of activation (less relevant; install too though) */
fu_device_add_flag (device, FWUPD_DEVICE_FLAG_INSTALL_PARENT_FIRST);
} else {
fu_device_add_internal_flag (device, FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
}
return TRUE;

View File

@ -11,8 +11,8 @@ With the UpdateCapsule boot service it can be used to update system firmware.
If you don't want or need this functionality you can use the
`-Dplugin_uefi_capsule=false` option.
Lenovo Specific Behaviour
-------------------------
Lenovo Specific Behavior
------------------------
On Lenovo hardware only the boot label is set to `Linux-Firmware-Updater` rather
than "Linux Firmware Updater" (with spaces) due to long-fixed EFI boot manager
@ -53,6 +53,14 @@ This plugin supports the following protocol ID:
* org.uefi.capsule
Update Behavior
---------------
The firmware is deployed when the OS is running, but it is only written when the
system has been restarted and the `fwupd*.efi` binary has been run. To achieve
this fwupd sets up the EFI `BootNext` variable, creating the new boot entry if
required.
GUID Generation
---------------

View File

@ -35,6 +35,12 @@ certificates found in the system KEK and optionally the EFI architecture. e.g.
...where `arch` is typically one of `IA32`, `X64`, `ARM` or `AA64`
Update Behavior
---------------
The firmware is deployed when the machine is in normal runtime mode, but it is
only activated when the system is restarted.
Vendor ID Security
------------------

View File

@ -699,7 +699,6 @@ fu_vli_device_init (FuVliDevice *self)
priv->spi_cmd_read_id_sz = 2;
priv->spi_auto_detect = TRUE;
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_ADD_COUNTERPART_GUIDS);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_NO_GUID_MATCHING);
}
static void

View File

@ -325,7 +325,6 @@ fu_vli_usbhub_msp430_device_init (FuVliUsbhubMsp430Device *self)
fu_device_add_icon (FU_DEVICE (self), "audio-card");
fu_device_set_protocol (FU_DEVICE (self), "com.vli.i2c");
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_NO_GUID_MATCHING);
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_PAIR);
fu_device_set_logical_id (FU_DEVICE (self), "I2C");
fu_device_set_summary (FU_DEVICE (self), "I²C Dock Management Device");

View File

@ -247,7 +247,6 @@ fu_vli_usbhub_pd_device_init (FuVliUsbhubPdDevice *self)
fu_device_set_protocol (FU_DEVICE (self), "com.vli.usbhub");
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_NO_GUID_MATCHING);
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_QUAD);
fu_device_set_install_duration (FU_DEVICE (self), 15); /* seconds */
fu_device_set_logical_id (FU_DEVICE (self), "PD");

View File

@ -496,7 +496,6 @@ fu_vli_usbhub_rtd21xx_device_init (FuVliUsbhubRtd21xxDevice *self)
fu_device_add_icon (FU_DEVICE (self), "video-display");
fu_device_set_protocol (FU_DEVICE (self), "com.vli.i2c");
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_NO_GUID_MATCHING);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_DUAL_IMAGE);
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_PAIR);
fu_device_set_install_duration (FU_DEVICE (self), 100); /* seconds */

View File

@ -32,6 +32,16 @@ This plugin uses the following plugin-specific quirks:
| `WacomI2cFlashBaseAddr` | Base address for firmware | 1.2.4 |
| `WacomI2cFlashSize` | Maximum size of the firmware zone | 1.2.4 |
Update Behavior
---------------
The device usually presents in runtime mode, but on detach re-enumerates with a
different HIDRAW PID in a bootloader mode. On attach the device 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.
Vendor ID Security
------------------

View File

@ -360,6 +360,7 @@ fu_wacom_device_init (FuWacomDevice *self)
fu_device_set_protocol (FU_DEVICE (self), "com.wacom.raw");
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_UPDATABLE);
fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_INTERNAL);
fu_device_add_internal_flag (FU_DEVICE (self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_set_version_format (FU_DEVICE (self), FWUPD_VERSION_FORMAT_PAIR);
}

View File

@ -40,6 +40,12 @@ These devices use the standard USB DeviceInstanceId values, e.g.
* `USB\VID_056A&PID_0378`
* `USB\VID_056A`
Update Behavior
---------------
The firmware is deployed when the device is in normal runtime mode, and the
device will reset when the new firmware has been written.
Vendor ID Security
------------------

View File

@ -339,32 +339,6 @@ fu_device_list_get_old (FuDeviceList *self, FuDevice *device)
return g_object_ref (item->device_old);
}
static FuDeviceItem *
fu_device_list_get_by_guids (FuDeviceList *self, GPtrArray *guids)
{
g_autoptr(GRWLockReaderLocker) locker = g_rw_lock_reader_locker_new (&self->devices_mutex);
g_return_val_if_fail (locker != NULL, NULL);
for (guint i = 0; i < self->devices->len; i++) {
FuDeviceItem *item = g_ptr_array_index (self->devices, i);
for (guint j = 0; j < guids->len; j++) {
const gchar *guid = g_ptr_array_index (guids, j);
if (fu_device_has_guid (item->device, guid))
return item;
}
}
for (guint i = 0; i < self->devices->len; i++) {
FuDeviceItem *item = g_ptr_array_index (self->devices, i);
if (item->device_old == NULL)
continue;
for (guint j = 0; j < guids->len; j++) {
const gchar *guid = g_ptr_array_index (guids, j);
if (fu_device_has_guid (item->device_old, guid))
return item;
}
}
return NULL;
}
static FuDeviceItem *
fu_device_list_get_by_guids_removed (FuDeviceList *self, GPtrArray *guids)
{
@ -703,7 +677,7 @@ fu_device_list_add (FuDeviceList *self, FuDevice *device)
/* verify a compatible device does not already exist */
item = fu_device_list_get_by_guids_removed (self, fu_device_get_guids (device));
if (item != NULL) {
if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_NO_GUID_MATCHING)) {
if (fu_device_has_internal_flag (device, FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID)) {
g_debug ("found compatible device %s recently removed, reusing "
"item from plugin %s for plugin %s",
fu_device_get_id (item->device),
@ -713,48 +687,7 @@ fu_device_list_add (FuDeviceList *self, FuDevice *device)
return;
} else {
g_debug ("not adding matching %s for device add, use "
"FWUPD_DEVICE_FLAG_NO_GUID_MATCHING if required",
fu_device_get_id (item->device));
}
}
/* added the same device, supporting same protocol */
item = fu_device_list_get_by_guids (self, fu_device_get_guids (device));
if (item != NULL &&
g_strcmp0 (fu_device_get_protocol (item->device),
fu_device_get_protocol (device)) == 0) {
if (!fu_device_has_flag (device, FWUPD_DEVICE_FLAG_NO_GUID_MATCHING)) {
if (fu_device_get_priority (device) < fu_device_get_priority (item->device)) {
g_debug ("ignoring device %s [%s:%s] as better device %s [%s:%s] already exists",
fu_device_get_id (device),
fu_device_get_plugin (device),
g_type_name (fu_device_get_specialized_gtype (device)),
fu_device_get_id (item->device),
fu_device_get_plugin (item->device),
g_type_name (fu_device_get_specialized_gtype (item->device)));
return;
}
if (fu_device_get_priority (device) == fu_device_get_priority (item->device)) {
g_warning ("ignoring device %s [%s:%s] existing device %s [%s:%s] already exists",
fu_device_get_id (device),
fu_device_get_plugin (device),
g_type_name (fu_device_get_specialized_gtype (device)),
fu_device_get_id (item->device),
fu_device_get_plugin (item->device),
g_type_name (fu_device_get_specialized_gtype (item->device)));
return;
}
g_debug ("removing device %s [%s:%s] as better device %s [%s:%s] added",
fu_device_get_id (item->device),
fu_device_get_plugin (item->device),
g_type_name (fu_device_get_specialized_gtype (item->device)),
fu_device_get_id (device),
fu_device_get_plugin (device),
g_type_name (fu_device_get_specialized_gtype (device)));
fu_device_list_remove (self, item->device);
} else {
g_debug ("not adding matching %s for device add, use "
"FWUPD_DEVICE_FLAG_NO_GUID_MATCHING if required",
"FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID if required",
fu_device_get_id (item->device));
}
}

View File

@ -943,103 +943,6 @@ fu_engine_requirements_parent_device_func (gconstpointer user_data)
g_assert (ret);
}
static void
fu_engine_device_priority_func (gconstpointer user_data)
{
FuDevice *device;
g_autoptr(FuDevice) device1 = fu_device_new ();
g_autoptr(FuDevice) device2 = fu_device_new ();
g_autoptr(FuDevice) device3 = fu_device_new ();
g_autoptr(FuDevice) device4 = fu_device_new ();
g_autoptr(FuDevice) device5 = fu_device_new ();
g_autoptr(GPtrArray) devices = NULL;
g_autoptr(FuEngine) engine = fu_engine_new (FU_APP_FLAGS_NONE);
g_autoptr(GError) error = NULL;
g_autoptr(XbSilo) silo_empty = xb_silo_new ();
/* no metadata in daemon */
fu_engine_set_silo (engine, silo_empty);
/* add low prio then high then low */
fu_device_set_id (device1, "id1");
fu_device_add_vendor_id (device1, "USB:FFFF");
fu_device_set_protocol (device1, "com.acme");
fu_device_set_priority (device1, 0);
fu_device_set_plugin (device1, "udev");
fu_device_add_instance_id (device1, "GUID1");
fu_device_convert_instance_ids (device1);
fu_engine_add_device (engine, device1);
fu_device_set_id (device2, "id2");
fu_device_add_vendor_id (device2, "USB:FFFF");
fu_device_set_protocol (device2, "com.acme");
fu_device_set_priority (device2, 1);
fu_device_set_plugin (device2, "redfish");
fu_device_add_instance_id (device2, "GUID1");
fu_device_set_name (device2, "123");
fu_device_convert_instance_ids (device2);
fu_engine_add_device (engine, device2);
fu_device_set_id (device3, "id3");
fu_device_add_vendor_id (device3, "USB:FFFF");
fu_device_set_protocol (device3, "com.acme");
fu_device_set_priority (device3, 0);
fu_device_set_plugin (device3, "uefi_capsule");
fu_device_add_instance_id (device3, "GUID1");
fu_device_convert_instance_ids (device3);
fu_engine_add_device (engine, device3);
/* get the high prio device */
device = fu_engine_get_device (engine, "867d5f8110f8aa79dd63d7440f21724264f10430", &error);
g_assert_no_error (error);
g_assert_cmpint (fu_device_get_priority (device), ==, 1);
g_clear_object (&device);
/* the now-removed low-prio device */
device = fu_engine_get_device (engine, "4e89d81a2e6fb4be2578d245fd8511c1f4ad0b58", &error);
g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND);
g_assert_null (device);
g_clear_error (&error);
/* the never-added 2nd low-prio device */
device = fu_engine_get_device (engine, "c48feddbbcfee514f530ce8f7f2dccd98b6cc150", &error);
g_assert_error (error, FWUPD_ERROR, FWUPD_ERROR_NOT_FOUND);
g_assert_null (device);
g_clear_error (&error);
/* add extra devices that should sort */
fu_device_set_id (device4, "id4");
fu_device_add_vendor_id (device4, "USB:FFFF");
fu_device_set_protocol (device4, "com.acme");
fu_device_set_priority (device4, 0);
fu_device_set_plugin (device4, "redfish");
fu_device_add_instance_id (device4, "GUID4");
fu_device_set_name (device4, "BCD");
fu_device_convert_instance_ids (device4);
fu_engine_add_device (engine, device4);
fu_device_set_id (device5, "id5");
fu_device_add_vendor_id (device5, "USB:FFFF");
fu_device_set_protocol (device5, "com.acme");
fu_device_set_priority (device5, 0);
fu_device_set_plugin (device5, "uefi_capsule");
fu_device_add_instance_id (device5, "GUID5");
fu_device_set_name (device5, "ABC");
fu_device_convert_instance_ids (device5);
fu_engine_add_device (engine, device5);
/* make sure the devices are all sorted properly */
devices = fu_engine_get_devices (engine, &error);
g_assert_no_error (error);
g_assert_nonnull (devices);
g_assert_cmpint (devices->len, ==, 3);
/* first should be top priority device */
device = g_ptr_array_index (devices, 0);
g_assert_cmpstr (fu_device_get_name (device), ==, "123");
device = g_ptr_array_index (devices, 1);
g_assert_cmpstr (fu_device_get_name (device), ==, "ABC");
device = g_ptr_array_index (devices, 2);
g_assert_cmpstr (fu_device_get_name (device), ==, "BCD");
}
static void
fu_engine_device_parent_func (gconstpointer user_data)
{
@ -2048,11 +1951,13 @@ fu_device_list_replug_auto_func (gconstpointer user_data)
/* fake child devices */
fu_device_set_id (device1, "device1");
fu_device_add_internal_flag (device1, FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_set_physical_id (device1, "ID");
fu_device_set_plugin (device1, "self-test");
fu_device_set_remove_delay (device1, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE);
fu_device_add_child (parent, device1);
fu_device_set_id (device2, "device2");
fu_device_add_internal_flag (device2, FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_set_physical_id (device2, "ID"); /* matches */
fu_device_set_plugin (device2, "self-test");
fu_device_set_remove_delay (device2, FU_DEVICE_REMOVE_DELAY_RE_ENUMERATE);
@ -2105,12 +2010,14 @@ fu_device_list_replug_user_func (gconstpointer user_data)
/* fake devices */
fu_device_set_id (device1, "device1");
fu_device_add_internal_flag (device1, FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_add_instance_id (device1, "foo");
fu_device_add_instance_id (device1, "bar");
fu_device_set_plugin (device1, "self-test");
fu_device_set_remove_delay (device1, FU_DEVICE_REMOVE_DELAY_USER_REPLUG);
fu_device_convert_instance_ids (device1);
fu_device_set_id (device2, "device2");
fu_device_add_internal_flag (device2, FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_add_instance_id (device2, "baz");
fu_device_add_instance_id (device2, "bar"); /* matches */
fu_device_set_plugin (device2, "self-test");
@ -2173,6 +2080,7 @@ fu_device_list_compatible_func (gconstpointer user_data)
fu_device_add_vendor_id (device1, "USB:0x20A0");
fu_device_set_version_format (device1, FWUPD_VERSION_FORMAT_TRIPLET);
fu_device_set_version (device1, "1.2.3");
fu_device_add_internal_flag (device1, FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_add_instance_id (device1, "foobar");
fu_device_add_instance_id (device1, "bootloader");
fu_device_set_remove_delay (device1, 100);
@ -2186,6 +2094,7 @@ fu_device_list_compatible_func (gconstpointer user_data)
fu_device_set_id (device2, "device2");
fu_device_set_plugin (device2, "plugin-for-bootloader");
fu_device_add_instance_id (device2, "bootloader");
fu_device_add_internal_flag (device2, FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID);
fu_device_convert_instance_ids (device2);
/* verify only a changed event was generated */
@ -3218,8 +3127,6 @@ main (int argc, char **argv)
fu_engine_requirements_version_format_func);
g_test_add_data_func ("/fwupd/engine{device-auto-parent}", self,
fu_engine_device_parent_func);
g_test_add_data_func ("/fwupd/engine{device-priority}", self,
fu_engine_device_priority_func);
g_test_add_data_func ("/fwupd/engine{install-duration}", self,
fu_engine_install_duration_func);
g_test_add_data_func ("/fwupd/engine{generate-md}", self,