kerneldevice: consolidate candidate rules in the base device
This patch implicitly enables in the generic device backend the manual-only greylist (ID_MM_DEVICE_MANUAL_SCAN_ONLY tag) and the platform TTY whitelist (ID_MM_PLATFORM_DRIVER_PROBE), which were not being applied.
This commit is contained in:
@@ -521,59 +521,6 @@ kernel_device_get_physdev_manufacturer (MMKernelDevice *self)
|
||||
return MM_KERNEL_DEVICE_GENERIC (self)->priv->physdev_manufacturer;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
kernel_device_is_candidate (MMKernelDevice *_self,
|
||||
gboolean manual_scan)
|
||||
{
|
||||
MMKernelDeviceGeneric *self;
|
||||
const gchar *name;
|
||||
|
||||
g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (_self), FALSE);
|
||||
|
||||
self = MM_KERNEL_DEVICE_GENERIC (_self);
|
||||
|
||||
name = mm_kernel_event_properties_get_name (self->priv->properties);
|
||||
|
||||
/* ignore VTs */
|
||||
if (strncmp (name, "tty", 3) == 0 && g_ascii_isdigit (name[3])) {
|
||||
mm_dbg ("(%s/%s) VT ignored",
|
||||
mm_kernel_event_properties_get_subsystem (self->priv->properties),
|
||||
mm_kernel_event_properties_get_name (self->priv->properties));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* only ports tagged as candidate */
|
||||
if (!mm_kernel_device_get_property_as_boolean (_self, "ID_MM_CANDIDATE")) {
|
||||
mm_dbg ("(%s/%s) device not flagged with ID_MM_CANDIDATE",
|
||||
mm_kernel_event_properties_get_subsystem (self->priv->properties),
|
||||
mm_kernel_event_properties_get_name (self->priv->properties));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* no devices without physical device */
|
||||
if (!self->priv->physdev_sysfs_path) {
|
||||
mm_dbg ("(%s/%s) device without physdev sysfs path",
|
||||
mm_kernel_event_properties_get_subsystem (self->priv->properties),
|
||||
mm_kernel_event_properties_get_name (self->priv->properties));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* ignore ports explicitly ignored; note that in this case the property
|
||||
* is set in this kernel device itself, unlike in the udev backend, that
|
||||
* goes in the parent udev device */
|
||||
if (mm_kernel_device_get_property_as_boolean (_self, "ID_MM_DEVICE_IGNORE")) {
|
||||
mm_dbg ("(%s/%s) device flagged with ID_MM_DEVICE_IGNORE",
|
||||
mm_kernel_event_properties_get_subsystem (self->priv->properties),
|
||||
mm_kernel_event_properties_get_name (self->priv->properties));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
mm_dbg ("(%s/%s) device is candidate",
|
||||
mm_kernel_event_properties_get_subsystem (self->priv->properties),
|
||||
mm_kernel_event_properties_get_name (self->priv->properties));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
kernel_device_cmp (MMKernelDevice *a,
|
||||
MMKernelDevice *b)
|
||||
@@ -1111,7 +1058,6 @@ mm_kernel_device_generic_class_init (MMKernelDeviceGenericClass *klass)
|
||||
kernel_device_class->get_physdev_subsystem = kernel_device_get_physdev_subsystem;
|
||||
kernel_device_class->get_physdev_manufacturer = kernel_device_get_physdev_manufacturer;
|
||||
kernel_device_class->get_parent_sysfs_path = kernel_device_get_parent_sysfs_path;
|
||||
kernel_device_class->is_candidate = kernel_device_is_candidate;
|
||||
kernel_device_class->cmp = kernel_device_cmp;
|
||||
kernel_device_class->has_property = kernel_device_has_property;
|
||||
kernel_device_class->get_property = kernel_device_get_property;
|
||||
|
@@ -442,81 +442,6 @@ kernel_device_get_parent_sysfs_path (MMKernelDevice *_self)
|
||||
return (self->priv->parent ? g_udev_device_get_sysfs_path (self->priv->parent) : NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
kernel_device_is_candidate (MMKernelDevice *_self,
|
||||
gboolean manual_scan)
|
||||
{
|
||||
MMKernelDeviceUdev *self;
|
||||
const gchar *physdev_subsys;
|
||||
const gchar *name;
|
||||
const gchar *subsys;
|
||||
|
||||
g_return_val_if_fail (MM_IS_KERNEL_DEVICE_UDEV (_self), FALSE);
|
||||
|
||||
self = MM_KERNEL_DEVICE_UDEV (_self);
|
||||
|
||||
if (!self->priv->device)
|
||||
return FALSE;
|
||||
|
||||
name = g_udev_device_get_name (self->priv->device);
|
||||
subsys = g_udev_device_get_subsystem (self->priv->device);
|
||||
|
||||
/* ignore VTs */
|
||||
if (strncmp (name, "tty", 3) == 0 && g_ascii_isdigit (name[3]))
|
||||
return FALSE;
|
||||
|
||||
/* Ignore devices that aren't completely configured by udev yet. If
|
||||
* ModemManager is started in parallel with udev, explicitly requesting
|
||||
* devices may return devices for which not all udev rules have yet been
|
||||
* applied (a bug in udev/gudev). Since we often need those rules to match
|
||||
* the device to a specific ModemManager driver, we need to ensure that all
|
||||
* rules have been processed before handling a device.
|
||||
*
|
||||
* This udev tag applies to each port in a device. In other words, the flag
|
||||
* may be set in some ports, but not in others */
|
||||
if (!mm_kernel_device_get_property_as_boolean (MM_KERNEL_DEVICE (self), "ID_MM_CANDIDATE"))
|
||||
return FALSE;
|
||||
|
||||
/* Load physical device. If there is no physical device, we don't process
|
||||
* the device. */
|
||||
ensure_physdev (self);
|
||||
if (!self->priv->physdev) {
|
||||
/* Log about it, but filter out some common ports that we know don't have
|
||||
* anything to do with mobile broadband.
|
||||
*/
|
||||
if ( strcmp (name, "console")
|
||||
&& strcmp (name, "ptmx")
|
||||
&& strcmp (name, "lo")
|
||||
&& strcmp (name, "tty")
|
||||
&& !strstr (name, "virbr"))
|
||||
mm_dbg ("(%s/%s): could not get port's parent device", subsys, name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Ignore blacklisted devices. */
|
||||
if (mm_kernel_device_get_global_property_as_boolean (MM_KERNEL_DEVICE (self), "ID_MM_DEVICE_IGNORE")) {
|
||||
mm_dbg ("(%s/%s): device is blacklisted", subsys, name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Is the device in the manual-only greylist? If so, return if this is an
|
||||
* automatic scan. */
|
||||
if (!manual_scan && mm_kernel_device_get_global_property_as_boolean (MM_KERNEL_DEVICE (self), "ID_MM_DEVICE_MANUAL_SCAN_ONLY")) {
|
||||
mm_dbg ("(%s/%s): device probed only in manual scan", subsys, name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If the physdev is a 'platform' or 'pnp' device that's not whitelisted, ignore it */
|
||||
physdev_subsys = mm_kernel_device_get_physdev_subsystem (MM_KERNEL_DEVICE (self));
|
||||
if ((!g_strcmp0 (physdev_subsys, "platform") || !g_strcmp0 (physdev_subsys, "pnp")) &&
|
||||
(!mm_kernel_device_get_global_property_as_boolean (MM_KERNEL_DEVICE (self), "ID_MM_PLATFORM_DRIVER_PROBE"))) {
|
||||
mm_dbg ("(%s/%s): port's parent platform driver is not whitelisted", subsys, name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
kernel_device_cmp (MMKernelDevice *_a,
|
||||
MMKernelDevice *_b)
|
||||
@@ -913,7 +838,6 @@ mm_kernel_device_udev_class_init (MMKernelDeviceUdevClass *klass)
|
||||
kernel_device_class->get_physdev_subsystem = kernel_device_get_physdev_subsystem;
|
||||
kernel_device_class->get_physdev_manufacturer = kernel_device_get_physdev_manufacturer;
|
||||
kernel_device_class->get_parent_sysfs_path = kernel_device_get_parent_sysfs_path;
|
||||
kernel_device_class->is_candidate = kernel_device_is_candidate;
|
||||
kernel_device_class->cmp = kernel_device_cmp;
|
||||
kernel_device_class->has_property = kernel_device_has_property;
|
||||
kernel_device_class->get_property = kernel_device_get_property;
|
||||
|
@@ -13,6 +13,10 @@
|
||||
* Copyright (C) 2016 Velocloud, Inc.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mm-log.h"
|
||||
#include "mm-kernel-device.h"
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (MMKernelDevice, mm_kernel_device, G_TYPE_OBJECT)
|
||||
@@ -123,11 +127,67 @@ gboolean
|
||||
mm_kernel_device_is_candidate (MMKernelDevice *self,
|
||||
gboolean manual_scan)
|
||||
{
|
||||
const gchar *physdev_subsys;
|
||||
const gchar *name;
|
||||
const gchar *subsys;
|
||||
|
||||
g_return_val_if_fail (MM_IS_KERNEL_DEVICE (self), FALSE);
|
||||
|
||||
return (MM_KERNEL_DEVICE_GET_CLASS (self)->is_candidate ?
|
||||
MM_KERNEL_DEVICE_GET_CLASS (self)->is_candidate (self, manual_scan) :
|
||||
FALSE);
|
||||
name = mm_kernel_device_get_name (self);
|
||||
subsys = mm_kernel_device_get_subsystem (self);
|
||||
|
||||
/* ignore VTs */
|
||||
if (strncmp (name, "tty", 3) == 0 && g_ascii_isdigit (name[3]))
|
||||
return FALSE;
|
||||
|
||||
/* Ignore devices that aren't completely configured by udev yet. If
|
||||
* ModemManager is started in parallel with udev, explicitly requesting
|
||||
* devices may return devices for which not all udev rules have yet been
|
||||
* applied (a bug in udev/gudev). Since we often need those rules to match
|
||||
* the device to a specific ModemManager driver, we need to ensure that all
|
||||
* rules have been processed before handling a device.
|
||||
*
|
||||
* This udev tag applies to each port in a device. In other words, the flag
|
||||
* may be set in some ports, but not in others */
|
||||
if (!mm_kernel_device_get_property_as_boolean (self, "ID_MM_CANDIDATE"))
|
||||
return FALSE;
|
||||
|
||||
/* Don't process device if no sysfs path */
|
||||
if (!mm_kernel_device_get_physdev_sysfs_path (self)) {
|
||||
/* Log about it, but filter out some common ports that we know don't have
|
||||
* anything to do with mobile broadband.
|
||||
*/
|
||||
if ( strcmp (name, "console")
|
||||
&& strcmp (name, "ptmx")
|
||||
&& strcmp (name, "lo")
|
||||
&& strcmp (name, "tty")
|
||||
&& !strstr (name, "virbr"))
|
||||
mm_dbg ("(%s/%s): could not get port's parent device", subsys, name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Ignore blacklisted devices. */
|
||||
if (mm_kernel_device_get_global_property_as_boolean (MM_KERNEL_DEVICE (self), "ID_MM_DEVICE_IGNORE")) {
|
||||
mm_dbg ("(%s/%s): device is blacklisted", subsys, name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Is the device in the manual-only greylist? If so, return if this is an
|
||||
* automatic scan. */
|
||||
if (!manual_scan && mm_kernel_device_get_global_property_as_boolean (MM_KERNEL_DEVICE (self), "ID_MM_DEVICE_MANUAL_SCAN_ONLY")) {
|
||||
mm_dbg ("(%s/%s): device probed only in manual scan", subsys, name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If the physdev is a 'platform' or 'pnp' device that's not whitelisted, ignore it */
|
||||
physdev_subsys = mm_kernel_device_get_physdev_subsystem (MM_KERNEL_DEVICE (self));
|
||||
if ((!g_strcmp0 (physdev_subsys, "platform") || !g_strcmp0 (physdev_subsys, "pnp")) &&
|
||||
(!mm_kernel_device_get_global_property_as_boolean (MM_KERNEL_DEVICE (self), "ID_MM_PLATFORM_DRIVER_PROBE"))) {
|
||||
mm_dbg ("(%s/%s): port's parent platform driver is not whitelisted", subsys, name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const gchar *
|
||||
|
@@ -44,9 +44,6 @@ struct _MMKernelDeviceClass {
|
||||
|
||||
const gchar * (* get_sysfs_path) (MMKernelDevice *self);
|
||||
|
||||
gboolean (* is_candidate) (MMKernelDevice *self,
|
||||
gboolean manual_scan);
|
||||
|
||||
const gchar * (* get_parent_sysfs_path) (MMKernelDevice *self);
|
||||
|
||||
const gchar * (* get_physdev_uid) (MMKernelDevice *self);
|
||||
|
Reference in New Issue
Block a user