From 3cb639a6bbac52bddace33844f643ca487741ef9 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Thu, 18 Apr 2013 16:46:17 +0200 Subject: 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. --- src/mm-plugin-manager.c | 59 ++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/src/mm-plugin-manager.c b/src/mm-plugin-manager.c index bae877a6..0fcb2d1a 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 -- cgit v1.2.3