diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2013-04-18 16:46:17 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2013-04-18 16:46:47 +0200 |
commit | 3cb639a6bbac52bddace33844f643ca487741ef9 (patch) | |
tree | ea00037eadab160a88217eaca4d332e0f27c573b | |
parent | 4d4d6141388e2eca8acdc8efaf3ee0b5e2a09ebb (diff) | |
download | ModemManager-3cb639a6bbac52bddace33844f643ca487741ef9.tar.gz |
plugin-manager: handle race condition during probing
The specific case:
* Modem exposes cdc-wdm port, Generic plugin probes it successfully as QMI.
* Modem exposes new ports, including the wwan one. All ttys fail probing
because they're neither AT nor QCDM (CnS in this case).
* The wwan port ends up without a port being suggested and is not grabbed.
The root cause of this is that we do not propagate the suggested plugin to newly
added ports when it's the Generic one. If it wasn't the Generic one, the newly
added ports would start with the suggested one for probing.
Now, handle this by looking for the device-specified plugin when the port
probing ends without a specific port given. If there is such a device-specified
plugin accept the port, and otherwise, reject it.
-rw-r--r-- | src/mm-plugin-manager.c | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/src/mm-plugin-manager.c b/src/mm-plugin-manager.c index bae877a6a..0fcb2d1a5 100644 --- a/src/mm-plugin-manager.c +++ b/src/mm-plugin-manager.c @@ -142,40 +142,49 @@ static void port_probe_context_finished (PortProbeContext *port_probe_ctx) { FindDeviceSupportContext *ctx = port_probe_ctx->parent_ctx; + MMPlugin *device_plugin; + + /* Get info about the currently scheduled plugin in the device */ + device_plugin = (MMPlugin *)mm_device_peek_plugin (ctx->device); if (!port_probe_ctx->best_plugin) { - gboolean cancel_remaining; - GList *l; + /* If the port appeared after an already probed port, which decided that + * the Generic plugin was the best one (which is by default not initially + * suggested), we'll end up arriving here. Don't ignore it, it may well + * be a wwan port that we do need to grab. */ + if (device_plugin) { + mm_dbg ("(Plugin Manager) [%s] assuming port can be handled by the '%s' plugin", + g_udev_device_get_name (port_probe_ctx->port), + mm_plugin_get_name (device_plugin)); + } else { + gboolean cancel_remaining; + GList *l; - mm_dbg ("(Plugin Manager) [%s] not supported by any plugin", - g_udev_device_get_name (port_probe_ctx->port)); + mm_dbg ("(Plugin Manager) [%s] not supported by any plugin", + g_udev_device_get_name (port_probe_ctx->port)); - /* Tell the device to ignore this port */ - mm_device_ignore_port (ctx->device, port_probe_ctx->port); + /* Tell the device to ignore this port */ + mm_device_ignore_port (ctx->device, port_probe_ctx->port); - /* If this is the last valid probe which was running (i.e. the last one - * not being deferred-until-suggested), cancel all remaining ones. */ - cancel_remaining = TRUE; - for (l = ctx->running_probes; l; l = g_list_next (l)) { - PortProbeContext *other = l->data; + /* If this is the last valid probe which was running (i.e. the last one + * not being deferred-until-suggested), cancel all remaining ones. */ + cancel_remaining = TRUE; + for (l = ctx->running_probes; l; l = g_list_next (l)) { + PortProbeContext *other = l->data; - /* Do not cancel anything if we find at least one probe which is not - * waiting for the suggested plugin */ - if (other != port_probe_ctx && !other->defer_until_suggested) { - cancel_remaining = FALSE; - break; + /* Do not cancel anything if we find at least one probe which is not + * waiting for the suggested plugin */ + if (other != port_probe_ctx && !other->defer_until_suggested) { + cancel_remaining = FALSE; + break; + } } - } - - if (cancel_remaining) - /* Set a NULL suggested plugin, will cancel the probes */ - suggest_port_probe_result (ctx, port_probe_ctx, NULL); + if (cancel_remaining) + /* Set a NULL suggested plugin, will cancel the probes */ + suggest_port_probe_result (ctx, port_probe_ctx, NULL); + } } else { - MMPlugin *device_plugin; - - device_plugin = (MMPlugin *)mm_device_peek_plugin (ctx->device); - /* Notify the plugin to the device, if this is the first port probing * result we got. * Also, if the previously suggested plugin was the GENERIC one and now |