diff options
author | Dan Williams <dcbw@redhat.com> | 2010-03-30 14:50:40 -0700 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2010-03-30 14:50:40 -0700 |
commit | 720e38aec0a50aa2136f01b7f3620a4e261c0406 (patch) | |
tree | 06dbd68d467b4652f6de97c9fe1b70b02b830a71 | |
parent | 39326f249105b7d71c63125f29e3bee2143a82d2 (diff) |
core: move physical device checking into the manager
It turns out that the manager needs to know about the physical
device so we can prevent multiple plugins from claiming ports on
the same modem.
-rw-r--r-- | plugins/mm-plugin-anydata.c | 11 | ||||
-rw-r--r-- | plugins/mm-plugin-generic.c | 11 | ||||
-rw-r--r-- | plugins/mm-plugin-gobi.c | 11 | ||||
-rw-r--r-- | plugins/mm-plugin-hso.c | 11 | ||||
-rw-r--r-- | plugins/mm-plugin-huawei.c | 11 | ||||
-rw-r--r-- | plugins/mm-plugin-longcheer.c | 11 | ||||
-rw-r--r-- | plugins/mm-plugin-mbm.c | 34 | ||||
-rw-r--r-- | plugins/mm-plugin-moto-c.c | 11 | ||||
-rw-r--r-- | plugins/mm-plugin-nokia.c | 11 | ||||
-rw-r--r-- | plugins/mm-plugin-novatel.c | 11 | ||||
-rw-r--r-- | plugins/mm-plugin-option.c | 11 | ||||
-rw-r--r-- | plugins/mm-plugin-sierra.c | 11 | ||||
-rw-r--r-- | plugins/mm-plugin-zte.c | 11 | ||||
-rw-r--r-- | src/mm-manager.c | 109 | ||||
-rw-r--r-- | src/mm-plugin-base.c | 77 | ||||
-rw-r--r-- | src/mm-plugin-base.h | 9 | ||||
-rw-r--r-- | src/mm-plugin.c | 9 | ||||
-rw-r--r-- | src/mm-plugin.h | 2 |
18 files changed, 164 insertions, 208 deletions
diff --git a/plugins/mm-plugin-anydata.c b/plugins/mm-plugin-anydata.c index fb6f84c6..94f4f105 100644 --- a/plugins/mm-plugin-anydata.c +++ b/plugins/mm-plugin-anydata.c @@ -106,7 +106,7 @@ grab_port (MMPluginBase *base, MMPluginBaseSupportsTask *task, GError **error) { - GUdevDevice *port = NULL, *physdev = NULL; + GUdevDevice *port = NULL; MMModem *modem = NULL; const char *name, *subsys, *devfile, *sysfs_path; guint32 caps; @@ -120,14 +120,6 @@ grab_port (MMPluginBase *base, return NULL; } - physdev = mm_plugin_base_supports_task_get_physdev (task); - g_assert (physdev); - sysfs_path = g_udev_device_get_sysfs_path (physdev); - if (!sysfs_path) { - g_set_error (error, 0, 0, "Could not get port's physical device sysfs path."); - return NULL; - } - subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); @@ -137,6 +129,7 @@ grab_port (MMPluginBase *base, return NULL; } + sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & CAP_CDMA) { modem = mm_modem_anydata_cdma_new (sysfs_path, diff --git a/plugins/mm-plugin-generic.c b/plugins/mm-plugin-generic.c index 377273e5..cdf2c66e 100644 --- a/plugins/mm-plugin-generic.c +++ b/plugins/mm-plugin-generic.c @@ -108,7 +108,7 @@ grab_port (MMPluginBase *base, MMPluginBaseSupportsTask *task, GError **error) { - GUdevDevice *port = NULL, *physdev = NULL; + GUdevDevice *port = NULL; MMModem *modem = NULL; const char *name, *subsys, *devfile, *sysfs_path, *driver; guint32 caps; @@ -133,15 +133,8 @@ grab_port (MMPluginBase *base, } } - physdev = mm_plugin_base_supports_task_get_physdev (task); - g_assert (physdev); - sysfs_path = g_udev_device_get_sysfs_path (physdev); - if (!sysfs_path) { - g_set_error (error, 0, 0, "Could not get port's physical device sysfs path."); - return NULL; - } - caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { modem = mm_generic_gsm_new (sysfs_path, diff --git a/plugins/mm-plugin-gobi.c b/plugins/mm-plugin-gobi.c index a504085f..fbe38783 100644 --- a/plugins/mm-plugin-gobi.c +++ b/plugins/mm-plugin-gobi.c @@ -102,7 +102,7 @@ grab_port (MMPluginBase *base, MMPluginBaseSupportsTask *task, GError **error) { - GUdevDevice *port = NULL, *physdev = NULL; + GUdevDevice *port = NULL; MMModem *modem = NULL; const char *name, *subsys, *sysfs_path; guint32 caps; @@ -110,18 +110,11 @@ grab_port (MMPluginBase *base, port = mm_plugin_base_supports_task_get_port (task); g_assert (port); - physdev = mm_plugin_base_supports_task_get_physdev (task); - g_assert (physdev); - sysfs_path = g_udev_device_get_sysfs_path (physdev); - if (!sysfs_path) { - g_set_error (error, 0, 0, "Could not get port's physical device sysfs path."); - return NULL; - } - subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { modem = mm_modem_gobi_gsm_new (sysfs_path, diff --git a/plugins/mm-plugin-hso.c b/plugins/mm-plugin-hso.c index 8493c9c1..dc0a8fcb 100644 --- a/plugins/mm-plugin-hso.c +++ b/plugins/mm-plugin-hso.c @@ -100,7 +100,7 @@ grab_port (MMPluginBase *base, MMPluginBaseSupportsTask *task, GError **error) { - GUdevDevice *port = NULL, *physdev = NULL; + GUdevDevice *port = NULL; MMModem *modem = NULL; const char *name, *subsys, *sysfs_path; char *devfile; @@ -131,18 +131,11 @@ grab_port (MMPluginBase *base, } } - physdev = mm_plugin_base_supports_task_get_physdev (task); - g_assert (physdev); - sysfs_path = g_udev_device_get_sysfs_path (physdev); - if (!sysfs_path) { - g_set_error (error, 0, 0, "Could not get port's physical device sysfs path."); - goto out; - } - caps = mm_plugin_base_supports_task_get_probed_capabilities (task); if (!(caps & MM_PLUGIN_BASE_PORT_CAP_GSM) && strcmp (subsys, "net")) goto out; + sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { modem = mm_modem_hso_new (sysfs_path, mm_plugin_base_supports_task_get_driver (task), diff --git a/plugins/mm-plugin-huawei.c b/plugins/mm-plugin-huawei.c index ab17139b..b4c97d6e 100644 --- a/plugins/mm-plugin-huawei.c +++ b/plugins/mm-plugin-huawei.c @@ -264,7 +264,7 @@ grab_port (MMPluginBase *base, MMPluginBaseSupportsTask *task, GError **error) { - GUdevDevice *port = NULL, *physdev = NULL; + GUdevDevice *port = NULL; MMModem *modem = NULL; const char *name, *subsys, *devfile, *sysfs_path; guint32 caps; @@ -279,14 +279,6 @@ grab_port (MMPluginBase *base, return NULL; } - physdev = mm_plugin_base_supports_task_get_physdev (task); - g_assert (physdev); - sysfs_path = g_udev_device_get_sysfs_path (physdev); - if (!sysfs_path) { - g_set_error (error, 0, 0, "Could not get port's physical device sysfs path."); - return NULL; - } - subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); @@ -296,6 +288,7 @@ grab_port (MMPluginBase *base, } caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { modem = mm_modem_huawei_gsm_new (sysfs_path, diff --git a/plugins/mm-plugin-longcheer.c b/plugins/mm-plugin-longcheer.c index 941238cb..f1b43ecf 100644 --- a/plugins/mm-plugin-longcheer.c +++ b/plugins/mm-plugin-longcheer.c @@ -107,7 +107,7 @@ grab_port (MMPluginBase *base, MMPluginBaseSupportsTask *task, GError **error) { - GUdevDevice *port = NULL, *physdev = NULL; + GUdevDevice *port = NULL; MMModem *modem = NULL; const char *name, *subsys, *sysfs_path; guint32 caps; @@ -133,18 +133,11 @@ grab_port (MMPluginBase *base, && g_udev_device_get_property_as_boolean (port, "ID_MM_LONGCHEER_TAGGED")) ptype = MM_PORT_TYPE_IGNORED; - physdev = mm_plugin_base_supports_task_get_physdev (task); - g_assert (physdev); - sysfs_path = g_udev_device_get_sysfs_path (physdev); - if (!sysfs_path) { - g_set_error (error, 0, 0, "Could not get port's physical device sysfs path."); - return NULL; - } - subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { modem = mm_generic_gsm_new (sysfs_path, diff --git a/plugins/mm-plugin-mbm.c b/plugins/mm-plugin-mbm.c index a80bd913..5554d84f 100644 --- a/plugins/mm-plugin-mbm.c +++ b/plugins/mm-plugin-mbm.c @@ -62,9 +62,12 @@ supports_port (MMPluginBase *base, MMModem *existing, MMPluginBaseSupportsTask *task) { + GUdevClient *client; + const char *sys[] = { "tty", "net", NULL }; GUdevDevice *port, *physdev; guint32 cached = 0, level; - const char *driver, *subsys; + const char *driver, *subsys, *physdev_path; + gboolean is_mbm; /* Can't do anything with non-serial ports */ port = mm_plugin_base_supports_task_get_port (task); @@ -79,9 +82,23 @@ supports_port (MMPluginBase *base, if (!driver) return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED; - physdev = mm_plugin_base_supports_task_get_physdev (task); + client = g_udev_client_new (sys); + if (!client) { + g_warning ("mbm: could not get udev client."); + return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED; + } + + /* Look up the port's physical device and see if this port is really an + * 'mbm' modem, since we have no other way of telling. + */ + physdev_path = mm_plugin_base_supports_task_get_physdev_path (task); + physdev = g_udev_client_query_by_sysfs_path (client, physdev_path); g_assert (physdev); - if (!g_udev_device_get_property_as_boolean (physdev, "ID_MM_ERICSSON_MBM")) + + is_mbm = g_udev_device_get_property_as_boolean (physdev, "ID_MM_ERICSSON_MBM"); + g_object_unref (client); + + if (!is_mbm) return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED; if (!strcmp (subsys, "net")) { @@ -111,7 +128,7 @@ grab_port (MMPluginBase *base, MMPluginBaseSupportsTask *task, GError **error) { - GUdevDevice *port = NULL, *physdev = NULL; + GUdevDevice *port = NULL; MMModem *modem = NULL; const char *name, *subsys, *sysfs_path; guint32 caps; @@ -119,14 +136,6 @@ grab_port (MMPluginBase *base, port = mm_plugin_base_supports_task_get_port (task); g_assert (port); - physdev = mm_plugin_base_supports_task_get_physdev (task); - g_assert (physdev); - sysfs_path = g_udev_device_get_sysfs_path (physdev); - if (!sysfs_path) { - g_set_error (error, 0, 0, "Could not get port's physical device sysfs path."); - return NULL; - } - subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); @@ -134,6 +143,7 @@ grab_port (MMPluginBase *base, if (!(caps & MM_PLUGIN_BASE_PORT_CAP_GSM) && strcmp (subsys, "net")) return NULL; + sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { modem = mm_modem_mbm_new (sysfs_path, mm_plugin_base_supports_task_get_driver (task), diff --git a/plugins/mm-plugin-moto-c.c b/plugins/mm-plugin-moto-c.c index 4f2a49c1..d798af4c 100644 --- a/plugins/mm-plugin-moto-c.c +++ b/plugins/mm-plugin-moto-c.c @@ -102,7 +102,7 @@ grab_port (MMPluginBase *base, MMPluginBaseSupportsTask *task, GError **error) { - GUdevDevice *port = NULL, *physdev = NULL; + GUdevDevice *port = NULL; MMModem *modem = NULL; const char *name, *subsys, *devfile, *sysfs_path; @@ -115,17 +115,10 @@ grab_port (MMPluginBase *base, return NULL; } - physdev = mm_plugin_base_supports_task_get_physdev (task); - g_assert (physdev); - sysfs_path = g_udev_device_get_sysfs_path (physdev); - if (!sysfs_path) { - g_set_error (error, 0, 0, "Could not get port's physical device sysfs path."); - return NULL; - } - subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); + sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { modem = mm_modem_moto_c_gsm_new (sysfs_path, mm_plugin_base_supports_task_get_driver (task), diff --git a/plugins/mm-plugin-nokia.c b/plugins/mm-plugin-nokia.c index 0bcf3945..2d0d6aff 100644 --- a/plugins/mm-plugin-nokia.c +++ b/plugins/mm-plugin-nokia.c @@ -105,7 +105,7 @@ grab_port (MMPluginBase *base, MMPluginBaseSupportsTask *task, GError **error) { - GUdevDevice *port = NULL, *physdev = NULL; + GUdevDevice *port = NULL; MMModem *modem = NULL; const char *name, *subsys, *devfile, *sysfs_path; guint32 caps; @@ -119,18 +119,11 @@ grab_port (MMPluginBase *base, return NULL; } - physdev = mm_plugin_base_supports_task_get_physdev (task); - g_assert (physdev); - sysfs_path = g_udev_device_get_sysfs_path (physdev); - if (!sysfs_path) { - g_set_error (error, 0, 0, "Could not get port's physical device sysfs path."); - return NULL; - } - subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { modem = mm_modem_nokia_new (sysfs_path, diff --git a/plugins/mm-plugin-novatel.c b/plugins/mm-plugin-novatel.c index 3b594818..a968836a 100644 --- a/plugins/mm-plugin-novatel.c +++ b/plugins/mm-plugin-novatel.c @@ -111,7 +111,7 @@ grab_port (MMPluginBase *base, MMPluginBaseSupportsTask *task, GError **error) { - GUdevDevice *port = NULL, *physdev = NULL; + GUdevDevice *port = NULL; MMModem *modem = NULL; const char *name, *subsys, *devfile, *sysfs_path; guint32 caps; @@ -125,18 +125,11 @@ grab_port (MMPluginBase *base, return NULL; } - physdev = mm_plugin_base_supports_task_get_physdev (task); - g_assert (physdev); - sysfs_path = g_udev_device_get_sysfs_path (physdev); - if (!sysfs_path) { - g_set_error (error, 0, 0, "Could not get port's physical device sysfs path."); - return NULL; - } - subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { modem = mm_modem_novatel_gsm_new (sysfs_path, diff --git a/plugins/mm-plugin-option.c b/plugins/mm-plugin-option.c index 694eebf3..101f9bd4 100644 --- a/plugins/mm-plugin-option.c +++ b/plugins/mm-plugin-option.c @@ -101,7 +101,7 @@ grab_port (MMPluginBase *base, MMPluginBaseSupportsTask *task, GError **error) { - GUdevDevice *port = NULL, *physdev = NULL; + GUdevDevice *port = NULL; MMModem *modem = NULL; const char *name, *subsys, *devfile, *sysfs_path; guint32 caps; @@ -117,14 +117,6 @@ grab_port (MMPluginBase *base, return NULL; } - physdev = mm_plugin_base_supports_task_get_physdev (task); - g_assert (physdev); - sysfs_path = g_udev_device_get_sysfs_path (physdev); - if (!sysfs_path) { - g_set_error (error, 0, 0, "Could not get port's physical device sysfs path."); - return NULL; - } - subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); @@ -138,6 +130,7 @@ grab_port (MMPluginBase *base, ptype = MM_PORT_TYPE_PRIMARY; caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { modem = mm_modem_option_new (sysfs_path, diff --git a/plugins/mm-plugin-sierra.c b/plugins/mm-plugin-sierra.c index 2b646674..8ace6532 100644 --- a/plugins/mm-plugin-sierra.c +++ b/plugins/mm-plugin-sierra.c @@ -123,7 +123,7 @@ grab_port (MMPluginBase *base, MMPluginBaseSupportsTask *task, GError **error) { - GUdevDevice *port = NULL, *physdev = NULL; + GUdevDevice *port = NULL; MMModem *modem = NULL; const char *name, *subsys, *devfile, *sysfs_path; guint32 caps; @@ -138,14 +138,6 @@ grab_port (MMPluginBase *base, return NULL; } - physdev = mm_plugin_base_supports_task_get_physdev (task); - g_assert (physdev); - sysfs_path = g_udev_device_get_sysfs_path (physdev); - if (!sysfs_path) { - g_set_error (error, 0, 0, "Could not get port's physical device sysfs path."); - return NULL; - } - subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); @@ -154,6 +146,7 @@ grab_port (MMPluginBase *base, ptype = MM_PORT_TYPE_SECONDARY; caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if ((caps & MM_PLUGIN_BASE_PORT_CAP_GSM) || (ptype != MM_PORT_TYPE_UNKNOWN)) { modem = mm_modem_sierra_gsm_new (sysfs_path, diff --git a/plugins/mm-plugin-zte.c b/plugins/mm-plugin-zte.c index 486c4361..e943bbfe 100644 --- a/plugins/mm-plugin-zte.c +++ b/plugins/mm-plugin-zte.c @@ -116,7 +116,7 @@ grab_port (MMPluginBase *base, MMPluginBaseSupportsTask *task, GError **error) { - GUdevDevice *port = NULL, *physdev = NULL; + GUdevDevice *port = NULL; MMModem *modem = NULL; const char *name, *subsys, *sysfs_path; guint32 caps; @@ -131,18 +131,11 @@ grab_port (MMPluginBase *base, else if (g_udev_device_get_property_as_boolean (port, "ID_MM_ZTE_PORT_TYPE_AUX")) ptype = MM_PORT_TYPE_SECONDARY; - physdev = mm_plugin_base_supports_task_get_physdev (task); - g_assert (physdev); - sysfs_path = g_udev_device_get_sysfs_path (physdev); - if (!sysfs_path) { - g_set_error (error, 0, 0, "Could not get port's physical device sysfs path."); - return NULL; - } - subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); caps = mm_plugin_base_supports_task_get_probed_capabilities (task); + sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task); if (!existing) { if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) { modem = mm_modem_zte_new (sysfs_path, 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); |