Bluetooth: hci_sync: Add helper functions to manipulate cmd_sync queue
[ Upstream commit505ea2b295
] 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> Stable-dep-of:2e7ed5f5e6
("Bluetooth: hci_sync: Use advertised PHYs on hci_le_ext_create_conn_sync") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
7bb27cbb4b
commit
357603f4d3
|
@ -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);
|
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,
|
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);
|
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_eir_sync(struct hci_dev *hdev);
|
||||||
int hci_update_class_sync(struct hci_dev *hdev);
|
int hci_update_class_sync(struct hci_dev *hdev);
|
||||||
|
|
|
@ -570,6 +570,17 @@ void hci_cmd_sync_init(struct hci_dev *hdev)
|
||||||
INIT_DELAYED_WORK(&hdev->adv_instance_expire, adv_timeout_expire);
|
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)
|
void hci_cmd_sync_clear(struct hci_dev *hdev)
|
||||||
{
|
{
|
||||||
struct hci_cmd_sync_work_entry *entry, *tmp;
|
struct hci_cmd_sync_work_entry *entry, *tmp;
|
||||||
|
@ -578,13 +589,8 @@ void hci_cmd_sync_clear(struct hci_dev *hdev)
|
||||||
cancel_work_sync(&hdev->reenable_adv_work);
|
cancel_work_sync(&hdev->reenable_adv_work);
|
||||||
|
|
||||||
mutex_lock(&hdev->cmd_sync_work_lock);
|
mutex_lock(&hdev->cmd_sync_work_lock);
|
||||||
list_for_each_entry_safe(entry, tmp, &hdev->cmd_sync_work_list, list) {
|
list_for_each_entry_safe(entry, tmp, &hdev->cmd_sync_work_list, list)
|
||||||
if (entry->destroy)
|
_hci_cmd_sync_cancel_entry(hdev, entry, -ECANCELED);
|
||||||
entry->destroy(hdev, entry->data, -ECANCELED);
|
|
||||||
|
|
||||||
list_del(&entry->list);
|
|
||||||
kfree(entry);
|
|
||||||
}
|
|
||||||
mutex_unlock(&hdev->cmd_sync_work_lock);
|
mutex_unlock(&hdev->cmd_sync_work_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,6 +682,115 @@ int hci_cmd_sync_queue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(hci_cmd_sync_queue);
|
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)
|
int hci_update_eir_sync(struct hci_dev *hdev)
|
||||||
{
|
{
|
||||||
struct hci_cp_write_eir cp;
|
struct hci_cp_write_eir cp;
|
||||||
|
@ -2932,7 +3047,8 @@ int hci_update_passive_scan(struct hci_dev *hdev)
|
||||||
hci_dev_test_flag(hdev, HCI_UNREGISTER))
|
hci_dev_test_flag(hdev, HCI_UNREGISTER))
|
||||||
return 0;
|
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)
|
int hci_write_sc_support_sync(struct hci_dev *hdev, u8 val)
|
||||||
|
|
Loading…
Reference in New Issue