aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/kerneldevice/mm-kernel-device-udev.c542
1 files changed, 220 insertions, 322 deletions
diff --git a/src/kerneldevice/mm-kernel-device-udev.c b/src/kerneldevice/mm-kernel-device-udev.c
index b39e58de..44fdd074 100644
--- a/src/kerneldevice/mm-kernel-device-udev.c
+++ b/src/kerneldevice/mm-kernel-device-udev.c
@@ -11,6 +11,7 @@
* GNU General Public License for more details:
*
* Copyright (C) 2016 Velocloud, Inc.
+ * Copyright (C) 2020 Aleksander Morgado <aleksander@aleksander.es>
*/
#include <string.h>
@@ -39,262 +40,238 @@ static GParamSpec *properties[PROP_LAST];
struct _MMKernelDeviceUdevPrivate {
GUdevDevice *device;
+
GUdevDevice *interface;
GUdevDevice *physdev;
guint16 vendor;
guint16 product;
guint16 revision;
+ gchar *driver;
MMKernelEventProperties *properties;
};
/*****************************************************************************/
-static gboolean
-get_device_ids (GUdevDevice *device,
- guint16 *vendor,
- guint16 *product,
- guint16 *revision)
-{
- GUdevDevice *parent = NULL;
- const gchar *vid = NULL, *pid = NULL, *rid = NULL, *parent_subsys;
- gboolean success = FALSE;
- char *pci_vid = NULL, *pci_pid = NULL;
-
- g_assert (vendor != NULL && product != NULL);
-
- parent = g_udev_device_get_parent (device);
- if (parent) {
- parent_subsys = g_udev_device_get_subsystem (parent);
- if (parent_subsys) {
- if (g_str_equal (parent_subsys, "bluetooth")) {
- /* Bluetooth devices report the VID/PID of the BT adapter here,
- * which isn't really what we want. Just return null IDs instead.
- */
- success = TRUE;
- goto out;
- } else if (g_str_equal (parent_subsys, "pcmcia")) {
- /* For PCMCIA devices we need to grab the PCMCIA subsystem's
- * manfid and cardid, since any IDs on the tty device itself
- * may be from PCMCIA controller or something else.
- */
- vid = g_udev_device_get_sysfs_attr (parent, "manf_id");
- pid = g_udev_device_get_sysfs_attr (parent, "card_id");
- if (!vid || !pid)
- goto out;
- } else if (g_str_equal (parent_subsys, "platform")) {
- /* Platform devices don't usually have a VID/PID */
- success = TRUE;
- goto out;
- } else if (g_str_has_prefix (parent_subsys, "usb") &&
- (!g_strcmp0 (g_udev_device_get_driver (parent), "qmi_wwan") ||
- !g_strcmp0 (g_udev_device_get_driver (parent), "cdc_mbim"))) {
- /* Need to look for vendor/product in the parent of the QMI/MBIM device */
- GUdevDevice *qmi_parent;
-
- qmi_parent = g_udev_device_get_parent (parent);
- if (qmi_parent) {
- vid = g_udev_device_get_property (qmi_parent, "ID_VENDOR_ID");
- pid = g_udev_device_get_property (qmi_parent, "ID_MODEL_ID");
- rid = g_udev_device_get_property (qmi_parent, "ID_REVISION");
- g_object_unref (qmi_parent);
- }
- } else if (g_str_equal (parent_subsys, "pci")) {
- const char *pci_id;
-
- /* We can't always rely on the model + vendor showing up on
- * the PCI device's child, so look at the PCI parent. PCI_ID
- * has the format "1931:000C".
- */
- pci_id = g_udev_device_get_property (parent, "PCI_ID");
- if (pci_id && strlen (pci_id) == 9 && pci_id[4] == ':') {
- vid = pci_vid = g_strdup (pci_id);
- pci_vid[4] = '\0';
- pid = pci_pid = g_strdup (pci_id + 5);
- }
- }
- }
- }
+static guint
+udev_device_get_sysfs_attr_as_hex (GUdevDevice *device,
+ const gchar *attribute)
+{
+ const gchar *attr;
+ guint val = 0;
- if (!vid)
- vid = g_udev_device_get_property (device, "ID_VENDOR_ID");
- if (!vid)
- goto out;
-
- if (strncmp (vid, "0x", 2) == 0)
- vid += 2;
- if (strlen (vid) != 4)
- goto out;
-
- if (!pid)
- pid = g_udev_device_get_property (device, "ID_MODEL_ID");
- if (!pid)
- goto out;
-
- if (strncmp (pid, "0x", 2) == 0)
- pid += 2;
- if (strlen (pid) != 4)
- goto out;
-
- *vendor = (guint16) (mm_utils_hex2byte (vid + 2) & 0xFF);
- *vendor |= (guint16) ((mm_utils_hex2byte (vid) & 0xFF) << 8);
-
- *product = (guint16) (mm_utils_hex2byte (pid + 2) & 0xFF);
- *product |= (guint16) ((mm_utils_hex2byte (pid) & 0xFF) << 8);
-
-
- /* Revision ID optional, default to 0x0000 if unknown */
- *revision = 0;
- if (!rid)
- rid = g_udev_device_get_property (device, "ID_REVISION");
- if (rid) {
- if (strncmp (rid, "0x", 2) == 0)
- rid += 2;
- if (strlen (rid) == 4) {
- *revision = (guint16) (mm_utils_hex2byte (rid + 2) & 0xFF);
- *revision |= (guint16) ((mm_utils_hex2byte (rid) & 0xFF) << 8);
- }
- }
+ attr = g_udev_device_get_sysfs_attr (device, attribute);
+ if (attr)
+ mm_get_uint_from_hex_str (attr, &val);
+ return val;
+}
- success = TRUE;
+/*****************************************************************************/
-out:
- if (parent)
- g_object_unref (parent);
- g_free (pci_vid);
- g_free (pci_pid);
- return success;
+static void
+preload_contents_other (MMKernelDeviceUdev *self)
+{
+ /* For any other kind of bus (or the absence of one, as in virtual devices),
+ * assume this is a single port device and don't try to match multiple ports
+ * together. Also, obviously, no vendor, product, revision or interface. */
+ self->priv->driver = g_strdup (g_udev_device_get_driver (self->priv->device));
}
static void
-ensure_device_ids (MMKernelDeviceUdev *self)
+preload_contents_platform (MMKernelDeviceUdev *self,
+ const gchar *platform)
{
- /* Revision is optional */
- if (self->priv->vendor || self->priv->product)
- return;
+ g_autoptr(GUdevDevice) iter = NULL;
- if (!self->priv->device)
- return;
+ iter = g_object_ref (self->priv->device);
+ while (iter) {
+ GUdevDevice *parent;
- if (!get_device_ids (self->priv->device, &self->priv->vendor, &self->priv->product, &self->priv->revision))
- mm_obj_dbg (self, "could not get vendor/product id");
-}
+ /* Store the first driver found */
+ if (!self->priv->driver)
+ self->priv->driver = g_strdup (g_udev_device_get_driver (iter));
-/*****************************************************************************/
+ /* Take first parent with the given platform subsystem as physical device */
+ if (!self->priv->physdev && (g_strcmp0 (g_udev_device_get_subsystem (iter), platform) == 0)) {
+ self->priv->physdev = g_object_ref (iter);
+ /* stop traversing as soon as the physical device is found */
+ break;
+ }
-static GUdevDevice *
-find_physical_gudevdevice (GUdevDevice *child)
+ parent = g_udev_device_get_parent (iter);
+ g_clear_object (&iter);
+ iter = parent;
+ }
+}
+
+static void
+preload_contents_pcmcia (MMKernelDeviceUdev *self)
{
- GUdevDevice *iter, *old = NULL;
- GUdevDevice *physdev = NULL;
- const char *subsys, *type, *name;
- guint32 i = 0;
- gboolean is_usb = FALSE, is_pcmcia = FALSE;
+ g_autoptr(GUdevDevice) iter = NULL;
+ gboolean pcmcia_subsystem_found = FALSE;
- /* Bluetooth rfcomm devices are "virtual" and don't necessarily have
- * parents at all.
- */
- name = g_udev_device_get_name (child);
- if (name && strncmp (name, "rfcomm", 6) == 0)
- return g_object_ref (child);
+ iter = g_object_ref (self->priv->device);
+ while (iter) {
+ g_autoptr(GUdevDevice) parent = NULL;
- iter = g_object_ref (child);
- while (iter && i++ < 8) {
- subsys = g_udev_device_get_subsystem (iter);
- if (subsys) {
- if (is_usb || g_str_has_prefix (subsys, "usb")) {
- is_usb = TRUE;
- type = g_udev_device_get_devtype (iter);
- if (type && !strcmp (type, "usb_device")) {
- physdev = iter;
- break;
- }
- } else if (is_pcmcia || !strcmp (subsys, "pcmcia")) {
- GUdevDevice *pcmcia_parent;
- const char *tmp_subsys;
-
- is_pcmcia = TRUE;
-
- /* If the parent of this PCMCIA device is no longer part of
- * the PCMCIA subsystem, we want to stop since we're looking
- * for the base PCMCIA device, not the PCMCIA controller which
- * is usually PCI or some other bus type.
- */
- pcmcia_parent = g_udev_device_get_parent (iter);
- if (pcmcia_parent) {
- tmp_subsys = g_udev_device_get_subsystem (pcmcia_parent);
- if (tmp_subsys && strcmp (tmp_subsys, "pcmcia"))
- physdev = iter;
- g_object_unref (pcmcia_parent);
- if (physdev)
- break;
- }
- } else if (!strcmp (subsys, "platform") ||
- !strcmp (subsys, "pci") ||
- !strcmp (subsys, "pnp") ||
- !strcmp (subsys, "sdio")) {
- /* Take the first parent as the physical device */
- physdev = iter;
- break;
- }
+ /* Store the first driver found */
+ if (!self->priv->driver)
+ self->priv->driver = g_strdup (g_udev_device_get_driver (iter));
+
+ if (g_strcmp0 (g_udev_device_get_subsystem (iter), "pcmcia") == 0)
+ pcmcia_subsystem_found = TRUE;
+
+ /* If the parent of this PCMCIA device is no longer part of
+ * the PCMCIA subsystem, we want to stop since we're looking
+ * for the base PCMCIA device, not the PCMCIA controller which
+ * is usually PCI or some other bus type.
+ */
+ parent = g_udev_device_get_parent (iter);
+
+ if (pcmcia_subsystem_found && parent && (g_strcmp0 (g_udev_device_get_subsystem (parent), "pcmcia") != 0)) {
+ self->priv->vendor = udev_device_get_sysfs_attr_as_hex (iter, "manf_id");
+ self->priv->product = udev_device_get_sysfs_attr_as_hex (iter, "card_id");
+ self->priv->physdev = g_object_ref (iter);
+ /* stop traversing as soon as the physical device is found */
+ break;
}
- old = iter;
- iter = g_udev_device_get_parent (old);
- g_object_unref (old);
+ g_clear_object (&iter);
+ iter = g_steal_pointer (&parent);
}
-
- return physdev;
}
static void
-ensure_physdev (MMKernelDeviceUdev *self)
+preload_contents_pci (MMKernelDeviceUdev *self)
{
- if (self->priv->physdev)
- return;
- if (self->priv->device)
- self->priv->physdev = find_physical_gudevdevice (self->priv->device);
-}
+ g_autoptr(GUdevDevice) iter = NULL;
-/*****************************************************************************/
+ iter = g_object_ref (self->priv->device);
+ while (iter) {
+ GUdevDevice *parent;
-static void
-ensure_interface (MMKernelDeviceUdev *self)
-{
- GUdevDevice *new_parent;
- GUdevDevice *parent;
+ /* Store the first driver found */
+ if (!self->priv->driver)
+ self->priv->driver = g_strdup (g_udev_device_get_driver (iter));
+
+ /* the PCI channel specific devices have their own drivers and
+ * subsystems, we can rely on the physical device being the first
+ * one that reports the 'pci' subsystem */
+ if (!self->priv->physdev && (g_strcmp0 (g_udev_device_get_subsystem (iter), "pci") == 0)) {
+ self->priv->vendor = udev_device_get_sysfs_attr_as_hex (iter, "vendor");
+ self->priv->product = udev_device_get_sysfs_attr_as_hex (iter, "device");
+ self->priv->revision = udev_device_get_sysfs_attr_as_hex (iter, "revision");
+ self->priv->physdev = g_object_ref (iter);
+ /* stop traversing as soon as the physical device is found */
+ break;
+ }
- if (self->priv->interface)
- return;
+ parent = g_udev_device_get_parent (iter);
+ g_clear_object (&iter);
+ iter = parent;
+ }
+}
- if (!self->priv->device)
- return;
+static void
+preload_contents_usb (MMKernelDeviceUdev *self)
+{
+ g_autoptr(GUdevDevice) iter = NULL;
- ensure_physdev (self);
+ iter = g_object_ref (self->priv->device);
+ while (iter) {
+ GUdevDevice *parent;
+ const gchar *devtype;
- parent = g_udev_device_get_parent (self->priv->device);
- while (1) {
- /* Abort if no parent found */
- if (!parent)
- break;
+ devtype = g_udev_device_get_devtype (iter);
- /* Look for the first parent that is a USB interface (i.e. has
- * bInterfaceClass) */
- if (g_udev_device_has_sysfs_attr (parent, "bInterfaceClass")) {
- self->priv->interface = parent;
- break;
+ /* is this the USB interface? */
+ if (!self->priv->interface && (g_strcmp0 (devtype, "usb_interface") == 0)) {
+ self->priv->interface = g_object_ref (iter);
+ self->priv->driver = g_strdup (g_udev_device_get_driver (iter));
}
- /* If unknown physdev, just stop right away */
- if (!self->priv->physdev || parent == self->priv->physdev) {
- g_object_unref (parent);
+ /* is this the USB physdev? */
+ if (!self->priv->physdev && (g_strcmp0 (devtype, "usb_device") == 0)) {
+ self->priv->vendor = udev_device_get_sysfs_attr_as_hex (iter, "idVendor");
+ self->priv->product = udev_device_get_sysfs_attr_as_hex (iter, "idProduct");
+ self->priv->revision = udev_device_get_sysfs_attr_as_hex (iter, "bcdDevice");
+ self->priv->physdev = g_object_ref (iter);
+ /* stop traversing as soon as the physical device is found */
break;
}
- new_parent = g_udev_device_get_parent (parent);
- g_object_unref (parent);
- parent = new_parent;
+ parent = g_udev_device_get_parent (iter);
+ g_clear_object (&iter);
+ iter = parent;
+ }
+}
+
+static gchar *
+find_device_bus_subsystem (MMKernelDeviceUdev *self)
+{
+ g_autoptr(GUdevDevice) iter = NULL;
+
+ iter = g_object_ref (self->priv->device);
+ while (iter) {
+ const gchar *subsys;
+ GUdevDevice *parent;
+
+ /* stop search as soon as we find a parent object
+ * of one of the supported bus subsystems */
+ subsys = g_udev_device_get_subsystem (iter);
+ if ((g_strcmp0 (subsys, "usb") == 0) ||
+ (g_strcmp0 (subsys, "pcmcia") == 0) ||
+ (g_strcmp0 (subsys, "pci") == 0) ||
+ (g_strcmp0 (subsys, "platform") == 0) ||
+ (g_strcmp0 (subsys, "pnp") == 0) ||
+ (g_strcmp0 (subsys, "sdio") == 0))
+ return g_strdup (subsys);
+
+ parent = g_udev_device_get_parent (iter);
+ g_clear_object (&iter);
+ iter = parent;
}
+
+ /* no more parents to check */
+ return NULL;
+}
+
+static void
+preload_contents (MMKernelDeviceUdev *self)
+{
+ g_autofree gchar *bus_subsys = NULL;
+
+ bus_subsys = find_device_bus_subsystem (self);
+ if (g_strcmp0 (bus_subsys, "usb") == 0)
+ preload_contents_usb (self);
+ else if (g_strcmp0 (bus_subsys, "pcmcia") == 0)
+ preload_contents_pcmcia (self);
+ else if (g_strcmp0 (bus_subsys, "pci") == 0)
+ preload_contents_pci (self);
+ else if ((g_strcmp0 (bus_subsys, "platform") == 0) ||
+ (g_strcmp0 (bus_subsys, "pnp") == 0) ||
+ (g_strcmp0 (bus_subsys, "sdio") == 0))
+ preload_contents_platform (self, bus_subsys);
+ else
+ preload_contents_other (self);
+
+ if (!bus_subsys)
+ return;
+
+ mm_obj_dbg (self, "port contents loaded:");
+ mm_obj_dbg (self, " bus: %s", bus_subsys ? bus_subsys : "n/a");
+ if (self->priv->interface)
+ mm_obj_dbg (self, " interface: %s", g_udev_device_get_sysfs_path (self->priv->interface));
+ if (self->priv->physdev)
+ mm_obj_dbg (self, " device: %s", g_udev_device_get_sysfs_path (self->priv->physdev));
+ if (self->priv->driver)
+ mm_obj_dbg (self, " driver: %s", self->priv->driver);
+ if (self->priv->vendor)
+ mm_obj_dbg (self, " vendor: %04x", self->priv->vendor);
+ if (self->priv->product)
+ mm_obj_dbg (self, " product: %04x", self->priv->product);
+ if (self->priv->revision)
+ mm_obj_dbg (self, " revision: %04x", self->priv->revision);
}
/*****************************************************************************/
@@ -328,46 +305,9 @@ kernel_device_get_name (MMKernelDevice *_self)
}
static const gchar *
-kernel_device_get_driver (MMKernelDevice *_self)
+kernel_device_get_driver (MMKernelDevice *self)
{
- MMKernelDeviceUdev *self;
- const gchar *driver, *subsys, *name;
-
- self = MM_KERNEL_DEVICE_UDEV (_self);
-
- if (!self->priv->device)
- return NULL;
-
- driver = g_udev_device_get_driver (self->priv->device);
- if (!driver) {
- GUdevDevice *parent;
-
- parent = g_udev_device_get_parent (self->priv->device);
- if (parent)
- driver = g_udev_device_get_driver (parent);
-
- /* Check for bluetooth; it's driver is a bunch of levels up so we
- * just check for the subsystem of the parent being bluetooth.
- */
- if (!driver && parent) {
- subsys = g_udev_device_get_subsystem (parent);
- if (subsys && !strcmp (subsys, "bluetooth"))
- driver = "bluetooth";
- }
-
- if (parent)
- g_object_unref (parent);
- }
-
- /* Newer kernels don't set up the rfcomm port parent in sysfs,
- * so we must infer it from the device name.
- */
- name = g_udev_device_get_name (self->priv->device);
- if (!driver && strncmp (name, "rfcomm", 6) == 0)
- driver = "bluetooth";
-
- /* Note: may return NULL! */
- return driver;
+ return MM_KERNEL_DEVICE_UDEV (self)->priv->driver;
}
static const gchar *
@@ -376,18 +316,16 @@ kernel_device_get_sysfs_path (MMKernelDevice *_self)
MMKernelDeviceUdev *self;
self = MM_KERNEL_DEVICE_UDEV (_self);
-
- if (!self->priv->device)
- return NULL;
-
- return g_udev_device_get_sysfs_path (MM_KERNEL_DEVICE_UDEV (self)->priv->device);
+ return (self->priv->device ?
+ g_udev_device_get_sysfs_path (self->priv->device) :
+ NULL);
}
static const gchar *
kernel_device_get_physdev_uid (MMKernelDevice *_self)
{
MMKernelDeviceUdev *self;
- const gchar *uid = NULL;
+ const gchar *uid = NULL;
self = MM_KERNEL_DEVICE_UDEV (_self);
@@ -398,7 +336,7 @@ kernel_device_get_physdev_uid (MMKernelDevice *_self)
}
/* Try to load from properties set on the physical device */
- if ((uid = mm_kernel_device_get_global_property (MM_KERNEL_DEVICE (self), ID_MM_PHYSDEV_UID)) != NULL)
+ if ((uid = mm_kernel_device_get_global_property (_self, ID_MM_PHYSDEV_UID)) != NULL)
return uid;
/* Use physical device sysfs path, if any */
@@ -411,33 +349,21 @@ kernel_device_get_physdev_uid (MMKernelDevice *_self)
}
static guint16
-kernel_device_get_physdev_vid (MMKernelDevice *_self)
+kernel_device_get_physdev_vid (MMKernelDevice *self)
{
- MMKernelDeviceUdev *self;
-
- self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_device_ids (self);
- return self->priv->vendor;
+ return MM_KERNEL_DEVICE_UDEV (self)->priv->vendor;
}
static guint16
-kernel_device_get_physdev_pid (MMKernelDevice *_self)
+kernel_device_get_physdev_pid (MMKernelDevice *self)
{
- MMKernelDeviceUdev *self;
-
- self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_device_ids (self);
- return self->priv->product;
+ return MM_KERNEL_DEVICE_UDEV (self)->priv->product;
}
static guint16
-kernel_device_get_physdev_revision (MMKernelDevice *_self)
+kernel_device_get_physdev_revision (MMKernelDevice *self)
{
- MMKernelDeviceUdev *self;
-
- self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_device_ids (self);
- return self->priv->revision;
+ return MM_KERNEL_DEVICE_UDEV (self)->priv->revision;
}
static const gchar *
@@ -446,11 +372,7 @@ kernel_device_get_physdev_sysfs_path (MMKernelDevice *_self)
MMKernelDeviceUdev *self;
self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_physdev (self);
- if (!self->priv->physdev)
- return NULL;
-
- return g_udev_device_get_sysfs_path (self->priv->physdev);
+ return (self->priv->physdev ? g_udev_device_get_sysfs_path (self->priv->physdev) : NULL);
}
static const gchar *
@@ -459,11 +381,7 @@ kernel_device_get_physdev_subsystem (MMKernelDevice *_self)
MMKernelDeviceUdev *self;
self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_physdev (self);
- if (!self->priv->physdev)
- return NULL;
-
- return g_udev_device_get_subsystem (self->priv->physdev);
+ return (self->priv->physdev ? g_udev_device_get_subsystem (self->priv->physdev) : NULL);
}
static const gchar *
@@ -472,11 +390,7 @@ kernel_device_get_physdev_manufacturer (MMKernelDevice *_self)
MMKernelDeviceUdev *self;
self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_physdev (self);
- if (!self->priv->physdev)
- return NULL;
-
- return g_udev_device_get_sysfs_attr (self->priv->physdev, "manufacturer");
+ return (self->priv->physdev ? g_udev_device_get_sysfs_attr (self->priv->physdev, "manufacturer") : NULL);
}
static const gchar *
@@ -485,11 +399,7 @@ kernel_device_get_physdev_product (MMKernelDevice *_self)
MMKernelDeviceUdev *self;
self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_physdev (self);
- if (!self->priv->physdev)
- return NULL;
-
- return g_udev_device_get_sysfs_attr (self->priv->physdev, "product");
+ return (self->priv->physdev ? g_udev_device_get_sysfs_attr (self->priv->physdev, "product") : NULL);
}
static gint
@@ -498,8 +408,7 @@ kernel_device_get_interface_class (MMKernelDevice *_self)
MMKernelDeviceUdev *self;
self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_interface (self);
- return (self->priv->interface ? g_udev_device_get_sysfs_attr_as_int (self->priv->interface, "bInterfaceClass") : -1);
+ return (self->priv->interface ? (gint) udev_device_get_sysfs_attr_as_hex (self->priv->interface, "bInterfaceClass") : -1);
}
static gint
@@ -508,8 +417,7 @@ kernel_device_get_interface_subclass (MMKernelDevice *_self)
MMKernelDeviceUdev *self;
self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_interface (self);
- return (self->priv->interface ? g_udev_device_get_sysfs_attr_as_int (self->priv->interface, "bInterfaceSubClass") : -1);
+ return (self->priv->interface ? (gint) udev_device_get_sysfs_attr_as_hex (self->priv->interface, "bInterfaceSubClass") : -1);
}
static gint
@@ -518,8 +426,7 @@ kernel_device_get_interface_protocol (MMKernelDevice *_self)
MMKernelDeviceUdev *self;
self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_interface (self);
- return (self->priv->interface ? g_udev_device_get_sysfs_attr_as_int (self->priv->interface, "bInterfaceProtocol") : -1);
+ return (self->priv->interface ? (gint) udev_device_get_sysfs_attr_as_hex (self->priv->interface, "bInterfaceProtocol") : -1);
}
static const gchar *
@@ -528,7 +435,6 @@ kernel_device_get_interface_sysfs_path (MMKernelDevice *_self)
MMKernelDeviceUdev *self;
self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_interface (self);
return (self->priv->interface ? g_udev_device_get_sysfs_path (self->priv->interface) : NULL);
}
@@ -538,7 +444,6 @@ kernel_device_get_interface_description (MMKernelDevice *_self)
MMKernelDeviceUdev *self;
self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_interface (self);
return (self->priv->interface ? g_udev_device_get_sysfs_attr (self->priv->interface, "interface") : NULL);
}
@@ -577,11 +482,7 @@ kernel_device_has_property (MMKernelDevice *_self,
MMKernelDeviceUdev *self;
self = MM_KERNEL_DEVICE_UDEV (_self);
-
- if (!self->priv->device)
- return FALSE;
-
- return g_udev_device_has_property (self->priv->device, property);
+ return (self->priv->device ? g_udev_device_has_property (self->priv->device, property) : FALSE);
}
static const gchar *
@@ -591,11 +492,7 @@ kernel_device_get_property (MMKernelDevice *_self,
MMKernelDeviceUdev *self;
self = MM_KERNEL_DEVICE_UDEV (_self);
-
- if (!self->priv->device)
- return NULL;
-
- return g_udev_device_get_property (self->priv->device, property);
+ return (self->priv->device ? g_udev_device_get_property (self->priv->device, property) : NULL);
}
static gboolean
@@ -605,8 +502,6 @@ kernel_device_has_global_property (MMKernelDevice *_self,
MMKernelDeviceUdev *self;
self = MM_KERNEL_DEVICE_UDEV (_self);
-
- ensure_physdev (self);
if (self->priv->physdev && g_udev_device_has_property (self->priv->physdev, property))
return TRUE;
@@ -622,7 +517,6 @@ kernel_device_get_global_property (MMKernelDevice *_self,
self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_physdev (self);
if (self->priv->physdev &&
g_udev_device_has_property (self->priv->physdev, property) &&
(str = g_udev_device_get_property (self->priv->physdev, property)) != NULL)
@@ -631,7 +525,6 @@ kernel_device_get_global_property (MMKernelDevice *_self,
return kernel_device_get_property (_self, property);
}
-
/*****************************************************************************/
MMKernelDevice *
@@ -726,8 +619,10 @@ initable_init (GInitable *initable,
const gchar *name;
/* When created from a GUdevDevice, we're done */
- if (self->priv->device)
+ if (self->priv->device) {
+ preload_contents (self);
return TRUE;
+ }
/* Otherwise, we do need properties with subsystem and name */
if (!self->priv->properties) {
@@ -771,6 +666,8 @@ initable_init (GInitable *initable,
g_object_unref (client);
}
+ if (self->priv->device)
+ preload_contents (self);
return TRUE;
}
@@ -779,10 +676,11 @@ dispose (GObject *object)
{
MMKernelDeviceUdev *self = MM_KERNEL_DEVICE_UDEV (object);
- g_clear_object (&self->priv->physdev);
- g_clear_object (&self->priv->interface);
- g_clear_object (&self->priv->device);
- g_clear_object (&self->priv->properties);
+ g_clear_pointer (&self->priv->driver, g_free);
+ g_clear_object (&self->priv->physdev);
+ g_clear_object (&self->priv->interface);
+ g_clear_object (&self->priv->device);
+ g_clear_object (&self->priv->properties);
G_OBJECT_CLASS (mm_kernel_device_udev_parent_class)->dispose (object);
}