aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2012-12-17 16:23:52 -0600
committerDan Williams <dcbw@redhat.com>2013-01-09 12:36:36 -0600
commit584ca5304f1a73e632dd737de8d36bf031d75153 (patch)
tree0beccab73d977863adef56e9c52e960d89b02319
parent002b9c8088b4c0431d442d3c59e41db81199102b (diff)
core: use number of endpoints as primary port type hintdcbw/06-endpoints
If a port's USB interface has three USB endpoints, it's almost certain they are going to be a bulk-in, bulk-out, and an interrupt endpoint. The presence of an interrupt endpoint usually signals that the port can support PPP and thus should likely be our data port. Use number of endpoints as a hint in addition to udev rules to hopefully get probing correct on a wider range of modems that we haven't seen before.
-rw-r--r--plugins/mm-plugin-generic.c15
-rw-r--r--plugins/mm-plugin-huawei.c8
-rw-r--r--plugins/mm-plugin-linktop.c15
-rw-r--r--plugins/mm-plugin-zte.c23
-rw-r--r--src/mm-plugin-base.c19
-rw-r--r--src/mm-plugin-base.h2
6 files changed, 71 insertions, 11 deletions
diff --git a/plugins/mm-plugin-generic.c b/plugins/mm-plugin-generic.c
index 46b9824a..a039b23f 100644
--- a/plugins/mm-plugin-generic.c
+++ b/plugins/mm-plugin-generic.c
@@ -32,6 +32,7 @@
#include "mm-errors.h"
#include "mm-serial-parsers.h"
#include "mm-log.h"
+#include "mm-at-serial-port.h"
G_DEFINE_TYPE (MMPluginGeneric, mm_plugin_generic, MM_TYPE_PLUGIN_BASE)
@@ -118,6 +119,7 @@ grab_port (MMPluginBase *base,
guint32 caps;
guint16 vendor = 0, product = 0;
MMPortType ptype;
+ MMAtPortFlags pflags = MM_AT_PORT_FLAG_NONE;
port = mm_plugin_base_supports_task_get_port (task);
g_assert (port);
@@ -146,6 +148,15 @@ grab_port (MMPluginBase *base,
caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
ptype = mm_plugin_base_probed_capabilities_to_port_type (caps);
+
+ /* 3-endpoint AT-capable ports are more likely to be the primary port */
+ if (ptype == MM_PORT_TYPE_AT) {
+ if (mm_plugin_base_supports_task_get_num_interface_endpoints (task) == 3) {
+ pflags = MM_AT_PORT_FLAG_PRIMARY;
+ mm_dbg ("(%s/%s) hinting PRIMARY due to possible Interrupt endpoint", subsys, name);
+ }
+ }
+
sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
if (!existing) {
if (caps & CAP_CDMA) {
@@ -165,14 +176,14 @@ grab_port (MMPluginBase *base,
}
if (modem) {
- if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) {
+ if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) {
g_object_unref (modem);
return NULL;
}
}
} else if (get_level_for_capabilities (caps)) {
modem = existing;
- if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error))
+ if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error))
return NULL;
}
diff --git a/plugins/mm-plugin-huawei.c b/plugins/mm-plugin-huawei.c
index 534d1a3c..5a4b3739 100644
--- a/plugins/mm-plugin-huawei.c
+++ b/plugins/mm-plugin-huawei.c
@@ -313,6 +313,14 @@ grab_port (MMPluginBase *base,
}
}
+ /* Last try; 3-endpoint AT-capable ports are more likely to be the primary port */
+ if (ptype == MM_PORT_TYPE_AT && !pflags) {
+ if (mm_plugin_base_supports_task_get_num_interface_endpoints (task) == 3) {
+ pflags = MM_AT_PORT_FLAG_PRIMARY;
+ mm_dbg ("(%s/%s) hinting PRIMARY due to possible Interrupt endpoint", subsys, name);
+ }
+ }
+
sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
if (!existing) {
if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) {
diff --git a/plugins/mm-plugin-linktop.c b/plugins/mm-plugin-linktop.c
index 874e355a..90a2c844 100644
--- a/plugins/mm-plugin-linktop.c
+++ b/plugins/mm-plugin-linktop.c
@@ -18,6 +18,7 @@
#include <gmodule.h>
#include "mm-plugin-linktop.h"
#include "mm-modem-linktop.h"
+#include "mm-log.h"
G_DEFINE_TYPE (MMPluginLinktop, mm_plugin_linktop, MM_TYPE_PLUGIN_BASE)
@@ -106,6 +107,7 @@ grab_port (MMPluginBase *base,
guint32 caps;
guint16 vendor = 0, product = 0;
MMPortType ptype;
+ MMAtPortFlags pflags = MM_AT_PORT_FLAG_NONE;
port = mm_plugin_base_supports_task_get_port (task);
g_assert (port);
@@ -126,6 +128,15 @@ grab_port (MMPluginBase *base,
caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
ptype = mm_plugin_base_probed_capabilities_to_port_type (caps);
+
+ /* 3-endpoint AT-capable ports are more likely to be the primary port */
+ if (ptype == MM_PORT_TYPE_AT) {
+ if (mm_plugin_base_supports_task_get_num_interface_endpoints (task) == 3) {
+ pflags = MM_AT_PORT_FLAG_PRIMARY;
+ mm_dbg ("(%s/%s) hinting PRIMARY due to possible Interrupt endpoint", subsys, name);
+ }
+ }
+
sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
if (!existing) {
if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) {
@@ -137,14 +148,14 @@ grab_port (MMPluginBase *base,
}
if (modem) {
- if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) {
+ if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) {
g_object_unref (modem);
return NULL;
}
}
} else if (get_level_for_capabilities (caps)) {
modem = existing;
- if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error))
+ if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error))
return NULL;
}
diff --git a/plugins/mm-plugin-zte.c b/plugins/mm-plugin-zte.c
index b339b212..be696af4 100644
--- a/plugins/mm-plugin-zte.c
+++ b/plugins/mm-plugin-zte.c
@@ -19,6 +19,7 @@
#include "mm-plugin-zte.h"
#include "mm-modem-zte.h"
#include "mm-generic-cdma.h"
+#include "mm-log.h"
G_DEFINE_TYPE (MMPluginZte, mm_plugin_zte, MM_TYPE_PLUGIN_BASE)
@@ -164,12 +165,6 @@ grab_port (MMPluginBase *base,
port = mm_plugin_base_supports_task_get_port (task);
g_assert (port);
- /* Look for port type hints */
- if (g_udev_device_get_property_as_boolean (port, "ID_MM_ZTE_PORT_TYPE_MODEM"))
- pflags = MM_AT_PORT_FLAG_PRIMARY;
- else if (g_udev_device_get_property_as_boolean (port, "ID_MM_ZTE_PORT_TYPE_AUX"))
- pflags = MM_AT_PORT_FLAG_SECONDARY;
-
subsys = g_udev_device_get_subsystem (port);
name = g_udev_device_get_name (port);
@@ -181,8 +176,22 @@ grab_port (MMPluginBase *base,
icera_dhcp = g_udev_device_get_property_as_boolean (port, "ID_MM_ZTE_ICERA_DHCP");
caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
- sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
ptype = mm_plugin_base_probed_capabilities_to_port_type (caps);
+
+ /* Look for port type hints */
+ if (g_udev_device_get_property_as_boolean (port, "ID_MM_ZTE_PORT_TYPE_MODEM"))
+ pflags = MM_AT_PORT_FLAG_PRIMARY;
+ else if (g_udev_device_get_property_as_boolean (port, "ID_MM_ZTE_PORT_TYPE_AUX"))
+ pflags = MM_AT_PORT_FLAG_SECONDARY;
+ else if (ptype == MM_PORT_TYPE_AT) {
+ /* 3-endpoint AT-capable ports are more likely to be the primary port */
+ if (mm_plugin_base_supports_task_get_num_interface_endpoints (task) == 3) {
+ pflags = MM_AT_PORT_FLAG_PRIMARY;
+ mm_dbg ("(%s/%s) hinting PRIMARY due to possible Interrupt endpoint", subsys, name);
+ }
+ }
+
+ sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
if (!existing) {
if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) {
modem = mm_modem_zte_new (sysfs_path,
diff --git a/src/mm-plugin-base.c b/src/mm-plugin-base.c
index 2fe8989a..b6c3830e 100644
--- a/src/mm-plugin-base.c
+++ b/src/mm-plugin-base.c
@@ -162,6 +162,7 @@ typedef struct {
GUdevDevice *port;
char *physdev_path;
char *driver;
+ guint32 endpoints;
guint open_id;
guint32 open_tries;
@@ -195,6 +196,8 @@ supports_task_new (MMPluginBase *self,
{
MMPluginBaseSupportsTask *task;
MMPluginBaseSupportsTaskPrivate *priv;
+ GUdevDevice *usb_interface;
+ int eps;
g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (MM_IS_PLUGIN_BASE (self), NULL);
@@ -213,6 +216,13 @@ supports_task_new (MMPluginBase *self,
priv->callback = callback;
priv->callback_data = callback_data;
+ usb_interface = g_udev_device_get_parent_with_subsystem (port, "usb", "usb_interface");
+ if (usb_interface) {
+ eps = g_udev_device_get_sysfs_attr_as_int (usb_interface, "bNumEndpoints");
+ priv->endpoints = CLAMP (eps, 0, 10);
+ g_object_unref (usb_interface);
+ }
+
return task;
}
@@ -253,6 +263,15 @@ mm_plugin_base_supports_task_get_driver (MMPluginBaseSupportsTask *task)
}
guint32
+mm_plugin_base_supports_task_get_num_interface_endpoints (MMPluginBaseSupportsTask *task)
+{
+ g_return_val_if_fail (task != NULL, 0);
+ g_return_val_if_fail (MM_IS_PLUGIN_BASE_SUPPORTS_TASK (task), 0);
+
+ return MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task)->endpoints;
+}
+
+guint32
mm_plugin_base_supports_task_get_probed_capabilities (MMPluginBaseSupportsTask *task)
{
g_return_val_if_fail (task != NULL, 0);
diff --git a/src/mm-plugin-base.h b/src/mm-plugin-base.h
index 9be886e7..a6a3d207 100644
--- a/src/mm-plugin-base.h
+++ b/src/mm-plugin-base.h
@@ -86,6 +86,8 @@ const char *mm_plugin_base_supports_task_get_physdev_path (MMPluginBaseSupportsT
const char *mm_plugin_base_supports_task_get_driver (MMPluginBaseSupportsTask *task);
+guint32 mm_plugin_base_supports_task_get_num_interface_endpoints (MMPluginBaseSupportsTask *task);
+
guint32 mm_plugin_base_supports_task_get_probed_capabilities (MMPluginBaseSupportsTask *task);
MMPortType mm_plugin_base_probed_capabilities_to_port_type (guint32 caps);