From 89466b583b699ad2323dc2a24bc5ccbe4e3a23ac Mon Sep 17 00:00:00 2001
From: Dan Williams <dan@ioncontrol.co>
Date: Sun, 2 Mar 2025 19:53:01 -0600
Subject: [PATCH] port-probe: ensure port is open for all plugin AT probes

If multiple plugins are selected for probing a modem with AT probes,
earlier plugins may only request some probes but not all.  When
those probes complete successfully, subsequent plugins won't re-do
the probes that were already completed, but jump to ones that
haven't yet been done.

For example, plugin A may request only AT probes but plugin B
may request AT, AT_PRODUCT, and AT_VENDOR. Plugin B will start
with AT_PRODUCT probes because plugin A already completed the AT
probe.

The code in probe_step() only opened the serial port for the
AT probe, I guess assuming that all AT-type probes would be
done in sequence. But in the above scenario they are not.

Instead, make sure the port is opened for all AT style probes
that have not yet been executed.

Fixes: 7937a89a37e941e9a77cddcce8226c316fe70821 port-probe: rework and consolidate port probe flow for AT/QCDM/QMI/MBIM

Signed-off-by: Dan Williams <dan@ioncontrol.co>
---
 src/mm-port-probe.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c
index 27f4b6e4c..45ffdde82 100644
--- a/src/mm-port-probe.c
+++ b/src/mm-port-probe.c
@@ -1333,6 +1333,12 @@ serial_open_at (MMPortProbe *self)
     return G_SOURCE_REMOVE;
 }
 
+#define PROBE_FLAGS_AT_MASK (MM_PORT_PROBE_AT | \
+                             MM_PORT_PROBE_AT_VENDOR | \
+                             MM_PORT_PROBE_AT_PRODUCT | \
+                             MM_PORT_PROBE_AT_ICERA | \
+                             MM_PORT_PROBE_AT_XMM)
+
 static void
 probe_step (MMPortProbe *self)
 {
@@ -1384,7 +1390,11 @@ probe_step (MMPortProbe *self)
         /* Fall through */
 
     case PROBE_STEP_AT_OPEN_PORT:
-        if ((ctx->flags & MM_PORT_PROBE_AT) && !(self->priv->flags & MM_PORT_PROBE_AT)) {
+        /* If the port has AT probes, but at least one of the AT probes hasn't
+         * completed yet, open the serial port.
+         */
+        if ((ctx->flags & PROBE_FLAGS_AT_MASK) &&
+            ((ctx->flags & PROBE_FLAGS_AT_MASK) != (self->priv->flags & PROBE_FLAGS_AT_MASK))) {
             mm_obj_msg (self, "probe step: AT open port");
             /* We might end up back here after later probe types fail, so make
              * sure we have a usable AT port.
@@ -1695,11 +1705,7 @@ mm_port_probe_run (MMPortProbe                *self,
     mm_obj_dbg (self, "launching port probing: '%s'", probe_list_str);
     g_free (probe_list_str);
 
-    if (ctx->flags & MM_PORT_PROBE_AT ||
-        ctx->flags & MM_PORT_PROBE_AT_VENDOR ||
-        ctx->flags & MM_PORT_PROBE_AT_PRODUCT ||
-        ctx->flags & MM_PORT_PROBE_AT_ICERA ||
-        ctx->flags & MM_PORT_PROBE_AT_XMM) {
+    if (ctx->flags & PROBE_FLAGS_AT_MASK) {
         ctx->at_probing_cancellable = g_cancellable_new ();
         /* If the main cancellable is cancelled, so will be the at-probing one */
         if (cancellable)
-- 
GitLab