]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Bluetooth: hci_core: Rework hci_dev_do_reset() to use hci_sync functions
authorHeitor Alves de Siqueira <halves@igalia.com>
Tue, 26 May 2026 13:50:57 +0000 (10:50 -0300)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Thu, 28 May 2026 12:52:21 +0000 (08:52 -0400)
The current HCI reset function in hci_core.c duplicates most of the work
done by hci_dev_close_sync(), and doesn't handle LE, advertising or
discovery.

Instead of porting these to hci_dev_do_reset(), directly call the
close/open functions from hci_sync to reset the hdev. MGMT now notifies
when a user performs a reset.

Suggested-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Heitor Alves de Siqueira <halves@igalia.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
net/bluetooth/hci_core.c

index c46c1236ebfab4e64811f3cf8a2e69e2566844c8..28d7929dc593778913cfa6273da279f3f1f49e35 100644 (file)
@@ -539,46 +539,9 @@ static int hci_dev_do_reset(struct hci_dev *hdev)
 
        hci_req_sync_lock(hdev);
 
-       /* Drop queues */
-       skb_queue_purge(&hdev->rx_q);
-       skb_queue_purge(&hdev->cmd_q);
-
-       /* Cancel these to avoid queueing non-chained pending work */
-       hci_dev_set_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
-       /* Wait for
-        *
-        *    if (!hci_dev_test_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE))
-        *        queue_delayed_work(&hdev->{cmd,ncmd}_timer)
-        *
-        * inside RCU section to see the flag or complete scheduling.
-        */
-       synchronize_rcu();
-       /* Explicitly cancel works in case scheduled after setting the flag. */
-       cancel_delayed_work(&hdev->cmd_timer);
-       cancel_delayed_work(&hdev->ncmd_timer);
-
-       /* Avoid potential lockdep warnings from the *_flush() calls by
-        * ensuring the workqueue is empty up front.
-        */
-       drain_workqueue(hdev->workqueue);
-
-       hci_dev_lock(hdev);
-       hci_inquiry_cache_flush(hdev);
-       hci_conn_hash_flush(hdev);
-       hci_dev_unlock(hdev);
-
-       if (hdev->flush)
-               hdev->flush(hdev);
-
-       hci_dev_clear_flag(hdev, HCI_CMD_DRAIN_WORKQUEUE);
-
-       atomic_set(&hdev->cmd_cnt, 1);
-       hdev->acl_cnt = 0;
-       hdev->sco_cnt = 0;
-       hdev->le_cnt = 0;
-       hdev->iso_cnt = 0;
-
-       ret = hci_reset_sync(hdev);
+       ret = hci_dev_close_sync(hdev);
+       if (!ret)
+               ret = hci_dev_open_sync(hdev);
 
        hci_req_sync_unlock(hdev);
        return ret;