summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSzymon Janc <szymon.janc@tieto.com>2011-03-10 16:10:34 +0100
committerJohan Hedberg <johan.hedberg@nokia.com>2011-03-10 22:02:56 +0200
commitc77263675b971943225ed62adb368727d67d7a4f (patch)
tree1583ccbcb1e37884e18fd29e30f9399090a91831
parentf22c60eab61f73a798039e6227e47126ca9c5c67 (diff)
downloadbluez-c77263675b971943225ed62adb368727d67d7a4f.tar.gz
Fix unloading of adapter drivers
Call driver remove callback only if corresponding probe succeed.
-rw-r--r--src/adapter.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/src/adapter.c b/src/adapter.c
index b119fd19e..e8abf4213 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -144,6 +144,8 @@ struct btd_adapter {
GSList *powered_callbacks;
gboolean name_stored;
+
+ GSList *loaded_drivers;
};
static void adapter_set_pairable_timeout(struct btd_adapter *adapter,
@@ -2246,23 +2248,25 @@ static void probe_driver(struct btd_adapter *adapter, gpointer user_data)
if (!adapter->up)
return;
+ if (driver->probe == NULL)
+ return;
+
err = driver->probe(adapter);
- if (err < 0)
+ if (err < 0) {
error("%s: %s (%d)", driver->name, strerror(-err), -err);
+ return;
+ }
+
+ adapter->loaded_drivers = g_slist_prepend(adapter->loaded_drivers,
+ driver);
}
static void load_drivers(struct btd_adapter *adapter)
{
GSList *l;
- for (l = adapter_drivers; l; l = l->next) {
- struct btd_adapter_driver *driver = l->data;
-
- if (driver->probe == NULL)
- continue;
-
- probe_driver(adapter, driver);
- }
+ for (l = adapter_drivers; l; l = l->next)
+ probe_driver(adapter, l->data);
}
static void load_connections(struct btd_adapter *adapter)
@@ -2477,16 +2481,20 @@ static void reply_pending_requests(struct btd_adapter *adapter)
}
}
-static void unload_drivers(struct btd_adapter *adapter)
+static void remove_driver(gpointer data, gpointer user_data)
{
- GSList *l;
+ struct btd_adapter_driver *driver = data;
+ struct btd_adapter *adapter = user_data;
- for (l = adapter_drivers; l; l = l->next) {
- struct btd_adapter_driver *driver = l->data;
+ if (driver->remove)
+ driver->remove(adapter);
+}
- if (driver->remove)
- driver->remove(adapter);
- }
+static void unload_drivers(struct btd_adapter *adapter)
+{
+ g_slist_foreach(adapter->loaded_drivers, remove_driver, adapter);
+ g_slist_free(adapter->loaded_drivers);
+ adapter->loaded_drivers = NULL;
}
static void set_mode_complete(struct btd_adapter *adapter)
@@ -3326,9 +3334,16 @@ int btd_register_adapter_driver(struct btd_adapter_driver *driver)
return 0;
}
+static void unload_driver(struct btd_adapter *adapter, gpointer data)
+{
+ adapter->loaded_drivers = g_slist_remove(adapter->loaded_drivers, data);
+}
+
void btd_unregister_adapter_driver(struct btd_adapter_driver *driver)
{
adapter_drivers = g_slist_remove(adapter_drivers, driver);
+
+ manager_foreach_adapter(unload_driver, driver);
}
static void agent_auth_cb(struct agent *agent, DBusError *derr,