Make all providers and plugins share a GUsbContext

This means we don't have more that one thread just watching for the USB
hotplug events. To achieve this split up the coldplug into setup and coldplug
phases and run the enumerate just once in the daemon.
This commit is contained in:
Richard Hughes 2016-12-08 17:29:51 +00:00
parent e34654e17f
commit bc93e4ab6e
13 changed files with 213 additions and 66 deletions

View File

@ -38,8 +38,6 @@
#include "config.h"
#include <gusb.h>
#include "dfu-device-private.h"
#include "dfu-error.h"
#include "dfu-context.h"
@ -286,17 +284,23 @@ dfu_context_device_removed_cb (GUsbContext *usb_context,
g_timeout_add (priv->timeout, dfu_context_device_timeout_cb, item);
}
static void
dfu_context_set_usb_context (DfuContext *context, GUsbContext *usb_ctx)
{
DfuContextPrivate *priv = GET_PRIVATE (context);
priv->usb_ctx = g_object_ref (usb_ctx);
g_signal_connect (priv->usb_ctx, "device-added",
G_CALLBACK (dfu_context_device_added_cb), context);
g_signal_connect (priv->usb_ctx, "device-removed",
G_CALLBACK (dfu_context_device_removed_cb), context);
}
static void
dfu_context_init (DfuContext *context)
{
DfuContextPrivate *priv = GET_PRIVATE (context);
priv->timeout = 5000;
priv->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) dfu_context_device_free);
priv->usb_ctx = g_usb_context_new (NULL);
g_signal_connect (priv->usb_ctx, "device-added",
G_CALLBACK (dfu_context_device_added_cb), context);
g_signal_connect (priv->usb_ctx, "device-removed",
G_CALLBACK (dfu_context_device_removed_cb), context);
}
static void
@ -324,7 +328,29 @@ DfuContext *
dfu_context_new (void)
{
DfuContext *context;
g_autoptr(GUsbContext) usb_ctx = g_usb_context_new (NULL);
context = g_object_new (DFU_TYPE_CONTEXT, NULL);
dfu_context_set_usb_context (context, usb_ctx);
return context;
}
/**
* dfu_context_new_with_context:
* @context: a #DfuContext
*
* Creates a new DFU context object.
*
* Return value: a new #DfuContext
*
* Since: 0.7.6
**/
DfuContext *
dfu_context_new_with_context (GUsbContext *usb_ctx)
{
DfuContext *context;
g_return_val_if_fail (G_USB_IS_CONTEXT (usb_ctx), NULL);
context = g_object_new (DFU_TYPE_CONTEXT, NULL);
dfu_context_set_usb_context (context, usb_ctx);
return context;
}

View File

@ -24,6 +24,7 @@
#include <glib-object.h>
#include <gio/gio.h>
#include <gusb.h>
#include "dfu-device.h"
@ -55,6 +56,7 @@ struct _DfuContextClass
};
DfuContext *dfu_context_new (void);
DfuContext *dfu_context_new_with_context (GUsbContext *usb_ctx);
gboolean dfu_context_enumerate (DfuContext *context,
GError **error);
GPtrArray *dfu_context_get_devices (DfuContext *context);

View File

