aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-manager.c109
-rw-r--r--src/mm-plugin-base.c77
-rw-r--r--src/mm-plugin-base.h9
-rw-r--r--src/mm-plugin.c9
-rw-r--r--src/mm-plugin.h2
5 files changed, 118 insertions, 88 deletions
diff --git a/src/mm-manager.c b/src/mm-manager.c
index d838fa1a..5a85f02a 100644
--- a/src/mm-manager.c
+++ b/src/mm-manager.c
@@ -299,6 +299,7 @@ typedef struct {
MMManager *manager;
char *subsys;
char *name;
+ char *physdev_path;
GSList *plugins;
GSList *cur_plugin;
guint defer_id;
@@ -309,7 +310,10 @@ typedef struct {
} SupportsInfo;
static SupportsInfo *
-supports_info_new (MMManager *self, const char *subsys, const char *name)
+supports_info_new (MMManager *self,
+ const char *subsys,
+ const char *name,
+ const char *physdev_path)
{
MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (self);
SupportsInfo *info;
@@ -318,6 +322,7 @@ supports_info_new (MMManager *self, const char *subsys, const char *name)
info->manager = self;
info->subsys = g_strdup (subsys);
info->name = g_strdup (name);
+ info->physdev_path = g_strdup (physdev_path);
info->plugins = g_slist_copy (priv->plugins);
info->cur_plugin = info->plugins;
return info;
@@ -358,8 +363,6 @@ static void supports_callback (MMPlugin *plugin,
static void try_supports_port (MMManager *manager,
MMPlugin *plugin,
- const char *subsys,
- const char *name,
SupportsInfo *info);
static gboolean
@@ -370,8 +373,6 @@ supports_defer_timeout (gpointer user_data)
g_debug ("(%s): re-checking support...", info->name);
try_supports_port (info->manager,
MM_PLUGIN (info->cur_plugin->data),
- info->subsys,
- info->name,
info);
return FALSE;
}
@@ -379,23 +380,28 @@ supports_defer_timeout (gpointer user_data)
static void
try_supports_port (MMManager *manager,
MMPlugin *plugin,
- const char *subsys,
- const char *name,
SupportsInfo *info)
{
MMPluginSupportsResult result;
- result = mm_plugin_supports_port (plugin, subsys, name, supports_callback, info);
+ result = mm_plugin_supports_port (plugin,
+ info->subsys,
+ info->name,
+ info->physdev_path,
+ supports_callback,
+ info);
switch (result) {
case MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED:
/* If the plugin knows it doesn't support the modem, just call the
* callback and indicate 0 support.
*/
- supports_callback (plugin, subsys, name, 0, info);
+ supports_callback (plugin, info->subsys, info->name, 0, info);
break;
case MM_PLUGIN_SUPPORTS_PORT_DEFER:
- g_debug ("(%s): (%s) deferring support check", mm_plugin_get_name (plugin), name);
+ g_debug ("(%s): (%s) deferring support check",
+ mm_plugin_get_name (plugin),
+ info->name);
if (info->defer_id)
g_source_remove (info->defer_id);
@@ -494,21 +500,59 @@ supports_callback (MMPlugin *plugin,
if (next_plugin) {
/* Try the next plugin */
- try_supports_port (info->manager, next_plugin, info->subsys, info->name, info);
+ try_supports_port (info->manager, next_plugin, info);
} else {
/* All done; let the best modem grab the port */
info->done_id = g_idle_add (do_grab_port, info);
}
}
+static GUdevDevice *
+find_physical_device (GUdevDevice *child)
+{
+ GUdevDevice *iter, *old = NULL;
+ GUdevDevice *physdev = NULL;
+ const char *subsys, *type;
+ guint32 i = 0;
+ gboolean is_usb = FALSE, is_pci = FALSE;
+
+ g_return_val_if_fail (child != NULL, NULL);
+
+ iter = g_object_ref (child);
+ while (iter && i++ < 8) {
+ subsys = g_udev_device_get_subsystem (iter);
+ if (subsys) {
+ if (is_usb || !strcmp (subsys, "usb")) {
+ is_usb = TRUE;
+ type = g_udev_device_get_devtype (iter);
+ if (type && !strcmp (type, "usb_device")) {
+ physdev = iter;
+ break;
+ }
+ } else if (is_pci || !strcmp (subsys, "pci")) {
+ is_pci = TRUE;
+ physdev = iter;
+ break;
+ }
+ }
+
+ old = iter;
+ iter = g_udev_device_get_parent (old);
+ g_object_unref (old);
+ }
+
+ return physdev;
+}
+
static void
device_added (MMManager *manager, GUdevDevice *device)
{
MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (manager);
- const char *subsys, *name;
+ const char *subsys, *name, *physdev_path;
SupportsInfo *info;
char *key;
gboolean found;
+ GUdevDevice *physdev = NULL;
g_return_if_fail (device != NULL);
@@ -527,15 +571,44 @@ device_added (MMManager *manager, GUdevDevice *device)
key = get_key (subsys, name);
found = !!g_hash_table_lookup (priv->supports, key);
- if (found) {
- g_free (key);
- return;
+ if (found)
+ goto out;
+
+ /* Find the port's physical device's sysfs path. This is the kernel device
+ * that "owns" all the ports of the device, like the USB device or the PCI
+ * device the provides each tty or network port.
+ */
+ physdev = find_physical_device (device);
+ if (!physdev) {
+ /* Warn 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"))
+ g_debug ("(%s/%s): could not get port's parent device", subsys, name);
+
+ goto out;
+ }
+
+ physdev_path = g_udev_device_get_sysfs_path (physdev);
+ if (!physdev_path) {
+ g_debug ("(%s/%s): could not get port's parent device sysfs path", subsys, name);
+ goto out;
}
- info = supports_info_new (manager, subsys, name);
- g_hash_table_insert (priv->supports, key, info);
+ /* Success; now ask plugins if they can handle this port */
+ info = supports_info_new (manager, subsys, name, physdev_path);
+ g_hash_table_insert (priv->supports, g_strdup (key), info);
+
+ try_supports_port (manager, MM_PLUGIN (info->cur_plugin->data), info);
- try_supports_port (manager, MM_PLUGIN (info->cur_plugin->data), subsys, name, info);
+out:
+ if (physdev)
+ g_object_unref (physdev);
+ g_free (key);
}
static void
diff --git a/src/mm-plugin-base.c b/src/mm-plugin-base.c
index 10204366..a8784be4 100644
--- a/src/mm-plugin-base.c
+++ b/src/mm-plugin-base.c
@@ -91,7 +91,7 @@ G_DEFINE_TYPE (MMPluginBaseSupportsTask, mm_plugin_base_supports_task, G_TYPE_OB
typedef struct {
MMPluginBase *plugin;
GUdevDevice *port;
- GUdevDevice *physdev;
+ char *physdev_path;
char *driver;
guint open_id;
@@ -119,7 +119,7 @@ typedef struct {
static MMPluginBaseSupportsTask *
supports_task_new (MMPluginBase *self,
GUdevDevice *port,
- GUdevDevice *physdev,
+ const char *physdev_path,
const char *driver,
MMSupportsPortResultFunc callback,
gpointer callback_data)
@@ -130,7 +130,7 @@ supports_task_new (MMPluginBase *self,
g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (MM_IS_PLUGIN_BASE (self), NULL);
g_return_val_if_fail (port != NULL, NULL);
- g_return_val_if_fail (physdev != NULL, NULL);
+ g_return_val_if_fail (physdev_path != NULL, NULL);
g_return_val_if_fail (driver != NULL, NULL);
g_return_val_if_fail (callback != NULL, NULL);
@@ -139,7 +139,7 @@ supports_task_new (MMPluginBase *self,
priv = MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task);
priv->plugin = self;
priv->port = g_object_ref (port);
- priv->physdev = g_object_ref (physdev);
+ priv->physdev_path = g_strdup (physdev_path);
priv->driver = g_strdup (driver);
priv->callback = callback;
priv->callback_data = callback_data;
@@ -165,13 +165,13 @@ mm_plugin_base_supports_task_get_port (MMPluginBaseSupportsTask *task)
return MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task)->port;
}
-GUdevDevice *
-mm_plugin_base_supports_task_get_physdev (MMPluginBaseSupportsTask *task)
+const char *
+mm_plugin_base_supports_task_get_physdev_path (MMPluginBaseSupportsTask *task)
{
g_return_val_if_fail (task != NULL, NULL);
g_return_val_if_fail (MM_IS_PLUGIN_BASE_SUPPORTS_TASK (task), NULL);
- return MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task)->physdev;
+ return MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task)->physdev_path;
}
const char *
@@ -255,7 +255,7 @@ supports_task_dispose (GObject *object)
mm_serial_port_flash_cancel (MM_SERIAL_PORT (priv->probe_port));
g_object_unref (priv->port);
- g_object_unref (priv->physdev);
+ g_free (priv->physdev_path);
g_free (priv->driver);
g_free (priv->probe_resp);
g_clear_error (&(priv->probe_error));
@@ -1037,58 +1037,21 @@ get_driver_name (GUdevDevice *device)
return ret;
}
-static GUdevDevice *
-real_find_physical_device (MMPluginBase *plugin, GUdevDevice *child)
-{
- GUdevDevice *iter, *old = NULL;
- GUdevDevice *physdev = NULL;
- const char *subsys, *type;
- guint32 i = 0;
- gboolean is_usb = FALSE, is_pci = FALSE;
-
- g_return_val_if_fail (child != NULL, NULL);
-
- iter = g_object_ref (child);
- while (iter && i++ < 8) {
- subsys = g_udev_device_get_subsystem (iter);
- if (subsys) {
- if (is_usb || !strcmp (subsys, "usb")) {
- is_usb = TRUE;
- type = g_udev_device_get_devtype (iter);
- if (type && !strcmp (type, "usb_device")) {
- physdev = iter;
- break;
- }
- } else if (is_pci || !strcmp (subsys, "pci")) {
- is_pci = TRUE;
- physdev = iter;
- break;
- }
- }
-
- old = iter;
- iter = g_udev_device_get_parent (old);
- g_object_unref (old);
- }
-
- return physdev;
-}
-
static MMPluginSupportsResult
supports_port (MMPlugin *plugin,
const char *subsys,
const char *name,
+ const char *physdev_path,
MMSupportsPortResultFunc callback,
gpointer callback_data)
{
MMPluginBase *self = MM_PLUGIN_BASE (plugin);
MMPluginBasePrivate *priv = MM_PLUGIN_BASE_GET_PRIVATE (self);
- GUdevDevice *port = NULL, *physdev = NULL;
+ GUdevDevice *port = NULL;
char *driver = NULL, *key = NULL;
MMPluginBaseSupportsTask *task;
MMPluginSupportsResult result = MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED;
MMModem *existing;
- const char *master_path;
key = get_key (subsys, name);
task = g_hash_table_lookup (priv->tasks, key);
@@ -1101,21 +1064,16 @@ supports_port (MMPlugin *plugin,
if (!port)
goto out;
- physdev = MM_PLUGIN_BASE_GET_CLASS (self)->find_physical_device (self, port);
- if (!physdev)
- goto out;
-
driver = get_driver_name (port);
if (!driver)
goto out;
- task = supports_task_new (self, port, physdev, driver, callback, callback_data);
+ task = supports_task_new (self, port, physdev_path, driver, callback, callback_data);
g_assert (task);
g_hash_table_insert (priv->tasks, g_strdup (key), g_object_ref (task));
/* Help the plugin out a bit by finding an existing modem for this port */
- master_path = g_udev_device_get_sysfs_path (physdev);
- existing = g_hash_table_lookup (priv->modems, master_path);
+ existing = g_hash_table_lookup (priv->modems, physdev_path);
result = MM_PLUGIN_BASE_GET_CLASS (self)->supports_port (self, existing, task);
if (result != MM_PLUGIN_SUPPORTS_PORT_IN_PROGRESS) {
@@ -1127,8 +1085,6 @@ supports_port (MMPlugin *plugin,
g_object_unref (task);
out:
- if (physdev)
- g_object_unref (physdev);
if (port)
g_object_unref (port);
g_free (key);
@@ -1169,7 +1125,7 @@ grab_port (MMPlugin *plugin,
MMPluginBaseSupportsTask *task;
char *key;
MMModem *existing = NULL, *modem = NULL;
- const char *master_path;
+ const char *physdev_path;
key = get_key (subsys, name);
task = g_hash_table_lookup (priv->tasks, key);
@@ -1179,13 +1135,13 @@ grab_port (MMPlugin *plugin,
}
/* Help the plugin out a bit by finding an existing modem for this port */
- master_path = g_udev_device_get_sysfs_path (mm_plugin_base_supports_task_get_physdev (task));
- existing = g_hash_table_lookup (priv->modems, master_path);
+ physdev_path = mm_plugin_base_supports_task_get_physdev_path (task);
+ existing = g_hash_table_lookup (priv->modems, physdev_path);
/* Let the modem grab the port */
modem = MM_PLUGIN_BASE_GET_CLASS (self)->grab_port (self, existing, task, error);
if (modem && !existing) {
- g_hash_table_insert (priv->modems, g_strdup (master_path), modem);
+ g_hash_table_insert (priv->modems, g_strdup (physdev_path), modem);
g_object_weak_ref (G_OBJECT (modem), modem_destroyed, self);
}
@@ -1277,7 +1233,6 @@ mm_plugin_base_class_init (MMPluginBaseClass *klass)
g_type_class_add_private (object_class, sizeof (MMPluginBasePrivate));
- klass->find_physical_device = real_find_physical_device;
klass->handle_probe_response = real_handle_probe_response;
/* Virtual methods */
diff --git a/src/mm-plugin-base.h b/src/mm-plugin-base.h
index 555113dc..fd3e7368 100644
--- a/src/mm-plugin-base.h
+++ b/src/mm-plugin-base.h
@@ -60,7 +60,7 @@ MMPlugin *mm_plugin_base_supports_task_get_plugin (MMPluginBaseSupportsTask *tas
GUdevDevice *mm_plugin_base_supports_task_get_port (MMPluginBaseSupportsTask *task);
-GUdevDevice *mm_plugin_base_supports_task_get_physdev (MMPluginBaseSupportsTask *task);
+const char *mm_plugin_base_supports_task_get_physdev_path (MMPluginBaseSupportsTask *task);
const char *mm_plugin_base_supports_task_get_driver (MMPluginBaseSupportsTask *task);
@@ -108,13 +108,6 @@ struct _MMPluginBaseClass {
void (*cancel_task) (MMPluginBase *plugin,
MMPluginBaseSupportsTask *task);
- /* Find a the physical device of a port, ie the USB or PCI or whatever
- * "master" device that owns the port. The GUdevDevice object returned
- * will be unref-ed by the caller.
- */
- GUdevDevice * (*find_physical_device) (MMPluginBase *plugin,
- GUdevDevice *port);
-
void (*handle_probe_response) (MMPluginBase *plugin,
MMPluginBaseSupportsTask *task,
const char *command,
diff --git a/src/mm-plugin.c b/src/mm-plugin.c
index 830f2d66..cc58e621 100644
--- a/src/mm-plugin.c
+++ b/src/mm-plugin.c
@@ -28,15 +28,22 @@ MMPluginSupportsResult
mm_plugin_supports_port (MMPlugin *plugin,
const char *subsys,
const char *name,
+ const char *physdev_path,
MMSupportsPortResultFunc callback,
gpointer user_data)
{
g_return_val_if_fail (MM_IS_PLUGIN (plugin), FALSE);
g_return_val_if_fail (subsys != NULL, FALSE);
g_return_val_if_fail (name != NULL, FALSE);
+ g_return_val_if_fail (physdev_path != NULL, FALSE);
g_return_val_if_fail (callback != NULL, FALSE);
- return MM_PLUGIN_GET_INTERFACE (plugin)->supports_port (plugin, subsys, name, callback, user_data);
+ return MM_PLUGIN_GET_INTERFACE (plugin)->supports_port (plugin,
+ subsys,
+ name,
+ physdev_path,
+ callback,
+ user_data);
}
void
diff --git a/src/mm-plugin.h b/src/mm-plugin.h
index d1e85b6a..40419d41 100644
--- a/src/mm-plugin.h
+++ b/src/mm-plugin.h
@@ -70,6 +70,7 @@ struct _MMPlugin {
MMPluginSupportsResult (*supports_port) (MMPlugin *self,
const char *subsys,
const char *name,
+ const char *physdev_path,
MMSupportsPortResultFunc callback,
gpointer user_data);
@@ -104,6 +105,7 @@ const char *mm_plugin_get_name (MMPlugin *plugin);
MMPluginSupportsResult mm_plugin_supports_port (MMPlugin *plugin,
const char *subsys,
const char *name,
+ const char *physdev_path,
MMSupportsPortResultFunc callback,
gpointer user_data);