aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/kerneldevice/mm-kernel-device-udev.c62
1 files changed, 46 insertions, 16 deletions
diff --git a/src/kerneldevice/mm-kernel-device-udev.c b/src/kerneldevice/mm-kernel-device-udev.c
index 3dc3eeb7..620d1441 100644
--- a/src/kerneldevice/mm-kernel-device-udev.c
+++ b/src/kerneldevice/mm-kernel-device-udev.c
@@ -39,7 +39,7 @@ static GParamSpec *properties[PROP_LAST];
struct _MMKernelDeviceUdevPrivate {
GUdevDevice *device;
- GUdevDevice *parent;
+ GUdevDevice *interface;
GUdevDevice *physdev;
guint16 vendor;
guint16 product;
@@ -263,12 +263,42 @@ ensure_physdev (MMKernelDeviceUdev *self)
/*****************************************************************************/
static void
-ensure_parent (MMKernelDeviceUdev *self)
+ensure_interface (MMKernelDeviceUdev *self)
{
- if (self->priv->parent)
+ GUdevDevice *new_parent;
+ GUdevDevice *parent;
+
+ if (self->priv->interface)
return;
- if (self->priv->device)
- self->priv->parent = g_udev_device_get_parent (self->priv->device);
+
+ if (!self->priv->device)
+ return;
+
+ ensure_physdev (self);
+
+ parent = g_udev_device_get_parent (self->priv->device);
+ while (1) {
+ /* Abort if no parent found */
+ if (!parent)
+ break;
+
+ /* 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;
+ }
+
+ /* If unknown physdev, just stop right away */
+ if (!self->priv->physdev || parent == self->priv->physdev) {
+ g_object_unref (parent);
+ break;
+ }
+
+ new_parent = g_udev_device_get_parent (parent);
+ g_object_unref (parent);
+ parent = new_parent;
+ }
}
/*****************************************************************************/
@@ -494,8 +524,8 @@ kernel_device_get_interface_class (MMKernelDevice *_self)
g_return_val_if_fail (MM_IS_KERNEL_DEVICE_UDEV (_self), -1);
self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_parent (self);
- return (self->priv->parent ? g_udev_device_get_sysfs_attr_as_int (self->priv->parent, "bInterfaceClass") : -1);
+ ensure_interface (self);
+ return (self->priv->interface ? g_udev_device_get_sysfs_attr_as_int (self->priv->interface, "bInterfaceClass") : -1);
}
static gint
@@ -506,8 +536,8 @@ kernel_device_get_interface_subclass (MMKernelDevice *_self)
g_return_val_if_fail (MM_IS_KERNEL_DEVICE_UDEV (_self), -1);
self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_parent (self);
- return (self->priv->parent ? g_udev_device_get_sysfs_attr_as_int (self->priv->parent, "bInterfaceSubClass") : -1);
+ ensure_interface (self);
+ return (self->priv->interface ? g_udev_device_get_sysfs_attr_as_int (self->priv->interface, "bInterfaceSubClass") : -1);
}
static gint
@@ -518,8 +548,8 @@ kernel_device_get_interface_protocol (MMKernelDevice *_self)
g_return_val_if_fail (MM_IS_KERNEL_DEVICE_UDEV (_self), -1);
self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_parent (self);
- return (self->priv->parent ? g_udev_device_get_sysfs_attr_as_int (self->priv->parent, "bInterfaceProtocol") : -1);
+ ensure_interface (self);
+ return (self->priv->interface ? g_udev_device_get_sysfs_attr_as_int (self->priv->interface, "bInterfaceProtocol") : -1);
}
static const gchar *
@@ -530,8 +560,8 @@ kernel_device_get_interface_sysfs_path (MMKernelDevice *_self)
g_return_val_if_fail (MM_IS_KERNEL_DEVICE_UDEV (_self), NULL);
self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_parent (self);
- return (self->priv->parent ? g_udev_device_get_sysfs_path (self->priv->parent) : NULL);
+ ensure_interface (self);
+ return (self->priv->interface ? g_udev_device_get_sysfs_path (self->priv->interface) : NULL);
}
static const gchar *
@@ -542,8 +572,8 @@ kernel_device_get_interface_description (MMKernelDevice *_self)
g_return_val_if_fail (MM_IS_KERNEL_DEVICE_UDEV (_self), NULL);
self = MM_KERNEL_DEVICE_UDEV (_self);
- ensure_parent (self);
- return (self->priv->parent ? g_udev_device_get_sysfs_attr (self->priv->parent, "interface") : NULL);
+ ensure_interface (self);
+ return (self->priv->interface ? g_udev_device_get_sysfs_attr (self->priv->interface, "interface") : NULL);
}
static gboolean
@@ -906,7 +936,7 @@ dispose (GObject *object)
MMKernelDeviceUdev *self = MM_KERNEL_DEVICE_UDEV (object);
g_clear_object (&self->priv->physdev);
- g_clear_object (&self->priv->parent);
+ g_clear_object (&self->priv->interface);
g_clear_object (&self->priv->device);
g_clear_object (&self->priv->properties);