Bluetooth: hci_sync: Add helper functions to manipulate cmd_sync queue
This adds functions to queue, dequeue and lookup into the cmd_sync list. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
parent
5f641f03ab
commit
505ea2b295
@ -48,6 +48,18 @@ int hci_cmd_sync_submit(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
|
||||
void *data, hci_cmd_sync_work_destroy_t destroy);
|
||||
int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
|
||||
void *data, hci_cmd_sync_work_destroy_t destroy);
|
||||
struct hci_cmd_sync_work_entry *
|
||||
hci_cmd_sync_lookup_entry(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
|
||||
void *data, hci_cmd_sync_work_destroy_t destroy);
|
||||
int hci_cmd_sync_queue_once(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
|
||||
void *data, hci_cmd_sync_work_destroy_t destroy);
|
||||
void hci_cmd_sync_cancel_entry(struct hci_dev *hdev,
|
||||
struct hci_cmd_sync_work_entry *entry);
|
||||
bool hci_cmd_sync_dequeue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
|
||||
void *data, hci_cmd_sync_work_destroy_t destroy);
|
||||
bool hci_cmd_sync_dequeue_once(struct hci_dev *hdev,
|
||||
hci_cmd_sync_work_func_t func, void *data,
|
||||
hci_cmd_sync_work_destroy_t destroy);
|
||||
|
||||
int hci_update_eir_sync(struct hci_dev *hdev);
|
||||
int hci_update_class_sync(struct hci_dev *hdev);
|
||||
|
@ -566,6 +566,17 @@ void hci_cmd_sync_init(struct hci_dev *hdev)
|
||||
INIT_DELAYED_WORK(&hdev->adv_instance_expire, adv_timeout_expire);
|
||||
}
|
||||
|
||||
static void _hci_cmd_sync_cancel_entry(struct hci_dev *hdev,
|
||||
struct hci_cmd_sync_work_entry *entry,
|
||||
int err)
|
||||
{
|
||||
if (entry->destroy)
|
||||
entry->destroy(hdev, entry->data, err);
|
||||
|
||||
list_del(&entry->list);
|
||||
kfree(entry);
|
||||
}
|
||||
|
||||
void hci_cmd_sync_clear(struct hci_dev *hdev)
|
||||
{
|
||||
struct hci_cmd_sync_work_entry *entry, *tmp;
|
||||
@ -574,13 +585,8 @@ void hci_cmd_sync_clear(struct hci_dev *hdev)
|
||||
cancel_work_sync(&hdev->reenable_adv_work);
|
||||
|
||||
mutex_lock(&hdev->cmd_sync_work_lock);
|
||||
list_for_each_entry_safe(entry, tmp, &hdev->cmd_sync_work_list, list) {
|
||||
if (entry->destroy)
|
||||
entry->destroy(hdev, entry->data, -ECANCELED);
|
||||
|
||||
list_del(&entry->list);
|
||||
kfree(entry);
|
||||
}
|
||||
list_for_each_entry_safe(entry, tmp, &hdev->cmd_sync_work_list, list)
|
||||
_hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
|
||||
mutex_unlock(&hdev->cmd_sync_work_lock);
|
||||
}
|
||||
|
||||
@ -669,6 +675,115 @@ int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
|
||||
}
|
||||
EXPORT_SYMBOL(hci_cmd_sync_queue);
|
||||
|
||||
static struct hci_cmd_sync_work_entry *
|
||||
_hci_cmd_sync_lookup_entry(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
|
||||
void *data, hci_cmd_sync_work_destroy_t destroy)
|
||||
{
|
||||
struct hci_cmd_sync_work_entry *entry, *tmp;
|
||||
|
||||
list_for_each_entry_safe(entry, tmp, &hdev->cmd_sync_work_list, list) {
|
||||
if (func && entry->func != func)
|
||||
continue;
|
||||
|
||||
if (data && entry->data != data)
|
||||
continue;
|
||||
|
||||
if (destroy && entry->destroy != destroy)
|
||||
continue;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Queue HCI command entry once:
|
||||
*
|
||||
* - Lookup if an entry already exist and only if it doesn't creates a new entry
|
||||
* and queue it.
|
||||
*/
|
||||
int hci_cmd_sync_queue_once(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
|
||||
void *data, hci_cmd_sync_work_destroy_t destroy)
|
||||
{
|
||||
if (hci_cmd_sync_lookup_entry(hdev, func, data, destroy))
|
||||
return 0;
|
||||
|
||||
return hci_cmd_sync_queue(hdev, func, data, destroy);
|
||||
}
|
||||
EXPORT_SYMBOL(hci_cmd_sync_queue_once);
|
||||
|
||||
/* Lookup HCI command entry:
|
||||
*
|
||||
* - Return first entry that matches by function callback or data or
|
||||
* destroy callback.
|
||||
*/
|
||||
struct hci_cmd_sync_work_entry *
|
||||
hci_cmd_sync_lookup_entry(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
|
||||
void *data, hci_cmd_sync_work_destroy_t destroy)
|
||||
{
|
||||
struct hci_cmd_sync_work_entry *entry;
|
||||
|
||||
mutex_lock(&hdev->cmd_sync_work_lock);
|
||||
entry = _hci_cmd_sync_lookup_entry(hdev, func, data, destroy);
|
||||
mutex_unlock(&hdev->cmd_sync_work_lock);
|
||||
|
||||
return entry;
|
||||
}
|
||||
EXPORT_SYMBOL(hci_cmd_sync_lookup_entry);
|
||||
|
||||
/* Cancel HCI command entry */
|
||||
void hci_cmd_sync_cancel_entry(struct hci_dev *hdev,
|
||||
struct hci_cmd_sync_work_entry *entry)
|
||||
{
|
||||
mutex_lock(&hdev->cmd_sync_work_lock);
|
||||
_hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
|
||||
mutex_unlock(&hdev->cmd_sync_work_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(hci_cmd_sync_cancel_entry);
|
||||
|
||||
/* Dequeue one HCI command entry:
|
||||
*
|
||||
* - Lookup and cancel first entry that matches.
|
||||
*/
|
||||
bool hci_cmd_sync_dequeue_once(struct hci_dev *hdev,
|
||||
hci_cmd_sync_work_func_t func,
|
||||
void *data, hci_cmd_sync_work_destroy_t destroy)
|
||||
{
|
||||
struct hci_cmd_sync_work_entry *entry;
|
||||
|
||||
entry = hci_cmd_sync_lookup_entry(hdev, func, data, destroy);
|
||||
if (!entry)
|
||||
return false;
|
||||
|
||||
hci_cmd_sync_cancel_entry(hdev, entry);
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(hci_cmd_sync_dequeue_once);
|
||||
|
||||
/* Dequeue HCI command entry:
|
||||
*
|
||||
* - Lookup and cancel any entry that matches by function callback or data or
|
||||
* destroy callback.
|
||||
*/
|
||||
bool hci_cmd_sync_dequeue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
|
||||
void *data, hci_cmd_sync_work_destroy_t destroy)
|
||||
{
|
||||
struct hci_cmd_sync_work_entry *entry;
|
||||
bool ret = false;
|
||||
|
||||
mutex_lock(&hdev->cmd_sync_work_lock);
|
||||
while ((entry = _hci_cmd_sync_lookup_entry(hdev, func, data,
|
||||
destroy))) {
|
||||
_hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
|
||||
ret = true;
|
||||
}
|
||||
mutex_unlock(&hdev->cmd_sync_work_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(hci_cmd_sync_dequeue);
|
||||
|
||||
int hci_update_eir_sync(struct hci_dev *hdev)
|
||||
{
|
||||
struct hci_cp_write_eir cp;
|
||||
@ -2881,7 +2996,8 @@ int hci_update_passive_scan(struct hci_dev *hdev)
|
||||
hci_dev_test_flag(hdev, HCI_UNREGISTER))
|
||||
return 0;
|
||||
|
||||
return hci_cmd_sync_queue(hdev, update_passive_scan_sync, NULL, NULL);
|
||||
return hci_cmd_sync_queue_once(hdev, update_passive_scan_sync, NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int hci_write_sc_support_sync(struct hci_dev *hdev, u8 val)
|
||||
|
Loading…
Reference in New Issue
Block a user