mirror of
https://git.proxmox.com/git/fwupd
synced 2025-06-07 11:47:53 +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);
|
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
|
static void
|
||||||
fu_udev_device_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
fu_udev_device_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,13 @@
|
|||||||
#define GUdevDevice GObject
|
#define GUdevDevice GObject
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_GUSB
|
||||||
|
#include <gusb.h>
|
||||||
|
#else
|
||||||
|
#define GUsbContext GObject
|
||||||
|
#define GUsbDevice GObject
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "fu-plugin.h"
|
#include "fu-plugin.h"
|
||||||
|
|
||||||
#define FU_TYPE_UDEV_DEVICE (fu_udev_device_get_type())
|
#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);
|
fu_udev_device_get_children_with_subsystem(FuUdevDevice *self, const gchar *subsystem);
|
||||||
FuUdevDevice *
|
FuUdevDevice *
|
||||||
fu_udev_device_get_parent_with_subsystem(FuUdevDevice *self, const gchar *subsystem);
|
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 *
|
FuUsbDevice *
|
||||||
fu_usb_device_new(FuContext *ctx, GUsbDevice *usb_device)
|
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);
|
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 {
|
LIBFWUPDPLUGIN_1.8.7 {
|
||||||
global:
|
global:
|
||||||
|
fu_udev_device_find_usb_device;
|
||||||
fu_udev_device_set_device_file;
|
fu_udev_device_set_device_file;
|
||||||
local: *;
|
local: *;
|
||||||
} LIBFWUPDPLUGIN_1.8.6;
|
} LIBFWUPDPLUGIN_1.8.6;
|
||||||
|
Loading…
Reference in New Issue
Block a user