]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
Bluetooth: hci_sync: Introduce hci_cmd_sync_run/hci_cmd_sync_run_once
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Mon, 26 Aug 2024 19:47:30 +0000 (15:47 -0400)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 30 Aug 2024 21:56:34 +0000 (17:56 -0400)
This introduces hci_cmd_sync_run/hci_cmd_sync_run_once which acts like
hci_cmd_sync_queue/hci_cmd_sync_queue_once but runs immediately when
already on hdev->cmd_sync_work context.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
include/net/bluetooth/hci_sync.h
net/bluetooth/hci_sync.c

index 75e052909b5fbf9ac32e4831705950e6a25933fa..f3052cb252efddf2358fb0038d0201bcf11fb848 100644 (file)
@@ -73,6 +73,10 @@ 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);
 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);
+int hci_cmd_sync_run(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
+                    void *data, hci_cmd_sync_work_destroy_t destroy);
+int hci_cmd_sync_run_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 *
 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);
index e79cd40bd079df3848ebc04efa777b8b4d48373a..5533e6f561b3a30ec61d4e5a45120446d8d292c6 100644 (file)
@@ -112,7 +112,7 @@ static void hci_cmd_sync_add(struct hci_request *req, u16 opcode, u32 plen,
        skb_queue_tail(&req->cmd_q, skb);
 }
 
-static int hci_cmd_sync_run(struct hci_request *req)
+static int hci_req_sync_run(struct hci_request *req)
 {
        struct hci_dev *hdev = req->hdev;
        struct sk_buff *skb;
@@ -169,7 +169,7 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
 
        hdev->req_status = HCI_REQ_PEND;
 
-       err = hci_cmd_sync_run(&req);
+       err = hci_req_sync_run(&req);
        if (err < 0)
                return ERR_PTR(err);
 
@@ -782,6 +782,44 @@ int hci_cmd_sync_queue_once(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
 }
 EXPORT_SYMBOL(hci_cmd_sync_queue_once);
 
+/* Run HCI command:
+ *
+ * - hdev must be running
+ * - if on cmd_sync_work then run immediately otherwise queue
+ */
+int hci_cmd_sync_run(struct hci_dev *hdev, hci_cmd_sync_work_func_t func,
+                    void *data, hci_cmd_sync_work_destroy_t destroy)
+{
+       /* Only queue command if hdev is running which means it had been opened
+        * and is either on init phase or is already up.
+        */
+       if (!test_bit(HCI_RUNNING, &hdev->flags))
+               return -ENETDOWN;
+
+       /* If on cmd_sync_work then run immediately otherwise queue */
+       if (current_work() == &hdev->cmd_sync_work)
+               return func(hdev, data);
+
+       return hci_cmd_sync_submit(hdev, func, data, destroy);
+}
+EXPORT_SYMBOL(hci_cmd_sync_run);
+
+/* Run HCI command entry once:
+ *
+ * - Lookup if an entry already exist and only if it doesn't creates a new entry
+ *   and run it.
+ * - if on cmd_sync_work then run immediately otherwise queue
+ */
+int hci_cmd_sync_run_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_run(hdev, func, data, destroy);
+}
+EXPORT_SYMBOL(hci_cmd_sync_run_once);
+
 /* Lookup HCI command entry:
  *
  * - Return first entry that matches by function callback or data or