base-modem: setup timeout monitoring in all control ports

If any of the control ports ends up timing out 10 consecutive times,
the modem will be flagged as invalid and it will be reprobed from
scratch.

This allows us to detect modems that end up irresponsive in QMI or
MBIM while they're still exposed in e.g. the USB bus.
This commit is contained in:
Aleksander Morgado
2022-06-30 11:15:04 +02:00
parent 8387629a8c
commit b91823012a
+36 -15
View File
@@ -147,9 +147,9 @@ mm_base_modem_get_dbus_id (MMBaseModem *self)
/******************************************************************************/
static void
serial_port_timed_out_cb (MMPortSerial *port,
guint n_consecutive_timeouts,
MMBaseModem *self)
port_timed_out_cb (MMPort *port,
guint n_consecutive_timeouts,
MMBaseModem *self)
{
/* If reached the maximum number of timeouts, invalidate modem */
if (n_consecutive_timeouts >= self->priv->max_timeouts) {
@@ -204,13 +204,6 @@ base_modem_create_tty_port (MMBaseModem *self,
if (!port)
return NULL;
/* Enable port timeout checks if requested to do so */
if (self->priv->max_timeouts > 0)
g_signal_connect (port,
MM_PORT_SIGNAL_TIMED_OUT,
G_CALLBACK (serial_port_timed_out_cb),
self);
/* Optional user-provided baudrate */
if (mm_kernel_device_has_property (kernel_device, ID_MM_TTY_BAUDRATE))
g_object_set (port,
@@ -369,6 +362,37 @@ base_modem_internal_grab_port (MMBaseModem *self,
return NULL;
}
/* Setup consecutive timeout watcher in all control ports */
if (self->priv->max_timeouts > 0) {
gboolean timeout_monitoring = FALSE;
if (MM_IS_PORT_SERIAL_AT (port)) {
mm_obj_dbg (port, "timeout monitoring enabled in AT port");
timeout_monitoring = TRUE;
} else if (MM_IS_PORT_SERIAL_QCDM (port)) {
mm_obj_dbg (port, "timeout monitoring enabled in QCDM port");
timeout_monitoring = TRUE;
}
#if defined WITH_QMI
else if (MM_IS_PORT_QMI (port)) {
mm_obj_dbg (port, "timeout monitoring enabled in QMI port");
timeout_monitoring = TRUE;
}
#endif
#if defined WITH_MBIM
else if (MM_IS_PORT_MBIM (port)) {
mm_obj_dbg (port, "timeout monitoring enabled in MBIM port");
timeout_monitoring = TRUE;
}
#endif
if (timeout_monitoring)
g_signal_connect (port,
MM_PORT_SIGNAL_TIMED_OUT,
G_CALLBACK (port_timed_out_cb),
self);
}
/* Store kernel device */
g_object_set (port, MM_PORT_KERNEL_DEVICE, kernel_device, NULL);
@@ -1719,11 +1743,8 @@ cleanup_modem_port (MMBaseModem *self,
mm_port_subsys_get_string (mm_port_get_subsys (MM_PORT (port))),
mm_port_get_device (MM_PORT (port)));
/* Cleanup for serial ports */
if (MM_IS_PORT_SERIAL (port)) {
g_signal_handlers_disconnect_by_func (port, serial_port_timed_out_cb, self);
return;
}
/* Cleanup on all control ports */
g_signal_handlers_disconnect_by_func (port, port_timed_out_cb, self);
#if defined WITH_MBIM
/* We need to close the MBIM port cleanly when disposing the modem object */