telit: add initial delay for AT ports to become responsive
Add a polling mechanism for port responsiveness, since some modem families require some time before being usable after the serial ports have been exposed by the kernel.
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "mm-common-telit.h"
|
||||
#include "mm-log-object.h"
|
||||
#include "mm-serial-parsers.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -28,6 +29,11 @@
|
||||
|
||||
#define TELIT_GE910_FAMILY_PID 0x0022
|
||||
|
||||
/* The following number of retries of the port responsiveness
|
||||
* check allows having up to 30 seconds of wait, that should
|
||||
* be fine for most of the modems */
|
||||
#define TELIT_PORT_CHECK_RETRIES 6
|
||||
|
||||
gboolean
|
||||
telit_grab_port (MMPlugin *self,
|
||||
MMBaseModem *modem,
|
||||
@@ -88,6 +94,7 @@ typedef struct {
|
||||
MMPortSerialAt *port;
|
||||
gboolean getportcfg_done;
|
||||
guint getportcfg_retries;
|
||||
guint port_responsive_retries;
|
||||
} TelitCustomInitContext;
|
||||
|
||||
gboolean
|
||||
@@ -274,6 +281,67 @@ out:
|
||||
g_object_unref (task);
|
||||
}
|
||||
|
||||
static void at_ready (MMPortSerialAt *port,
|
||||
GAsyncResult *res,
|
||||
GTask *task);
|
||||
|
||||
static void
|
||||
wait_for_ready (GTask *task)
|
||||
{
|
||||
TelitCustomInitContext *ctx;
|
||||
|
||||
ctx = g_task_get_task_data (task);
|
||||
|
||||
if (ctx->port_responsive_retries == 0) {
|
||||
telit_custom_init_step (task);
|
||||
return;
|
||||
}
|
||||
ctx->port_responsive_retries--;
|
||||
|
||||
mm_port_serial_at_command (
|
||||
ctx->port,
|
||||
"AT",
|
||||
5,
|
||||
FALSE, /* raw */
|
||||
FALSE, /* allow_cached */
|
||||
g_task_get_cancellable (task),
|
||||
(GAsyncReadyCallback)at_ready,
|
||||
task);
|
||||
}
|
||||
|
||||
static void
|
||||
at_ready (MMPortSerialAt *port,
|
||||
GAsyncResult *res,
|
||||
GTask *task)
|
||||
{
|
||||
MMPortProbe *probe;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
probe = g_task_get_source_object (task);
|
||||
|
||||
mm_port_serial_at_command_finish (port, res, &error);
|
||||
if (error) {
|
||||
/* On a timeout or send error, wait */
|
||||
if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT) ||
|
||||
g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_SEND_FAILED)) {
|
||||
wait_for_ready (task);
|
||||
return;
|
||||
}
|
||||
/* On an unknown error, make it fatal */
|
||||
if (!mm_serial_parser_v1_is_known_error (error)) {
|
||||
mm_obj_warn (probe, "custom port initialization logic failed: %s", error->message);
|
||||
g_task_return_boolean (task, TRUE);
|
||||
g_object_unref (task);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* When successful mark the port as AT and continue checking #PORTCFG */
|
||||
mm_obj_dbg (probe, "port is AT");
|
||||
mm_port_probe_set_result_at (probe, TRUE);
|
||||
telit_custom_init_step (task);
|
||||
}
|
||||
|
||||
void
|
||||
telit_custom_init (MMPortProbe *probe,
|
||||
MMPortSerialAt *port,
|
||||
@@ -283,15 +351,27 @@ telit_custom_init (MMPortProbe *probe,
|
||||
{
|
||||
TelitCustomInitContext *ctx;
|
||||
GTask *task;
|
||||
gboolean wait_needed;
|
||||
|
||||
ctx = g_slice_new (TelitCustomInitContext);
|
||||
ctx->port = g_object_ref (port);
|
||||
ctx->getportcfg_done = FALSE;
|
||||
ctx->getportcfg_retries = 3;
|
||||
|
||||
ctx->port_responsive_retries = TELIT_PORT_CHECK_RETRIES;
|
||||
task = g_task_new (probe, cancellable, callback, user_data);
|
||||
g_task_set_check_cancellable (task, FALSE);
|
||||
g_task_set_task_data (task, ctx, (GDestroyNotify)telit_custom_init_context_free);
|
||||
|
||||
/* Some Telit modems require an initial delay for the ports to be responsive
|
||||
* If no explicit tag is present, the modem does not need this step
|
||||
* and can directly look for #PORTCFG support */
|
||||
wait_needed = mm_kernel_device_get_global_property_as_boolean (mm_port_probe_peek_port (probe),
|
||||
"ID_MM_TELIT_PORT_DELAY");
|
||||
if (wait_needed) {
|
||||
mm_obj_dbg (probe, "Start polling for port responsiveness");
|
||||
wait_for_ready (task);
|
||||
return;
|
||||
}
|
||||
|
||||
telit_custom_init_step (task);
|
||||
}
|
||||
|
Reference in New Issue
Block a user