@ -71,6 +71,7 @@ typedef struct {
GDBusNodeInfo *introspection_daemon;
GDBusProxy *proxy_uid;
GDBusProxy *proxy_upower;
GUsbContext *usb_ctx;
GKeyFile *config;
GMainLoop *loop;
GPtrArray *devices; /* of FuDeviceItem */
@ -260,7 +261,7 @@ fu_main_invocation_return_error (FuMainPrivate *priv,
}
static gboolean
fu_main_load_plugins (GHashTable *plugins, GError **error)
fu_main_load_plugins (FuMainPrivate *priv, GError **error)
{
FuPlugin *plugin;
GModule *module;
@ -296,13 +297,14 @@ fu_main_load_plugins (GHashTable *plugins, GError **error)
g_warning ("plugin %s requires name", filename);
continue;
}
fu_plugin_set_usb_context (plugin, priv->usb_ctx);
/* add */
g_hash_table_insert (plugins, g_strdup (plugin->name), plugin);
g_hash_table_insert (priv->plugins, g_strdup (plugin->name), plugin);
}
/* start them all up */
values = g_hash_table_get_values (plugins);
values = g_hash_table_get_values (priv->plugins);
for (GList *l = values; l != NULL; l = l->next) {
plugin = FU_PLUGIN (l->data);
if (!fu_plugin_run_startup (plugin, error))
@ -2138,6 +2140,24 @@ fu_main_daemon_get_property (GDBusConnection *connection_, const gchar *sender,
return NULL;
}
static void
fu_main_providers_setup (FuMainPrivate *priv)
{
g_autoptr(AsProfileTask) ptask = NULL;
ptask = as_profile_start_literal (priv->profile, "FuMain:setup");
for (guint i = 0; i < priv->providers->len; i++) {
g_autoptr(GError) error = NULL;
g_autoptr(AsProfileTask) ptask2 = NULL;
FuProvider *provider = g_ptr_array_index (priv->providers, i);
ptask2 = as_profile_start (priv->profile,
"FuMain:setup{%s}",
fu_provider_get_name (provider));
if (!fu_provider_setup (FU_PROVIDER (provider), &error))
g_warning ("Failed to setup: %s", error->message);
}
}
static void
fu_main_providers_coldplug (FuMainPrivate *priv)
{
@ -2181,6 +2201,8 @@ fu_main_on_bus_acquired_cb (GDBusConnection *connection,
g_assert (registration_id > 0);
/* add devices */
fu_main_providers_setup (priv);
g_usb_context_enumerate (priv->usb_ctx);
fu_main_providers_coldplug (priv);
/* connect to D-Bus directly */
@ -2471,7 +2493,7 @@ main (int argc, char *argv[])
/* load plugin */
priv->plugins = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify) fu_plugin_free);
if (!fu_main_load_plugins (priv->plugins, &error)) {
if (!fu_main_load_plugins (priv, &error)) {
g_print ("failed to load plugins: %s\n", error->message);
retval = EXIT_FAILURE;
goto out;
@ -2519,6 +2541,18 @@ main (int argc, char *argv[])
/* last as least priority */
fu_main_add_provider (priv, fu_provider_usb_new ());
/* set shared USB context */
priv->usb_ctx = g_usb_context_new (&error);
if (priv->usb_ctx == NULL) {
g_warning ("FuMain: failed to get USB context: %s",
error->message);
goto out;
}
for (guint i = 0; i < priv->providers->len; i++) {
FuProvider *provider = g_ptr_array_index (priv->providers, i);
fu_provider_set_usb_context (provider, priv->usb_ctx);
}
/* load introspection from file */
priv->introspection_daemon = fu_main_load_introspection (FWUPD_DBUS_INTERFACE ".xml",
&error);
@ -2570,6 +2604,8 @@ out:
g_object_unref (priv->proxy_uid);
if (priv->proxy_upower != NULL)
g_object_unref (priv->proxy_upower);
if (priv->usb_ctx != NULL)
g_object_unref (priv->usb_ctx);
if (priv->config != NULL)
g_key_file_unref (priv->config);
if (priv->connection != NULL)

View File

@ -56,6 +56,18 @@ fu_plugin_new (GModule *module)
return plugin;
}
GUsbContext *
fu_plugin_get_usb_context (FuPlugin *plugin)
{
return g_object_ref (plugin->usb_ctx);
}
void
fu_plugin_set_usb_context (FuPlugin *plugin, GUsbContext *usb_ctx)
{
g_set_object (&plugin->usb_ctx, usb_ctx);
}
void
fu_plugin_free (FuPlugin *plugin)
{
@ -69,6 +81,8 @@ fu_plugin_free (FuPlugin *plugin)
}
/* deallocate */
if (plugin->usb_ctx != NULL)
g_object_unref (plugin->usb_ctx);
g_module_close (plugin->module);
g_free (plugin->name);
g_free (plugin->priv);

View File

@ -24,6 +24,7 @@
#include <glib-object.h>
#include <gmodule.h>
#include <gusb.h>
#include "fu-device.h"
@ -34,6 +35,7 @@ typedef struct FuPlugin FuPlugin;
struct FuPlugin {
GModule *module;
GUsbContext *usb_ctx;
gboolean enabled;
gchar *name;
FuPluginPrivate *priv;
@ -80,6 +82,9 @@ gboolean fu_plugin_run_device_update (FuPlugin *plugin,
FuDevice *device,
GBytes *data,
GError **error);
GUsbContext *fu_plugin_get_usb_context (FuPlugin *plugin);
void fu_plugin_set_usb_context (FuPlugin *plugin,
GUsbContext *usb_ctx);
G_END_DECLS

View File

@ -541,11 +541,17 @@ fu_provider_chug_device_removed_cb (GUsbContext *ctx,
}
static gboolean
fu_provider_chug_coldplug (FuProvider *provider, GError **error)
fu_provider_chug_setup (FuProvider *provider, GError **error)
{
FuProviderChug *provider_chug = FU_PROVIDER_CHUG (provider);
FuProviderChugPrivate *priv = GET_PRIVATE (provider_chug);
g_usb_context_enumerate (priv->usb_ctx);
priv->usb_ctx = fu_provider_get_usb_context (provider);
g_signal_connect (priv->usb_ctx, "device-added",
G_CALLBACK (fu_provider_chug_device_added_cb),
provider_chug);
g_signal_connect (priv->usb_ctx, "device-removed",
G_CALLBACK (fu_provider_chug_device_removed_cb),
provider_chug);
return TRUE;
}
@ -556,7 +562,7 @@ fu_provider_chug_class_init (FuProviderChugClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
provider_class->get_name = fu_provider_chug_get_name;
provider_class->coldplug = fu_provider_chug_coldplug;
provider_class->setup = fu_provider_chug_setup;
provider_class->update_online = fu_provider_chug_update;
provider_class->verify = fu_provider_chug_verify;
object_class->finalize = fu_provider_chug_finalize;
@ -568,14 +574,7 @@ fu_provider_chug_init (FuProviderChug *provider_chug)
FuProviderChugPrivate *priv = GET_PRIVATE (provider_chug);
priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify) fu_provider_chug_device_free);
priv->usb_ctx = g_usb_context_new (NULL);
priv->device_queue = ch_device_queue_new ();
g_signal_connect (priv->usb_ctx, "device-added",
G_CALLBACK (fu_provider_chug_device_added_cb),
provider_chug);
g_signal_connect (priv->usb_ctx, "device-removed",
G_CALLBACK (fu_provider_chug_device_removed_cb),
provider_chug);
}
static void

View File

@ -877,7 +877,7 @@ fu_provider_dell_detect_tpm (FuProvider *provider, GError **error)
}
static gboolean
fu_provider_dell_coldplug (FuProvider *provider, GError **error)
fu_provider_dell_setup (FuProvider *provider, GError **error)
{
FuProviderDell *provider_dell = FU_PROVIDER_DELL (provider);
FuProviderDellPrivate *priv = GET_PRIVATE (provider_dell);
@ -885,6 +885,15 @@ fu_provider_dell_coldplug (FuProvider *provider, GError **error)
gint uefi_supported = 0;
struct smbios_struct *de_table;
/* get USB */
priv->usb_ctx = fu_provider_get_usb_context (provider);
g_signal_connect (priv->usb_ctx, "device-added",
G_CALLBACK (fu_provider_dell_device_added_cb),
provider_dell);
g_signal_connect (priv->usb_ctx, "device-removed",
G_CALLBACK (fu_provider_dell_device_removed_cb),
provider_dell);
if (priv->fake_smbios) {
g_debug ("Dell: called with fake SMBIOS implementation. "
"We're ignoring test for SBMIOS table and ESRT. "
@ -924,14 +933,15 @@ fu_provider_dell_coldplug (FuProvider *provider, GError **error)
return FALSE;
}
return TRUE;
}
/* enumerate looking for a connected dock */
g_usb_context_enumerate (priv->usb_ctx);
static gboolean
fu_provider_dell_coldplug (FuProvider *provider, GError **error)
{
/* look for switchable TPM */
if (!fu_provider_dell_detect_tpm (provider, error))
g_debug ("Dell: No switchable TPM detected");
return TRUE;
}
@ -1009,7 +1019,7 @@ fu_provider_dell_update_offline (FuProvider *provider,
#endif
/* test the flash counter
* - devices with 0 left at coldplug aren't allowed offline updates
* - devices with 0 left at setup aren't allowed offline updates
* - devices greater than 0 should show a warning when near 0
*/
flashes_left = fu_device_get_flashes_left (device);
@ -1210,6 +1220,7 @@ fu_provider_dell_class_init (FuProviderDellClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
provider_class->get_name = fu_provider_dell_get_name;
provider_class->setup = fu_provider_dell_setup;
provider_class->coldplug = fu_provider_dell_coldplug;
provider_class->unlock = fu_provider_dell_unlock;
provider_class->update_offline = fu_provider_dell_update_offline;
@ -1225,13 +1236,6 @@ fu_provider_dell_init (FuProviderDell *provider_dell)
priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify) fu_provider_dell_device_free);
priv->usb_ctx = g_usb_context_new (NULL);
g_signal_connect (priv->usb_ctx, "device-added",
G_CALLBACK (fu_provider_dell_device_added_cb),
provider_dell);
g_signal_connect (priv->usb_ctx, "device-removed",
G_CALLBACK (fu_provider_dell_device_removed_cb),
provider_dell);
priv->fake_smbios = FALSE;
if (g_getenv ("FWUPD_DELL_FAKE_SMBIOS") != NULL)
priv->fake_smbios = TRUE;
@ -1244,7 +1248,8 @@ fu_provider_dell_finalize (GObject *object)
FuProviderDellPrivate *priv = GET_PRIVATE (provider_dell);
g_hash_table_unref (priv->devices);
g_object_unref (priv->usb_ctx);
if (priv->usb_ctx != NULL)
g_object_unref (priv->usb_ctx);
G_OBJECT_CLASS (fu_provider_dell_parent_class)->finalize (object);
}

