Age | Commit message (Collapse) | Author |
|
Ensure that the cdc-wdm port probing task is canceled if the
modem drops off the bus before the task completes.
This prevents the task from preventing other port probing tasks from starting.
|
|
After the modem recovers, the ports are up but not yet responsive. When MM tries to probe the ports, they do not respond.
As a result, the probing tasks are left ongoing, waiting for a response from the modem.
If the modem drops off the bus for any reason, the cdc-wdm port probing task is not immediately canceled.
This patch fixes this issue by passing a cancellable object to mm_port_mbim_open().
In other words, the patch ensures that the cdc-wdm port probing task is canceled if the
modem drops off the bus before the task completes. This prevents the task from preventing
other port probing tasks from starting.
|
|
|
|
We can remove the port type hint udev tags for the wwan subsystem, as
that logic is now incorporated in the port type hint processing logic
in the daemon itself.
This makes it clearer to know what exact hints are being used, as the
logic is in a single place and it has proper logging of all possible
cases.
|
|
Do not do this in the plugin; instead, do it along with the logic that
looks for port type hints in udev, so that we can properly warn if
things don't match.
|
|
Explicitly log when a tag is found, and also warn if too many por type
hints are provided in the same port.
|
|
When processing the hints for port probing we don't care if the AT
port is flagged as primary or secondary.
|
|
This will make it slightly easier to port mm_port_serial_at_command() to
use GTask, since we won't have to keep a pointer to the result in GTask
after _finish() has been called.
In most cases the caller needs the value anyway, so this doesn't add too
much hasle.
|
|
When QCDM is not required we don't run an explicit QCDM port probing
operation.
In this case, though, we should not assume that the port is QCDM
capable, even if it is also flagged as ignored.
Instead, we'll flag the port as QCDM capable and ignored only if there
was a udev port type hint associated to the port. Otherwise, we'll
report the port as not being QCDM capable, and the port won't even be
reported in the list of ports as its type is unknown.
|
|
|
|
The QCDM/DIAG port is usually nowadays exclusively used by applications
gathering traces from the modem, so avoid port probing and grabbing
when plugins set the property MM_PLUGIN_ALLOWED_QCDM.
A new property MM_PLUGIN_REQUIRED_QCDM is created for those plugins
requiring the QCDM port for properly using a modem.
|
|
We originally did only 3 attempts every 3s, so the maximum probing
time for a given TTY port looking for AT capabilities was 9 seconds.
We now duplicate the amount of times, so up to 18s of port probing,
which is quite a lot more than before, but unfortunately it's needed
because most new modems take a lot of time to boot up internally.
The way to avoid this long probing time is to make sure port type
hints for the possible AT ports are set correctly.
Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/379
|
|
Add support for the Linux wwan subsystem that started to expose
control channel as character devices (e.g. /dev/wwan0p1MBIM...).
Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
|
|
For QRTR devices, create the qmi ports using the QRTR node.
|
|
Most older Qualcomm SoCs (e.g. MSM8916, MSM8974, ...) communicate with
the integrated modem via shared memory (SMD channels). This is similar
to QRTR on newer SoCs, but without the "network" layer. In fact, the
older SoCs also have QRTR, but the modem QMI services are not exposed
there.
The mainline Linux kernel exposes SMD channels via the "remote processor
messaging bus" (rpmsg). Through special IOCTL calls it is possible to
create a char device for a rpmsg/SMD channel. We can then use these to
send QMI/AT messages to the modem, much like the ordinary serial char
devices when using a Qualcomm modem through USB.
This commit introduces support for the new 'rpmsg' subsystem, which
allows exporting QMI-capable and AT-capable ports.
By default NO rpmsg port is flagged as candidate, it is assumed that
the plugin adding support for the rpmsg subsystem will add specific
rules to do so (e.g. so that non-modem ports are explicitly not
flagged as candidate).
All rpmsg ports will be probed for AT or QMI capabilities, unless
explicit port type hints (e.g. ID_MM_PORT_TYPE_QMI or
ID_MM_PORT_TYPE_AT_PRIMARY) are set.
These changes are highly based on the initial integration work done by
Stephan Gerhold <stephan@gerhold.net> in postmarketOS, see:
https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/merge_requests/363
|
|
Back in Linux < 3.6 days, the cdc-wdm ports exposed by the QMI driver
were flagged as owned by the 'usb' subsystem. That changed in 3.6 when
the subsystem was renamed to 'usbmisc':
https://mail.gnome.org/archives/networkmanager-list/2012-June/msg00125.html
This patch removes all monitoring of the 'usb' subsystem completely,
which is anyway a valid subsystem but for which we shouldn't need any
special handling. Right now, with newer kernels, we were using that
monitoring exclusively to get notified of full USB device remove
events, which is really not required as we already process the port
removals one by one.
We simplify the logic everywhere that attempted to match either the
'usb' or 'usbmisc' subsystems, and we no longer require the explicit
checks for the port name being named 'cdc-wdm[0-9]*' in the code, as
that is already taken care of by the ID_MM_CANDIDATE udev tag rule.
|
|
We have assumed until now that all QMI ports are based on the
qmi_wwan driver, exposed in the 'usbmisc' subsystem by the cdc-wdm
driver.
This may no longer be true, so allow creating QMI ports with
an explicit subsystem instead of defaulting always to USBMISC.
|
|
We have assumed until now that all MBIM ports are based on the
cdc_mbim driver, exposed in the 'usbmisc' subsystem by the cdc-wdm
driver.
This may no longer be true, so allow creating MBIM ports with
an explicit subsystem instead of defaulting always to USBMISC.
|
|
We have assumed until now that all QCDM ports are based on TTY
drivers, e.g. exposed via USB.
This may no longer be true, so allow creating QCDM ports with
an explicit subsystem instead of defaulting always to TTY.
|
|
Back in Linux < 3.6 days, the cdc-wdm ports exposed by the QMI driver
were flagged as owned by the 'usb' subsystem. That changed in 3.6 when
the subsystem was renamed to 'usbmisc':
https://mail.gnome.org/archives/networkmanager-list/2012-June/msg00125.html
So, rename the port subsystem type enumn to 'usbmisc'.
|
|
It is no longer true that all QMI ports are exposed by the qmi_wwan
driver and that all MBIM ports are exposed by the cdc_mbim driver.
There are other generic setups that allow exposing these types of
ports using different drivers, and usually we can also know the type
of port in advance via other means. Therefore, allow adding udev port
type hints for QMI and MBIM ports as well.
|
|
There should be no need to do an early check to filter out ports of
the wrong subsystem.
For the user of these methods it is irrelevant if the FALSE is
returned because the port is of the wrong subsystem, or because the
test wasn't added to be probed, or because the test actually failed.
In other words, the ports where the test succeeded will only have
succeeded if they are of the correct subsystem and if the test was
actually executed successfully.
|
|
|
|
|
|
mm-port-probe.c:1091:7: error: initialization discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
1091 | { "AT", 3, mm_port_probe_response_processor_is_at },
| ^~~~
...
|
|
To be in sync with the qmi_device_close_async() underlying method,
given that the synchronous one is deprecated.
|
|
Instead of flagging them as 'ignored' so that they aren't probed, we
can also flag them as 'audio' now, so that the logic knows which port
to report as used for audio in the Call object.
|
|
By default the build used -Wno-unused-but-set-variable but that's
clearly not what we want. Fix those problems.
When using clang, the compiler doesn't error on unknown compile
options, so let's add -Werror to the checking too.
CC='clang'
configure:3408: checking for gcc
configure:3435: result: clang
...
configure:17644: checking whether gcc understands -Wno-unused-but-set-variable
configure:17657: clang -c -Wall -std=gnu89 -g -O2 -Wmissing-declarations -Wmissing-prototypes -Wdeclaration-after-statement -Wstrict-prototypes -Wno-unused-parameter -Wno-sign-compare -Wno-deprecated-declarations -Wno-unused-but-set-variable conftest.c >&5
warning: unknown warning option '-Wno-unused-but-set-variable'; did you mean '-Wno-unused-const-variable'? [-Wunknown-warning-option]
1 warning generated.
configure:17657: $? = 0
configure:17666: result: yes
Reported-by: Torsten Hilbrich <torsten.hilbrich@secunet.com>
|
|
This prevents errors due to nasty typos in the strings.
We define all symbols in a single header file that is NOT considered
part of the API, as there is no need for MM clients to know about
these tags code-wise. These tags are only meaningful when associated
to devices in udev.
Information of each tag is included in the general API documentation.
https://gitlab.freedesktop.org/mobile-broadband/ModemManager/issues/88
|
|
And check that the string given in the tag is actually a valid one.
|
|
Set the serial port flow control from the udev tag
ID_MM_TTY_FLOW_CONTROL before accessing the port.
|
|
|
|
|
|
Same thing as we do for Icera.
|
|
Most Qualcomm-based MBIM devices also support QMI over MBIM. We will
try to check in runtime whether the MBIM device supports QMI over
MBIM, and if so, setup a QmiDevice within the MMPortMbim.
|
|
Ports flagged as being QCDM will not be probed for AT. QCDM probing
will be performed normally, the udev tags only give hints, we still
need to know whether the TTYs are QCDM-capable or not.
|
|
Ports flagged with one of the common AT port type hints will not be
probed for QCDM.
AT probing will be performed normally, the udev tags only give hints,
we still need to know whether the TTYs are AT-capable or not.
|
|
And remove all custom logic from all plugins that were doing just that.
|
|
|
|
|
|
We cannot in any way try to disconnect a GCancellable from within a
cancellation handler, or we'll deadlock.
Thread 1 (Thread 0x7fe98bf25700 (LWP 12079)):
#0 0x00007fe98a355f36 in pthread_cond_wait@@GLIBC_2.3.2 () from /lib/libpthread.so.0
#1 0x00007fe98a7f5ac0 in g_cond_wait () from /usr/lib/libglib-2.0.so.0
#2 0x00007fe98ad14650 in g_cancellable_disconnect () from /usr/lib/libgio-2.0.so.0
#3 0x000000000045be5d in port_probe_run_context_free ()
#4 0x00007fe98ad519ed in g_task_finalize () from /usr/lib/libgio-2.0.so.0
#5 0x00007fe98aaaa7b3 in g_object_unref () from /usr/lib/libgobject-2.0.so.0
#6 0x000000000045b5f8 in port_probe_task_return_error_if_cancelled ()
#7 0x000000000045c57d in serial_probe_at_parse_response ()
#8 0x00007fe98ad42ed2 in g_simple_async_result_complete () from /usr/lib/libgio-2.0.so.0
#9 0x0000000000485c7d in serial_command_ready ()
#10 0x00007fe98ad42ed2 in g_simple_async_result_complete () from /usr/lib/libgio-2.0.so.0
#11 0x0000000000482345 in command_context_complete_and_free ()
#12 0x0000000000482fa5 in port_serial_got_response ()
#13 0x00000000004830f5 in port_serial_response_wait_cancelled ()
#14 0x00007fe98aaa70c5 in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
#15 0x00007fe98aab47ce in signal_emit_unlocked_R () from /usr/lib/libgobject-2.0.so.0
#16 0x00007fe98aabb595 in g_signal_emit_valist () from /usr/lib/libgobject-2.0.so.0
#17 0x00007fe98aabb662 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
#18 0x00007fe98ad144c5 in g_cancellable_cancel () from /usr/lib/libgio-2.0.so.0
#19 0x00007fe98aaa70c5 in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
#20 0x00007fe98aab47ce in signal_emit_unlocked_R () from /usr/lib/libgobject-2.0.so.0
#21 0x00007fe98aabb595 in g_signal_emit_valist () from /usr/lib/libgobject-2.0.so.0
#22 0x00007fe98aabb662 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
#23 0x00007fe98ad144c5 in g_cancellable_cancel () from /usr/lib/libgio-2.0.so.0
#24 0x000000000042e9f6 in port_context_cancel ()
#25 0x00007fe989b99a4c in ffi_call_unix64 () at ../src/x86/unix64.S:75
#26 0x00007fe989b994b9 in ffi_call (cif=0x7fffc41dcdb0, fn=0x42ea40 <device_context_port_released>, rvalue=<optimized out>, avalue=0x7fffc41dccd0) at ../src/x86/ffi64.c:492
#27 0x00007fe98aaa7700 in g_cclosure_marshal_generic () from /usr/lib/libgobject-2.0.so.0
#28 0x00007fe98aaa70c5 in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
#29 0x00007fe98aab47ce in signal_emit_unlocked_R () from /usr/lib/libgobject-2.0.so.0
#30 0x00007fe98aabb595 in g_signal_emit_valist () from /usr/lib/libgobject-2.0.so.0
#31 0x00007fe98aabb662 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
#32 0x000000000042c8f0 in mm_device_release_port ()
#33 0x000000000042a6cb in device_removed ()
#34 0x000000000042af94 in handle_kernel_event ()
#35 0x000000000042b356 in report_kernel_event_auth_ready ()
#36 0x00007fe98ad51783 in g_task_return_now () from /usr/lib/libgio-2.0.so.0
#37 0x00007fe98ad517b9 in complete_in_idle_cb () from /usr/lib/libgio-2.0.so.0
#38 0x00007fe98a7bda5e in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
#39 0x00007fe98a7bddb8 in g_main_context_iterate.isra () from /usr/lib/libglib-2.0.so.0
#40 0x00007fe98a7be042 in g_main_loop_run () from /usr/lib/libglib-2.0.so.0
#41 0x0000000000428dc4 in main ()
So, just clear the cancellation id before going on with the handler logic.
|
|
Program received signal SIGSEGV, Segmentation fault.
strchr () at ../sysdeps/arm/armv6/strchr.S:28
28 ../sysdeps/arm/armv6/strchr.S: No such file or directory.
(gdb) bt
#0 strchr () at ../sysdeps/arm/armv6/strchr.S:28
#1 0x76b121c8 in g_param_spec_pool_lookup () from ~/buildroot/output/staging/lib/libgobject-2.0.so.0
#2 0x76b0cf44 in g_object_new_valist () from ~/buildroot/output/staging/lib/libgobject-2.0.so.0
#3 0x76b0d39c in g_object_new () from ~/buildroot/output/staging/lib/libgobject-2.0.so.0
#4 0x75f75e40 in mm_plugin_create () at ublox/mm-plugin-ublox.c:99
#5 0x00031550 in load_plugin (path=0xe9b68 "/usr/lib/ModemManager/libmm-plugin-ublox.so") at mm-plugin-manager.c:1521
#6 load_plugins (error=0x7efffa68, self=0xdc4f0) at mm-plugin-manager.c:1574
#7 initable_init (initable=<optimized out>, cancellable=<optimized out>, error=0x7efffa68) at mm-plugin-manager.c:1679
#8 0x76b9b278 in g_initable_new_valist () from ~/buildroot/output/staging/lib/libgio-2.0.so.0
#9 0x76b9b2e0 in g_initable_new () from ~/buildroot/output/staging/lib/libgio-2.0.so.0
#10 0x000324d0 in mm_plugin_manager_new (plugin_dir=0xe9c40 "/usr/lib/ModemManager", error=error@entry=0x7efffa68) at mm-plugin-manager.c:1620
#11 0x0002da08 in initable_init (initable=0xddb40, cancellable=<optimized out>, error=0x7efffa68) at mm-base-manager.c:1113
#12 0x76b9b278 in g_initable_new_valist () from ~/buildroot/output/staging/lib/libgio-2.0.so.0
#13 0x76b9b2e0 in g_initable_new () from ~/buildroot/output/staging/lib/libgio-2.0.so.0
#14 0x0002e81c in mm_base_manager_new (connection=connection@entry=0xe1070, plugin_dir=plugin_dir@entry=0x9efb0 "/usr/lib/ModemManager",
auto_scan=auto_scan@entry=1, initial_kernel_events=initial_kernel_events@entry=0x0, enable_test=0, error=0x7efffa68, error@entry=0x7efffa60)
at mm-base-manager.c:957
#15 0x0002b6ec in bus_acquired_cb (connection=0xe1070, name=<optimized out>, user_data=<optimized out>) at main.c:87
#16 0x76c26864 in connection_get_cb () from ~/buildroot/output/staging/lib/libgio-2.0.so.0
#17 0x76bc76cc in g_task_return_now () from ~/buildroot/output/staging/lib/libgio-2.0.so.0
#18 0x76bc7d50 in g_task_return () from
~/buildroot/output/staging/lib/libgio-2.0.so.0
See similar bug in GStreamer:
https://bugzilla.gnome.org/show_bug.cgi?id=740191
|
|
|
|
g_free and g_object_unref are in form of `void (*)(gpointer)`, which
matches the GDestroyNotify signature. An explicit GDestroyNotify cast on
g_free and g_object_unref is thus not needed.
|
|
A new 'ID_MM_TTY_BAUDRATE' per-port udev tag is introduced, which
allows specifying the baudrate that will be used when opening a
specific serial port.
E.g.:
ACTION!="add|change|move", GOTO="mm_my_modem_end"
DEVPATH=="/devices/pci0000:00/0000:00:1d.0/usb1/1-1/1-1.3/*", ENV{ID_MM_TTY_BAUDRATE}="115200"
LABEL="mm_my_modem_end"
https://bugs.freedesktop.org/show_bug.cgi?id=100158
|
|
If a port has been flagged as ignored with the ID_MM_PORT_IGNORE udev property,
we shouldn't open and probe the ports in any way, just flag them as ignored. We
still report them in the list of modem ports, but just with "unknown" type and
therefore not using them for anything.
|
|
Instead of relying constantly on GUdevDevice objects reported by GUdev, we now
use a new generic object (MMKernelDevice) for which we provide an initial GUdev
based backend.
|
|
|
|
When we were completing tasks in idle, the logic was like this:
* Schedule task completion in idle
* self->priv->task = NULL
* (idle) Task completion callback called
This meant that the self->priv->task was always set to NULL before the
completion callback was called, which is what we wanted as a new task may be
scheduled in the callback itself.
Now, without completing in idle, we were wrongly doing:
* Task completion callback called
* self->priv->task = NULL
This commit fixes the logic by making sure self->priv->task = NULL before any
task completion.
|
|
The task completion may try to enqueue a next probe task and in
mm_port_probe_run() it asserts there's no task linked.
https://bugs.freedesktop.org/show_bug.cgi?id=94664
Fixes: 1939c5ace50240127276efacec5c7f166483bb79
|