mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-11-16 08:44:38 +08:00
Add support for multiple potential adapter_ops implementations
This patch changes the adapter_ops registration procedure to simply add the callback struct into a list. The actual adapter_ops implementation that gets used gets chosen in the adapter_ops_setup function.
This commit is contained in:
parent
f92841301d
commit
d300441574
@ -2341,7 +2341,7 @@ static struct btd_adapter_ops hci_ops = {
|
||||
|
||||
static int hciops_init(void)
|
||||
{
|
||||
return btd_register_adapter_ops(&hci_ops);
|
||||
return btd_register_adapter_ops(&hci_ops, FALSE);
|
||||
}
|
||||
static void hciops_exit(void)
|
||||
{
|
||||
|
@ -72,6 +72,8 @@
|
||||
static DBusConnection *connection = NULL;
|
||||
static GSList *adapter_drivers = NULL;
|
||||
|
||||
static GSList *ops_candidates = NULL;
|
||||
|
||||
const struct btd_adapter_ops *adapter_ops = NULL;
|
||||
|
||||
struct session_req {
|
||||
@ -3574,31 +3576,48 @@ int btd_adapter_switch_offline(struct btd_adapter *adapter)
|
||||
return adapter_ops->set_powered(adapter->dev_id, FALSE);
|
||||
}
|
||||
|
||||
int btd_register_adapter_ops(struct btd_adapter_ops *btd_adapter_ops)
|
||||
int btd_register_adapter_ops(struct btd_adapter_ops *ops, gboolean priority)
|
||||
{
|
||||
/* Already registered */
|
||||
if (adapter_ops)
|
||||
return -EALREADY;
|
||||
|
||||
if (btd_adapter_ops->setup == NULL)
|
||||
if (ops->setup == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
adapter_ops = btd_adapter_ops;
|
||||
if (priority)
|
||||
ops_candidates = g_slist_prepend(ops_candidates, ops);
|
||||
else
|
||||
ops_candidates = g_slist_append(ops_candidates, ops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void btd_adapter_cleanup_ops(struct btd_adapter_ops *btd_adapter_ops)
|
||||
void btd_adapter_cleanup_ops(struct btd_adapter_ops *ops)
|
||||
{
|
||||
adapter_ops->cleanup();
|
||||
ops_candidates = g_slist_remove(ops_candidates, ops);
|
||||
ops->cleanup();
|
||||
|
||||
if (adapter_ops == ops)
|
||||
adapter_ops = NULL;
|
||||
}
|
||||
|
||||
int adapter_ops_setup(void)
|
||||
{
|
||||
if (!adapter_ops)
|
||||
GSList *l;
|
||||
int ret;
|
||||
|
||||
if (!ops_candidates)
|
||||
return -EINVAL;
|
||||
|
||||
return adapter_ops->setup();
|
||||
for (l = ops_candidates; l != NULL; l = g_slist_next(l)) {
|
||||
struct btd_adapter_ops *ops = l->data;
|
||||
|
||||
ret = ops->setup();
|
||||
if (ret < 0)
|
||||
continue;
|
||||
|
||||
adapter_ops = ops;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void btd_adapter_register_powered_callback(struct btd_adapter *adapter,
|
||||
|
@ -233,7 +233,7 @@ struct btd_adapter_ops {
|
||||
gpointer user_data);
|
||||
};
|
||||
|
||||
int btd_register_adapter_ops(struct btd_adapter_ops *btd_adapter_ops);
|
||||
int btd_register_adapter_ops(struct btd_adapter_ops *ops, gboolean priority);
|
||||
void btd_adapter_cleanup_ops(struct btd_adapter_ops *btd_adapter_ops);
|
||||
int adapter_ops_setup(void);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user