Merge remote branch 'origin/master' into qcdm

This commit is contained in:
Dan Williams
2010-03-11 13:43:06 -08:00
6 changed files with 248 additions and 41 deletions
+54 -1
View File
@@ -77,6 +77,8 @@ typedef enum {
PROBE_STATE_LAST
} ProbeState;
static void probe_complete (MMPluginBaseSupportsTask *task);
/*****************************************************************************/
G_DEFINE_TYPE (MMPluginBaseSupportsTask, mm_plugin_base_supports_task, G_TYPE_OBJECT)
@@ -91,6 +93,7 @@ typedef struct {
guint open_id;
guint32 open_tries;
guint full_id;
MMAtSerialPort *probe_port;
guint32 probed_caps;
@@ -198,6 +201,11 @@ mm_plugin_base_supports_task_complete (MMPluginBaseSupportsTask *task,
priv = MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task);
g_return_if_fail (priv->callback != NULL);
if (priv->full_id) {
g_source_remove (priv->full_id);
priv->full_id = 0;
}
subsys = g_udev_device_get_subsystem (priv->port);
name = g_udev_device_get_name (priv->port);
@@ -251,11 +259,15 @@ supports_task_dispose (GObject *object)
if (priv->open_id)
g_source_remove (priv->open_id);
if (priv->full_id)
g_source_remove (priv->full_id);
if (priv->probe_id)
g_source_remove (priv->probe_id);
if (priv->probe_port)
if (priv->probe_port) {
mm_serial_port_close (priv->probe_port);
g_object_unref (priv->probe_port);
}
G_OBJECT_CLASS (mm_plugin_base_supports_task_parent_class)->dispose (object);
}
@@ -349,6 +361,44 @@ parse_cgmm (const char *buf)
return 0;
}
static const char *dq_strings[] = {
"option/faema_", "os_logids.h", NULL
};
static void
port_buffer_full (MMSerialPort *port, GString *buffer, gpointer user_data)
{
MMPluginBaseSupportsTask *task = MM_PLUGIN_BASE_SUPPORTS_TASK (user_data);
MMPluginBaseSupportsTaskPrivate *priv = MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (user_data);
const char **iter;
size_t iter_len;
int i;
/* Check for an immediate disqualification response. There are some
* ports (Option Icera-based chipsets have them, as do Qualcomm Gobi
* devices before their firmware is loaded) that just shouldn't be
* probed if we get a certain response because we know they can't be
* used. Kernel bugs (at least with 2.6.31 and 2.6.32) also trigger port
* flow control kernel oopses if we read too much data for these ports.
*/
for (iter = &dq_strings[0]; iter && *iter; iter++) {
/* Search in the response for the item; the response could have embedded
* nulls so we can't use memcmp() or strstr() on the whole response.
*/
iter_len = strlen (*iter);
for (i = 0; i < buffer->len - iter_len; i++) {
if (!memcmp (&buffer->str[i], *iter, iter_len)) {
/* Immediately close the port and complete probing */
priv->probed_caps = 0;
mm_serial_port_close (priv->probe_port);
probe_complete (task);
return;
}
}
}
}
static gboolean
emit_probe_result (gpointer user_data)
{
@@ -626,6 +676,9 @@ try_open (gpointer user_data)
port = mm_plugin_base_supports_task_get_port (task);
g_assert (port);
task_priv->full_id = g_signal_connect (task_priv->probe_port, "buffer-full",
G_CALLBACK (port_buffer_full), task);
g_debug ("(%s): probe requested by plugin '%s'",
g_udev_device_get_name (port),
mm_plugin_get_name (MM_PLUGIN (task_priv->plugin)));