mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-07 17:45:23 +00:00
udev: Use the new FuUdevDevice abstraction
This commit is contained in:
parent
9d6e0e743b
commit
dd5b43f63b
@ -12,9 +12,11 @@
|
|||||||
#include "fu-rom.h"
|
#include "fu-rom.h"
|
||||||
#include "fu-plugin-vfuncs.h"
|
#include "fu-plugin-vfuncs.h"
|
||||||
|
|
||||||
struct FuPluginData {
|
void
|
||||||
GUdevClient *gudev_client;
|
fu_plugin_init (FuPlugin *plugin)
|
||||||
};
|
{
|
||||||
|
fu_plugin_add_udev_subsystem (plugin, "pci");
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
fu_plugin_verify (FuPlugin *plugin,
|
fu_plugin_verify (FuPlugin *plugin,
|
||||||
@ -65,194 +67,51 @@ fu_plugin_verify (FuPlugin *plugin,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gchar *
|
gboolean
|
||||||
fu_plugin_udev_generate_vendor_id (GUdevDevice *device)
|
fu_plugin_udev_device_added (FuPlugin *plugin, GUdevDevice *udev_device, GError **error)
|
||||||
{
|
|
||||||
const gchar *pci_id;
|
|
||||||
const gchar *subsys;
|
|
||||||
guint64 vid;
|
|
||||||
g_autofree gchar *subsys_up = NULL;
|
|
||||||
g_autofree gchar *vid_str = NULL;
|
|
||||||
|
|
||||||
/* get upper cased subsystem */
|
|
||||||
subsys = g_udev_device_get_subsystem (device);
|
|
||||||
if (subsys == NULL)
|
|
||||||
return NULL;
|
|
||||||
subsys_up = g_ascii_strup (subsys, -1);
|
|
||||||
|
|
||||||
/* get vendor ID */
|
|
||||||
pci_id = g_udev_device_get_property (device, "PCI_ID");
|
|
||||||
if (pci_id != NULL) {
|
|
||||||
g_auto(GStrv) split = g_strsplit (pci_id, ":", 2);
|
|
||||||
vid_str = g_strdup (split[0]);
|
|
||||||
}
|
|
||||||
if (vid_str == NULL) {
|
|
||||||
g_warning ("no vendor ID for %s",
|
|
||||||
g_udev_device_get_sysfs_path (device));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
vid = g_ascii_strtoull (vid_str, NULL, 16);
|
|
||||||
if (vid == 0x0) {
|
|
||||||
g_warning ("failed to parse %s", vid_str);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return g_strdup_printf ("%s:0x%04X", subsys_up, (guint) vid);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
fu_plugin_udev_add (FuPlugin *plugin, GUdevDevice *device)
|
|
||||||
{
|
{
|
||||||
FuDevice *dev_tmp;
|
FuDevice *dev_tmp;
|
||||||
const gchar *display_name;
|
const gchar *guid = NULL;
|
||||||
const gchar *guid;
|
|
||||||
const gchar *id = NULL;
|
const gchar *id = NULL;
|
||||||
const gchar *product;
|
|
||||||
const gchar *vendor;
|
|
||||||
g_autofree gchar *rom_fn = NULL;
|
g_autofree gchar *rom_fn = NULL;
|
||||||
g_autofree gchar *vendor_id = NULL;
|
|
||||||
g_autofree gchar *version = NULL;
|
|
||||||
g_auto(GStrv) split = NULL;
|
|
||||||
g_autoptr(AsProfile) profile = as_profile_new ();
|
g_autoptr(AsProfile) profile = as_profile_new ();
|
||||||
g_autoptr(AsProfileTask) ptask = NULL;
|
g_autoptr(AsProfileTask) ptask = NULL;
|
||||||
g_autoptr(FuDevice) dev = NULL;
|
g_autoptr(FuDevice) dev = NULL;
|
||||||
|
|
||||||
/* interesting device? */
|
/* interesting device? */
|
||||||
guid = g_udev_device_get_property (device, "FWUPD_GUID");
|
if (g_strcmp0 (g_udev_device_get_subsystem (udev_device), "pci") != 0)
|
||||||
|
return TRUE;
|
||||||
|
guid = g_udev_device_get_property (udev_device, "FWUPD_GUID");
|
||||||
if (guid == NULL)
|
if (guid == NULL)
|
||||||
return;
|
return TRUE;
|
||||||
|
|
||||||
/* get data */
|
/* get data */
|
||||||
ptask = as_profile_start (profile, "FuPluginUdev:client-add{%s}", guid);
|
ptask = as_profile_start (profile, "FuPluginUdev:client-add{%s}", guid);
|
||||||
g_assert (ptask != NULL);
|
g_assert (ptask != NULL);
|
||||||
g_debug ("adding udev device: %s", g_udev_device_get_sysfs_path (device));
|
g_debug ("adding udev device: %s", g_udev_device_get_sysfs_path (udev_device));
|
||||||
|
|
||||||
/* is already in database */
|
/* is already in database */
|
||||||
id = g_udev_device_get_sysfs_path (device);
|
id = g_udev_device_get_sysfs_path (udev_device);
|
||||||
dev_tmp = fu_plugin_cache_lookup (plugin, id);
|
dev_tmp = fu_plugin_cache_lookup (plugin, id);
|
||||||
if (dev_tmp != NULL) {
|
if (dev_tmp != NULL) {
|
||||||
g_debug ("ignoring duplicate %s", id);
|
g_debug ("ignoring duplicate %s", id);
|
||||||
return;
|
return TRUE;
|
||||||
}
|
|
||||||
|
|
||||||
/* get the FW version from the BCD device revision */
|
|
||||||
product = g_udev_device_get_property (device, "PRODUCT");
|
|
||||||
if (product != NULL) {
|
|
||||||
split = g_strsplit (product, "/", -1);
|
|
||||||
if (g_strv_length (split) != 3) {
|
|
||||||
g_warning ("env{PRODUCT} is invalid: %s", product);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
version = g_strdup (split[2]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* did we get enough data */
|
/* did we get enough data */
|
||||||
dev = fu_device_new ();
|
dev = fu_udev_device_new (udev_device);
|
||||||
|
fu_device_set_quirks (dev, fu_plugin_get_quirks (plugin));
|
||||||
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL);
|
fu_device_add_flag (dev, FWUPD_DEVICE_FLAG_INTERNAL);
|
||||||
fu_device_set_platform_id (dev, id);
|
|
||||||
fu_device_add_guid (dev, guid);
|
fu_device_add_guid (dev, guid);
|
||||||
fu_device_add_icon (dev, "audio-card");
|
fu_device_add_icon (dev, "audio-card");
|
||||||
display_name = g_udev_device_get_property (device, "FWUPD_MODEL");
|
|
||||||
if (display_name == NULL)
|
|
||||||
display_name = g_udev_device_get_property (device, "ID_MODEL_FROM_DATABASE");
|
|
||||||
if (display_name != NULL)
|
|
||||||
fu_device_set_name (dev, display_name);
|
|
||||||
vendor = g_udev_device_get_property (device, "FWUPD_VENDOR");
|
|
||||||
if (vendor == NULL)
|
|
||||||
vendor = g_udev_device_get_property (device, "ID_VENDOR_FROM_DATABASE");
|
|
||||||
if (vendor != NULL)
|
|
||||||
fu_device_set_vendor (dev, vendor);
|
|
||||||
if (version != NULL)
|
|
||||||
fu_device_set_version (dev, version);
|
|
||||||
|
|
||||||
/* set vendor ID */
|
|
||||||
vendor_id = fu_plugin_udev_generate_vendor_id (device);
|
|
||||||
if (vendor_id != NULL)
|
|
||||||
fu_device_set_vendor_id (FU_DEVICE (dev), vendor_id);
|
|
||||||
|
|
||||||
/* get the FW version from the rom when unlocked */
|
/* get the FW version from the rom when unlocked */
|
||||||
rom_fn = g_build_filename (g_udev_device_get_sysfs_path (device), "rom", NULL);
|
rom_fn = g_build_filename (g_udev_device_get_sysfs_path (udev_device), "rom", NULL);
|
||||||
if (g_file_test (rom_fn, G_FILE_TEST_EXISTS))
|
if (g_file_test (rom_fn, G_FILE_TEST_EXISTS))
|
||||||
fu_device_set_metadata (dev, "RomFilename", rom_fn);
|
fu_device_set_metadata (dev, "RomFilename", rom_fn);
|
||||||
|
|
||||||
/* insert to hash */
|
/* insert to hash */
|
||||||
fu_plugin_cache_add (plugin, id, dev);
|
fu_plugin_cache_add (plugin, id, dev);
|
||||||
fu_plugin_device_add_delay (plugin, dev);
|
fu_plugin_device_add_delay (plugin, dev);
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
fu_plugin_udev_remove (FuPlugin *plugin, GUdevDevice *device)
|
|
||||||
{
|
|
||||||
FuDevice *dev;
|
|
||||||
const gchar *id;
|
|
||||||
|
|
||||||
/* interesting device? */
|
|
||||||
if (g_udev_device_get_property (device, "FWUPD_GUID") == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* already in database */
|
|
||||||
id = g_udev_device_get_sysfs_path (device);
|
|
||||||
dev = fu_plugin_cache_lookup (plugin, id);
|
|
||||||
if (dev == NULL)
|
|
||||||
return;
|
|
||||||
fu_plugin_device_remove (plugin, dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
fu_plugin_udev_uevent_cb (GUdevClient *gudev_client,
|
|
||||||
const gchar *action,
|
|
||||||
GUdevDevice *udev_device,
|
|
||||||
FuPlugin *plugin)
|
|
||||||
{
|
|
||||||
if (g_strcmp0 (action, "remove") == 0) {
|
|
||||||
fu_plugin_udev_remove (plugin, udev_device);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (g_strcmp0 (action, "add") == 0) {
|
|
||||||
fu_plugin_udev_add (plugin, udev_device);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fu_plugin_init (FuPlugin *plugin)
|
|
||||||
{
|
|
||||||
FuPluginData *data = fu_plugin_alloc_data (plugin, sizeof (FuPluginData));
|
|
||||||
const gchar *subsystems[] = { "pci", NULL };
|
|
||||||
|
|
||||||
data->gudev_client = g_udev_client_new (subsystems);
|
|
||||||
g_signal_connect (data->gudev_client, "uevent",
|
|
||||||
G_CALLBACK (fu_plugin_udev_uevent_cb), plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fu_plugin_destroy (FuPlugin *plugin)
|
|
||||||
{
|
|
||||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
|
||||||
g_object_unref (data->gudev_client);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
fu_plugin_coldplug (FuPlugin *plugin, GError **error)
|
|
||||||
{
|
|
||||||
FuPluginData *data = fu_plugin_get_data (plugin);
|
|
||||||
GList *devices;
|
|
||||||
GUdevDevice *udev_device;
|
|
||||||
const gchar *devclass[] = { "pci", NULL };
|
|
||||||
g_autoptr(AsProfile) profile = as_profile_new ();
|
|
||||||
|
|
||||||
/* get all devices of class */
|
|
||||||
for (guint i = 0; devclass[i] != NULL; i++) {
|
|
||||||
g_autoptr(AsProfileTask) ptask = NULL;
|
|
||||||
ptask = as_profile_start (profile, "FuPluginUdev:coldplug{%s}", devclass[i]);
|
|
||||||
g_assert (ptask != NULL);
|
|
||||||
devices = g_udev_client_query_by_subsystem (data->gudev_client,
|
|
||||||
devclass[i]);
|
|
||||||
for (GList *l = devices; l != NULL; l = l->next) {
|
|
||||||
udev_device = l->data;
|
|
||||||
fu_plugin_udev_add (plugin, udev_device);
|
|
||||||
}
|
|
||||||
g_list_foreach (devices, (GFunc) g_object_unref, NULL);
|
|
||||||
g_list_free (devices);
|
|
||||||
}
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user