View File

@ -205,11 +205,22 @@ fu_provider_dfu_device_removed_cb (DfuContext *ctx,
}
static gboolean
fu_provider_dfu_coldplug (FuProvider *provider, GError **error)
fu_provider_dfu_setup (FuProvider *provider, GError **error)
{
g_autoptr(GUsbContext) usb_ctx = NULL;
FuProviderDfu *provider_dfu = FU_PROVIDER_DFU (provider);
FuProviderDfuPrivate *priv = GET_PRIVATE (provider_dfu);
dfu_context_enumerate (priv->context, NULL);
usb_ctx = fu_provider_get_usb_context (provider);
priv->context = dfu_context_new_with_context (usb_ctx);
g_signal_connect (priv->context, "device-added",
G_CALLBACK (fu_provider_dfu_device_added_cb),
provider_dfu);
g_signal_connect (priv->context, "device-removed",
G_CALLBACK (fu_provider_dfu_device_removed_cb),
provider_dfu);
g_signal_connect (priv->context, "device-changed",
G_CALLBACK (fu_provider_dfu_device_changed_cb),
provider_dfu);
return TRUE;
}
@ -391,7 +402,7 @@ fu_provider_dfu_class_init (FuProviderDfuClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
provider_class->get_name = fu_provider_dfu_get_name;
provider_class->coldplug = fu_provider_dfu_coldplug;
provider_class->setup = fu_provider_dfu_setup;
provider_class->update_online = fu_provider_dfu_update;
provider_class->verify = fu_provider_dfu_verify;
object_class->finalize = fu_provider_dfu_finalize;
@ -403,16 +414,6 @@ fu_provider_dfu_init (FuProviderDfu *provider_dfu)
FuProviderDfuPrivate *priv = GET_PRIVATE (provider_dfu);
priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify) g_object_unref);
priv->context = dfu_context_new ();
g_signal_connect (priv->context, "device-added",
G_CALLBACK (fu_provider_dfu_device_added_cb),
provider_dfu);
g_signal_connect (priv->context, "device-removed",
G_CALLBACK (fu_provider_dfu_device_removed_cb),
provider_dfu);
g_signal_connect (priv->context, "device-changed",
G_CALLBACK (fu_provider_dfu_device_changed_cb),
provider_dfu);
}
static void

