diff options
author | Aleksander Morgado <aleksandermj@chromium.org> | 2024-03-06 13:47:55 +0000 |
---|---|---|
committer | Aleksander Morgado <aleksandermj@chromium.org> | 2024-03-12 10:15:59 +0000 |
commit | bd255849dcdbcaa3280033b0974a6a5e0473566e (patch) | |
tree | 128d517534eb046d521d471233ffd3c4b390d285 /src | |
parent | 07f1f5864204dfdf455067def863fcd20c8c6a26 (diff) |
base-manager: reprobe device on late port additions
There is no guarantee from the kernel that the ports of a given device
will all be notified via uevents on a timely manner. We assume it, but
we cannot be completely sure.
There are two main scenarios that we have been seen when the ports of a
device are not notified close enough to each other:
* A modem object is created, but not with the desired control protocol.
E.g. a QMI or MBIM modem would end up controlled via AT commands if
the cdc-wdm port was added too late.
* A modem object is not created at all, and the device object was
removed completely. E.g. when the net port addition in a QMI or MBIM
modem happens too late.
In order to avoid those cases, we will now fully reprobe all the ports
of the device from scratch whenever a new valid port addition happens
after the initial probing of the device has already been completed. If a
modem object is available at that time, we will remove it right away.
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-base-manager.c | 230 | ||||
-rw-r--r-- | src/mm-device.c | 43 | ||||
-rw-r--r-- | src/mm-device.h | 20 | ||||
-rw-r--r-- | src/mm-plugin-manager.c | 101 | ||||
-rw-r--r-- | src/mm-plugin-manager.h | 8 | ||||
-rw-r--r-- | src/mm-port-probe.c | 35 | ||||
-rw-r--r-- | src/mm-port-probe.h | 5 |
7 files changed, 310 insertions, 132 deletions
diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c index eec4cd86..a2951d22 100644 --- a/src/mm-base-manager.c +++ b/src/mm-base-manager.c @@ -206,34 +206,31 @@ device_support_check_ready (MMPluginManager *plugin_manager, GAsyncResult *res, FindDeviceSupportContext *ctx) { - GError *error = NULL; - MMPlugin *plugin; + g_autoptr(GError) error = NULL; + g_autoptr(MMPlugin) plugin = NULL; /* If the device support check fails, either with an error, or afterwards - * when trying to create a modem object, we must remove the MMDevice from - * the tracking table of devices, so that a manual scan request afterwards - * re-scans all ports. */ + * when trying to create a modem object, we must reset the port probe list + * in the MMDevice, so that a manual scan request afterwards re-scans all + * ports. */ /* Receive plugin result from the plugin manager */ plugin = mm_plugin_manager_device_support_check_finish (plugin_manager, res, &error); if (!plugin) { mm_obj_msg (ctx->self, "couldn't check support for device '%s': %s", mm_device_get_uid (ctx->device), error->message); - g_error_free (error); - g_hash_table_remove (ctx->self->priv->devices, mm_device_get_uid (ctx->device)); + mm_device_reset_port_probe_list (ctx->device); find_device_support_context_free (ctx); return; } /* Set the plugin as the one expected in the device */ mm_device_set_plugin (ctx->device, G_OBJECT (plugin)); - g_object_unref (plugin); if (!mm_device_create_modem (ctx->device, &error)) { mm_obj_warn (ctx->self, "couldn't create modem for device '%s': %s", mm_device_get_uid (ctx->device), error->message); - g_error_free (error); - g_hash_table_remove (ctx->self->priv->devices, mm_device_get_uid (ctx->device)); + mm_device_reset_port_probe_list (ctx->device); find_device_support_context_free (ctx); return; } @@ -297,14 +294,175 @@ device_removed (MMBaseManager *self, } static void +device_support_check_add_all_ports (MMBaseManager *self, + MMDevice *device) +{ + FindDeviceSupportContext *ctx; + GList *l; + + g_assert (!mm_plugin_manager_device_support_check_ongoing (self->priv->plugin_manager, device)); + + /* There is no running device support context, so we launch a new one */ + ctx = g_slice_new (FindDeviceSupportContext); + ctx->self = g_object_ref (self); + ctx->device = g_object_ref (device); + mm_plugin_manager_device_support_check (self->priv->plugin_manager, + device, + (GAsyncReadyCallback) device_support_check_ready, + ctx); + + g_assert (mm_plugin_manager_device_support_check_ongoing (self->priv->plugin_manager, device)); + + /* Iterate all known ports and notify them one by one */ + for (l = mm_device_peek_port_probe_list (device); l; l = g_list_next (l)) { + mm_plugin_manager_device_support_check_add_port (self->priv->plugin_manager, + device, + mm_port_probe_peek_port (MM_PORT_PROBE (l->data))); + } +} + +static void +device_support_check_add_single_port (MMBaseManager *self, + MMDevice *device, + MMKernelDevice *port) +{ + FindDeviceSupportContext *ctx; + gboolean added; + + /* Try to add the port to an already running device support context */ + if (mm_plugin_manager_device_support_check_add_port (self->priv->plugin_manager, device, port)) + return; + + /* There is no running device support context, so we launch a new one */ + ctx = g_slice_new (FindDeviceSupportContext); + ctx->self = g_object_ref (self); + ctx->device = g_object_ref (device); + mm_plugin_manager_device_support_check (self->priv->plugin_manager, + device, + (GAsyncReadyCallback) device_support_check_ready, + ctx); + + /* Retry now, which should never fail */ + added = mm_plugin_manager_device_support_check_add_port (self->priv->plugin_manager, device, port); + g_assert (added); +} + +static void +existing_port (MMBaseManager *self, + MMDevice *device, + MMKernelDevice *port) +{ + const gchar *name; + const gchar *uid; + + name = mm_kernel_device_get_name (port); + uid = mm_device_get_uid (device); + + mm_obj_dbg (self, "port %s already available in device '%s'", name, uid); + + /* If the port exists already in the device, and we already have a valid modem + * object created, there is no point in processing this event, we can warn about + * the situation and bail out. This may happen e.g. if a manual scan is requested + * after having successfully finished the last probing operation. */ + if (mm_device_peek_plugin (device) && mm_device_peek_modem (device)) { + mm_obj_dbg (self, "ignoring port %s as device '%s' already has a valid modem", name, uid); + return; + } + + /* The port exists in the device, but we don't have a valid modem associated with + * it. This may happen if a manual scan is requested after having failed the last + * device probing operation. We need to relaunch a new device probing task, unless + * one is already running. */ + device_support_check_add_single_port (self, device, port); +} + +static void +additional_port (MMBaseManager *self, + MMDevice *device, + MMKernelDevice *port) +{ + MMBaseModem *modem; + const gchar *name; + const gchar *uid; + + name = mm_kernel_device_get_name (port); + uid = mm_device_get_uid (device); + + mm_obj_dbg (self, "additional port %s in device '%s'", name, uid); + + /* Do nothing if the device is ignoring the new port */ + if (!mm_device_grab_port (device, port)) + return; + + /* If there is an ongoing support check, we can add the single port right away */ + if (mm_plugin_manager_device_support_check_ongoing (self->priv->plugin_manager, device)) { + device_support_check_add_single_port (self, device, port); + return; + } + + mm_obj_warn (self, "additional port %s in device '%s' added after device probing has already finished", name, uid); + + /* If there is no plugin assigned in the device, it means the device probing had failed earlier, + * for example if none of the ports that were used for the device probing were usable control ports */ + if (!mm_device_peek_plugin (device)) { + g_assert (!mm_device_peek_modem (device)); + mm_obj_info (self, "last device '%s' probing had failed, will retry", uid); + device_support_check_add_all_ports (self, device); + return; + } + + /* If there is no modem object assigned to the device, it means the modem object creation had failed earlier, + * for example if a required port was missing (e.g. missing net port in a QMI or MBIM modem) */ + modem = mm_device_peek_modem (device); + if (!modem) { + mm_obj_info (self, "last modem object creation in device '%s' had failed, will retry", uid); + device_support_check_add_all_ports (self, device); + return; + } + + mm_obj_info (self, "last modem object creation in device '%s' succeeded, but we have a new port addition, will retry", uid); + g_cancellable_cancel (mm_base_modem_peek_cancellable (modem)); + mm_device_remove_modem (device); + device_support_check_add_all_ports (self, device); +} + +static void +first_port (MMBaseManager *self, + MMKernelDevice *port, + gboolean hotplugged) +{ + g_autoptr(MMDevice) device = NULL; + const gchar *name; + const gchar *uid; + const gchar *physdev; + + name = mm_kernel_device_get_name (port); + uid = mm_kernel_device_get_physdev_uid (port); + + mm_obj_dbg (self, "port %s is first in device '%s'", name, uid); + + physdev = mm_kernel_device_get_physdev_sysfs_path (port); + device = mm_device_new (uid, physdev, hotplugged, FALSE, self->priv->object_manager); + + /* If the device is ignoring the new port, discard the new device as well */ + if (!mm_device_grab_port (device, port)) { + mm_obj_dbg (self, "discarding device '%s' as the first port is not grabbed", uid); + return; + } + + /* Store the device */ + g_hash_table_insert (self->priv->devices, g_strdup (uid), g_steal_pointer (&device)); +} + +static void device_added (MMBaseManager *self, MMKernelDevice *port, gboolean hotplugged, gboolean manual_scan) { MMDevice *device; - const gchar *physdev_uid; const gchar *name; + const gchar *uid; g_return_if_fail (port != NULL); @@ -333,15 +491,15 @@ device_added (MMBaseManager *self, /* Get the port's physical device's uid. All ports of the same physical * device will share the same uid. */ - physdev_uid = mm_kernel_device_get_physdev_uid (port); - g_assert (physdev_uid); + uid = mm_kernel_device_get_physdev_uid (port); + g_assert (uid); /* If the device is inhibited, do nothing else */ - if (is_device_inhibited (self, physdev_uid)) { + if (is_device_inhibited (self, uid)) { /* Note: we will not report as hotplugged an inhibited device port * because we don't know what was done with the port out of our * context. */ - device_inhibited_track_port (self, physdev_uid, port, manual_scan); + device_inhibited_track_port (self, uid, port, manual_scan); return; } @@ -349,42 +507,22 @@ device_added (MMBaseManager *self, if (!mm_filter_port (self->priv->filter, port, manual_scan)) return; - /* If already added, ignore new event */ - if (find_device_by_port (self, port)) { - mm_obj_dbg (self, "port %s already added", name); + /* If the port is already added, don't add it again */ + device = find_device_by_port (self, port); + if (device) { + existing_port (self, device, port); return; } /* See if we already created an object to handle ports in this device */ - device = find_device_by_physdev_uid (self, physdev_uid); - if (!device) { - const gchar *physdev; - FindDeviceSupportContext *ctx; - - mm_obj_dbg (self, "port %s is first in device %s", name, physdev_uid); - - physdev = mm_kernel_device_get_physdev_sysfs_path (port); - - /* Keep the device listed in the Manager */ - device = mm_device_new (physdev_uid, physdev, hotplugged, FALSE, self->priv->object_manager); - g_hash_table_insert (self->priv->devices, - g_strdup (physdev_uid), - device); - - /* Launch device support check */ - ctx = g_slice_new (FindDeviceSupportContext); - ctx->self = g_object_ref (self); - ctx->device = g_object_ref (device); - mm_plugin_manager_device_support_check ( - self->priv->plugin_manager, - device, - (GAsyncReadyCallback) device_support_check_ready, - ctx); - } else - mm_obj_dbg (self, "additional port %s in device %s", name, physdev_uid); + device = find_device_by_physdev_uid (self, uid); + if (device) { + additional_port (self, device, port); + return; + } - /* Grab the port in the existing device. */ - mm_device_grab_port (device, port); + /* This is the first port in a new device */ + first_port (self, port, hotplugged); } #if defined WITH_QRTR diff --git a/src/mm-device.c b/src/mm-device.c index 3d98b4ba..e6bd36bb 100644 --- a/src/mm-device.c +++ b/src/mm-device.c @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details: * - * Copyright (C) 2012 Google, Inc. + * Copyright (C) 2012-2024 Google, Inc. */ #include <config.h> @@ -26,6 +26,7 @@ #include "mm-device.h" #include "mm-plugin.h" #include "mm-log-object.h" +#include "mm-daemon-enums-types.h" static void log_object_iface_init (MMLogObjectInterface *iface); @@ -46,7 +47,6 @@ enum { }; enum { - SIGNAL_PORT_GRABBED, SIGNAL_PORT_RELEASED, SIGNAL_LAST }; @@ -76,7 +76,8 @@ struct _MMDevicePrivate { /* Kernel drivers managing this device */ gchar **drivers; - /* Best plugin to manage this device */ + /* Best plugin to manage this device, only if the device probing + * has finished successfully. */ MMPlugin *plugin; /* Lists of port probes in the device */ @@ -213,7 +214,7 @@ add_port_driver (MMDevice *self, self->priv->drivers[n_items + 1] = NULL; } -void +gboolean mm_device_grab_port (MMDevice *self, MMKernelDevice *kernel_port) { @@ -221,22 +222,19 @@ mm_device_grab_port (MMDevice *self, MMKernelDevice *lower_port; if (mm_device_owns_port (self, kernel_port)) - return; + return TRUE; lower_port = mm_kernel_device_peek_lower_device (kernel_port); if (lower_port) { g_autoptr(GError) error = NULL; /* No port probing done, at this point this is not something we require - * as all the virtual instantiated ports are net devices. We also avoid - * emitting the PORT_GRABBED signal in the MMDevice, because that is - * exclusively linked to a port being added to the list of probes, which - * we don't do here. */ + * as all the virtual instantiated ports are net devices. */ if (self->priv->modem && !mm_base_modem_grab_link_port (self->priv->modem, kernel_port, &error)) mm_obj_dbg (self, "fully ignoring link port %s from now on: %s", mm_kernel_device_get_name (kernel_port), error->message); - return; + return FALSE; } if (!g_strcmp0 ("net", mm_kernel_device_get_subsystem (kernel_port)) && mm_kernel_device_get_wwandev_sysfs_path (kernel_port)) { @@ -256,7 +254,7 @@ mm_device_grab_port (MMDevice *self, mm_obj_dbg (self, "fully ignoring link port %s from now on: %s", mm_kernel_device_get_name (kernel_port), error->message); - return; + return FALSE; } } @@ -278,8 +276,7 @@ mm_device_grab_port (MMDevice *self, probe = mm_port_probe_new (self, kernel_port); self->priv->port_probes = g_list_prepend (self->priv->port_probes, probe); - /* Notify about the grabbed port */ - g_signal_emit (self, signals[SIGNAL_PORT_GRABBED], 0, kernel_port); + return TRUE; } void @@ -627,6 +624,17 @@ mm_device_peek_port_probe_list (MMDevice *self) return self->priv->port_probes; } +void +mm_device_reset_port_probe_list (MMDevice *self) +{ + GList *l; + + mm_obj_dbg (self, "port probe list reset..."); + for (l = self->priv->port_probes; l; l = g_list_next (l)) { + mm_port_probe_reset (MM_PORT_PROBE (l->data)); + } +} + gboolean mm_device_get_hotplugged (MMDevice *self) { @@ -981,15 +989,6 @@ mm_device_class_init (MMDeviceClass *klass) G_PARAM_READWRITE); g_object_class_install_property (object_class, PROP_INHIBITED, properties[PROP_INHIBITED]); - signals[SIGNAL_PORT_GRABBED] = - g_signal_new (MM_DEVICE_PORT_GRABBED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (MMDeviceClass, port_grabbed), - NULL, NULL, - g_cclosure_marshal_generic, - G_TYPE_NONE, 1, MM_TYPE_KERNEL_DEVICE); - signals[SIGNAL_PORT_RELEASED] = g_signal_new (MM_DEVICE_PORT_RELEASED, G_OBJECT_CLASS_TYPE (object_class), diff --git a/src/mm-device.h b/src/mm-device.h index f80d6adb..eb376974 100644 --- a/src/mm-device.h +++ b/src/mm-device.h @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details: * - * Copyright (C) 2012 Google, Inc. + * Copyright (C) 2012-2024 Google, Inc. */ #ifndef MM_DEVICE_H @@ -42,7 +42,6 @@ typedef struct _MMDevicePrivate MMDevicePrivate; #define MM_DEVICE_INHIBITED "inhibited" #define MM_DEVICE_OBJECT_MANAGER "object-manager" -#define MM_DEVICE_PORT_GRABBED "port-grabbed" #define MM_DEVICE_PORT_RELEASED "port-released" struct _MMDevice { @@ -54,8 +53,6 @@ struct _MMDeviceClass { GObjectClass parent; /* signals */ - void (* port_grabbed) (MMDevice *self, - MMKernelDevice *port); void (* port_released) (MMDevice *self, MMKernelDevice *port); }; @@ -69,7 +66,7 @@ MMDevice *mm_device_new (const gchar *uid, gboolean virtual, GDBusObjectManagerServer *object_manager); -void mm_device_grab_port (MMDevice *self, +gboolean mm_device_grab_port (MMDevice *self, MMKernelDevice *kernel_port); gboolean mm_device_owns_port (MMDevice *self, MMKernelDevice *kernel_port); @@ -96,7 +93,6 @@ gboolean mm_device_inhibit_finish (MMDevice *self, gboolean mm_device_uninhibit (MMDevice *self, GError **error); - const gchar *mm_device_get_uid (MMDevice *self); const gchar *mm_device_get_physdev (MMDevice *self); const gchar **mm_device_get_drivers (MMDevice *self); @@ -109,14 +105,16 @@ GObject *mm_device_peek_plugin (MMDevice *self); GObject *mm_device_get_plugin (MMDevice *self); MMBaseModem *mm_device_peek_modem (MMDevice *self); MMBaseModem *mm_device_get_modem (MMDevice *self); -GObject *mm_device_peek_port_probe (MMDevice *self, - MMKernelDevice *kernel_port); -GObject *mm_device_get_port_probe (MMDevice *self, - MMKernelDevice *kernel_port); -GList *mm_device_peek_port_probe_list (MMDevice *self); gboolean mm_device_get_hotplugged (MMDevice *self); gboolean mm_device_get_inhibited (MMDevice *self); +GObject *mm_device_peek_port_probe (MMDevice *self, + MMKernelDevice *kernel_port); +GObject *mm_device_get_port_probe (MMDevice *self, + MMKernelDevice *kernel_port); +GList *mm_device_peek_port_probe_list (MMDevice *self); +void mm_device_reset_port_probe_list (MMDevice *self); + /* For testing purposes */ void mm_device_virtual_grab_ports (MMDevice *self, const gchar **ports); diff --git a/src/mm-plugin-manager.c b/src/mm-plugin-manager.c index c2438664..0179e5d0 100644 --- a/src/mm-plugin-manager.c +++ b/src/mm-plugin-manager.c @@ -784,10 +784,9 @@ struct _DeviceContext { * is reset to 0. */ guint extra_probing_time_id; - /* Signal connection ids for the grabbed/released signals from the device. - * These are the signals that will give us notifications of what ports are - * available (or suddenly unavailable) in the device. */ - gulong grabbed_id; + /* Signal connection ids for the released signal from the device. This is a + * signal that will give us notifications of ports suddenly unavailable in + * the device. */ gulong released_id; /* Port support check contexts being run */ @@ -800,7 +799,6 @@ device_context_unref (DeviceContext *device_context) if (g_atomic_int_dec_and_test (&device_context->ref_count)) { /* When the last reference is gone there must be no source scheduled and no * pending port tasks. */ - g_assert (!device_context->grabbed_id); g_assert (!device_context->released_id); g_assert (!device_context->min_wait_time_id); g_assert (!device_context->min_probing_time_id); @@ -898,18 +896,13 @@ device_context_complete (DeviceContext *device_context) /* Steal the task from the context */ g_assert (device_context->task); - task = device_context->task; - device_context->task = NULL; + task = g_steal_pointer (&device_context->task); /* Log about the time required to complete the checks */ mm_obj_dbg (self, "task %s: finished in '%lf' seconds", device_context->name, g_timer_elapsed (device_context->timer, NULL)); /* Remove signal handlers */ - if (device_context->grabbed_id) { - g_signal_handler_disconnect (device_context->device, device_context->grabbed_id); - device_context->grabbed_id = 0; - } if (device_context->released_id) { g_signal_handler_disconnect (device_context->device, device_context->released_id); device_context->released_id = 0; @@ -1276,16 +1269,13 @@ device_context_port_released (DeviceContext *device_context, } static void -device_context_port_grabbed (DeviceContext *device_context, - MMKernelDevice *port) +device_context_port_added (MMPluginManager *self, + DeviceContext *device_context, + MMKernelDevice *port) { - MMPluginManager *self; - PortContext *port_context; - - /* Recover plugin manager */ - self = MM_PLUGIN_MANAGER (device_context->self); + PortContext *port_context; - mm_obj_dbg (self, "task %s: port grabbed: %s", + mm_obj_dbg (self, "task %s: port added: %s", device_context->name, mm_kernel_device_get_name (port)); /* Ignore if for any reason we still have it in the running list */ @@ -1311,7 +1301,7 @@ device_context_port_grabbed (DeviceContext *device_context, (GSourceFunc) device_context_extra_probing_time_elapsed, device_context); - /* Setup a new port context for the newly grabbed port */ + /* Setup a new port context for the newly added port */ port_context = port_context_new (self, device_context->name, device_context->device, @@ -1332,7 +1322,7 @@ device_context_port_grabbed (DeviceContext *device_context, /* Store the port reference in the list within the device */ device_context->port_contexts = g_list_prepend (device_context->port_contexts, port_context) ; - /* If the port has been grabbed after the min wait timeout expired, launch + /* If the port has been added after the min wait timeout expired, launch * probing directly */ device_context_run_port_context (device_context, port_context); } @@ -1394,17 +1384,12 @@ device_context_run (MMPluginManager *self, gpointer user_data) { g_assert (!device_context->task); - g_assert (!device_context->grabbed_id); g_assert (!device_context->released_id); g_assert (!device_context->min_wait_time_id); g_assert (!device_context->min_probing_time_id); g_assert (!device_context->extra_probing_time_id); - /* Connect to device port grabbed/released notifications from the device */ - device_context->grabbed_id = g_signal_connect_swapped (device_context->device, - MM_DEVICE_PORT_GRABBED, - G_CALLBACK (device_context_port_grabbed), - device_context); + /* Connect to device port released notifications from the device */ device_context->released_id = g_signal_connect_swapped (device_context->device, MM_DEVICE_PORT_RELEASED, G_CALLBACK (device_context_port_released), @@ -1507,21 +1492,6 @@ plugin_manager_peek_device_context (MMPluginManager *self, return NULL; } -gboolean -mm_plugin_manager_device_support_check_cancel (MMPluginManager *self, - MMDevice *device) -{ - DeviceContext *device_context; - - /* If the device context isn't found, ignore the cancellation request. */ - device_context = plugin_manager_peek_device_context (self, device); - if (!device_context) - return FALSE; - - /* Request cancellation, will be completed asynchronously */ - return device_context_cancel (device_context); -} - static void device_context_run_ready (MMPluginManager *self, GAsyncResult *res, @@ -1599,6 +1569,53 @@ mm_plugin_manager_device_support_check (MMPluginManager *self, } /*****************************************************************************/ +/* Cancel the ongoing device support check, if any */ + +gboolean +mm_plugin_manager_device_support_check_cancel (MMPluginManager *self, + MMDevice *device) +{ + DeviceContext *device_context; + + /* If the device context isn't found, ignore the cancellation request. */ + device_context = plugin_manager_peek_device_context (self, device); + if (!device_context) + return FALSE; + + /* Request cancellation, will be completed asynchronously */ + return device_context_cancel (device_context); +} + +/*****************************************************************************/ +/* Ask if there is an ongoing device support check */ + +gboolean +mm_plugin_manager_device_support_check_ongoing (MMPluginManager *self, + MMDevice *device) +{ + return !!plugin_manager_peek_device_context (self, device); +} + +/*****************************************************************************/ +/* Report a new port to the ongoing device support check */ + +gboolean +mm_plugin_manager_device_support_check_add_port (MMPluginManager *self, + MMDevice *device, + MMKernelDevice *port) +{ + DeviceContext *device_context; + + device_context = plugin_manager_peek_device_context (self, device); + if (device_context) { + device_context_port_added (self, device_context, port); + return TRUE; + } + + return FALSE; +} + +/*****************************************************************************/ /* Look for plugin */ MMPlugin * diff --git a/src/mm-plugin-manager.h b/src/mm-plugin-manager.h index f1ddcc29..41a2d405 100644 --- a/src/mm-plugin-manager.h +++ b/src/mm-plugin-manager.h @@ -67,6 +67,14 @@ gboolean mm_plugin_manager_device_support_check_cancel (MMPluginManager MMPlugin * mm_plugin_manager_device_support_check_finish (MMPluginManager *self, GAsyncResult *res, GError **error); + +gboolean mm_plugin_manager_device_support_check_ongoing (MMPluginManager *self, + MMDevice *device); + +gboolean mm_plugin_manager_device_support_check_add_port (MMPluginManager *self, + MMDevice *device, + MMKernelDevice *port); + MMPlugin *mm_plugin_manager_peek_plugin (MMPluginManager *self, const gchar *plugin_name); const gchar **mm_plugin_manager_get_subsystems (MMPluginManager *self); diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c index 548b5bdc..5b4f7927 100644 --- a/src/mm-port-probe.c +++ b/src/mm-port-probe.c @@ -86,6 +86,15 @@ struct _MMPortProbePrivate { MMDevice *device; MMKernelDevice *port; + /* From udev tags */ + gboolean is_ignored; + gboolean is_gps; + gboolean is_audio; + gboolean maybe_at; + gboolean maybe_qcdm; + gboolean maybe_qmi; + gboolean maybe_mbim; + /* Probing results */ guint32 flags; gboolean is_at; @@ -97,20 +106,28 @@ struct _MMPortProbePrivate { gboolean is_qmi; gboolean is_mbim; - /* From udev tags */ - gboolean is_ignored; - gboolean is_gps; - gboolean is_audio; - gboolean maybe_at; - gboolean maybe_qcdm; - gboolean maybe_qmi; - gboolean maybe_mbim; - /* Current probing task. Only one can be available at a time */ GTask *task; }; /*****************************************************************************/ + +void +mm_port_probe_reset (MMPortProbe *self) +{ + g_assert (!self->priv->task); + self->priv->flags = 0; + self->priv->is_at = FALSE; + self->priv->is_qcdm = FALSE; + g_clear_pointer (&self->priv->vendor, g_free); + g_clear_pointer (&self->priv->product, g_free); + self->priv->is_icera = FALSE; + self->priv->is_xmm = FALSE; + self->priv->is_qmi = FALSE; + self->priv->is_mbim = FALSE; +} + +/*****************************************************************************/ /* Probe task completions. * Always make sure that the stored task is NULL when the task is completed. */ diff --git a/src/mm-port-probe.h b/src/mm-port-probe.h index 5dd56a8f..faa3a12c 100644 --- a/src/mm-port-probe.h +++ b/src/mm-port-probe.h @@ -81,8 +81,9 @@ typedef gboolean (* MMPortProbeAtCustomInitFinish) (MMPortProbe *probe, GType mm_port_probe_get_type (void); G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMPortProbe, g_object_unref) -MMPortProbe *mm_port_probe_new (MMDevice *device, - MMKernelDevice *port); +MMPortProbe *mm_port_probe_new (MMDevice *device, + MMKernelDevice *port); +void mm_port_probe_reset (MMPortProbe *self); MMDevice *mm_port_probe_peek_device (MMPortProbe *self); MMDevice *mm_port_probe_get_device (MMPortProbe *self); |