diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-base-manager.c | 104 | ||||
-rw-r--r-- | src/mm-device.c | 73 | ||||
-rw-r--r-- | src/mm-device.h | 21 |
3 files changed, 138 insertions, 60 deletions
diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c index 071d92e2..130e5ad1 100644 --- a/src/mm-base-manager.c +++ b/src/mm-base-manager.c @@ -137,6 +137,24 @@ find_device_by_port (MMBaseManager *manager, } static MMDevice * +find_device_by_port_name (MMBaseManager *manager, + const gchar *subsystem, + const gchar *name) +{ + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init (&iter, manager->priv->devices); + while (g_hash_table_iter_next (&iter, &key, &value)) { + MMDevice *candidate = MM_DEVICE (value); + + if (mm_device_owns_port_name (candidate, subsystem, name)) + return candidate; + } + return NULL; +} + +static MMDevice * find_device_by_physdev_uid (MMBaseManager *self, const gchar *physdev_uid) { @@ -208,24 +226,24 @@ static void device_inhibited_track_port (MMBaseManager *self, MMKernelDevice *port, gboolean manual_scan); static void device_inhibited_untrack_port (MMBaseManager *self, - MMKernelDevice *port); + const gchar *subsystem, + const gchar *name); static void -device_removed (MMBaseManager *self, - MMKernelDevice *kernel_device) +device_removed (MMBaseManager *self, + const gchar *subsystem, + const gchar *name) { - g_autoptr(MMDevice) device = NULL; - const gchar *name; - - g_return_if_fail (kernel_device != NULL); + g_autoptr(MMDevice) device = NULL; - device = find_device_by_port (self, kernel_device); + g_assert (subsystem && name); + device = find_device_by_port_name (self, subsystem, name); if (!device) { /* If the device was inhibited and the port is gone, untrack it. * This is only needed for ports that were tracked out of device objects. * In this case we don't rely on the physdev uid, as API-reported * remove kernel events may not include uid. */ - device_inhibited_untrack_port (self, kernel_device); + device_inhibited_untrack_port (self, subsystem, name); return; } @@ -236,9 +254,8 @@ device_removed (MMBaseManager *self, * ourselves. */ g_object_ref (device); - name = mm_kernel_device_get_name (kernel_device); mm_obj_info (self, "port %s released by device '%s'", name, mm_device_get_uid (device)); - mm_device_release_port (device, kernel_device); + mm_device_release_port_name (device, subsystem, name); /* If port probe list gets empty, remove the device object iself */ if (!mm_device_peek_port_probe_list (device)) { @@ -283,7 +300,7 @@ device_added (MMBaseManager *self, /* This could mean that device changed, losing its candidate * flags (such as Bluetooth RFCOMM devices upon disconnect. * Try to forget it. */ - device_removed (self, port); + device_removed (self, mm_kernel_device_get_subsystem (port), name); mm_obj_dbg (self, "port %s not candidate", name); return; } @@ -346,11 +363,10 @@ handle_kernel_event (MMBaseManager *self, MMKernelEventProperties *properties, GError **error) { - MMKernelDevice *kernel_device; - const gchar *action; - const gchar *subsystem; - const gchar *name; - const gchar *uid; + const gchar *action; + const gchar *subsystem; + const gchar *name; + const gchar *uid; action = mm_kernel_event_properties_get_action (properties); if (!action) { @@ -387,25 +403,27 @@ handle_kernel_event (MMBaseManager *self, mm_obj_dbg (self, " name: %s", name); mm_obj_dbg (self, " uid: %s", uid ? uid : "n/a"); + if (g_strcmp0 (action, "add") == 0) { + g_autoptr(MMKernelDevice) kernel_device = NULL; #if defined WITH_UDEV - if (!mm_context_get_test_no_udev ()) - kernel_device = mm_kernel_device_udev_new_from_properties (properties, error); - else + if (!mm_context_get_test_no_udev ()) + kernel_device = mm_kernel_device_udev_new_from_properties (properties, error); + else #endif - kernel_device = mm_kernel_device_generic_new (properties, error); - - if (!kernel_device) - return FALSE; + kernel_device = mm_kernel_device_generic_new (properties, error); + if (!kernel_device) + return FALSE; - if (g_strcmp0 (action, "add") == 0) device_added (self, kernel_device, TRUE, TRUE); - else if (g_strcmp0 (action, "remove") == 0) - device_removed (self, kernel_device); - else - g_assert_not_reached (); - g_object_unref (kernel_device); + return TRUE; + } - return TRUE; + if (g_strcmp0 (action, "remove") == 0) { + device_removed (self, subsystem, name); + return TRUE; + } + + g_assert_not_reached (); } #if defined WITH_UDEV @@ -415,13 +433,18 @@ handle_uevent (MMBaseManager *self, const gchar *action, GUdevDevice *device) { - g_autoptr(MMKernelDevice) kernel_device = NULL; + if (g_str_equal (action, "add") || g_str_equal (action, "move") || g_str_equal (action, "change")) { + g_autoptr(MMKernelDevice) kernel_device = NULL; - kernel_device = mm_kernel_device_udev_new (device); - if (g_str_equal (action, "add") || g_str_equal (action, "move") || g_str_equal (action, "change")) + kernel_device = mm_kernel_device_udev_new (device); device_added (self, kernel_device, TRUE, FALSE); - else if (g_str_equal (action, "remove")) - device_removed (self, kernel_device); + return; + } + + if (g_str_equal (action, "remove")) { + device_removed (self, g_udev_device_get_subsystem (device), g_udev_device_get_name (device)); + return; + } } typedef struct { @@ -886,7 +909,8 @@ is_device_inhibited (MMBaseManager *self, static void device_inhibited_untrack_port (MMBaseManager *self, - MMKernelDevice *kernel_port) + const gchar *subsystem, + const gchar *name) { GHashTableIter iter; gchar *uid; @@ -900,8 +924,10 @@ device_inhibited_untrack_port (MMBaseManager *self, InhibitedDevicePortInfo *port_info; port_info = (InhibitedDevicePortInfo *)(l->data); - if (mm_kernel_device_cmp (port_info->kernel_port, kernel_port)) { - mm_obj_dbg (self, "released port %s while inhibited", mm_kernel_device_get_name (kernel_port)); + + if ((g_strcmp0 (subsystem, mm_kernel_device_get_subsystem (port_info->kernel_port)) == 0) && + (g_strcmp0 (name, mm_kernel_device_get_name (port_info->kernel_port)) == 0)) { + mm_obj_dbg (self, "released port %s while inhibited", name); inhibited_device_port_info_free (port_info); info->port_infos = g_list_delete_link (info->port_infos, l); return; diff --git a/src/mm-device.c b/src/mm-device.c index a128d63e..ddd420fe 100644 --- a/src/mm-device.c +++ b/src/mm-device.c @@ -97,32 +97,56 @@ struct _MMDevicePrivate { /*****************************************************************************/ static MMPortProbe * -device_find_probe_with_device (MMDevice *self, - MMKernelDevice *kernel_port, - gboolean lookup_ignored) +probe_list_lookup_by_device (GList *port_probes, + MMKernelDevice *kernel_port) { GList *l; - for (l = self->priv->port_probes; l; l = g_list_next (l)) { + for (l = port_probes; l; l = g_list_next (l)) { MMPortProbe *probe = MM_PORT_PROBE (l->data); if (mm_kernel_device_cmp (mm_port_probe_peek_port (probe), kernel_port)) return probe; } + return NULL; +} - if (!lookup_ignored) - return NULL; +static MMPortProbe * +probe_list_lookup_by_name (GList *port_probes, + const gchar *subsystem, + const gchar *name) +{ + GList *l; - for (l = self->priv->ignored_port_probes; l; l = g_list_next (l)) { - MMPortProbe *probe = MM_PORT_PROBE (l->data); + for (l = port_probes; l; l = g_list_next (l)) { + MMPortProbe *probe = MM_PORT_PROBE (l->data); + MMKernelDevice *probe_device; - if (mm_kernel_device_cmp (mm_port_probe_peek_port (probe), kernel_port)) + probe_device = mm_port_probe_peek_port (probe); + if ((g_strcmp0 (subsystem, mm_kernel_device_get_subsystem (probe_device)) == 0) && + (g_strcmp0 (name, mm_kernel_device_get_name (probe_device)) == 0)) return probe; } - return NULL; } +static MMPortProbe * +device_find_probe_with_device (MMDevice *self, + MMKernelDevice *kernel_port, + gboolean lookup_ignored) +{ + MMPortProbe *probe; + + probe = probe_list_lookup_by_device (self->priv->port_probes, kernel_port); + if (probe) + return probe; + + if (!lookup_ignored) + return NULL; + + return probe_list_lookup_by_device (self->priv->ignored_port_probes, kernel_port); +} + gboolean mm_device_owns_port (MMDevice *self, MMKernelDevice *kernel_port) @@ -130,6 +154,28 @@ mm_device_owns_port (MMDevice *self, return !!device_find_probe_with_device (self, kernel_port, TRUE); } +static MMPortProbe * +device_find_probe_with_name (MMDevice *self, + const gchar *subsystem, + const gchar *name) +{ + MMPortProbe *probe; + + probe = probe_list_lookup_by_name (self->priv->port_probes, subsystem, name); + if (probe) + return probe; + + return probe_list_lookup_by_name (self->priv->ignored_port_probes, subsystem, name); +} + +gboolean +mm_device_owns_port_name (MMDevice *self, + const gchar *subsystem, + const gchar *name) +{ + return !!device_find_probe_with_name (self, subsystem, name); +} + static void add_port_driver (MMDevice *self, MMKernelDevice *kernel_port) @@ -190,12 +236,13 @@ mm_device_grab_port (MMDevice *self, } void -mm_device_release_port (MMDevice *self, - MMKernelDevice *kernel_port) +mm_device_release_port_name (MMDevice *self, + const gchar *subsystem, + const gchar *name) { MMPortProbe *probe; - probe = device_find_probe_with_device (self, kernel_port, TRUE); + probe = device_find_probe_with_name (self, subsystem, name); if (probe) { /* Found, remove from lists and destroy probe */ if (g_list_find (self->priv->port_probes, probe)) diff --git a/src/mm-device.h b/src/mm-device.h index d78a97c9..00d5977a 100644 --- a/src/mm-device.h +++ b/src/mm-device.h @@ -67,14 +67,19 @@ MMDevice *mm_device_new (const gchar *uid, gboolean virtual, GDBusObjectManagerServer *object_manager); -void mm_device_grab_port (MMDevice *self, - MMKernelDevice *kernel_port); -void mm_device_release_port (MMDevice *self, - MMKernelDevice *kernel_port); -gboolean mm_device_owns_port (MMDevice *self, - MMKernelDevice *kernel_port); -void mm_device_ignore_port (MMDevice *self, - MMKernelDevice *kernel_port); +void mm_device_grab_port (MMDevice *self, + MMKernelDevice *kernel_port); +gboolean mm_device_owns_port (MMDevice *self, + MMKernelDevice *kernel_port); +void mm_device_ignore_port (MMDevice *self, + MMKernelDevice *kernel_port); + +gboolean mm_device_owns_port_name (MMDevice *self, + const gchar *subsystem, + const gchar *name); +void mm_device_release_port_name (MMDevice *self, + const gchar *subsystem, + const gchar *name); gboolean mm_device_create_modem (MMDevice *self, GError **error); |