diff options
-rw-r--r-- | include/ModemManager-tags.h | 18 | ||||
-rw-r--r-- | src/mm-base-modem.c | 15 | ||||
-rw-r--r-- | src/mm-plugin.c | 9 |
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); } } |