aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-08-31 14:19:50 +0200
committerAleksander Morgado <aleksander@lanedo.com>2012-08-31 15:11:30 +0200
commitfa8c09ca668d27af39c28b9590c5c48410c6b3d5 (patch)
tree36043feea3781fb90b41b110ddcf1538379ebb34
parent061e184d393e22d4331f8f004be110a0176ea4dc (diff)
port-probe: speed up QCDM probing a bit
This is the port to git master of the following commit: commit 01201860de5565a78823913423c6b2a762e3731f Author: Dan Williams <dcbw@redhat.com> Date: Tue Aug 28 21:12:14 2012 -0500 core: speed up QCDM probing a bit The point of sending two "version info" commands was to ensure that the terminating 0x7E of the first one was processed as a QCDM frame boundary and that any random data in the buffer (like AT commands from probing) got cleared out. The second command would always get processed as a valid QCDM command if the device supported QCDM, since there was no garbage before it. Instead of that dance, just prepend the version info message with an extra 0x7E to ensure a clean QCDM frame which the device hopefully responds to immediately. Second, actually process that response instead of throwing it away. Should save about 3 seconds when probing QCDM ports.
-rw-r--r--src/mm-port-probe.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c
index f30e8fdc..123736b9 100644
--- a/src/mm-port-probe.c
+++ b/src/mm-port-probe.c
@@ -398,10 +398,8 @@ serial_probe_qcdm_parse_response (MMQcdmSerialPort *port,
QcdmResult *result;
gint err = QCDM_SUCCESS;
gboolean is_qcdm = FALSE;
-
- /* Just the initial poke; ignore it */
- if (!self)
- return;
+ gboolean retry = FALSE;
+ PortProbeRunTask *task = self->priv->task;
/* If already cancelled, do nothing else */
if (port_probe_run_is_cancelled (self))
@@ -417,12 +415,35 @@ serial_probe_qcdm_parse_response (MMQcdmSerialPort *port,
g_udev_device_get_subsystem (self->priv->port),
g_udev_device_get_name (self->priv->port),
err);
+ retry = TRUE;
} else {
/* yay, probably a QCDM port */
is_qcdm = TRUE;
qcdm_result_unref (result);
}
+ } else {
+ if (!g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT))
+ mm_dbg ("QCDM probe error: (%d) %s", error->code, error->message);
+ retry = TRUE;
+ }
+
+ if (retry) {
+ GByteArray *cmd2;
+
+ cmd2 = g_object_steal_data (G_OBJECT (self), "cmd2");
+ if (cmd2) {
+ /* second try */
+ mm_qcdm_serial_port_queue_command (MM_QCDM_SERIAL_PORT (task->serial),
+ cmd2,
+ 3,
+ NULL,
+ (MMQcdmSerialResponseFn)serial_probe_qcdm_parse_response,
+ self);
+ return;
+ }
+
+ /* no more retries left */
}
/* Set probing result */
@@ -440,6 +461,7 @@ serial_probe_qcdm (MMPortProbe *self)
GByteArray *verinfo = NULL;
GByteArray *verinfo2;
gint len;
+ guint8 marker = 0x7E;
task->source_id = 0;
@@ -486,9 +508,14 @@ serial_probe_qcdm (MMPortProbe *self)
return FALSE;
}
- /* Build up the probe command */
- verinfo = g_byte_array_sized_new (50);
- len = qcdm_cmd_version_info_new ((gchar *) verinfo->data, 50);
+ /* 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_free (verinfo, TRUE);
port_probe_run_task_complete (
@@ -501,24 +528,18 @@ serial_probe_qcdm (MMPortProbe *self)
g_udev_device_get_name (self->priv->port)));
return FALSE;
}
- verinfo->len = len;
+ verinfo->len = len + 1;
- /* Queuing the command takes ownership over it; dup it for the second try */
+ /* 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);
- /* Send the command twice; the ports often need to be woken up */
mm_qcdm_serial_port_queue_command (MM_QCDM_SERIAL_PORT (task->serial),
verinfo,
3,
NULL,
(MMQcdmSerialResponseFn)serial_probe_qcdm_parse_response,
- NULL);
- mm_qcdm_serial_port_queue_command (MM_QCDM_SERIAL_PORT (task->serial),
- verinfo2,
- 3,
- NULL,
- (MMQcdmSerialResponseFn)serial_probe_qcdm_parse_response,
self);
return FALSE;