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.
This commit is contained in:
Crag Wang 2022-06-27 13:14:46 +08:00 committed by cragw
parent 0491b07a93
commit f68092ea9d
6 changed files with 39 additions and 24 deletions

View File

@ -42,8 +42,9 @@
#define ATOMIC_HUB1_PID 0x541A #define ATOMIC_HUB1_PID 0x541A
#define DELL_VID 0x413C #define DELL_VID 0x413C
#define WD19_BASE 0x04 #define DOCK_BASE_TYPE_UNKNOWN 0x0
#define ATOMIC_BASE 0x05 #define DOCK_BASE_TYPE_SALOMON 0x04
#define DOCK_BASE_TYPE_ATOMIC 0x05
gboolean gboolean
fu_dell_dock_set_power(FuDevice *device, guint8 target, gboolean enabled, GError **error); fu_dell_dock_set_power(FuDevice *device, guint8 target, gboolean enabled, GError **error);

View File

@ -29,11 +29,11 @@ struct _FuDellDockHub {
G_DEFINE_TYPE(FuDellDockHub, fu_dell_dock_hub, FU_TYPE_HID_DEVICE) G_DEFINE_TYPE(FuDellDockHub, fu_dell_dock_hub, FU_TYPE_HID_DEVICE)
void 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; 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", 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_vid(FU_USB_DEVICE(device)),
(guint)fu_usb_device_get_pid(FU_USB_DEVICE(device))); (guint)fu_usb_device_get_pid(FU_USB_DEVICE(device)));

View File

@ -32,4 +32,4 @@ G_DECLARE_FINAL_TYPE(FuDellDockHub, fu_dell_dock_hub, FU, DELL_DOCK_HUB, FuHidDe
FuDellDockHub * FuDellDockHub *
fu_dell_dock_hub_new(FuUsbDevice *device); fu_dell_dock_hub_new(FuUsbDevice *device);
void void
fu_dell_dock_hub_add_instance(FuDevice *device, guint8 ec_type); fu_dell_dock_hub_add_instance(FuDevice *device, guint8 dock_type);

View File

@ -183,7 +183,7 @@ fu_dell_dock_module_is_usb4(FuDevice *device)
} }
guint8 guint8
fu_dell_dock_get_ec_type(FuDevice *device) fu_dell_dock_get_dock_type(FuDevice *device)
{ {
FuDellDockEc *self = FU_DELL_DOCK_EC(device); FuDellDockEc *self = FU_DELL_DOCK_EC(device);
return self->base_type; return self->base_type;
@ -347,10 +347,10 @@ fu_dell_dock_is_valid_dock(FuDevice *device, GError **error)
self->base_type = result[0]; self->base_type = result[0];
/* this will trigger setting up all the quirks */ /* 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); fu_device_add_instance_id(device, DELL_DOCK_EC_INSTANCE_ID);
return TRUE; 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); fu_device_add_instance_id(device, DELL_DOCK_ATOMIC_EC_INSTANCE_ID);
return TRUE; return TRUE;
} }

View File

@ -48,4 +48,4 @@ fu_dell_dock_ec_commit_package(FuDevice *device, GBytes *blob_fw, GError **error
gboolean gboolean
fu_dell_dock_module_is_usb4(FuDevice *device); fu_dell_dock_module_is_usb4(FuDevice *device);
guint8 guint8
fu_dell_dock_get_ec_type(FuDevice *device); fu_dell_dock_get_dock_type(FuDevice *device);

View File

@ -79,7 +79,7 @@ fu_plugin_dell_dock_probe(FuPlugin *plugin, FuDevice *proxy, GError **error)
/* create mst endpoint */ /* create mst endpoint */
mst_device = fu_dell_dock_mst_new(ctx); 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; instance_id_mst = DELL_DOCK_VMM6210_INSTANCE_ID;
else else
instance_id_mst = DELL_DOCK_VM5331_INSTANCE_ID; 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 */ /* create package version endpoint */
status_device = fu_dell_dock_status_new(ctx); 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; instance_id_status = DELL_DOCK_ATOMIC_STATUS_INSTANCE_ID;
else if (fu_dell_dock_module_is_usb4(FU_DEVICE(ec_device))) else if (fu_dell_dock_module_is_usb4(FU_DEVICE(ec_device)))
instance_id_status = DELL_DOCK_DOCK2_INSTANCE_ID; 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(FuDeviceLocker) locker = NULL;
g_autoptr(FuDellDockHub) hub = NULL; g_autoptr(FuDellDockHub) hub = NULL;
const gchar *key = NULL; const gchar *hub_cache_key = "hub-usb3-gen1";
GPtrArray *devices; GPtrArray *devices;
FuDevice *ec_device; FuDevice *ec_device;
FuDevice *hub_dev;
guint device_vid; guint device_vid;
guint device_pid; guint device_pid;
guint8 dock_type;
/* not interesting */ /* not interesting */
if (!FU_IS_USB_DEVICE(device)) 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) if (locker == NULL)
return FALSE; 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)) { 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)) if (!fu_plugin_dell_dock_probe(plugin, FU_DEVICE(hub), error))
return FALSE; 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); devices = fu_plugin_get_devices(plugin);
ec_device = fu_plugin_dell_dock_get_ec(devices); ec_device = fu_plugin_dell_dock_get_ec(devices);
if (ec_device != NULL) { if (ec_device == NULL) {
guint8 ec_type = fu_dell_dock_get_ec_type(ec_device); fu_plugin_cache_add(plugin, hub_cache_key, FU_DEVICE(hub));
fu_dell_dock_hub_add_instance(FU_DEVICE(hub), ec_type); 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)); 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; return TRUE;
} }