View File

@ -219,12 +219,26 @@ fu_provider_ebitdo_device_removed_cb (GUsbContext *ctx,
g_hash_table_remove (priv->devices, platform_id);
}
static gboolean
fu_provider_ebitdo_setup (FuProvider *provider, GError **error)
{
FuProviderEbitdo *provider_ebitdo = FU_PROVIDER_EBITDO (provider);
FuProviderEbitdoPrivate *priv = GET_PRIVATE (provider_ebitdo);
priv->usb_ctx = fu_provider_get_usb_context (provider);
g_signal_connect (priv->usb_ctx, "device-added",
G_CALLBACK (fu_provider_ebitdo_device_added_cb),
provider_ebitdo);
g_signal_connect (priv->usb_ctx, "device-removed",
G_CALLBACK (fu_provider_ebitdo_device_removed_cb),
provider_ebitdo);
return TRUE;
}
static gboolean
fu_provider_ebitdo_coldplug (FuProvider *provider, GError **error)
{
FuProviderEbitdo *provider_ebitdo = FU_PROVIDER_EBITDO (provider);
FuProviderEbitdoPrivate *priv = GET_PRIVATE (provider_ebitdo);
g_usb_context_enumerate (priv->usb_ctx);
priv->done_enumerate = TRUE;
return TRUE;
}
@ -236,6 +250,7 @@ fu_provider_ebitdo_class_init (FuProviderEbitdoClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
provider_class->get_name = fu_provider_ebitdo_get_name;
provider_class->setup = fu_provider_ebitdo_setup;
provider_class->coldplug = fu_provider_ebitdo_coldplug;
provider_class->update_online = fu_provider_ebitdo_update;
object_class->finalize = fu_provider_ebitdo_finalize;
@ -249,13 +264,6 @@ fu_provider_ebitdo_init (FuProviderEbitdo *provider_ebitdo)
g_free, (GDestroyNotify) g_object_unref);
priv->devices_runtime = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify) g_object_unref);
priv->usb_ctx = g_usb_context_new (NULL);
g_signal_connect (priv->usb_ctx, "device-added",
G_CALLBACK (fu_provider_ebitdo_device_added_cb),
provider_ebitdo);
g_signal_connect (priv->usb_ctx, "device-removed",
G_CALLBACK (fu_provider_ebitdo_device_removed_cb),
provider_ebitdo);
}
static void

