Bluetooth: hci_sync: Convert MGMT_OP_SET_CONNECTABLE to use cmd_sync
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Fri, 12 Nov 2021 00:48:43 +0000 (16:48 -0800)
committerMarcel Holtmann <marcel@holtmann.org>
Tue, 16 Nov 2021 14:13:34 +0000 (15:13 +0100)
This makes MGMT_OP_SET_CONNEABLE use hci_cmd_sync_queue instead of
use a dedicated connetable_update work.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
include/net/bluetooth/hci_core.h
include/net/bluetooth/hci_sync.h
net/bluetooth/hci_request.c
net/bluetooth/hci_sync.c
net/bluetooth/mgmt.c

index 5f57ff8..acb46ae 100644 (file)
@@ -495,7 +495,6 @@ struct hci_dev {
        struct work_struct      discov_update;
        struct work_struct      bg_scan_update;
        struct work_struct      scan_update;
-       struct work_struct      connectable_update;
        struct delayed_work     le_scan_disable;
        struct delayed_work     le_scan_restart;
 
@@ -1826,7 +1825,6 @@ void mgmt_new_conn_param(struct hci_dev *hdev, bdaddr_t *bdaddr,
                         u16 max_interval, u16 latency, u16 timeout);
 void mgmt_smp_complete(struct hci_conn *conn, bool complete);
 bool mgmt_get_connectable(struct hci_dev *hdev);
-void mgmt_set_connectable_complete(struct hci_dev *hdev, u8 status);
 u8 mgmt_get_adv_discov_flags(struct hci_dev *hdev);
 void mgmt_advertising_added(struct sock *sk, struct hci_dev *hdev,
                            u8 instance);
index d335c0c..0336c1b 100644 (file)
@@ -93,6 +93,8 @@ int hci_set_powered_sync(struct hci_dev *hdev, u8 val);
 int hci_update_discoverable_sync(struct hci_dev *hdev);
 int hci_update_discoverable(struct hci_dev *hdev);
 
+int hci_update_connectable_sync(struct hci_dev *hdev);
+
 int hci_start_discovery_sync(struct hci_dev *hdev);
 int hci_stop_discovery_sync(struct hci_dev *hdev);
 
index 9f355d8..98bf425 100644 (file)
@@ -1987,47 +1987,6 @@ static void scan_update_work(struct work_struct *work)
        hci_req_sync(hdev, update_scan, 0, HCI_CMD_TIMEOUT, NULL);
 }
 
-static int connectable_update(struct hci_request *req, unsigned long opt)
-{
-       struct hci_dev *hdev = req->hdev;
-
-       hci_dev_lock(hdev);
-
-       __hci_req_update_scan(req);
-
-       /* If BR/EDR is not enabled and we disable advertising as a
-        * by-product of disabling connectable, we need to update the
-        * advertising flags.
-        */
-       if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
-               __hci_req_update_adv_data(req, hdev->cur_adv_instance);
-
-       /* Update the advertising parameters if necessary */
-       if (hci_dev_test_flag(hdev, HCI_ADVERTISING) ||
-           !list_empty(&hdev->adv_instances)) {
-               if (ext_adv_capable(hdev))
-                       __hci_req_start_ext_adv(req, hdev->cur_adv_instance);
-               else
-                       __hci_req_enable_advertising(req);
-       }
-
-       __hci_update_background_scan(req);
-
-       hci_dev_unlock(hdev);
-
-       return 0;
-}
-
-static void connectable_update_work(struct work_struct *work)
-{
-       struct hci_dev *hdev = container_of(work, struct hci_dev,
-                                           connectable_update);
-       u8 status;
-
-       hci_req_sync(hdev, connectable_update, 0, HCI_CMD_TIMEOUT, &status);
-       mgmt_set_connectable_complete(hdev, status);
-}
-
 static u8 get_service_classes(struct hci_dev *hdev)
 {
        struct bt_uuid *uuid;
@@ -2841,7 +2800,6 @@ void hci_request_setup(struct hci_dev *hdev)
        INIT_WORK(&hdev->discov_update, discov_update);
        INIT_WORK(&hdev->bg_scan_update, bg_scan_update);
        INIT_WORK(&hdev->scan_update, scan_update_work);
-       INIT_WORK(&hdev->connectable_update, connectable_update_work);
        INIT_DELAYED_WORK(&hdev->discov_off, discov_off);
        INIT_DELAYED_WORK(&hdev->le_scan_disable, le_scan_disable_work);
        INIT_DELAYED_WORK(&hdev->le_scan_restart, le_scan_restart_work);
@@ -2856,7 +2814,6 @@ void hci_request_cancel_all(struct hci_dev *hdev)
        cancel_work_sync(&hdev->discov_update);
        cancel_work_sync(&hdev->bg_scan_update);
        cancel_work_sync(&hdev->scan_update);
-       cancel_work_sync(&hdev->connectable_update);
        cancel_delayed_work_sync(&hdev->discov_off);
        cancel_delayed_work_sync(&hdev->le_scan_disable);
        cancel_delayed_work_sync(&hdev->le_scan_restart);
index 7be9f8a..ad86caf 100644 (file)
@@ -4480,6 +4480,37 @@ int hci_update_discoverable(struct hci_dev *hdev)
        return 0;
 }
 
