kerneldevice: allow loading device revision

This commit is contained in:
Aleksander Morgado
2018-12-17 16:32:57 +01:00
committed by Dan Williams
parent dcd49dee88
commit bc39201f76
4 changed files with 80 additions and 3 deletions

View File

@@ -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;
@@ -302,6 +303,29 @@ preload_physdev_pid (MMKernelDeviceGeneric *self)
mm_kernel_event_properties_get_name (self->priv->properties));
}
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)
{
@@ -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;

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -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);