diff options
author | Dan Williams <dcbw@redhat.com> | 2012-12-17 16:23:52 -0600 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2013-01-09 12:36:36 -0600 |
commit | 584ca5304f1a73e632dd737de8d36bf031d75153 (patch) | |
tree | 0beccab73d977863adef56e9c52e960d89b02319 | |
parent | 002b9c8088b4c0431d442d3c59e41db81199102b (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.c | 15 | ||||
-rw-r--r-- | plugins/mm-plugin-huawei.c | 8 | ||||
-rw-r--r-- | plugins/mm-plugin-linktop.c | 15 | ||||
-rw-r--r-- | plugins/mm-plugin-zte.c | 23 | ||||
-rw-r--r-- | src/mm-plugin-base.c | 19 | ||||
-rw-r--r-- | src/mm-plugin-base.h | 2 |
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); |