mirror of
https://git.proxmox.com/git/fwupd
synced 2025-06-05 01:42:21 +00:00
Add a helper to get a GUsbDevice from a FuUdevDevice
This commit is contained in:
parent
507b38dea9
commit
ac48c865a0
@ -2081,6 +2081,75 @@ fu_udev_device_get_children_with_subsystem(FuUdevDevice *self, const gchar *cons
|
||||
return g_steal_pointer(&out);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_udev_device_find_usb_device:
|
||||
* @FuUdevDevice: a #FuUdevDevice
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
* Gets the matching #GUsbDevice for the #GUdevDevice.
|
||||
*
|
||||
* NOTE: This should never be stored in the device class as an instance variable, as the lifecycle
|
||||
* for `GUsbDevice` may be different to the `FuUdevDevice`. Every time the `GUsbDevice` is used
|
||||
* this function should be called.
|
||||
*
|
||||
* Returns: (transfer full): a #GUsbDevice, or NULL if unset or invalid
|
||||
*
|
||||
* Since: 1.8.7
|
||||
**/
|
||||
GUsbDevice *
|
||||
fu_udev_device_find_usb_device(FuUdevDevice *self, GError **error)
|
||||
{
|
||||
#if defined(HAVE_GUDEV) && defined(HAVE_GUSB)
|
||||
FuUdevDevicePrivate *priv = GET_PRIVATE(self);
|
||||
guint8 bus = 0;
|
||||
guint8 address = 0;
|
||||
g_autoptr(GUdevDevice) udev_device = g_object_ref(priv->udev_device);
|
||||
g_autoptr(GUsbContext) usb_ctx = NULL;
|
||||
g_autoptr(GUsbDevice) usb_device = NULL;
|
||||
|
||||
g_return_val_if_fail(FU_IS_UDEV_DEVICE(self), NULL);
|
||||
g_return_val_if_fail(error == NULL || *error == NULL, NULL);
|
||||
|
||||
/* look at the current device and all the parent devices until we can find the USB data */
|
||||
while (TRUE) {
|
||||
g_autoptr(GUdevDevice) udev_device_parent = NULL;
|
||||
bus = g_udev_device_get_sysfs_attr_as_int(udev_device, "busnum");
|
||||
address = g_udev_device_get_sysfs_attr_as_int(udev_device, "devnum");
|
||||
if (bus != 0 || address != 0)
|
||||
break;
|
||||
udev_device_parent = g_udev_device_get_parent(udev_device);
|
||||
g_set_object(&udev_device, udev_device_parent);
|
||||
}
|
||||
|
||||
/* nothing found */
|
||||
if (bus == 0x0 && address == 0x0) {
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"No parent device with busnum and devnum");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* match device */
|
||||
usb_ctx = g_usb_context_new(error);
|
||||
if (usb_ctx == NULL)
|
||||
return NULL;
|
||||
usb_device = g_usb_context_find_by_bus_address(usb_ctx, bus, address, error);
|
||||
if (usb_device == NULL)
|
||||
return NULL;
|
||||
#if G_USB_CHECK_VERSION(0, 4, 1)
|
||||
g_usb_device_add_tag(usb_device, "is-transient");
|
||||
#endif
|
||||
return g_steal_pointer(&usb_device);
|
||||
#else
|
||||
g_set_error_literal(error,
|
||||
FWUPD_ERROR,
|
||||
FWUPD_ERROR_NOT_SUPPORTED,
|
||||
"Not supported as <gudev.h> or <gusb.h> is unavailable");
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
fu_udev_device_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
|
@ -13,6 +13,13 @@
|
||||
#define GUdevDevice GObject
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GUSB
|
||||
#include <gusb.h>
|
||||
#else
|
||||
#define GUsbContext GObject
|
||||
#define GUsbDevice GObject
|
||||
#endif
|
||||
|
||||
#include "fu-plugin.h"
|
||||
|
||||
#define FU_TYPE_UDEV_DEVICE (fu_udev_device_get_type())
|
||||
@ -139,3 +146,6 @@ GPtrArray *
|
||||
fu_udev_device_get_children_with_subsystem(FuUdevDevice *self, const gchar *subsystem);
|
||||
FuUdevDevice *
|
||||
fu_udev_device_get_parent_with_subsystem(FuUdevDevice *self, const gchar *subsystem);
|
||||
|
||||
GUsbDevice *
|
||||
fu_udev_device_find_usb_device(FuUdevDevice *self, GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
@ -834,6 +834,13 @@ fu_udev_device_unbind_driver(FuDevice *device, GError **error)
|
||||
FuUsbDevice *
|
||||
fu_usb_device_new(FuContext *ctx, GUsbDevice *usb_device)
|
||||
{
|
||||
#if G_USB_CHECK_VERSION(0, 4, 3)
|
||||
if (g_usb_device_has_tag(usb_device, "is-transient")) {
|
||||
g_critical("cannot use a device built using fu_udev_device_find_usb_device() as "
|
||||
"the GUsbContext is different");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
return g_object_new(FU_TYPE_USB_DEVICE, "context", ctx, "usb-device", usb_device, NULL);
|
||||
}
|
||||
|
||||
|
@ -1139,6 +1139,7 @@ LIBFWUPDPLUGIN_1.8.6 {
|
||||
|
||||
LIBFWUPDPLUGIN_1.8.7 {
|
||||
global:
|
||||
fu_udev_device_find_usb_device;
|
||||
fu_udev_device_set_device_file;
|
||||
local: *;
|
||||
} LIBFWUPDPLUGIN_1.8.6;
|
||||
|
Loading…
Reference in New Issue
Block a user