diff options
-rw-r--r-- | src/kerneldevice/mm-kernel-device-generic.c | 34 | ||||
-rw-r--r-- | src/kerneldevice/mm-kernel-device-udev.c | 37 | ||||
-rw-r--r-- | src/kerneldevice/mm-kernel-device.c | 10 | ||||
-rw-r--r-- | src/kerneldevice/mm-kernel-device.h | 2 |
4 files changed, 80 insertions, 3 deletions
diff --git a/src/kerneldevice/mm-kernel-device-generic.c b/src/kerneldevice/mm-kernel-device-generic.c index 9d956bc37..53cd73784 100644 --- a/src/kerneldevice/mm-kernel-device-generic.c +++ b/src/kerneldevice/mm-kernel-device-generic.c @@ -62,6 +62,7 @@ struct _MMKernelDeviceGenericPrivate { gchar *physdev_sysfs_path; guint16 physdev_vid; guint16 physdev_pid; + guint16 physdev_revision; gchar *physdev_subsystem; gchar *physdev_manufacturer; gchar *physdev_product; @@ -303,6 +304,29 @@ preload_physdev_pid (MMKernelDeviceGeneric *self) } static void +preload_physdev_revision (MMKernelDeviceGeneric *self) +{ + if (!self->priv->physdev_revision && self->priv->physdev_sysfs_path) { + guint val; + + val = read_sysfs_property_as_hex (self->priv->physdev_sysfs_path, "bcdDevice"); + if (val && val <= G_MAXUINT16) + self->priv->physdev_revision = val; + } + + if (self->priv->physdev_revision) { + mm_dbg ("(%s/%s) revision (ID_REVISION): 0x%04x", + mm_kernel_event_properties_get_subsystem (self->priv->properties), + mm_kernel_event_properties_get_name (self->priv->properties), + self->priv->physdev_revision); + g_object_set_data_full (G_OBJECT (self), "ID_REVISION", g_strdup_printf ("%04x", self->priv->physdev_revision), g_free); + } else + mm_dbg ("(%s/%s) revision: unknown", + mm_kernel_event_properties_get_subsystem (self->priv->properties), + mm_kernel_event_properties_get_name (self->priv->properties)); +} + +static void preload_physdev_subsystem (MMKernelDeviceGeneric *self) { if (!self->priv->physdev_subsystem && self->priv->physdev_sysfs_path) { @@ -415,6 +439,7 @@ preload_contents (MMKernelDeviceGeneric *self) preload_driver (self); preload_physdev_vid (self); preload_physdev_pid (self); + preload_physdev_revision (self); preload_physdev_subsystem (self); } @@ -523,6 +548,14 @@ kernel_device_get_physdev_pid (MMKernelDevice *self) return MM_KERNEL_DEVICE_GENERIC (self)->priv->physdev_pid; } +static guint16 +kernel_device_get_physdev_revision (MMKernelDevice *self) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (self), 0); + + return MM_KERNEL_DEVICE_GENERIC (self)->priv->physdev_revision; +} + static const gchar * kernel_device_get_physdev_sysfs_path (MMKernelDevice *self) { @@ -1088,6 +1121,7 @@ mm_kernel_device_generic_class_init (MMKernelDeviceGenericClass *klass) kernel_device_class->get_physdev_uid = kernel_device_get_physdev_uid; kernel_device_class->get_physdev_vid = kernel_device_get_physdev_vid; kernel_device_class->get_physdev_pid = kernel_device_get_physdev_pid; + kernel_device_class->get_physdev_revision = kernel_device_get_physdev_revision; kernel_device_class->get_physdev_sysfs_path = kernel_device_get_physdev_sysfs_path; kernel_device_class->get_physdev_subsystem = kernel_device_get_physdev_subsystem; kernel_device_class->get_physdev_manufacturer = kernel_device_get_physdev_manufacturer; diff --git a/src/kerneldevice/mm-kernel-device-udev.c b/src/kerneldevice/mm-kernel-device-udev.c index da668f3c5..4b06969e3 100644 --- a/src/kerneldevice/mm-kernel-device-udev.c +++ b/src/kerneldevice/mm-kernel-device-udev.c @@ -43,6 +43,7 @@ struct _MMKernelDeviceUdevPrivate { GUdevDevice *physdev; guint16 vendor; guint16 product; + guint16 revision; MMKernelEventProperties *properties; }; @@ -52,10 +53,11 @@ struct _MMKernelDeviceUdevPrivate { static gboolean get_device_ids (GUdevDevice *device, guint16 *vendor, - guint16 *product) + guint16 *product, + guint16 *revision) { GUdevDevice *parent = NULL; - const gchar *vid = NULL, *pid = NULL, *parent_subsys; + const gchar *vid = NULL, *pid = NULL, *rid = NULL, *parent_subsys; gboolean success = FALSE; char *pci_vid = NULL, *pci_pid = NULL; @@ -94,6 +96,7 @@ get_device_ids (GUdevDevice *device, 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")) { @@ -139,6 +142,20 @@ get_device_ids (GUdevDevice *device, *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); + } + } + success = TRUE; out: @@ -152,13 +169,14 @@ out: static void ensure_device_ids (MMKernelDeviceUdev *self) { + /* Revision is optional */ if (self->priv->vendor || self->priv->product) return; if (!self->priv->device) return; - if (!get_device_ids (self->priv->device, &self->priv->vendor, &self->priv->product)) + if (!get_device_ids (self->priv->device, &self->priv->vendor, &self->priv->product, &self->priv->revision)) mm_dbg ("(%s/%s) could not get vendor/product id", g_udev_device_get_subsystem (self->priv->device), g_udev_device_get_name (self->priv->device)); @@ -396,6 +414,18 @@ kernel_device_get_physdev_pid (MMKernelDevice *_self) return self->priv->product; } +static guint16 +kernel_device_get_physdev_revision (MMKernelDevice *_self) +{ + MMKernelDeviceUdev *self; + + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_UDEV (_self), 0); + + self = MM_KERNEL_DEVICE_UDEV (_self); + ensure_device_ids (self); + return self->priv->revision; +} + static const gchar * kernel_device_get_physdev_sysfs_path (MMKernelDevice *_self) { @@ -896,6 +926,7 @@ mm_kernel_device_udev_class_init (MMKernelDeviceUdevClass *klass) kernel_device_class->get_physdev_uid = kernel_device_get_physdev_uid; kernel_device_class->get_physdev_vid = kernel_device_get_physdev_vid; kernel_device_class->get_physdev_pid = kernel_device_get_physdev_pid; + kernel_device_class->get_physdev_revision = kernel_device_get_physdev_revision; kernel_device_class->get_physdev_sysfs_path = kernel_device_get_physdev_sysfs_path; kernel_device_class->get_physdev_subsystem = kernel_device_get_physdev_subsystem; kernel_device_class->get_physdev_manufacturer = kernel_device_get_physdev_manufacturer; diff --git a/src/kerneldevice/mm-kernel-device.c b/src/kerneldevice/mm-kernel-device.c index c9c9139a3..35c840a89 100644 --- a/src/kerneldevice/mm-kernel-device.c +++ b/src/kerneldevice/mm-kernel-device.c @@ -93,6 +93,16 @@ mm_kernel_device_get_physdev_pid (MMKernelDevice *self) 0); } +guint16 +mm_kernel_device_get_physdev_revision (MMKernelDevice *self) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE (self), 0); + + return (MM_KERNEL_DEVICE_GET_CLASS (self)->get_physdev_revision ? + MM_KERNEL_DEVICE_GET_CLASS (self)->get_physdev_revision (self) : + 0); +} + const gchar * mm_kernel_device_get_physdev_subsystem (MMKernelDevice *self) { diff --git a/src/kerneldevice/mm-kernel-device.h b/src/kerneldevice/mm-kernel-device.h index 2493b87ae..6e66d4d2c 100644 --- a/src/kerneldevice/mm-kernel-device.h +++ b/src/kerneldevice/mm-kernel-device.h @@ -49,6 +49,7 @@ struct _MMKernelDeviceClass { const gchar * (* get_physdev_uid) (MMKernelDevice *self); guint16 (* get_physdev_vid) (MMKernelDevice *self); guint16 (* get_physdev_pid) (MMKernelDevice *self); + guint16 (* get_physdev_revision) (MMKernelDevice *self); const gchar * (* get_physdev_sysfs_path) (MMKernelDevice *self); const gchar * (* get_physdev_subsystem) (MMKernelDevice *self); const gchar * (* get_physdev_manufacturer) (MMKernelDevice *self); @@ -84,6 +85,7 @@ const gchar *mm_kernel_device_get_interface_sysfs_path (MMKernelDevice *self); const gchar *mm_kernel_device_get_physdev_uid (MMKernelDevice *self); guint16 mm_kernel_device_get_physdev_vid (MMKernelDevice *self); guint16 mm_kernel_device_get_physdev_pid (MMKernelDevice *self); +guint16 mm_kernel_device_get_physdev_revision (MMKernelDevice *self); const gchar *mm_kernel_device_get_physdev_sysfs_path (MMKernelDevice *self); const gchar *mm_kernel_device_get_physdev_subsystem (MMKernelDevice *self); const gchar *mm_kernel_device_get_physdev_manufacturer (MMKernelDevice *self); |