diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2012-08-31 14:19:50 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2012-08-31 15:11:30 +0200 |
commit | fa8c09ca668d27af39c28b9590c5c48410c6b3d5 (patch) | |
tree | 36043feea3781fb90b41b110ddcf1538379ebb34 | |
parent | 061e184d393e22d4331f8f004be110a0176ea4dc (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.c | 53 |
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; |