aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/ModemManager-tags.h18
-rw-r--r--src/mm-base-modem.c15
-rw-r--r--src/mm-plugin.c9
3 files changed, 41 insertions, 1 deletions
diff --git a/include/ModemManager-tags.h b/include/ModemManager-tags.h
index 2029aa90..d3a06d24 100644
--- a/include/ModemManager-tags.h
+++ b/include/ModemManager-tags.h
@@ -252,6 +252,24 @@
*/
#define ID_MM_TTY_FLOW_CONTROL "ID_MM_TTY_FLOW_CONTROL"
+/**
+ * ID_MM_REQUIRED:
+ *
+ * This is a port-specific tag that allows users to specify that the modem
+ * must be able to successfully probe and use the given control port.
+ *
+ * If this tag is set and the port probing procedure fails, the modem object
+ * will not be created, which is the same as if the port didn't exist in the
+ * first place.
+ *
+ * E.g. this tag may be set on a QMI control port if we want to make sure the
+ * modem object exposed by ModemManager is QMI-capable and never an AT-based
+ * modem created due to falling back on a failed QMI port probing procedure.
+ *
+ * Since: 1.22
+ */
+#define ID_MM_REQUIRED "ID_MM_REQUIRED"
+
/*
* The following symbols are deprecated. We don't add them to -compat
* because this -tags file is not really part of the installed API.
diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c
index 58fbf450..f5a983c0 100644
--- a/src/mm-base-modem.c
+++ b/src/mm-base-modem.c
@@ -470,8 +470,21 @@ mm_base_modem_grab_port (MMBaseModem *self,
MMPortSerialAtFlag at_pflags,
GError **error)
{
- if (!base_modem_internal_grab_port (self, kernel_device, FALSE, ptype, at_pflags, error))
+ g_autoptr(GError) inner_error = NULL;
+
+ if (!base_modem_internal_grab_port (self, kernel_device, FALSE, ptype, at_pflags, &inner_error)) {
+ /* If the port was REQUIRED via udev tags and we failed to grab it, we will report
+ * a fatal error. */
+ if (mm_kernel_device_get_property_as_boolean (kernel_device, ID_MM_REQUIRED)) {
+ mm_obj_err (self, "required port '%s/%s' failed to be grabbed",
+ mm_kernel_device_get_subsystem (kernel_device),
+ mm_kernel_device_get_name (kernel_device));
+ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_ABORTED,
+ "Required port failed to be grabbed");
+ } else
+ g_propagate_error (error, g_steal_pointer (&inner_error));
return FALSE;
+ }
mm_obj_dbg (self, "port '%s/%s' grabbed",
mm_kernel_device_get_subsystem (kernel_device),
diff --git a/src/mm-plugin.c b/src/mm-plugin.c
index 725391fc..464e3fd7 100644
--- a/src/mm-plugin.c
+++ b/src/mm-plugin.c
@@ -1084,6 +1084,15 @@ mm_plugin_create_modem (MMPlugin *self,
next:
if (!grabbed) {
mm_obj_warn (self, "could not grab port %s: %s", name, inner_error ? inner_error->message : "unknown error");
+
+ /* An ABORTED error is emitted exclusively when the port grabbing operation
+ * detects that a REQUIRED port is unusable. */
+ if (g_error_matches (inner_error, MM_CORE_ERROR, MM_CORE_ERROR_ABORTED)) {
+ g_propagate_error (error, inner_error);
+ g_clear_object (&modem);
+ return NULL;
+ }
+
g_clear_error (&inner_error);
}
}