+int hci_update_connectable_sync(struct hci_dev *hdev)
+{
+       int err;
+
+       err = hci_update_scan_sync(hdev);
+       if (err)
+               return err;
+
+       /* If BR/EDR is not enabled and we disable advertising as a
+        * by-product of disabling connectable, we need to update the
+        * advertising flags.
+        */
+       if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
+               err = hci_update_adv_data_sync(hdev, hdev->cur_adv_instance);
+
+       /* Update the advertising parameters if necessary */
+       if (hci_dev_test_flag(hdev, HCI_ADVERTISING) ||
+           !list_empty(&hdev->adv_instances)) {
+               if (ext_adv_capable(hdev))
+                       err = hci_start_ext_adv_sync(hdev,
+                                                    hdev->cur_adv_instance);
+               else
+                       err = hci_enable_advertising_sync(hdev);
+
+               if (err)
+                       return err;
+       }
+
+       return hci_update_passive_scan_sync(hdev);
+}
+
 static int hci_inquiry_sync(struct hci_dev *hdev, u8 length)
 {
        const u8 giac[3] = { 0x33, 0x8b, 0x9e };
index 2697e1e..f8f74d3 100644 (file)
@@ -1537,31 +1537,26 @@ failed:
        return err;
 }
 
-void mgmt_set_connectable_complete(struct hci_dev *hdev, u8 status)
+static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data,
+                                         int err)
 {
-       struct mgmt_pending_cmd *cmd;
+       struct mgmt_pending_cmd *cmd = data;
 
-       bt_dev_dbg(hdev, "status 0x%02x", status);
+       bt_dev_dbg(hdev, "err %d", err);
 
        hci_dev_lock(hdev);
 
-       cmd = pending_find(MGMT_OP_SET_CONNECTABLE, hdev);
-       if (!cmd)
-               goto unlock;
-
-       if (status) {
-               u8 mgmt_err = mgmt_status(status);
+       if (err) {
+               u8 mgmt_err = mgmt_status(err);
                mgmt_cmd_status(cmd->sk, cmd->index, cmd->opcode, mgmt_err);
-               goto remove_cmd;
+               goto done;
        }
 
        send_settings_rsp(cmd->sk, MGMT_OP_SET_CONNECTABLE, hdev);
        new_settings(hdev, cmd->sk);
 
-remove_cmd:
-       mgmt_pending_remove(cmd);
-
-unlock:
+done:
+       mgmt_pending_free(cmd);
        hci_dev_unlock(hdev);
 }
 
@@ -1594,6 +1589,13 @@ static int set_connectable_update_settings(struct hci_dev *hdev,
        return 0;
 }
 
+static int set_connectable_sync(struct hci_dev *hdev, void *data)
+{
+       BT_DBG("%s", hdev->name);
+
+       return hci_update_connectable_sync(hdev);
+}
+
 static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
                           u16 len)
 {
@@ -1626,7 +1628,7 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
                goto failed;
        }
 
-       cmd = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, hdev, data, len);
+       cmd = mgmt_pending_new(sk, MGMT_OP_SET_CONNECTABLE, hdev, data, len);
        if (!cmd) {
                err = -ENOMEM;
                goto failed;
@@ -1643,8 +1645,8 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data,
                hci_dev_clear_flag(hdev, HCI_CONNECTABLE);
        }
 
-       queue_work(hdev->req_workqueue, &hdev->connectable_update);
-       err = 0;
+       err = hci_cmd_sync_queue(hdev, set_connectable_sync, cmd,
+                                mgmt_set_connectable_complete);
 
 failed:
        hci_dev_unlock(hdev);