diff options
author | Aleksander Morgado <aleksandermj@chromium.org> | 2023-03-27 13:42:33 +0000 |
---|---|---|
committer | Aleksander Morgado <aleksandermj@chromium.org> | 2023-04-13 11:54:04 +0000 |
commit | 7e0663f922425cb33e9c53745e51eec1e5dd89c4 (patch) | |
tree | d924a1a9f17587d8c7139cff2ad564e58b193351 /src/mm-base-modem.c | |
parent | 79b15cf87ce3d94a061f2f37eec2f00eb3987cc6 (diff) | |
download | ModemManager-7e0663f922425cb33e9c53745e51eec1e5dd89c4.tar.gz |
udev: new ID_MM_REQUIRED tag
Users with QMI or MBIM capable modems may want to ensure that these
are never managed using plain AT commands, as that also involves using
PPP. This fallback to AT could happen if the QMI or MBIM port probing
fails for whatever reason.
The new `ID_MM_REQUIRED` udev tag allows specifying that a given port
MUST be successfully grabbed when creating a new modem object, or
otherwise the modem object will not be created at all (even if there
are other fallback control ports like AT that could have been used).
Use this tag with caution.
It is assumed that when this tag is used some other external process
may be monitoring the existence of the modem object in DBus as exposed
by ModemManager, and if it does not appear for any reason then the
modem would be reseted with some other mechanism (e.g. GPIOs, if
available). If no such mechanism to autorecover the modem is in place,
using this tag may leave the modem exposed in the kernel but ignored
by ModemManager.
This tag must be applied on the specific port for which the existence
and usability must be ensured.
E.g. flagging the MBIM port of the Fibocom L850 module as required:
$ vim /lib/udev/rules.d/78-mm-test.rules
ACTION!="add|change|move|bind", GOTO="mm_test_rules_end"
SUBSYSTEMS=="usb", ATTRS{bInterfaceNumber}=="?*", ENV{.MM_USBIFNUM}="$attr{bInterfaceNumber}"
ATTRS{idVendor}=="2cb7", ATTRS{idProduct}=="0007", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_REQUIRED}="1"
LABEL="mm_test_rules_end"
$ sudo udevadm control --reload
$ sudo udevadm trigger
$ sudo udevadm info -p /sys/class/usbmisc/cdc-wdm0
...
E: ID_MM_REQUIRED=1
E: ID_MM_CANDIDATE=1
Diffstat (limited to 'src/mm-base-modem.c')
-rw-r--r-- | src/mm-base-modem.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c index 58fbf450e..f5a983c0e 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), |