View File

@ -200,12 +200,26 @@ fu_provider_usb_device_removed_cb (GUsbContext *ctx,
g_hash_table_remove (priv->devices, platform_id);
}
static gboolean
fu_provider_usb_setup (FuProvider *provider, GError **error)
{
FuProviderUsb *provider_usb = FU_PROVIDER_USB (provider);
FuProviderUsbPrivate *priv = GET_PRIVATE (provider_usb);
priv->usb_ctx = fu_provider_get_usb_context (provider);
g_signal_connect (priv->usb_ctx, "device-added",
G_CALLBACK (fu_provider_usb_device_added_cb),
provider_usb);
g_signal_connect (priv->usb_ctx, "device-removed",
G_CALLBACK (fu_provider_usb_device_removed_cb),
provider_usb);
return TRUE;
}
static gboolean
fu_provider_usb_coldplug (FuProvider *provider, GError **error)
{
FuProviderUsb *provider_usb = FU_PROVIDER_USB (provider);
FuProviderUsbPrivate *priv = GET_PRIVATE (provider_usb);
g_usb_context_enumerate (priv->usb_ctx);
priv->done_enumerate = TRUE;
return TRUE;
}
@ -217,6 +231,7 @@ fu_provider_usb_class_init (FuProviderUsbClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
provider_class->get_name = fu_provider_usb_get_name;
provider_class->setup = fu_provider_usb_setup;
provider_class->coldplug = fu_provider_usb_coldplug;
object_class->finalize = fu_provider_usb_finalize;
}
@ -227,13 +242,6 @@ fu_provider_usb_init (FuProviderUsb *provider_usb)
FuProviderUsbPrivate *priv = GET_PRIVATE (provider_usb);
priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, (GDestroyNotify) g_object_unref);
priv->usb_ctx = g_usb_context_new (NULL);
g_signal_connect (priv->usb_ctx, "device-added",
G_CALLBACK (fu_provider_usb_device_added_cb),
provider_usb);
g_signal_connect (priv->usb_ctx, "device-removed",
G_CALLBACK (fu_provider_usb_device_removed_cb),
provider_usb);
}
static void

