From 97c1e727c4ad91a734685c49b81e071d3eeb4039 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Wed, 16 Oct 2019 16:28:54 -0500 Subject: [PATCH] Add new device flags indicating update resilience fwupd clients will ideally use this information as part of a policy to schedule updates in the background without user interactions on safe devices. --- libfwupd/fwupd-enums.c | 12 ++++++++++++ libfwupd/fwupd-enums.h | 6 ++++++ plugins/ata/fu-ata-device.c | 4 +++- plugins/colorhug/colorhug.quirk | 12 ++++++------ plugins/dell-dock/dell-dock.quirk | 11 ++++++----- plugins/dell-dock/fu-dell-dock-i2c-tbt.c | 2 ++ plugins/nvme/fu-nvme-device.c | 4 +++- plugins/synapticsmst/fu-synapticsmst-device.c | 1 + plugins/thunderbolt/fu-plugin-thunderbolt.c | 1 + plugins/uefi/fu-plugin-uefi.c | 1 + 10 files changed, 41 insertions(+), 13 deletions(-) diff --git a/libfwupd/fwupd-enums.c b/libfwupd/fwupd-enums.c index 54ea1a850..729af6716 100644 --- a/libfwupd/fwupd-enums.c +++ b/libfwupd/fwupd-enums.c @@ -173,6 +173,12 @@ fwupd_device_flag_to_string (FwupdDeviceFlags device_flag) return "can-verify"; if (device_flag == FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE) return "can-verify-image"; + if (device_flag == FWUPD_DEVICE_FLAG_DUAL_IMAGE) + return "dual-image"; + if (device_flag == FWUPD_DEVICE_FLAG_SELF_RECOVERY) + return "self-recovery"; + if (device_flag == FWUPD_DEVICE_FLAG_USABLE_DURING_UPDATE) + return "usable-during-update"; if (device_flag == FWUPD_DEVICE_FLAG_UNKNOWN) return "unknown"; return NULL; @@ -247,6 +253,12 @@ fwupd_device_flag_from_string (const gchar *device_flag) return FWUPD_DEVICE_FLAG_CAN_VERIFY; if (g_strcmp0 (device_flag, "can-verify-image") == 0) return FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE; + if (g_strcmp0 (device_flag, "dual-image") == 0) + return FWUPD_DEVICE_FLAG_DUAL_IMAGE; + if (g_strcmp0 (device_flag, "self-recovery") == 0) + return FWUPD_DEVICE_FLAG_SELF_RECOVERY; + if (g_strcmp0 (device_flag, "usable-during-update") == 0) + return FWUPD_DEVICE_FLAG_USABLE_DURING_UPDATE; return FWUPD_DEVICE_FLAG_UNKNOWN; } diff --git a/libfwupd/fwupd-enums.h b/libfwupd/fwupd-enums.h index 224a16b39..34b762573 100644 --- a/libfwupd/fwupd-enums.h +++ b/libfwupd/fwupd-enums.h @@ -94,6 +94,9 @@ typedef enum { * @FWUPD_DEVICE_FLAG_WILL_DISAPPEAR: Device will disappear after update and can't be verified * @FWUPD_DEVICE_FLAG_CAN_VERIFY: Device checksums can be compared against metadata * @FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE: Image can be dumped from device for verification + * @FWUPD_DEVICE_FLAG_DUAL_IMAGE: Device update architecture uses A/B partitions for updates + * @FWUPD_DEVICE_FLAG_SELF_RECOVERY: In flashing mode device will only accept intended payloads + * @FWUPD_DEVICE_FLAG_USABLE_DURING_UPDATE: Device remains usable while fwupd flashes or schedules the update * * The device flags. **/ @@ -125,6 +128,9 @@ typedef enum { #define FWUPD_DEVICE_FLAG_WILL_DISAPPEAR (1u << 24) /* Since: 1.3.3 */ #define FWUPD_DEVICE_FLAG_CAN_VERIFY (1u << 25) /* Since: 1.3.3 */ #define FWUPD_DEVICE_FLAG_CAN_VERIFY_IMAGE (1u << 26) /* Since: 1.3.3 */ +#define FWUPD_DEVICE_FLAG_DUAL_IMAGE (1u << 27) /* Since: 1.3.3 */ +#define FWUPD_DEVICE_FLAG_SELF_RECOVERY (1u << 28) /* Since: 1.3.3 */ +#define FWUPD_DEVICE_FLAG_USABLE_DURING_UPDATE (1u << 29) /* Since: 1.3.3 */ #define FWUPD_DEVICE_FLAG_UNKNOWN G_MAXUINT64 /* Since: 0.7.3 */ typedef guint64 FwupdDeviceFlags; diff --git a/plugins/ata/fu-ata-device.c b/plugins/ata/fu-ata-device.c index bb096c7e5..30f3524fe 100644 --- a/plugins/ata/fu-ata-device.c +++ b/plugins/ata/fu-ata-device.c @@ -343,8 +343,10 @@ fu_ata_device_probe (FuUdevDevice *device, GError **error) /* look at the PCI and USB depth to work out if in an external enclosure */ self->pci_depth = fu_udev_device_get_slot_depth (device, "pci"); self->usb_depth = fu_udev_device_get_slot_depth (device, "usb"); - if (self->pci_depth <= 2 && self->usb_depth <= 2) + if (self->pci_depth <= 2 && self->usb_depth <= 2) { fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_INTERNAL); + fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_USABLE_DURING_UPDATE); + } return TRUE; } diff --git a/plugins/colorhug/colorhug.quirk b/plugins/colorhug/colorhug.quirk index 81f25f4bc..c3c665f95 100644 --- a/plugins/colorhug/colorhug.quirk +++ b/plugins/colorhug/colorhug.quirk @@ -1,7 +1,7 @@ # ColorHug1 [DeviceInstanceId=USB\VID_273F&PID_1000] Plugin = colorhug -Flags = is-bootloader +Flags = is-bootloader,self-recovery Guid = 40338ceb-b966-4eae-adae-9c32edfcc484 FirmwareSizeMin = 0x2000 FirmwareSizeMax = 0x8000 @@ -10,7 +10,7 @@ InstallDuration = 8 [DeviceInstanceId=USB\VID_273F&PID_1001] Plugin = colorhug -Flags = none +Flags = self-recovery Summary = An open source display colorimeter Icon = colorimeter-colorhug Guid = 40338ceb-b966-4eae-adae-9c32edfcc484 @@ -20,7 +20,7 @@ InstallDuration = 8 # ColorHug2 [DeviceInstanceId=USB\VID_273F&PID_1004] Plugin = colorhug -Flags = none +Flags = self-recovery Summary = An open source display colorimeter Icon = colorimeter-colorhug Guid = 2082b5e0-7a64-478a-b1b2-e3404fab6dad @@ -31,7 +31,7 @@ InstallDuration = 8 [DeviceInstanceId=USB\VID_273F&PID_1005] Plugin = colorhug -Flags = is-bootloader +Flags = is-bootloader,self-recovery Guid = 2082b5e0-7a64-478a-b1b2-e3404fab6dad CounterpartGuid = USB\VID_273F&PID_1004 InstallDuration = 8 @@ -39,7 +39,7 @@ InstallDuration = 8 # ColorHugALS [DeviceInstanceId=USB\VID_273F&PID_1007] Plugin = colorhug -Flags = halfsize,none +Flags = halfsize,self-recovery Summary = An open source ambient light sensor Guid = 84f40464-9272-4ef7-9399-cd95f12da696 FirmwareSizeMin = 0x1000 @@ -49,7 +49,7 @@ InstallDuration = 5 [DeviceInstanceId=USB\VID_273F&PID_1006] Plugin = colorhug -Flags = halfsize,is-bootloader +Flags = halfsize,is-bootloader,self-recovery Guid = 84f40464-9272-4ef7-9399-cd95f12da696 CounterpartGuid = USB\VID_273F&PID_1007 InstallDuration = 5 diff --git a/plugins/dell-dock/dell-dock.quirk b/plugins/dell-dock/dell-dock.quirk index 6329a34c4..b25d64c73 100644 --- a/plugins/dell-dock/dell-dock.quirk +++ b/plugins/dell-dock/dell-dock.quirk @@ -33,7 +33,7 @@ Plugin = dell_dock Vendor = Dell Inc Icon = dock-usb FirmwareSize = 0x10000 -Flags = require-ac,updatable +Flags = require-ac,updatable,dual-image,usable-during-update DellDockUnlockTarget = 8 DellDockBlobMajorOffset = 0x7F6E DellDockBlobMinorOffset = 0x7F6F @@ -48,7 +48,7 @@ Vendor = Dell Inc Plugin = dell_dock Icon = dock-usb FirmwareSize = 0x10000 -Flags = require-ac,updatable,has-bridge +Flags = require-ac,updatable,has-bridge,dual-image,usable-during-update DellDockUnlockTarget = 7 DellDockBlobMajorOffset = 0x7F52 DellDockBlobMinorOffset = 0x7F53 @@ -64,7 +64,7 @@ Vendor = Dell Inc Icon = dock-usb FirmwareSizeMin = 0x1FFC0 FirmwareSizeMax = 0x20000 -Flags = require-ac +Flags = require-ac,dual-image,self-recovery,usable-during-update Children = FuDellDockStatus|USB\VID_413C&PID_B06E&hub&status,FuDellDockMst|MST-panamera-vmm5331-259 DellDockUnlockTarget = 1 DellDockBoardMin = 6 @@ -78,6 +78,7 @@ Name = Package level of Dell dock Summary = A representation of dock update status Plugin = dell_dock Vendor = Dell Inc +Flags = self-recovery,usable-during-update FirmwareSize = 24 InstallDuration = 5 DellDockBlobVersionOffset = 0x14 @@ -89,7 +90,7 @@ Summary = Multi Stream Transport controller Vendor = Dell Inc Plugin = synapticsmst ParentGuid = USB\VID_413C&PID_B06E&hub&embedded -Flags = skip-restart,require-ac +Flags = skip-restart,require-ac,dual-image,usable-during-update FirmwareSize=524288 DellDockUnlockTarget = 9 InstallDuration = 95 @@ -107,7 +108,7 @@ Vendor = Dell Inc ParentGuid = USB\VID_413C&PID_B06E&hub&embedded FirmwareSizeMin=0x40000 FirmwareSizeMax=0x80000 -Flags = require-ac +Flags = require-ac,dual-image Icon = thunderbolt InstallDuration = 22 DellDockInstallDurationI2C = 181 diff --git a/plugins/dell-dock/fu-dell-dock-i2c-tbt.c b/plugins/dell-dock/fu-dell-dock-i2c-tbt.c index c84f50f60..ccb635dfa 100644 --- a/plugins/dell-dock/fu-dell-dock-i2c-tbt.c +++ b/plugins/dell-dock/fu-dell-dock-i2c-tbt.c @@ -224,6 +224,8 @@ fu_dell_dock_tbt_probe (FuDevice *device, GError **error) fu_device_set_physical_id (device, fu_device_get_physical_id (parent)); fu_device_set_logical_id (FU_DEVICE (device), "tbt"); fu_device_add_instance_id (device, DELL_DOCK_TBT_INSTANCE_ID); + /* this is true only when connected to non-thunderbolt port */ + fu_device_add_flag (device, FWUPD_DEVICE_FLAG_USABLE_DURING_UPDATE); return TRUE; } diff --git a/plugins/nvme/fu-nvme-device.c b/plugins/nvme/fu-nvme-device.c index cba2b6a66..caab7cd39 100644 --- a/plugins/nvme/fu-nvme-device.c +++ b/plugins/nvme/fu-nvme-device.c @@ -351,8 +351,10 @@ fu_nvme_device_probe (FuUdevDevice *device, GError **error) /* look at the PCI depth to work out if in an external enclosure */ self->pci_depth = fu_udev_device_get_slot_depth (device, "pci"); - if (self->pci_depth <= 2) + if (self->pci_depth <= 2) { fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_INTERNAL); + fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_USABLE_DURING_UPDATE); + } /* all devices need at least a warm reset, but some quirked drives * need a full "cold" shutdown and startup */ diff --git a/plugins/synapticsmst/fu-synapticsmst-device.c b/plugins/synapticsmst/fu-synapticsmst-device.c index b5a48bb51..e3a645a6e 100644 --- a/plugins/synapticsmst/fu-synapticsmst-device.c +++ b/plugins/synapticsmst/fu-synapticsmst-device.c @@ -1196,6 +1196,7 @@ fu_synapticsmst_device_rescan (FuDevice *device, GError **error) case FU_SYNAPTICSMST_FAMILY_PANAMERA: fu_device_set_firmware_size_max (device, 0x80000); fu_device_add_instance_id (device, "MST-panamera"); + fu_device_add_flag (device, FWUPD_DEVICE_FLAG_DUAL_IMAGE); break; default: break; diff --git a/plugins/thunderbolt/fu-plugin-thunderbolt.c b/plugins/thunderbolt/fu-plugin-thunderbolt.c index 8827e0a62..3896a85a2 100644 --- a/plugins/thunderbolt/fu-plugin-thunderbolt.c +++ b/plugins/thunderbolt/fu-plugin-thunderbolt.c @@ -379,6 +379,7 @@ fu_plugin_thunderbolt_add (FuPlugin *plugin, GUdevDevice *device) (guint) did, is_native ? "-native" : ""); fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_UPDATABLE); + fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_DUAL_IMAGE); } else { device_id = g_strdup ("TBT-fixed"); fu_device_set_update_error (dev, "Missing non-active nvmem"); diff --git a/plugins/uefi/fu-plugin-uefi.c b/plugins/uefi/fu-plugin-uefi.c index fec2ecf31..48dbce66f 100644 --- a/plugins/uefi/fu-plugin-uefi.c +++ b/plugins/uefi/fu-plugin-uefi.c @@ -901,6 +901,7 @@ fu_plugin_coldplug (FuPlugin *plugin, GError **error) "RequireShimForSecureBoot", data->require_shim_for_sb); fu_device_add_flag (FU_DEVICE (dev), FWUPD_DEVICE_FLAG_UPDATABLE); + fu_device_add_flag (FU_DEVICE (dev), FWUPD_DEVICE_FLAG_USABLE_DURING_UPDATE); } fu_plugin_device_add (plugin, FU_DEVICE (dev)); }