From 2319f1930619ca15562c2c39a7c7f0affe7bb7f5 Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Mon, 14 Mar 2022 20:29:07 +0000 Subject: [PATCH] Allow a plugin to only use the RemoveDelay when waiting for replug Only opt-in plugins that have been tested -- unconditionally enabling this may cause regressions on devices like docks. Fixes https://github.com/fwupd/fwupd/issues/4378 --- libfwupdplugin/fu-device.c | 4 ++++ libfwupdplugin/fu-device.h | 10 ++++++++++ plugins/ccgx/fu-ccgx-dmc-device.c | 1 + plugins/colorhug/fu-colorhug-device.c | 1 + src/fu-device-list.c | 13 ++++++++++++- 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/libfwupdplugin/fu-device.c b/libfwupdplugin/fu-device.c index d97a93b18..c9cf96608 100644 --- a/libfwupdplugin/fu-device.c +++ b/libfwupdplugin/fu-device.c @@ -233,6 +233,8 @@ fu_device_internal_flag_to_string(FuDeviceInternalFlags flag) return "md-set-signed"; if (flag == FU_DEVICE_INTERNAL_AUTO_PAUSE_POLLING) return "auto-pause-polling"; + if (flag == FU_DEVICE_INTERNAL_FLAG_ONLY_WAIT_FOR_REPLUG) + return "only-wait-for-replug"; return NULL; } @@ -299,6 +301,8 @@ fu_device_internal_flag_from_string(const gchar *flag) return FU_DEVICE_INTERNAL_FLAG_MD_SET_SIGNED; if (g_strcmp0(flag, "auto-pause-polling") == 0) return FU_DEVICE_INTERNAL_AUTO_PAUSE_POLLING; + if (g_strcmp0(flag, "only-wait-for-replug") == 0) + return FU_DEVICE_INTERNAL_FLAG_ONLY_WAIT_FOR_REPLUG; return FU_DEVICE_INTERNAL_FLAG_UNKNOWN; } diff --git a/libfwupdplugin/fu-device.h b/libfwupdplugin/fu-device.h index 16e5a594b..ac4ae96b5 100644 --- a/libfwupdplugin/fu-device.h +++ b/libfwupdplugin/fu-device.h @@ -458,6 +458,16 @@ typedef guint64 FuDeviceInternalFlags; */ #define FU_DEVICE_INTERNAL_AUTO_PAUSE_POLLING (1ull << 24) +/** + * FU_DEVICE_INTERNAL_FLAG_ONLY_WAIT_FOR_REPLUG: + * + * Only use the device removal delay when explicitly waiting for a replug, rather than every time + * the device is removed. + * + * Since: 1.8.1 + */ +#define FU_DEVICE_INTERNAL_FLAG_ONLY_WAIT_FOR_REPLUG (1ull << 25) + /* accessors */ gchar * fu_device_to_string(FuDevice *self); diff --git a/plugins/ccgx/fu-ccgx-dmc-device.c b/plugins/ccgx/fu-ccgx-dmc-device.c index 422a1fd0d..b755bfc3a 100644 --- a/plugins/ccgx/fu-ccgx-dmc-device.c +++ b/plugins/ccgx/fu-ccgx-dmc-device.c @@ -748,6 +748,7 @@ fu_ccgx_dmc_device_init(FuCcgxDmcDevice *self) 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_add_internal_flag(FU_DEVICE(self), FU_DEVICE_INTERNAL_FLAG_ONLY_WAIT_FOR_REPLUG); fu_device_register_private_flag(FU_DEVICE(self), FU_CCGX_DMC_DEVICE_FLAG_HAS_MANUAL_REPLUG, "has-manual-replug"); diff --git a/plugins/colorhug/fu-colorhug-device.c b/plugins/colorhug/fu-colorhug-device.c index 309afadbb..908ecb701 100644 --- a/plugins/colorhug/fu-colorhug-device.c +++ b/plugins/colorhug/fu-colorhug-device.c @@ -592,6 +592,7 @@ fu_colorhug_device_init(FuColorhugDevice *self) fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_ADD_COUNTERPART_GUIDS); fu_device_add_flag(FU_DEVICE(self), FWUPD_DEVICE_FLAG_UNSIGNED_PAYLOAD); fu_device_add_internal_flag(FU_DEVICE(self), FU_DEVICE_INTERNAL_FLAG_REPLUG_MATCH_GUID); + fu_device_add_internal_flag(FU_DEVICE(self), FU_DEVICE_INTERNAL_FLAG_ONLY_WAIT_FOR_REPLUG); fu_device_register_private_flag(FU_DEVICE(self), FU_COLORHUG_DEVICE_FLAG_HALFSIZE, "halfsize"); diff --git a/src/fu-device-list.c b/src/fu-device-list.c index 641e35809..f961da4bd 100644 --- a/src/fu-device-list.c +++ b/src/fu-device-list.c @@ -446,6 +446,17 @@ fu_device_list_remove_with_delay(FuDeviceItem *item) item); } +static gboolean +fu_device_list_should_remove_with_delay(FuDevice *device) +{ + if (fu_device_get_remove_delay(device) == 0) + return FALSE; + if (fu_device_has_internal_flag(device, FU_DEVICE_INTERNAL_FLAG_ONLY_WAIT_FOR_REPLUG) && + !fu_device_has_flag(device, FWUPD_DEVICE_FLAG_WAIT_FOR_REPLUG)) + return FALSE; + return TRUE; +} + /** * fu_device_list_remove: * @self: a device list @@ -487,7 +498,7 @@ fu_device_list_remove(FuDeviceList *self, FuDevice *device) } /* delay the removal and check for replug */ - if (fu_device_get_remove_delay(item->device) > 0) { + if (fu_device_list_should_remove_with_delay(item->device)) { fu_device_list_remove_with_delay(item); return; }