summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2018-12-17 16:32:57 +0100
committerDan Williams <dcbw@redhat.com>2019-01-03 18:53:52 +0000
commitbc39201f761bd667bcd0c5eb53643a180ce53327 (patch)
treef6c3f3751b6db3dfd19f875432450ac118827f87 /src
parentdcd49dee8899bfb4ccae7a0bbc200a0a62aeeb04 (diff)
downloadModemManager-bc39201f761bd667bcd0c5eb53643a180ce53327.tar.gz
kerneldevice: allow loading device revision
Diffstat (limited to 'src')
-rw-r--r--src/kerneldevice/mm-kernel-device-generic.c34
-rw-r--r--src/kerneldevice/mm-kernel-device-udev.c37
-rw-r--r--src/kerneldevice/mm-kernel-device.c10
-rw-r--r--src/kerneldevice/mm-kernel-device.h2
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);