From f68092ea9dd021d2ba0b5afb32539552c76546d4 Mon Sep 17 00:00:00 2001 From: Crag Wang Date: Mon, 27 Jun 2022 13:14:46 +0800 Subject: [PATCH] dell-dock: cache hub device and add it until ec is added The usb3 hub 413c:b06f may be added to the plugin ahead of ec device while dock type is yet known at that time. Cache the hub until ec can tell the instance id, then add it to the plugin. --- plugins/dell-dock/fu-dell-dock-common.h | 5 +-- plugins/dell-dock/fu-dell-dock-hub.c | 4 +-- plugins/dell-dock/fu-dell-dock-hub.h | 2 +- plugins/dell-dock/fu-dell-dock-i2c-ec.c | 6 ++-- plugins/dell-dock/fu-dell-dock-i2c-ec.h | 2 +- plugins/dell-dock/fu-plugin-dell-dock.c | 44 ++++++++++++++++--------- 6 files changed, 39 insertions(+), 24 deletions(-) diff --git a/plugins/dell-dock/fu-dell-dock-common.h b/plugins/dell-dock/fu-dell-dock-common.h index 149444916..4042309da 100644 --- a/plugins/dell-dock/fu-dell-dock-common.h +++ b/plugins/dell-dock/fu-dell-dock-common.h @@ -42,8 +42,9 @@ #define ATOMIC_HUB1_PID 0x541A #define DELL_VID 0x413C -#define WD19_BASE 0x04 -#define ATOMIC_BASE 0x05 +#define DOCK_BASE_TYPE_UNKNOWN 0x0 +#define DOCK_BASE_TYPE_SALOMON 0x04 +#define DOCK_BASE_TYPE_ATOMIC 0x05 gboolean fu_dell_dock_set_power(FuDevice *device, guint8 target, gboolean enabled, GError **error); diff --git a/plugins/dell-dock/fu-dell-dock-hub.c b/plugins/dell-dock/fu-dell-dock-hub.c index 6c0f38337..86a24662e 100644 --- a/plugins/dell-dock/fu-dell-dock-hub.c +++ b/plugins/dell-dock/fu-dell-dock-hub.c @@ -29,11 +29,11 @@ struct _FuDellDockHub { G_DEFINE_TYPE(FuDellDockHub, fu_dell_dock_hub, FU_TYPE_HID_DEVICE) void -fu_dell_dock_hub_add_instance(FuDevice *device, guint8 ec_type) +fu_dell_dock_hub_add_instance(FuDevice *device, guint8 dock_type) { g_autofree gchar *devid = NULL; - if (ec_type == ATOMIC_BASE) { + if (dock_type == DOCK_BASE_TYPE_ATOMIC) { devid = g_strdup_printf("USB\\VID_%04X&PID_%04X&atomic_hub", (guint)fu_usb_device_get_vid(FU_USB_DEVICE(device)), (guint)fu_usb_device_get_pid(FU_USB_DEVICE(device))); diff --git a/plugins/dell-dock/fu-dell-dock-hub.h b/plugins/dell-dock/fu-dell-dock-hub.h index f7f6339ab..ce73b2cf3 100644 --- a/plugins/dell-dock/fu-dell-dock-hub.h +++ b/plugins/dell-dock/fu-dell-dock-hub.h @@ -32,4 +32,4 @@ G_DECLARE_FINAL_TYPE(FuDellDockHub, fu_dell_dock_hub, FU, DELL_DOCK_HUB, FuHidDe FuDellDockHub * fu_dell_dock_hub_new(FuUsbDevice *device); void -fu_dell_dock_hub_add_instance(FuDevice *device, guint8 ec_type); +fu_dell_dock_hub_add_instance(FuDevice *device, guint8 dock_type); diff --git a/plugins/dell-dock/fu-dell-dock-i2c-ec.c b/plugins/dell-dock/fu-dell-dock-i2c-ec.c index a3580df1f..632856c9a 100644 --- a/plugins/dell-dock/fu-dell-dock-i2c-ec.c +++ b/plugins/dell-dock/fu-dell-dock-i2c-ec.c @@ -183,7 +183,7 @@ fu_dell_dock_module_is_usb4(FuDevice *device) } guint8 -fu_dell_dock_get_ec_type(FuDevice *device) +fu_dell_dock_get_dock_type(FuDevice *device) { FuDellDockEc *self = FU_DELL_DOCK_EC(device); return self->base_type; @@ -347,10 +347,10 @@ fu_dell_dock_is_valid_dock(FuDevice *device, GError **error) self->base_type = result[0]; /* this will trigger setting up all the quirks */ - if (self->base_type == WD19_BASE) { + if (self->base_type == DOCK_BASE_TYPE_SALOMON) { fu_device_add_instance_id(device, DELL_DOCK_EC_INSTANCE_ID); return TRUE; - } else if (self->base_type == ATOMIC_BASE) { + } else if (self->base_type == DOCK_BASE_TYPE_ATOMIC) { fu_device_add_instance_id(device, DELL_DOCK_ATOMIC_EC_INSTANCE_ID); return TRUE; } diff --git a/plugins/dell-dock/fu-dell-dock-i2c-ec.h b/plugins/dell-dock/fu-dell-dock-i2c-ec.h index 69f580159..c6c3267bc 100644 --- a/plugins/dell-dock/fu-dell-dock-i2c-ec.h +++ b/plugins/dell-dock/fu-dell-dock-i2c-ec.h @@ -48,4 +48,4 @@ fu_dell_dock_ec_commit_package(FuDevice *device, GBytes *blob_fw, GError **error gboolean fu_dell_dock_module_is_usb4(FuDevice *device); guint8 -fu_dell_dock_get_ec_type(FuDevice *device); +fu_dell_dock_get_dock_type(FuDevice *device); diff --git a/plugins/dell-dock/fu-plugin-dell-dock.c b/plugins/dell-dock/fu-plugin-dell-dock.c index 6fc680fb5..80553277e 100644 --- a/plugins/dell-dock/fu-plugin-dell-dock.c +++ b/plugins/dell-dock/fu-plugin-dell-dock.c @@ -79,7 +79,7 @@ fu_plugin_dell_dock_probe(FuPlugin *plugin, FuDevice *proxy, GError **error) /* create mst endpoint */ mst_device = fu_dell_dock_mst_new(ctx); - if (fu_dell_dock_get_ec_type(FU_DEVICE(ec_device)) == ATOMIC_BASE) + if (fu_dell_dock_get_dock_type(FU_DEVICE(ec_device)) == DOCK_BASE_TYPE_ATOMIC) instance_id_mst = DELL_DOCK_VMM6210_INSTANCE_ID; else instance_id_mst = DELL_DOCK_VM5331_INSTANCE_ID; @@ -94,7 +94,7 @@ fu_plugin_dell_dock_probe(FuPlugin *plugin, FuDevice *proxy, GError **error) /* create package version endpoint */ status_device = fu_dell_dock_status_new(ctx); - if (fu_dell_dock_get_ec_type(FU_DEVICE(ec_device)) == ATOMIC_BASE) + if (fu_dell_dock_get_dock_type(FU_DEVICE(ec_device)) == DOCK_BASE_TYPE_ATOMIC) instance_id_status = DELL_DOCK_ATOMIC_STATUS_INSTANCE_ID; else if (fu_dell_dock_module_is_usb4(FU_DEVICE(ec_device))) instance_id_status = DELL_DOCK_DOCK2_INSTANCE_ID; @@ -144,11 +144,13 @@ fu_plugin_dell_dock_backend_device_added(FuPlugin *plugin, FuDevice *device, GEr { g_autoptr(FuDeviceLocker) locker = NULL; g_autoptr(FuDellDockHub) hub = NULL; - const gchar *key = NULL; + const gchar *hub_cache_key = "hub-usb3-gen1"; GPtrArray *devices; FuDevice *ec_device; + FuDevice *hub_dev; guint device_vid; guint device_pid; + guint8 dock_type; /* not interesting */ if (!FU_IS_USB_DEVICE(device)) @@ -177,27 +179,39 @@ fu_plugin_dell_dock_backend_device_added(FuPlugin *plugin, FuDevice *device, GEr if (locker == NULL) return FALSE; + /* probe extend devices under Usb3.1 Gen 2 Hub */ if (fu_device_has_private_flag(FU_DEVICE(hub), FU_DELL_DOCK_HUB_FLAG_HAS_BRIDGE)) { - /* only add the device with parent to cache */ - key = fu_device_get_id(FU_DEVICE(hub)); - if (fu_plugin_cache_lookup(plugin, key) != NULL) { - g_debug("Ignoring already added device %s", key); - return TRUE; - } - /* probe for extended devices */ if (!fu_plugin_dell_dock_probe(plugin, FU_DEVICE(hub), error)) return FALSE; - fu_plugin_cache_add(plugin, key, FU_DEVICE(hub)); } - /* add hub instance id after ec probed */ + /* process hub devices if ec device is added */ devices = fu_plugin_get_devices(plugin); ec_device = fu_plugin_dell_dock_get_ec(devices); - if (ec_device != NULL) { - guint8 ec_type = fu_dell_dock_get_ec_type(ec_device); - fu_dell_dock_hub_add_instance(FU_DEVICE(hub), ec_type); + if (ec_device == NULL) { + fu_plugin_cache_add(plugin, hub_cache_key, FU_DEVICE(hub)); + return TRUE; } + + /* determine dock type by ec */ + dock_type = fu_dell_dock_get_dock_type(ec_device); + if (dock_type == DOCK_BASE_TYPE_UNKNOWN) { + g_set_error(error, + FWUPD_ERROR, + FWUPD_ERROR_READ, + "can't read base dock type from EC"); + return FALSE; + } + fu_dell_dock_hub_add_instance(FU_DEVICE(hub), dock_type); fu_plugin_device_add(plugin, FU_DEVICE(hub)); + + /* add hub instance id for the cached device */ + hub_dev = fu_plugin_cache_lookup(plugin, hub_cache_key); + if (hub_dev != NULL) { + fu_dell_dock_hub_add_instance(FU_DEVICE(hub_dev), dock_type); + fu_plugin_device_add(plugin, FU_DEVICE(hub_dev)); + fu_plugin_cache_remove(plugin, hub_cache_key); + } return TRUE; }