core: move physical device checking into the manager
It turns out that the manager needs to know about the physical device so we can prevent multiple plugins from claiming ports on the same modem.
This commit is contained in:
@@ -106,7 +106,7 @@ grab_port (MMPluginBase *base,
|
||||
MMPluginBaseSupportsTask *task,
|
||||
GError **error)
|
||||
{
|
||||
GUdevDevice *port = NULL, *physdev = NULL;
|
||||
GUdevDevice *port = NULL;
|
||||
MMModem *modem = NULL;
|
||||
const char *name, *subsys, *devfile, *sysfs_path;
|
||||
guint32 caps;
|
||||
@@ -120,14 +120,6 @@ grab_port (MMPluginBase *base,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
physdev = mm_plugin_base_supports_task_get_physdev (task);
|
||||
g_assert (physdev);
|
||||
sysfs_path = g_udev_device_get_sysfs_path (physdev);
|
||||
if (!sysfs_path) {
|
||||
g_set_error (error, 0, 0, "Could not get port's physical device sysfs path.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
subsys = g_udev_device_get_subsystem (port);
|
||||
name = g_udev_device_get_name (port);
|
||||
|
||||
@@ -137,6 +129,7 @@ grab_port (MMPluginBase *base,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
|
||||
if (!existing) {
|
||||
if (caps & CAP_CDMA) {
|
||||
modem = mm_modem_anydata_cdma_new (sysfs_path,
|
||||
|
@@ -108,7 +108,7 @@ grab_port (MMPluginBase *base,
|
||||
MMPluginBaseSupportsTask *task,
|
||||
GError **error)
|
||||
{
|
||||
GUdevDevice *port = NULL, *physdev = NULL;
|
||||
GUdevDevice *port = NULL;
|
||||
MMModem *modem = NULL;
|
||||
const char *name, *subsys, *devfile, *sysfs_path, *driver;
|
||||
guint32 caps;
|
||||
@@ -133,15 +133,8 @@ grab_port (MMPluginBase *base,
|
||||
}
|
||||
}
|
||||
|
||||
physdev = mm_plugin_base_supports_task_get_physdev (task);
|
||||
g_assert (physdev);
|
||||
sysfs_path = g_udev_device_get_sysfs_path (physdev);
|
||||
if (!sysfs_path) {
|
||||
g_set_error (error, 0, 0, "Could not get port's physical device sysfs path.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
|
||||
sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
|
||||
if (!existing) {
|
||||
if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) {
|
||||
modem = mm_generic_gsm_new (sysfs_path,
|
||||
|
@@ -102,7 +102,7 @@ grab_port (MMPluginBase *base,
|
||||
MMPluginBaseSupportsTask *task,
|
||||
GError **error)
|
||||
{
|
||||
GUdevDevice *port = NULL, *physdev = NULL;
|
||||
GUdevDevice *port = NULL;
|
||||
MMModem *modem = NULL;
|
||||
const char *name, *subsys, *sysfs_path;
|
||||
guint32 caps;
|
||||
@@ -110,18 +110,11 @@ grab_port (MMPluginBase *base,
|
||||
port = mm_plugin_base_supports_task_get_port (task);
|
||||
g_assert (port);
|
||||
|
||||
physdev = mm_plugin_base_supports_task_get_physdev (task);
|
||||
g_assert (physdev);
|
||||
sysfs_path = g_udev_device_get_sysfs_path (physdev);
|
||||
if (!sysfs_path) {
|
||||
g_set_error (error, 0, 0, "Could not get port's physical device sysfs path.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
subsys = g_udev_device_get_subsystem (port);
|
||||
name = g_udev_device_get_name (port);
|
||||
|
||||
caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
|
||||
sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
|
||||
if (!existing) {
|
||||
if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) {
|
||||
modem = mm_modem_gobi_gsm_new (sysfs_path,
|
||||
|
@@ -100,7 +100,7 @@ grab_port (MMPluginBase *base,
|
||||
MMPluginBaseSupportsTask *task,
|
||||
GError **error)
|
||||
{
|
||||
GUdevDevice *port = NULL, *physdev = NULL;
|
||||
GUdevDevice *port = NULL;
|
||||
MMModem *modem = NULL;
|
||||
const char *name, *subsys, *sysfs_path;
|
||||
char *devfile;
|
||||
@@ -131,18 +131,11 @@ grab_port (MMPluginBase *base,
|
||||
}
|
||||
}
|
||||
|
||||
physdev = mm_plugin_base_supports_task_get_physdev (task);
|
||||
g_assert (physdev);
|
||||
sysfs_path = g_udev_device_get_sysfs_path (physdev);
|
||||
if (!sysfs_path) {
|
||||
g_set_error (error, 0, 0, "Could not get port's physical device sysfs path.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
|
||||
if (!(caps & MM_PLUGIN_BASE_PORT_CAP_GSM) && strcmp (subsys, "net"))
|
||||
goto out;
|
||||
|
||||
sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
|
||||
if (!existing) {
|
||||
modem = mm_modem_hso_new (sysfs_path,
|
||||
mm_plugin_base_supports_task_get_driver (task),
|
||||
|
@@ -264,7 +264,7 @@ grab_port (MMPluginBase *base,
|
||||
MMPluginBaseSupportsTask *task,
|
||||
GError **error)
|
||||
{
|
||||
GUdevDevice *port = NULL, *physdev = NULL;
|
||||
GUdevDevice *port = NULL;
|
||||
MMModem *modem = NULL;
|
||||
const char *name, *subsys, *devfile, *sysfs_path;
|
||||
guint32 caps;
|
||||
@@ -279,14 +279,6 @@ grab_port (MMPluginBase *base,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
physdev = mm_plugin_base_supports_task_get_physdev (task);
|
||||
g_assert (physdev);
|
||||
sysfs_path = g_udev_device_get_sysfs_path (physdev);
|
||||
if (!sysfs_path) {
|
||||
g_set_error (error, 0, 0, "Could not get port's physical device sysfs path.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
subsys = g_udev_device_get_subsystem (port);
|
||||
name = g_udev_device_get_name (port);
|
||||
|
||||
@@ -296,6 +288,7 @@ grab_port (MMPluginBase *base,
|
||||
}
|
||||
|
||||
caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
|
||||
sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
|
||||
if (!existing) {
|
||||
if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) {
|
||||
modem = mm_modem_huawei_gsm_new (sysfs_path,
|
||||
|
@@ -107,7 +107,7 @@ grab_port (MMPluginBase *base,
|
||||
MMPluginBaseSupportsTask *task,
|
||||
GError **error)
|
||||
{
|
||||
GUdevDevice *port = NULL, *physdev = NULL;
|
||||
GUdevDevice *port = NULL;
|
||||
MMModem *modem = NULL;
|
||||
const char *name, *subsys, *sysfs_path;
|
||||
guint32 caps;
|
||||
@@ -133,18 +133,11 @@ grab_port (MMPluginBase *base,
|
||||
&& g_udev_device_get_property_as_boolean (port, "ID_MM_LONGCHEER_TAGGED"))
|
||||
ptype = MM_PORT_TYPE_IGNORED;
|
||||
|
||||
physdev = mm_plugin_base_supports_task_get_physdev (task);
|
||||
g_assert (physdev);
|
||||
sysfs_path = g_udev_device_get_sysfs_path (physdev);
|
||||
if (!sysfs_path) {
|
||||
g_set_error (error, 0, 0, "Could not get port's physical device sysfs path.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
subsys = g_udev_device_get_subsystem (port);
|
||||
name = g_udev_device_get_name (port);
|
||||
|
||||
caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
|
||||
sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
|
||||
if (!existing) {
|
||||
if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) {
|
||||
modem = mm_generic_gsm_new (sysfs_path,
|
||||
|
@@ -62,9 +62,12 @@ supports_port (MMPluginBase *base,
|
||||
MMModem *existing,
|
||||
MMPluginBaseSupportsTask *task)
|
||||
{
|
||||
GUdevClient *client;
|
||||
const char *sys[] = { "tty", "net", NULL };
|
||||
GUdevDevice *port, *physdev;
|
||||
guint32 cached = 0, level;
|
||||
const char *driver, *subsys;
|
||||
const char *driver, *subsys, *physdev_path;
|
||||
gboolean is_mbm;
|
||||
|
||||
/* Can't do anything with non-serial ports */
|
||||
port = mm_plugin_base_supports_task_get_port (task);
|
||||
@@ -79,9 +82,23 @@ supports_port (MMPluginBase *base,
|
||||
if (!driver)
|
||||
return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED;
|
||||
|
||||
physdev = mm_plugin_base_supports_task_get_physdev (task);
|
||||
client = g_udev_client_new (sys);
|
||||
if (!client) {
|
||||
g_warning ("mbm: could not get udev client.");
|
||||
return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/* Look up the port's physical device and see if this port is really an
|
||||
* 'mbm' modem, since we have no other way of telling.
|
||||
*/
|
||||
physdev_path = mm_plugin_base_supports_task_get_physdev_path (task);
|
||||
physdev = g_udev_client_query_by_sysfs_path (client, physdev_path);
|
||||
g_assert (physdev);
|
||||
if (!g_udev_device_get_property_as_boolean (physdev, "ID_MM_ERICSSON_MBM"))
|
||||
|
||||
is_mbm = g_udev_device_get_property_as_boolean (physdev, "ID_MM_ERICSSON_MBM");
|
||||
g_object_unref (client);
|
||||
|
||||
if (!is_mbm)
|
||||
return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED;
|
||||
|
||||
if (!strcmp (subsys, "net")) {
|
||||
@@ -111,7 +128,7 @@ grab_port (MMPluginBase *base,
|
||||
MMPluginBaseSupportsTask *task,
|
||||
GError **error)
|
||||
{
|
||||
GUdevDevice *port = NULL, *physdev = NULL;
|
||||
GUdevDevice *port = NULL;
|
||||
MMModem *modem = NULL;
|
||||
const char *name, *subsys, *sysfs_path;
|
||||
guint32 caps;
|
||||
@@ -119,14 +136,6 @@ grab_port (MMPluginBase *base,
|
||||
port = mm_plugin_base_supports_task_get_port (task);
|
||||
g_assert (port);
|
||||
|
||||
physdev = mm_plugin_base_supports_task_get_physdev (task);
|
||||
g_assert (physdev);
|
||||
sysfs_path = g_udev_device_get_sysfs_path (physdev);
|
||||
if (!sysfs_path) {
|
||||
g_set_error (error, 0, 0, "Could not get port's physical device sysfs path.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
subsys = g_udev_device_get_subsystem (port);
|
||||
name = g_udev_device_get_name (port);
|
||||
|
||||
@@ -134,6 +143,7 @@ grab_port (MMPluginBase *base,
|
||||
if (!(caps & MM_PLUGIN_BASE_PORT_CAP_GSM) && strcmp (subsys, "net"))
|
||||
return NULL;
|
||||
|
||||
sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
|
||||
if (!existing) {
|
||||
modem = mm_modem_mbm_new (sysfs_path,
|
||||
mm_plugin_base_supports_task_get_driver (task),
|
||||
|
@@ -102,7 +102,7 @@ grab_port (MMPluginBase *base,
|
||||
MMPluginBaseSupportsTask *task,
|
||||
GError **error)
|
||||
{
|
||||
GUdevDevice *port = NULL, *physdev = NULL;
|
||||
GUdevDevice *port = NULL;
|
||||
MMModem *modem = NULL;
|
||||
const char *name, *subsys, *devfile, *sysfs_path;
|
||||
|
||||
@@ -115,17 +115,10 @@ grab_port (MMPluginBase *base,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
physdev = mm_plugin_base_supports_task_get_physdev (task);
|
||||
g_assert (physdev);
|
||||
sysfs_path = g_udev_device_get_sysfs_path (physdev);
|
||||
if (!sysfs_path) {
|
||||
g_set_error (error, 0, 0, "Could not get port's physical device sysfs path.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
subsys = g_udev_device_get_subsystem (port);
|
||||
name = g_udev_device_get_name (port);
|
||||
|
||||
sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
|
||||
if (!existing) {
|
||||
modem = mm_modem_moto_c_gsm_new (sysfs_path,
|
||||
mm_plugin_base_supports_task_get_driver (task),
|
||||
|
@@ -105,7 +105,7 @@ grab_port (MMPluginBase *base,
|
||||
MMPluginBaseSupportsTask *task,
|
||||
GError **error)
|
||||
{
|
||||
GUdevDevice *port = NULL, *physdev = NULL;
|
||||
GUdevDevice *port = NULL;
|
||||
MMModem *modem = NULL;
|
||||
const char *name, *subsys, *devfile, *sysfs_path;
|
||||
guint32 caps;
|
||||
@@ -119,18 +119,11 @@ grab_port (MMPluginBase *base,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
physdev = mm_plugin_base_supports_task_get_physdev (task);
|
||||
g_assert (physdev);
|
||||
sysfs_path = g_udev_device_get_sysfs_path (physdev);
|
||||
if (!sysfs_path) {
|
||||
g_set_error (error, 0, 0, "Could not get port's physical device sysfs path.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
subsys = g_udev_device_get_subsystem (port);
|
||||
name = g_udev_device_get_name (port);
|
||||
|
||||
caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
|
||||
sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
|
||||
if (!existing) {
|
||||
if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) {
|
||||
modem = mm_modem_nokia_new (sysfs_path,
|
||||
|
@@ -111,7 +111,7 @@ grab_port (MMPluginBase *base,
|
||||
MMPluginBaseSupportsTask *task,
|
||||
GError **error)
|
||||
{
|
||||
GUdevDevice *port = NULL, *physdev = NULL;
|
||||
GUdevDevice *port = NULL;
|
||||
MMModem *modem = NULL;
|
||||
const char *name, *subsys, *devfile, *sysfs_path;
|
||||
guint32 caps;
|
||||
@@ -125,18 +125,11 @@ grab_port (MMPluginBase *base,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
physdev = mm_plugin_base_supports_task_get_physdev (task);
|
||||
g_assert (physdev);
|
||||
sysfs_path = g_udev_device_get_sysfs_path (physdev);
|
||||
if (!sysfs_path) {
|
||||
g_set_error (error, 0, 0, "Could not get port's physical device sysfs path.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
subsys = g_udev_device_get_subsystem (port);
|
||||
name = g_udev_device_get_name (port);
|
||||
|
||||
caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
|
||||
sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
|
||||
if (!existing) {
|
||||
if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) {
|
||||
modem = mm_modem_novatel_gsm_new (sysfs_path,
|
||||
|
@@ -101,7 +101,7 @@ grab_port (MMPluginBase *base,
|
||||
MMPluginBaseSupportsTask *task,
|
||||
GError **error)
|
||||
{
|
||||
GUdevDevice *port = NULL, *physdev = NULL;
|
||||
GUdevDevice *port = NULL;
|
||||
MMModem *modem = NULL;
|
||||
const char *name, *subsys, *devfile, *sysfs_path;
|
||||
guint32 caps;
|
||||
@@ -117,14 +117,6 @@ grab_port (MMPluginBase *base,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
physdev = mm_plugin_base_supports_task_get_physdev (task);
|
||||
g_assert (physdev);
|
||||
sysfs_path = g_udev_device_get_sysfs_path (physdev);
|
||||
if (!sysfs_path) {
|
||||
g_set_error (error, 0, 0, "Could not get port's physical device sysfs path.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
subsys = g_udev_device_get_subsystem (port);
|
||||
name = g_udev_device_get_name (port);
|
||||
|
||||
@@ -138,6 +130,7 @@ grab_port (MMPluginBase *base,
|
||||
ptype = MM_PORT_TYPE_PRIMARY;
|
||||
|
||||
caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
|
||||
sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
|
||||
if (!existing) {
|
||||
if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) {
|
||||
modem = mm_modem_option_new (sysfs_path,
|
||||
|
@@ -123,7 +123,7 @@ grab_port (MMPluginBase *base,
|
||||
MMPluginBaseSupportsTask *task,
|
||||
GError **error)
|
||||
{
|
||||
GUdevDevice *port = NULL, *physdev = NULL;
|
||||
GUdevDevice *port = NULL;
|
||||
MMModem *modem = NULL;
|
||||
const char *name, *subsys, *devfile, *sysfs_path;
|
||||
guint32 caps;
|
||||
@@ -138,14 +138,6 @@ grab_port (MMPluginBase *base,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
physdev = mm_plugin_base_supports_task_get_physdev (task);
|
||||
g_assert (physdev);
|
||||
sysfs_path = g_udev_device_get_sysfs_path (physdev);
|
||||
if (!sysfs_path) {
|
||||
g_set_error (error, 0, 0, "Could not get port's physical device sysfs path.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
subsys = g_udev_device_get_subsystem (port);
|
||||
name = g_udev_device_get_name (port);
|
||||
|
||||
@@ -154,6 +146,7 @@ grab_port (MMPluginBase *base,
|
||||
ptype = MM_PORT_TYPE_SECONDARY;
|
||||
|
||||
caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
|
||||
sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
|
||||
if (!existing) {
|
||||
if ((caps & MM_PLUGIN_BASE_PORT_CAP_GSM) || (ptype != MM_PORT_TYPE_UNKNOWN)) {
|
||||
modem = mm_modem_sierra_gsm_new (sysfs_path,
|
||||
|
@@ -116,7 +116,7 @@ grab_port (MMPluginBase *base,
|
||||
MMPluginBaseSupportsTask *task,
|
||||
GError **error)
|
||||
{
|
||||
GUdevDevice *port = NULL, *physdev = NULL;
|
||||
GUdevDevice *port = NULL;
|
||||
MMModem *modem = NULL;
|
||||
const char *name, *subsys, *sysfs_path;
|
||||
guint32 caps;
|
||||
@@ -131,18 +131,11 @@ grab_port (MMPluginBase *base,
|
||||
else if (g_udev_device_get_property_as_boolean (port, "ID_MM_ZTE_PORT_TYPE_AUX"))
|
||||
ptype = MM_PORT_TYPE_SECONDARY;
|
||||
|
||||
physdev = mm_plugin_base_supports_task_get_physdev (task);
|
||||
g_assert (physdev);
|
||||
sysfs_path = g_udev_device_get_sysfs_path (physdev);
|
||||
if (!sysfs_path) {
|
||||
g_set_error (error, 0, 0, "Could not get port's physical device sysfs path.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
subsys = g_udev_device_get_subsystem (port);
|
||||
name = g_udev_device_get_name (port);
|
||||
|
||||
caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
|
||||
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,
|
||||
|
109
src/mm-manager.c
109
src/mm-manager.c
@@ -299,6 +299,7 @@ typedef struct {
|
||||
MMManager *manager;
|
||||
char *subsys;
|
||||
char *name;
|
||||
char *physdev_path;
|
||||
GSList *plugins;
|
||||
GSList *cur_plugin;
|
||||
guint defer_id;
|
||||
@@ -309,7 +310,10 @@ typedef struct {
|
||||
} SupportsInfo;
|
||||
|
||||
static SupportsInfo *
|
||||
supports_info_new (MMManager *self, const char *subsys, const char *name)
|
||||
supports_info_new (MMManager *self,
|
||||
const char *subsys,
|
||||
const char *name,
|
||||
const char *physdev_path)
|
||||
{
|
||||
MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (self);
|
||||
SupportsInfo *info;
|
||||
@@ -318,6 +322,7 @@ supports_info_new (MMManager *self, const char *subsys, const char *name)
|
||||
info->manager = self;
|
||||
info->subsys = g_strdup (subsys);
|
||||
info->name = g_strdup (name);
|
||||
info->physdev_path = g_strdup (physdev_path);
|
||||
info->plugins = g_slist_copy (priv->plugins);
|
||||
info->cur_plugin = info->plugins;
|
||||
return info;
|
||||
@@ -358,8 +363,6 @@ static void supports_callback (MMPlugin *plugin,
|
||||
|
||||
static void try_supports_port (MMManager *manager,
|
||||
MMPlugin *plugin,
|
||||
const char *subsys,
|
||||
const char *name,
|
||||
SupportsInfo *info);
|
||||
|
||||
static gboolean
|
||||
@@ -370,8 +373,6 @@ supports_defer_timeout (gpointer user_data)
|
||||
g_debug ("(%s): re-checking support...", info->name);
|
||||
try_supports_port (info->manager,
|
||||
MM_PLUGIN (info->cur_plugin->data),
|
||||
info->subsys,
|
||||
info->name,
|
||||
info);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -379,23 +380,28 @@ supports_defer_timeout (gpointer user_data)
|
||||
static void
|
||||
try_supports_port (MMManager *manager,
|
||||
MMPlugin *plugin,
|
||||
const char *subsys,
|
||||
const char *name,
|
||||
SupportsInfo *info)
|
||||
{
|
||||
MMPluginSupportsResult result;
|
||||
|
||||
result = mm_plugin_supports_port (plugin, subsys, name, supports_callback, info);
|
||||
result = mm_plugin_supports_port (plugin,
|
||||
info->subsys,
|
||||
info->name,
|
||||
info->physdev_path,
|
||||
supports_callback,
|
||||
info);
|
||||
|
||||
switch (result) {
|
||||
case MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED:
|
||||
/* If the plugin knows it doesn't support the modem, just call the
|
||||
* callback and indicate 0 support.
|
||||
*/
|
||||
supports_callback (plugin, subsys, name, 0, info);
|
||||
supports_callback (plugin, info->subsys, info->name, 0, info);
|
||||
break;
|
||||
case MM_PLUGIN_SUPPORTS_PORT_DEFER:
|
||||
g_debug ("(%s): (%s) deferring support check", mm_plugin_get_name (plugin), name);
|
||||
g_debug ("(%s): (%s) deferring support check",
|
||||
mm_plugin_get_name (plugin),
|
||||
info->name);
|
||||
if (info->defer_id)
|
||||
g_source_remove (info->defer_id);
|
||||
|
||||
@@ -494,21 +500,59 @@ supports_callback (MMPlugin *plugin,
|
||||
|
||||
if (next_plugin) {
|
||||
/* Try the next plugin */
|
||||
try_supports_port (info->manager, next_plugin, info->subsys, info->name, info);
|
||||
try_supports_port (info->manager, next_plugin, info);
|
||||
} else {
|
||||
/* All done; let the best modem grab the port */
|
||||
info->done_id = g_idle_add (do_grab_port, info);
|
||||
}
|
||||
}
|
||||
|
||||
static GUdevDevice *
|
||||
find_physical_device (GUdevDevice *child)
|
||||
{
|
||||
GUdevDevice *iter, *old = NULL;
|
||||
GUdevDevice *physdev = NULL;
|
||||
const char *subsys, *type;
|
||||
guint32 i = 0;
|
||||
gboolean is_usb = FALSE, is_pci = FALSE;
|
||||
|
||||
g_return_val_if_fail (child != NULL, NULL);
|
||||
|
||||
iter = g_object_ref (child);
|
||||
while (iter && i++ < 8) {
|
||||
subsys = g_udev_device_get_subsystem (iter);
|
||||
if (subsys) {
|
||||
if (is_usb || !strcmp (subsys, "usb")) {
|
||||
is_usb = TRUE;
|
||||
type = g_udev_device_get_devtype (iter);
|
||||
if (type && !strcmp (type, "usb_device")) {
|
||||
physdev = iter;
|
||||
break;
|
||||
}
|
||||
} else if (is_pci || !strcmp (subsys, "pci")) {
|
||||
is_pci = TRUE;
|
||||
physdev = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
old = iter;
|
||||
iter = g_udev_device_get_parent (old);
|
||||
g_object_unref (old);
|
||||
}
|
||||
|
||||
return physdev;
|
||||
}
|
||||
|
||||
static void
|
||||
device_added (MMManager *manager, GUdevDevice *device)
|
||||
{
|
||||
MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (manager);
|
||||
const char *subsys, *name;
|
||||
const char *subsys, *name, *physdev_path;
|
||||
SupportsInfo *info;
|
||||
char *key;
|
||||
gboolean found;
|
||||
GUdevDevice *physdev = NULL;
|
||||
|
||||
g_return_if_fail (device != NULL);
|
||||
|
||||
@@ -527,15 +571,44 @@ device_added (MMManager *manager, GUdevDevice *device)
|
||||
|
||||
key = get_key (subsys, name);
|
||||
found = !!g_hash_table_lookup (priv->supports, key);
|
||||
if (found) {
|
||||
g_free (key);
|
||||
return;
|
||||
if (found)
|
||||
goto out;
|
||||
|
||||
/* Find the port's physical device's sysfs path. This is the kernel device
|
||||
* that "owns" all the ports of the device, like the USB device or the PCI
|
||||
* device the provides each tty or network port.
|
||||
*/
|
||||
physdev = find_physical_device (device);
|
||||
if (!physdev) {
|
||||
/* Warn about it, but filter out some common ports that we know don't have
|
||||
* anything to do with mobile broadband.
|
||||
*/
|
||||
if ( strcmp (name, "console")
|
||||
&& strcmp (name, "ptmx")
|
||||
&& strcmp (name, "lo")
|
||||
&& strcmp (name, "tty")
|
||||
&& !strstr (name, "virbr"))
|
||||
g_debug ("(%s/%s): could not get port's parent device", subsys, name);
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
info = supports_info_new (manager, subsys, name);
|
||||
g_hash_table_insert (priv->supports, key, info);
|
||||
physdev_path = g_udev_device_get_sysfs_path (physdev);
|
||||
if (!physdev_path) {
|
||||
g_debug ("(%s/%s): could not get port's parent device sysfs path", subsys, name);
|
||||
goto out;
|
||||
}
|
||||
|
||||
try_supports_port (manager, MM_PLUGIN (info->cur_plugin->data), subsys, name, info);
|
||||
/* Success; now ask plugins if they can handle this port */
|
||||
info = supports_info_new (manager, subsys, name, physdev_path);
|
||||
g_hash_table_insert (priv->supports, g_strdup (key), info);
|
||||
|
||||
try_supports_port (manager, MM_PLUGIN (info->cur_plugin->data), info);
|
||||
|
||||
out:
|
||||
if (physdev)
|
||||
g_object_unref (physdev);
|
||||
g_free (key);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -91,7 +91,7 @@ G_DEFINE_TYPE (MMPluginBaseSupportsTask, mm_plugin_base_supports_task, G_TYPE_OB
|
||||
typedef struct {
|
||||
MMPluginBase *plugin;
|
||||
GUdevDevice *port;
|
||||
GUdevDevice *physdev;
|
||||
char *physdev_path;
|
||||
char *driver;
|
||||
|
||||
guint open_id;
|
||||
@@ -119,7 +119,7 @@ typedef struct {
|
||||
static MMPluginBaseSupportsTask *
|
||||
supports_task_new (MMPluginBase *self,
|
||||
GUdevDevice *port,
|
||||
GUdevDevice *physdev,
|
||||
const char *physdev_path,
|
||||
const char *driver,
|
||||
MMSupportsPortResultFunc callback,
|
||||
gpointer callback_data)
|
||||
@@ -130,7 +130,7 @@ supports_task_new (MMPluginBase *self,
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
g_return_val_if_fail (MM_IS_PLUGIN_BASE (self), NULL);
|
||||
g_return_val_if_fail (port != NULL, NULL);
|
||||
g_return_val_if_fail (physdev != NULL, NULL);
|
||||
g_return_val_if_fail (physdev_path != NULL, NULL);
|
||||
g_return_val_if_fail (driver != NULL, NULL);
|
||||
g_return_val_if_fail (callback != NULL, NULL);
|
||||
|
||||
@@ -139,7 +139,7 @@ supports_task_new (MMPluginBase *self,
|
||||
priv = MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task);
|
||||
priv->plugin = self;
|
||||
priv->port = g_object_ref (port);
|
||||
priv->physdev = g_object_ref (physdev);
|
||||
priv->physdev_path = g_strdup (physdev_path);
|
||||
priv->driver = g_strdup (driver);
|
||||
priv->callback = callback;
|
||||
priv->callback_data = callback_data;
|
||||
@@ -165,13 +165,13 @@ mm_plugin_base_supports_task_get_port (MMPluginBaseSupportsTask *task)
|
||||
return MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task)->port;
|
||||
}
|
||||
|
||||
GUdevDevice *
|
||||
mm_plugin_base_supports_task_get_physdev (MMPluginBaseSupportsTask *task)
|
||||
const char *
|
||||
mm_plugin_base_supports_task_get_physdev_path (MMPluginBaseSupportsTask *task)
|
||||
{
|
||||
g_return_val_if_fail (task != NULL, NULL);
|
||||
g_return_val_if_fail (MM_IS_PLUGIN_BASE_SUPPORTS_TASK (task), NULL);
|
||||
|
||||
return MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task)->physdev;
|
||||
return MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task)->physdev_path;
|
||||
}
|
||||
|
||||
const char *
|
||||
@@ -255,7 +255,7 @@ supports_task_dispose (GObject *object)
|
||||
mm_serial_port_flash_cancel (MM_SERIAL_PORT (priv->probe_port));
|
||||
|
||||
g_object_unref (priv->port);
|
||||
g_object_unref (priv->physdev);
|
||||
g_free (priv->physdev_path);
|
||||
g_free (priv->driver);
|
||||
g_free (priv->probe_resp);
|
||||
g_clear_error (&(priv->probe_error));
|
||||
@@ -1037,58 +1037,21 @@ get_driver_name (GUdevDevice *device)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static GUdevDevice *
|
||||
real_find_physical_device (MMPluginBase *plugin, GUdevDevice *child)
|
||||
{
|
||||
GUdevDevice *iter, *old = NULL;
|
||||
GUdevDevice *physdev = NULL;
|
||||
const char *subsys, *type;
|
||||
guint32 i = 0;
|
||||
gboolean is_usb = FALSE, is_pci = FALSE;
|
||||
|
||||
g_return_val_if_fail (child != NULL, NULL);
|
||||
|
||||
iter = g_object_ref (child);
|
||||
while (iter && i++ < 8) {
|
||||
subsys = g_udev_device_get_subsystem (iter);
|
||||
if (subsys) {
|
||||
if (is_usb || !strcmp (subsys, "usb")) {
|
||||
is_usb = TRUE;
|
||||
type = g_udev_device_get_devtype (iter);
|
||||
if (type && !strcmp (type, "usb_device")) {
|
||||
physdev = iter;
|
||||
break;
|
||||
}
|
||||
} else if (is_pci || !strcmp (subsys, "pci")) {
|
||||
is_pci = TRUE;
|
||||
physdev = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
old = iter;
|
||||
iter = g_udev_device_get_parent (old);
|
||||
g_object_unref (old);
|
||||
}
|
||||
|
||||
return physdev;
|
||||
}
|
||||
|
||||
static MMPluginSupportsResult
|
||||
supports_port (MMPlugin *plugin,
|
||||
const char *subsys,
|
||||
const char *name,
|
||||
const char *physdev_path,
|
||||
MMSupportsPortResultFunc callback,
|
||||
gpointer callback_data)
|
||||
{
|
||||
MMPluginBase *self = MM_PLUGIN_BASE (plugin);
|
||||
MMPluginBasePrivate *priv = MM_PLUGIN_BASE_GET_PRIVATE (self);
|
||||
GUdevDevice *port = NULL, *physdev = NULL;
|
||||
GUdevDevice *port = NULL;
|
||||
char *driver = NULL, *key = NULL;
|
||||
MMPluginBaseSupportsTask *task;
|
||||
MMPluginSupportsResult result = MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED;
|
||||
MMModem *existing;
|
||||
const char *master_path;
|
||||
|
||||
key = get_key (subsys, name);
|
||||
task = g_hash_table_lookup (priv->tasks, key);
|
||||
@@ -1101,21 +1064,16 @@ supports_port (MMPlugin *plugin,
|
||||
if (!port)
|
||||
goto out;
|
||||
|
||||
physdev = MM_PLUGIN_BASE_GET_CLASS (self)->find_physical_device (self, port);
|
||||
if (!physdev)
|
||||
goto out;
|
||||
|
||||
driver = get_driver_name (port);
|
||||
if (!driver)
|
||||
goto out;
|
||||
|
||||
task = supports_task_new (self, port, physdev, driver, callback, callback_data);
|
||||
task = supports_task_new (self, port, physdev_path, driver, callback, callback_data);
|
||||
g_assert (task);
|
||||
g_hash_table_insert (priv->tasks, g_strdup (key), g_object_ref (task));
|
||||
|
||||
/* Help the plugin out a bit by finding an existing modem for this port */
|
||||
master_path = g_udev_device_get_sysfs_path (physdev);
|
||||
existing = g_hash_table_lookup (priv->modems, master_path);
|
||||
existing = g_hash_table_lookup (priv->modems, physdev_path);
|
||||
|
||||
result = MM_PLUGIN_BASE_GET_CLASS (self)->supports_port (self, existing, task);
|
||||
if (result != MM_PLUGIN_SUPPORTS_PORT_IN_PROGRESS) {
|
||||
@@ -1127,8 +1085,6 @@ supports_port (MMPlugin *plugin,
|
||||
g_object_unref (task);
|
||||
|
||||
out:
|
||||
if (physdev)
|
||||
g_object_unref (physdev);
|
||||
if (port)
|
||||
g_object_unref (port);
|
||||
g_free (key);
|
||||
@@ -1169,7 +1125,7 @@ grab_port (MMPlugin *plugin,
|
||||
MMPluginBaseSupportsTask *task;
|
||||
char *key;
|
||||
MMModem *existing = NULL, *modem = NULL;
|
||||
const char *master_path;
|
||||
const char *physdev_path;
|
||||
|
||||
key = get_key (subsys, name);
|
||||
task = g_hash_table_lookup (priv->tasks, key);
|
||||
@@ -1179,13 +1135,13 @@ grab_port (MMPlugin *plugin,
|
||||
}
|
||||
|
||||
/* Help the plugin out a bit by finding an existing modem for this port */
|
||||
master_path = g_udev_device_get_sysfs_path (mm_plugin_base_supports_task_get_physdev (task));
|
||||
existing = g_hash_table_lookup (priv->modems, master_path);
|
||||
physdev_path = mm_plugin_base_supports_task_get_physdev_path (task);
|
||||
existing = g_hash_table_lookup (priv->modems, physdev_path);
|
||||
|
||||
/* Let the modem grab the port */
|
||||
modem = MM_PLUGIN_BASE_GET_CLASS (self)->grab_port (self, existing, task, error);
|
||||
if (modem && !existing) {
|
||||
g_hash_table_insert (priv->modems, g_strdup (master_path), modem);
|
||||
g_hash_table_insert (priv->modems, g_strdup (physdev_path), modem);
|
||||
g_object_weak_ref (G_OBJECT (modem), modem_destroyed, self);
|
||||
}
|
||||
|
||||
@@ -1277,7 +1233,6 @@ mm_plugin_base_class_init (MMPluginBaseClass *klass)
|
||||
|
||||
g_type_class_add_private (object_class, sizeof (MMPluginBasePrivate));
|
||||
|
||||
klass->find_physical_device = real_find_physical_device;
|
||||
klass->handle_probe_response = real_handle_probe_response;
|
||||
|
||||
/* Virtual methods */
|
||||
|
@@ -60,7 +60,7 @@ MMPlugin *mm_plugin_base_supports_task_get_plugin (MMPluginBaseSupportsTask *tas
|
||||
|
||||
GUdevDevice *mm_plugin_base_supports_task_get_port (MMPluginBaseSupportsTask *task);
|
||||
|
||||
GUdevDevice *mm_plugin_base_supports_task_get_physdev (MMPluginBaseSupportsTask *task);
|
||||
const char *mm_plugin_base_supports_task_get_physdev_path (MMPluginBaseSupportsTask *task);
|
||||
|
||||
const char *mm_plugin_base_supports_task_get_driver (MMPluginBaseSupportsTask *task);
|
||||
|
||||
@@ -108,13 +108,6 @@ struct _MMPluginBaseClass {
|
||||
void (*cancel_task) (MMPluginBase *plugin,
|
||||
MMPluginBaseSupportsTask *task);
|
||||
|
||||
/* Find a the physical device of a port, ie the USB or PCI or whatever
|
||||
* "master" device that owns the port. The GUdevDevice object returned
|
||||
* will be unref-ed by the caller.
|
||||
*/
|
||||
GUdevDevice * (*find_physical_device) (MMPluginBase *plugin,
|
||||
GUdevDevice *port);
|
||||
|
||||
void (*handle_probe_response) (MMPluginBase *plugin,
|
||||
MMPluginBaseSupportsTask *task,
|
||||
const char *command,
|
||||
|
@@ -28,15 +28,22 @@ MMPluginSupportsResult
|
||||
mm_plugin_supports_port (MMPlugin *plugin,
|
||||
const char *subsys,
|
||||
const char *name,
|
||||
const char *physdev_path,
|
||||
MMSupportsPortResultFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_return_val_if_fail (MM_IS_PLUGIN (plugin), FALSE);
|
||||
g_return_val_if_fail (subsys != NULL, FALSE);
|
||||
g_return_val_if_fail (name != NULL, FALSE);
|
||||
g_return_val_if_fail (physdev_path != NULL, FALSE);
|
||||
g_return_val_if_fail (callback != NULL, FALSE);
|
||||
|
||||
return MM_PLUGIN_GET_INTERFACE (plugin)->supports_port (plugin, subsys, name, callback, user_data);
|
||||
return MM_PLUGIN_GET_INTERFACE (plugin)->supports_port (plugin,
|
||||
subsys,
|
||||
name,
|
||||
physdev_path,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -70,6 +70,7 @@ struct _MMPlugin {
|
||||
MMPluginSupportsResult (*supports_port) (MMPlugin *self,
|
||||
const char *subsys,
|
||||
const char *name,
|
||||
const char *physdev_path,
|
||||
MMSupportsPortResultFunc callback,
|
||||
gpointer user_data);
|
||||
|
||||
@@ -104,6 +105,7 @@ const char *mm_plugin_get_name (MMPlugin *plugin);
|
||||
MMPluginSupportsResult mm_plugin_supports_port (MMPlugin *plugin,
|
||||
const char *subsys,
|
||||
const char *name,
|
||||
const char *physdev_path,
|
||||
MMSupportsPortResultFunc callback,
|
||||
gpointer user_data);
|
||||
|
||||
|
Reference in New Issue
Block a user