diff options
author | Dan Williams <dcbw@redhat.com> | 2012-08-28 21:12:14 -0500 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2012-08-29 10:02:18 -0500 |
commit | 90e705f0dcf44acf288075c79a77a933fc433a0d (patch) | |
tree | 84912b6d790011dc4f6aad6ecdc329741fe019d7 | |
parent | 94b37c44664de016245d2626f57fc96dfc44ff01 (diff) |
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-plugin-base.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/src/mm-plugin-base.c b/src/mm-plugin-base.c index 74ef71a9..a66e3cc9 100644 --- a/src/mm-plugin-base.c +++ b/src/mm-plugin-base.c @@ -643,17 +643,15 @@ qcdm_verinfo_cb (MMQcdmSerialPort *port, MMPluginBaseSupportsTaskPrivate *priv; QcdmResult *result; int err = QCDM_SUCCESS; - - /* Just the initial poke; ignore it */ - if (!user_data) - return; + GByteArray *cmd2; task = MM_PLUGIN_BASE_SUPPORTS_TASK (user_data); priv = MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task); if (error) { - /* Probably not a QCDM port */ - goto done; + if (!g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) + mm_dbg ("QCDM probe error: (%d) %s", error->code, error->message); + goto again; } /* Parse the response */ @@ -661,14 +659,24 @@ qcdm_verinfo_cb (MMQcdmSerialPort *port, if (!result) { g_warning ("(%s) failed to parse QCDM version info command result: %d", g_udev_device_get_name (priv->port), err); - goto done; + goto again; } /* yay, probably a QCDM port */ qcdm_result_unref (result); priv->probed_caps |= MM_PLUGIN_BASE_PORT_CAP_QCDM; -done: probe_complete (task); + return; + +again: + cmd2 = g_object_steal_data (G_OBJECT (task), "cmd2"); + if (cmd2) { + /* second try */ + mm_qcdm_serial_port_queue_command (priv->qcdm_port, cmd2, 3, qcdm_verinfo_cb, task); + } else { + /* all done */ + probe_complete (task); + } } static void @@ -679,6 +687,7 @@ try_qcdm_probe (MMPluginBaseSupportsTask *task) GError *error = NULL; GByteArray *verinfo = NULL, *verinfo2; gint len; + guint8 marker = 0x7E; /* Close the AT port */ if (priv->probe_port) { @@ -707,24 +716,29 @@ try_qcdm_probe (MMPluginBaseSupportsTask *task) return; } - /* Build up the probe command */ - verinfo = g_byte_array_sized_new (50); - len = qcdm_cmd_version_info_new ((char *) 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); g_warning ("(%s) failed to create QCDM version info command", name); probe_complete (task); return; } - verinfo->len = len; + verinfo->len = len + 1; - /* Queuing the command takes ownership over it; copy it for the second try */ + /* Queuing the command takes ownership over it; save a copy 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 (task), "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 (priv->qcdm_port, verinfo, 3, qcdm_verinfo_cb, NULL); - mm_qcdm_serial_port_queue_command (priv->qcdm_port, verinfo2, 3, qcdm_verinfo_cb, task); + mm_qcdm_serial_port_queue_command (priv->qcdm_port, verinfo, 3, qcdm_verinfo_cb, task); } static void |