From 7a63a4c41c018f90cdfc4fd45ecb7648d1fad33d Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Tue, 1 Dec 2020 11:05:46 +0000 Subject: [PATCH] Export the driver name from FuUdevDevice We have to supply it when using fu_device_bind_driver(), so we need to get the old value for ->attach() to avoid guessing what driver was previously loaded. --- libfwupdplugin/fu-udev-device.c | 55 +++++++++++++++++++++++++++++++-- libfwupdplugin/fu-udev-device.h | 1 + libfwupdplugin/fwupdplugin.map | 6 ++++ 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/libfwupdplugin/fu-udev-device.c b/libfwupdplugin/fu-udev-device.c index a6339d9dc..9c322fa1b 100644 --- a/libfwupdplugin/fu-udev-device.c +++ b/libfwupdplugin/fu-udev-device.c @@ -43,6 +43,7 @@ typedef struct guint32 subsystem_model; guint8 revision; gchar *subsystem; + gchar *driver; gchar *device_file; gint fd; FuUdevDeviceFlags flags; @@ -54,6 +55,7 @@ enum { PROP_0, PROP_UDEV_DEVICE, PROP_SUBSYSTEM, + PROP_DRIVER, PROP_DEVICE_FILE, PROP_LAST }; @@ -151,6 +153,8 @@ fu_udev_device_to_string (FuDevice *device, guint idt, GString *str) fu_common_string_append_kv (str, idt, "SysfsPath", g_udev_device_get_sysfs_path (priv->udev_device)); fu_common_string_append_kv (str, idt, "Subsystem", priv->subsystem); + if (priv->driver != NULL) + fu_common_string_append_kv (str, idt, "Driver", priv->driver); } if (g_getenv ("FU_UDEV_DEVICE_DEBUG") != NULL) { g_autoptr(GUdevDevice) udev_parent = NULL; @@ -182,6 +186,20 @@ fu_udev_device_set_subsystem (FuUdevDevice *self, const gchar *subsystem) g_object_notify (G_OBJECT (self), "subsystem"); } +static void +fu_udev_device_set_driver (FuUdevDevice *self, const gchar *driver) +{ + FuUdevDevicePrivate *priv = GET_PRIVATE (self); + + /* not changed */ + if (g_strcmp0 (priv->driver, driver) == 0) + return; + + g_free (priv->driver); + priv->driver = g_strdup (driver); + g_object_notify (G_OBJECT (self), "driver"); +} + static void fu_udev_device_set_device_file (FuUdevDevice *self, const gchar *device_file) { @@ -420,12 +438,11 @@ fu_udev_device_probe (FuDevice *device, GError **error) } /* add the driver */ - tmp = g_udev_device_get_driver (priv->udev_device); - if (tmp != NULL) { + if (priv->driver != NULL) { g_autofree gchar *devid = NULL; devid = g_strdup_printf ("%s\\DRIVER_%s", subsystem, - tmp); + priv->driver); fu_device_add_instance_id_full (device, devid, FU_DEVICE_INSTANCE_FLAG_ONLY_QUIRKS); } @@ -491,6 +508,7 @@ fu_udev_device_set_dev (FuUdevDevice *self, GUdevDevice *udev_device) return; #ifdef HAVE_GUDEV fu_udev_device_set_subsystem (self, g_udev_device_get_subsystem (priv->udev_device)); + fu_udev_device_set_driver (self, g_udev_device_get_driver (priv->udev_device)); fu_udev_device_set_device_file (self, g_udev_device_get_device_file (priv->udev_device)); /* try to get one line summary */ @@ -704,6 +722,24 @@ fu_udev_device_get_subsystem (FuUdevDevice *self) return priv->subsystem; } +/** + * fu_udev_device_get_driver: + * @self: A #FuUdevDevice + * + * Gets the device driver, e.g. "psmouse". + * + * Returns: a subsystem, or NULL if unset or invalid + * + * Since: 1.5.3 + **/ +const gchar * +fu_udev_device_get_driver (FuUdevDevice *self) +{ + FuUdevDevicePrivate *priv = GET_PRIVATE (self); + g_return_val_if_fail (FU_IS_UDEV_DEVICE (self), NULL); + return priv->driver; +} + /** * fu_udev_device_get_device_file: * @self: A #FuUdevDevice @@ -1530,6 +1566,9 @@ fu_udev_device_get_property (GObject *object, guint prop_id, case PROP_SUBSYSTEM: g_value_set_string (value, priv->subsystem); break; + case PROP_DRIVER: + g_value_set_string (value, priv->driver); + break; case PROP_DEVICE_FILE: g_value_set_string (value, priv->device_file); break; @@ -1551,6 +1590,9 @@ fu_udev_device_set_property (GObject *object, guint prop_id, case PROP_SUBSYSTEM: fu_udev_device_set_subsystem (self, g_value_get_string (value)); break; + case PROP_DRIVER: + fu_udev_device_set_driver (self, g_value_get_string (value)); + break; case PROP_DEVICE_FILE: fu_udev_device_set_device_file (self, g_value_get_string (value)); break; @@ -1567,6 +1609,7 @@ fu_udev_device_finalize (GObject *object) FuUdevDevicePrivate *priv = GET_PRIVATE (self); g_free (priv->subsystem); + g_free (priv->driver); g_free (priv->device_file); if (priv->udev_device != NULL) g_object_unref (priv->udev_device); @@ -1621,6 +1664,12 @@ fu_udev_device_class_init (FuUdevDeviceClass *klass) G_PARAM_STATIC_NAME); g_object_class_install_property (object_class, PROP_SUBSYSTEM, pspec); + pspec = g_param_spec_string ("driver", NULL, NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME); + g_object_class_install_property (object_class, PROP_DRIVER, pspec); + pspec = g_param_spec_string ("device-file", NULL, NULL, NULL, G_PARAM_READWRITE | diff --git a/libfwupdplugin/fu-udev-device.h b/libfwupdplugin/fu-udev-device.h index a973c521c..168508046 100644 --- a/libfwupdplugin/fu-udev-device.h +++ b/libfwupdplugin/fu-udev-device.h @@ -62,6 +62,7 @@ GUdevDevice *fu_udev_device_get_dev (FuUdevDevice *self); const gchar *fu_udev_device_get_device_file (FuUdevDevice *self); const gchar *fu_udev_device_get_sysfs_path (FuUdevDevice *self); const gchar *fu_udev_device_get_subsystem (FuUdevDevice *self); +const gchar *fu_udev_device_get_driver (FuUdevDevice *self); guint32 fu_udev_device_get_vendor (FuUdevDevice *self); guint32 fu_udev_device_get_model (FuUdevDevice *self); guint32 fu_udev_device_get_subsystem_vendor (FuUdevDevice *self); diff --git a/libfwupdplugin/fwupdplugin.map b/libfwupdplugin/fwupdplugin.map index 2d5213472..3ba240d7a 100644 --- a/libfwupdplugin/fwupdplugin.map +++ b/libfwupdplugin/fwupdplugin.map @@ -687,3 +687,9 @@ LIBFWUPDPLUGIN_1.5.2 { fu_volume_is_internal; local: *; } LIBFWUPDPLUGIN_1.5.1; + +LIBFWUPDPLUGIN_1.5.3 { + global: + fu_udev_device_get_driver; + local: *; +} LIBFWUPDPLUGIN_1.5.2;