kerneldevice: allow loading device revision
This commit is contained in:

committed by
Dan Williams

parent
dcd49dee88
commit
bc39201f76
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user