diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-manager.c | 86 |
1 files changed, 50 insertions, 36 deletions
diff --git a/src/mm-manager.c b/src/mm-manager.c index c6445cf6..aa109a99 100644 --- a/src/mm-manager.c +++ b/src/mm-manager.c @@ -271,6 +271,7 @@ typedef struct { GSList *plugins; GSList *cur_plugin; guint defer_id; + guint done_id; guint32 best_level; MMPlugin *best_plugin; @@ -301,6 +302,9 @@ supports_info_free (SupportsInfo *info) if (info->defer_id) g_source_remove (info->defer_id); + if (info->done_id) + g_source_remove (info->done_id); + g_free (info->subsys); g_free (info->name); g_slist_free (info->plugins); @@ -373,12 +377,8 @@ try_supports_port (MMManager *manager, } } -static void -supports_callback (MMPlugin *plugin, - const char *subsys, - const char *name, - guint32 level, - gpointer user_data) +static gboolean +do_grab_port (gpointer user_data) { SupportsInfo *info = user_data; MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (info->manager); @@ -386,32 +386,6 @@ supports_callback (MMPlugin *plugin, GError *error = NULL; char *key; GSList *iter; - MMPlugin *next_plugin = NULL; - - info->cur_plugin = info->cur_plugin->next; - if (info->cur_plugin) - next_plugin = MM_PLUGIN (info->cur_plugin->data); - - /* Is this plugin's result better than any one we've tried before? */ - if (level > info->best_level) { - info->best_level = level; - info->best_plugin = plugin; - } - - /* Prevent the generic plugin from probing devices that are already supported - * by other plugins. For Huawei for example, secondary ports shouldn't - * be probed, but the generic plugin would happily do so if allowed to. - */ - if ( next_plugin - && !strcmp (mm_plugin_get_name (next_plugin), MM_PLUGIN_GENERIC_NAME) - && info->best_plugin) - next_plugin = NULL; - - /* Try the next plugin */ - if (next_plugin) { - try_supports_port (info->manager, next_plugin, info->subsys, info->name, info); - return; - } /* No more plugins to try */ if (info->best_plugin) { @@ -431,15 +405,15 @@ supports_callback (MMPlugin *plugin, mm_plugin_get_name (info->best_plugin), type_name, mm_modem_get_device (modem), - name); + info->name); add_modem (info->manager, modem); } else { g_warning ("%s: plugin '%s' claimed to support %s/%s but couldn't: (%d) %s", __func__, mm_plugin_get_name (info->best_plugin), - subsys, - name, + info->subsys, + info->name, error ? error->code : -1, (error && error->message) ? error->message : "(unknown)"); } @@ -447,13 +421,53 @@ supports_callback (MMPlugin *plugin, /* Tell each plugin to clean up any outstanding supports task */ for (iter = info->plugins; iter; iter = g_slist_next (iter)) - mm_plugin_cancel_supports_port (MM_PLUGIN (iter->data), subsys, name); + mm_plugin_cancel_supports_port (MM_PLUGIN (iter->data), info->subsys, info->name); g_slist_free (info->plugins); info->cur_plugin = info->plugins = NULL; key = get_key (info->subsys, info->name); g_hash_table_remove (priv->supports, key); g_free (key); + + return FALSE; +} + +static void +supports_callback (MMPlugin *plugin, + const char *subsys, + const char *name, + guint32 level, + gpointer user_data) +{ + SupportsInfo *info = user_data; + MMPlugin *next_plugin = NULL; + + info->cur_plugin = info->cur_plugin->next; + if (info->cur_plugin) + next_plugin = MM_PLUGIN (info->cur_plugin->data); + + /* Is this plugin's result better than any one we've tried before? */ + if (level > info->best_level) { + info->best_level = level; + info->best_plugin = plugin; + } + + /* Prevent the generic plugin from probing devices that are already supported + * by other plugins. For Huawei for example, secondary ports shouldn't + * be probed, but the generic plugin would happily do so if allowed to. + */ + if ( next_plugin + && !strcmp (mm_plugin_get_name (next_plugin), MM_PLUGIN_GENERIC_NAME) + && info->best_plugin) + next_plugin = NULL; + + if (next_plugin) { + /* Try the next plugin */ + try_supports_port (info->manager, next_plugin, info->subsys, info->name, info); + } else { + /* All done; let the best modem grab the port */ + info->done_id = g_idle_add (do_grab_port, info); + } } static void |