aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mm-plugin.c22
-rw-r--r--src/mm-plugin.h1
-rw-r--r--src/mm-port-probe.c153
-rw-r--r--src/mm-port-probe.h1
4 files changed, 107 insertions, 70 deletions
diff --git a/src/mm-plugin.c b/src/mm-plugin.c
index f4d84ad4..97dcbc44 100644
--- a/src/mm-plugin.c
+++ b/src/mm-plugin.c
@@ -91,6 +91,7 @@ struct _MMPluginPrivate {
gboolean at;
gboolean single_at;
gboolean qcdm;
+ gboolean qcdm_required;
gboolean qmi;
gboolean mbim;
gboolean icera_probe;
@@ -124,6 +125,7 @@ enum {
PROP_ALLOWED_AT,
PROP_ALLOWED_SINGLE_AT,
PROP_ALLOWED_QCDM,
+ PROP_REQUIRED_QCDM,
PROP_ALLOWED_QMI,
PROP_ALLOWED_MBIM,
PROP_ICERA_PROBE,
@@ -802,7 +804,7 @@ mm_plugin_supports_port (MMPlugin *self,
probe_run_flags |= MM_PORT_PROBE_AT;
else if (self->priv->single_at)
probe_run_flags |= MM_PORT_PROBE_AT;
- if (self->priv->qcdm)
+ if (self->priv->qcdm || self->priv->qcdm_required)
probe_run_flags |= MM_PORT_PROBE_QCDM;
} else if (g_str_equal (mm_kernel_device_get_subsystem (port), "usbmisc")) {
if (self->priv->qmi && !g_strcmp0 (mm_kernel_device_get_driver (port), "qmi_wwan"))
@@ -821,7 +823,7 @@ mm_plugin_supports_port (MMPlugin *self,
probe_run_flags |= MM_PORT_PROBE_MBIM;
if (self->priv->qmi)
probe_run_flags |= MM_PORT_PROBE_QMI;
- if (self->priv->qcdm)
+ if (self->priv->qcdm || self->priv->qcdm_required)
probe_run_flags |= MM_PORT_PROBE_QCDM;
if (self->priv->at)
probe_run_flags |= MM_PORT_PROBE_AT;
@@ -893,6 +895,7 @@ mm_plugin_supports_port (MMPlugin *self,
self->priv->send_lf,
self->priv->custom_at_probe,
self->priv->custom_init,
+ self->priv->qcdm_required,
cancellable,
(GAsyncReadyCallback) port_probe_run_ready,
task);
@@ -1238,6 +1241,10 @@ set_property (GObject *object,
/* Construct only */
self->priv->qcdm = g_value_get_boolean (value);
break;
+ case PROP_REQUIRED_QCDM:
+ /* Construct only */
+ self->priv->qcdm_required = g_value_get_boolean (value);
+ break;
case PROP_ALLOWED_QMI:
/* Construct only */
self->priv->qmi = g_value_get_boolean (value);
@@ -1350,6 +1357,9 @@ get_property (GObject *object,
case PROP_ALLOWED_QCDM:
g_value_set_boolean (value, self->priv->qcdm);
break;
+ case PROP_REQUIRED_QCDM:
+ g_value_set_boolean (value, self->priv->qcdm_required);
+ break;
case PROP_ALLOWED_QMI:
g_value_set_boolean (value, self->priv->qmi);
break;
@@ -1584,6 +1594,14 @@ mm_plugin_class_init (MMPluginClass *klass)
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property
+ (object_class, PROP_REQUIRED_QCDM,
+ g_param_spec_boolean (MM_PLUGIN_REQUIRED_QCDM,
+ "Required QCDM",
+ "Whether QCDM ports are required in this plugin",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property
(object_class, PROP_ALLOWED_QMI,
g_param_spec_boolean (MM_PLUGIN_ALLOWED_QMI,
"Allowed QMI",
diff --git a/src/mm-plugin.h b/src/mm-plugin.h
index 3c00ed1a..1c071383 100644
--- a/src/mm-plugin.h
+++ b/src/mm-plugin.h
@@ -62,6 +62,7 @@
#define MM_PLUGIN_ALLOWED_AT "allowed-at"
#define MM_PLUGIN_ALLOWED_SINGLE_AT "allowed-single-at"
#define MM_PLUGIN_ALLOWED_QCDM "allowed-qcdm"
+#define MM_PLUGIN_REQUIRED_QCDM "required-qcdm"
#define MM_PLUGIN_ALLOWED_QMI "allowed-qmi"
#define MM_PLUGIN_ALLOWED_MBIM "allowed-mbim"
#define MM_PLUGIN_ICERA_PROBE "icera-probe"
diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c
index ed7d36ab..650a05c5 100644
--- a/src/mm-port-probe.c
+++ b/src/mm-port-probe.c
@@ -380,6 +380,9 @@ typedef struct {
/* ---- MBIM probing specific context ---- */
MMPortMbim *mbim_port;
#endif
+
+ /* ---- QCDM probing specific context ---- */
+ gboolean qcdm_required;
} PortProbeRunContext;
static gboolean serial_probe_at (MMPortProbe *self);
@@ -756,84 +759,96 @@ serial_probe_qcdm (MMPortProbe *self)
if (port_probe_task_return_error_if_cancelled (self))
return G_SOURCE_REMOVE;
- mm_obj_dbg (self, "probing QCDM...");
+ /* Check if port requires QCDM probing */
+ if (!ctx->qcdm_required) {
+ /* Ok, this is probably a QCDM port */
+ mm_obj_dbg (self, "Likely a QCDM port, but plugin does not require probing and grabbing...");
+ mm_port_probe_set_result_qcdm (self, TRUE);
+ self->priv->is_ignored = TRUE;
+ /* Reschedule probing */
+ serial_probe_schedule (self);
- /* If open, close the AT port */
- if (ctx->serial) {
- /* Explicitly clear the buffer full signal handler */
- if (ctx->buffer_full_id) {
- g_signal_handler_disconnect (ctx->serial, ctx->buffer_full_id);
- ctx->buffer_full_id = 0;
+ return G_SOURCE_REMOVE;
+ } else {
+ mm_obj_dbg (self, "probing QCDM...");
+
+ /* If open, close the AT port */
+ if (ctx->serial) {
+ /* Explicitly clear the buffer full signal handler */
+ if (ctx->buffer_full_id) {
+ g_signal_handler_disconnect (ctx->serial, ctx->buffer_full_id);
+ ctx->buffer_full_id = 0;
+ }
+ mm_port_serial_close (ctx->serial);
+ g_object_unref (ctx->serial);
}
- mm_port_serial_close (ctx->serial);
- g_object_unref (ctx->serial);
- }
- if (g_str_equal (mm_kernel_device_get_subsystem (self->priv->port), "wwan"))
- subsys = MM_PORT_SUBSYS_WWAN;
+ if (g_str_equal (mm_kernel_device_get_subsystem (self->priv->port), "wwan"))
+ subsys = MM_PORT_SUBSYS_WWAN;
- /* Open the QCDM port */
- ctx->serial = MM_PORT_SERIAL (mm_port_serial_qcdm_new (mm_kernel_device_get_name (self->priv->port), subsys));
- if (!ctx->serial) {
- port_probe_task_return_error (self,
- g_error_new (MM_CORE_ERROR,
- MM_CORE_ERROR_FAILED,
- "(%s/%s) Couldn't create QCDM port",
- mm_kernel_device_get_subsystem (self->priv->port),
- mm_kernel_device_get_name (self->priv->port)));
- return G_SOURCE_REMOVE;
- }
+ /* Open the QCDM port */
+ ctx->serial = MM_PORT_SERIAL (mm_port_serial_qcdm_new (mm_kernel_device_get_name (self->priv->port), subsys));
+ if (!ctx->serial) {
+ port_probe_task_return_error (self,
+ g_error_new (MM_CORE_ERROR,
+ MM_CORE_ERROR_FAILED,
+ "(%s/%s) Couldn't create QCDM port",
+ mm_kernel_device_get_subsystem (self->priv->port),
+ mm_kernel_device_get_name (self->priv->port)));
+ return G_SOURCE_REMOVE;
+ }
- /* Setup port if needed */
- common_serial_port_setup (self, ctx->serial);
+ /* Setup port if needed */
+ common_serial_port_setup (self, ctx->serial);
- /* Try to open the port */
- if (!mm_port_serial_open (ctx->serial, &error)) {
- port_probe_task_return_error (self,
- g_error_new (MM_SERIAL_ERROR,
- MM_SERIAL_ERROR_OPEN_FAILED,
- "(%s/%s) Failed to open QCDM port: %s",
- mm_kernel_device_get_subsystem (self->priv->port),
- mm_kernel_device_get_name (self->priv->port),
- (error ? error->message : "unknown error")));
- g_clear_error (&error);
- return G_SOURCE_REMOVE;
- }
+ /* Try to open the port */
+ if (!mm_port_serial_open (ctx->serial, &error)) {
+ port_probe_task_return_error (self,
+ g_error_new (MM_SERIAL_ERROR,
+ MM_SERIAL_ERROR_OPEN_FAILED,
+ "(%s/%s) Failed to open QCDM port: %s",
+ mm_kernel_device_get_subsystem (self->priv->port),
+ mm_kernel_device_get_name (self->priv->port),
+ (error ? error->message : "unknown error")));
+ g_clear_error (&error);
+ return G_SOURCE_REMOVE;
+ }
- /* Build up the probe command; 0x7E is the frame marker, so put one at the
- * beginning of the buffer to ensure that the device discards any AT
- * commands that probing might have sent earlier. Should help devices
- * respond more quickly and speed up QCDM probing.
- */
- verinfo = g_byte_array_sized_new (10);
- g_byte_array_append (verinfo, &marker, 1);
- len = qcdm_cmd_version_info_new ((char *) (verinfo->data + 1), 9);
- if (len <= 0) {
+ /* Build up the probe command; 0x7E is the frame marker, so put one at the
+ * beginning of the buffer to ensure that the device discards any AT
+ * commands that probing might have sent earlier. Should help devices
+ * respond more quickly and speed up QCDM probing.
+ */
+ verinfo = g_byte_array_sized_new (10);
+ g_byte_array_append (verinfo, &marker, 1);
+ len = qcdm_cmd_version_info_new ((char *) (verinfo->data + 1), 9);
+ if (len <= 0) {
+ g_byte_array_unref (verinfo);
+ port_probe_task_return_error (self,
+ g_error_new (MM_SERIAL_ERROR,
+ MM_SERIAL_ERROR_OPEN_FAILED,
+ "(%s/%s) Failed to create QCDM version info command",
+ mm_kernel_device_get_subsystem (self->priv->port),
+ mm_kernel_device_get_name (self->priv->port)));
+ return G_SOURCE_REMOVE;
+ }
+ verinfo->len = len + 1;
+
+ /* Queuing the command takes ownership over it; save it for the second try */
+ verinfo2 = g_byte_array_sized_new (verinfo->len);
+ g_byte_array_append (verinfo2, verinfo->data, verinfo->len);
+ g_object_set_data_full (G_OBJECT (self), "cmd2", verinfo2, (GDestroyNotify) g_byte_array_unref);
+
+ mm_port_serial_qcdm_command (MM_PORT_SERIAL_QCDM (ctx->serial),
+ verinfo,
+ 3,
+ NULL,
+ (GAsyncReadyCallback) serial_probe_qcdm_parse_response,
+ self);
g_byte_array_unref (verinfo);
- port_probe_task_return_error (self,
- g_error_new (MM_SERIAL_ERROR,
- MM_SERIAL_ERROR_OPEN_FAILED,
- "(%s/%s) Failed to create QCDM version info command",
- mm_kernel_device_get_subsystem (self->priv->port),
- mm_kernel_device_get_name (self->priv->port)));
+
return G_SOURCE_REMOVE;
}
- verinfo->len = len + 1;
-
- /* Queuing the command takes ownership over it; save it for the second try */
- verinfo2 = g_byte_array_sized_new (verinfo->len);
- g_byte_array_append (verinfo2, verinfo->data, verinfo->len);
- g_object_set_data_full (G_OBJECT (self), "cmd2", verinfo2, (GDestroyNotify) g_byte_array_unref);
-
- mm_port_serial_qcdm_command (MM_PORT_SERIAL_QCDM (ctx->serial),
- verinfo,
- 3,
- NULL,
- (GAsyncReadyCallback) serial_probe_qcdm_parse_response,
- self);
- g_byte_array_unref (verinfo);
-
- return G_SOURCE_REMOVE;
}
/***************************************************************/
@@ -1428,6 +1443,7 @@ mm_port_probe_run (MMPortProbe *self,
gboolean at_send_lf,
const MMPortProbeAtCommand *at_custom_probe,
const MMAsyncMethod *at_custom_init,
+ gboolean qcdm_required,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
@@ -1453,6 +1469,7 @@ mm_port_probe_run (MMPortProbe *self,
ctx->at_custom_probe = at_custom_probe;
ctx->at_custom_init = at_custom_init ? (MMPortProbeAtCustomInit)at_custom_init->async : NULL;
ctx->at_custom_init_finish = at_custom_init ? (MMPortProbeAtCustomInitFinish)at_custom_init->finish : NULL;
+ ctx->qcdm_required = qcdm_required;
ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
/* The context will be owned by the task */
diff --git a/src/mm-port-probe.h b/src/mm-port-probe.h
index 9c2fd893..5dd56a8f 100644
--- a/src/mm-port-probe.h
+++ b/src/mm-port-probe.h
@@ -117,6 +117,7 @@ void mm_port_probe_run (MMPortProbe *self,
gboolean at_send_lf,
const MMPortProbeAtCommand *at_custom_probe,
const MMAsyncMethod *at_custom_init,
+ gboolean qcdm_required,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);