View File

@ -34,6 +34,10 @@
#include "fu-plugin.h"
#include "fu-provider-uefi.h"
typedef struct {
GUsbContext *usb_ctx;
} FuProviderPrivate;
static void fu_provider_finalize (GObject *object);
enum {
@ -46,7 +50,8 @@ enum {
static guint signals[SIGNAL_LAST] = { 0 };
G_DEFINE_TYPE (FuProvider, fu_provider, G_TYPE_OBJECT)
G_DEFINE_TYPE_WITH_PRIVATE (FuProvider, fu_provider, G_TYPE_OBJECT)
#define GET_PRIVATE(o) (fu_provider_get_instance_private (o))
static gboolean
fu_provider_offline_invalidate (GError **error)
@ -92,6 +97,15 @@ fu_provider_offline_setup (GError **error)
return TRUE;
}
gboolean
fu_provider_setup (FuProvider *provider, GError **error)
{
FuProviderClass *klass = FU_PROVIDER_GET_CLASS (provider);
if (klass->setup != NULL)
return klass->setup (provider, error);
return TRUE;
}
gboolean
fu_provider_coldplug (FuProvider *provider, GError **error)
{
@ -425,6 +439,20 @@ fu_provider_get_checksum_type (FuProviderVerifyFlags flags)
return G_CHECKSUM_SHA1;
}
GUsbContext *
fu_provider_get_usb_context (FuProvider *provider)
{
FuProviderPrivate *priv = GET_PRIVATE (provider);
return g_object_ref (priv->usb_ctx);
}
void
fu_provider_set_usb_context (FuProvider *provider, GUsbContext *usb_ctx)
{
FuProviderPrivate *priv = GET_PRIVATE (provider);
g_set_object (&priv->usb_ctx, usb_ctx);
}
static void
fu_provider_class_init (FuProviderClass *klass)
{
@ -464,5 +492,11 @@ fu_provider_init (FuProvider *provider)
static void
fu_provider_finalize (GObject *object)
{
FuProvider *provider = FU_PROVIDER (object);
FuProviderPrivate *priv = GET_PRIVATE (provider);
if (priv->usb_ctx != NULL)
g_object_unref (priv->usb_ctx);
G_OBJECT_CLASS (fu_provider_parent_class)->finalize (object);
}

View File

@ -23,6 +23,7 @@
#define __FU_PROVIDER_H
#include <glib-object.h>
#include <gusb.h>
#include "fu-device.h"
#include "fu-plugin.h"
@ -45,6 +46,8 @@ struct _FuProviderClass
/* vfunc */
const gchar *(*get_name) (FuProvider *provider);
gboolean (*setup) (FuProvider *provider,
GError **error);
gboolean (*coldplug) (FuProvider *provider,
GError **error);
gboolean (*verify) (FuProvider *provider,
@ -93,6 +96,8 @@ void fu_provider_set_status (FuProvider *provider,
void fu_provider_set_percentage (FuProvider *provider,
guint percentage);
const gchar *fu_provider_get_name (FuProvider *provider);
gboolean fu_provider_setup (FuProvider *provider,
GError **error);
gboolean fu_provider_coldplug (FuProvider *provider,
GError **error);
gboolean fu_provider_update (FuProvider *provider,
@ -117,6 +122,10 @@ gboolean fu_provider_get_results (FuProvider *provider,
GError **error);
GChecksumType fu_provider_get_checksum_type (FuProviderVerifyFlags flags);
GUsbContext *fu_provider_get_usb_context (FuProvider *provider);
void fu_provider_set_usb_context (FuProvider *provider,
GUsbContext *usb_ctx);
G_END_DECLS
#endif /* __FU_PROVIDER_H */

View File

@ -49,7 +49,7 @@ fu_plugin_device_probe (FuPlugin *plugin, FuDevice *device, GError **error)
/* get version */
platform_id = fu_device_get_id (device);
usb_ctx = g_usb_context_new (NULL);
usb_ctx = fu_plugin_get_usb_context (plugin);
usb_device = g_usb_context_find_by_platform_id (usb_ctx,
platform_id,
error);