Bluetooth: Move hci_abort_conn to hci_conn.c
authorBrian Gix <brian.gix@intel.com>
Tue, 16 Aug 2022 16:41:20 +0000 (09:41 -0700)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Wed, 31 Aug 2022 22:45:56 +0000 (15:45 -0700)
hci_abort_conn() is a wrapper around a number of DISCONNECT and
CREATE_CONN_CANCEL commands that was being invoked from hci_request
request queues, which are now deprecated. There are two versions:
hci_abort_conn() which can be invoked from the hci_event thread, and
hci_abort_conn_sync() which can be invoked within a hci_sync cmd chain.

Signed-off-by: Brian Gix <brian.gix@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
include/net/bluetooth/hci_core.h
net/bluetooth/hci_conn.c
net/bluetooth/hci_request.c
net/bluetooth/hci_request.h
net/bluetooth/mgmt.c

index e7862903187d856f501cc5b5abdf8659814d2af2..932153e688645e57d59e5f4209ab4d107e29ae12 100644 (file)
@@ -2075,6 +2075,7 @@ int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip);
 void mgmt_adv_monitor_device_lost(struct hci_dev *hdev, u16 handle,
                                  bdaddr_t *bdaddr, u8 addr_type);
 
+int hci_abort_conn(struct hci_conn *conn, u8 reason);
 u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
                      u16 to_multiplier);
 void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
index 337e74d0f8b1b8fc24677058266d766a97efdb43..7a59c44870503ee12d37f64b8428b5c5cc7c4a69 100644 (file)
@@ -2760,3 +2760,79 @@ u32 hci_conn_get_phy(struct hci_conn *conn)
 
        return phys;
 }
+
+int hci_abort_conn(struct hci_conn *conn, u8 reason)
+{
+       int r = 0;
+
+       switch (conn->state) {
+       case BT_CONNECTED:
+       case BT_CONFIG:
+               if (conn->type == AMP_LINK) {
+                       struct hci_cp_disconn_phy_link cp;
+
+                       cp.phy_handle = HCI_PHY_HANDLE(conn->handle);
+                       cp.reason = reason;
+                       r = hci_send_cmd(conn->hdev, HCI_OP_DISCONN_PHY_LINK,
+                                        sizeof(cp), &cp);
+               } else {
+                       struct hci_cp_disconnect dc;
+
+                       dc.handle = cpu_to_le16(conn->handle);
+                       dc.reason = reason;
+                       r = hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT,
+                                        sizeof(dc), &dc);
+               }
+
+               conn->state = BT_DISCONN;
+
+               break;
+       case BT_CONNECT:
+               if (conn->type == LE_LINK) {
+                       if (test_bit(HCI_CONN_SCANNING, &conn->flags))
+                               break;
+                       r = hci_send_cmd(conn->hdev,
+                                        HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL);
+               } else if (conn->type == ACL_LINK) {
+                       if (conn->hdev->hci_ver < BLUETOOTH_VER_1_2)
+                               break;
+                       r = hci_send_cmd(conn->hdev,
+                                        HCI_OP_CREATE_CONN_CANCEL,
+                                        6, &conn->dst);
+               }
+               break;
+       case BT_CONNECT2:
+               if (conn->type == ACL_LINK) {
+                       struct hci_cp_reject_conn_req rej;
+
+                       bacpy(&rej.bdaddr, &conn->dst);
+                       rej.reason = reason;
+
+                       r = hci_send_cmd(conn->hdev,
+                                        HCI_OP_REJECT_CONN_REQ,
+                                        sizeof(rej), &rej);
+               } else if (conn->type == SCO_LINK || conn->type == ESCO_LINK) {
+                       struct hci_cp_reject_sync_conn_req rej;
+
+                       bacpy(&rej.bdaddr, &conn->dst);
+
+                       /* SCO rejection has its own limited set of
+                        * allowed error values (0x0D-0x0F) which isn't
+                        * compatible with most values passed to this
+                        * function. To be safe hard-code one of the
+                        * values that's suitable for SCO.
+                        */
+                       rej.reason = HCI_ERROR_REJ_LIMITED_RESOURCES;
+
+                       r = hci_send_cmd(conn->hdev,
+                                        HCI_OP_REJECT_SYNC_CONN_REQ,
+                                        sizeof(rej), &rej);
+               }
+               break;
+       default:
+               conn->state = BT_CLOSED;
+               break;
+       }
+
+       return r;
+}
index 2e19a271d7a1c338b9c2972e4fee172969ebcd81..5a0296a4352eff79e49c86cd5bdf7ddafb16dfab 100644 (file)
@@ -909,99 +909,6 @@ static void set_random_addr(struct hci_request *req, bdaddr_t *rpa)
        hci_req_add(req, HCI_OP_LE_SET_RANDOM_ADDR, 6, rpa);
 }
 
-static void __hci_abort_conn(struct hci_request *req, struct hci_conn *conn,
-                            u8 reason)
-{
-       switch (conn->state) {
-       case BT_CONNECTED:
-       case BT_CONFIG:
-               if (conn->type == AMP_LINK) {
-                       struct hci_cp_disconn_phy_link cp;
-
-                       cp.phy_handle = HCI_PHY_HANDLE(conn->handle);
-                       cp.reason = reason;
-                       hci_req_add(req, HCI_OP_DISCONN_PHY_LINK, sizeof(cp),
-                                   &cp);
-               } else {
-                       struct hci_cp_disconnect dc;
-
-                       dc.handle = cpu_to_le16(conn->handle);
-                       dc.reason = reason;
-                       hci_req_add(req, HCI_OP_DISCONNECT, sizeof(dc), &dc);
-               }
-
-               conn->state = BT_DISCONN;
-
-               break;
-       case BT_CONNECT:
-               if (conn->type == LE_LINK) {
-                       if (test_bit(HCI_CONN_SCANNING, &conn->flags))
-                               break;
-                       hci_req_add(req, HCI_OP_LE_CREATE_CONN_CANCEL,
-                                   0, NULL);
-               } else if (conn->type == ACL_LINK) {
-                       if (req->hdev->hci_ver < BLUETOOTH_VER_1_2)
-                               break;
-                       hci_req_add(req, HCI_OP_CREATE_CONN_CANCEL,
-                                   6, &conn->dst);
-               }
-               break;
-       case BT_CONNECT2:
-               if (conn->type == ACL_LINK) {
-                       struct hci_cp_reject_conn_req rej;
-
-                       bacpy(&rej.bdaddr, &conn->dst);
-                       rej.reason = reason;
-
-                       hci_req_add(req, HCI_OP_REJECT_CONN_REQ,
-                                   sizeof(rej), &rej);
-               } else if (conn->type == SCO_LINK || conn->type == ESCO_LINK) {
-                       struct hci_cp_reject_sync_conn_req rej;
-
-                       bacpy(&rej.bdaddr, &conn->dst);
-
-                       /* SCO rejection has its own limited set of
-                        * allowed error values (0x0D-0x0F) which isn't
-                        * compatible with most values passed to this
-                        * function. To be safe hard-code one of the
-                        * values that's suitable for SCO.
-                        */
-                       rej.reason = HCI_ERROR_REJ_LIMITED_RESOURCES;
-
-                       hci_req_add(req, HCI_OP_REJECT_SYNC_CONN_REQ,
-                                   sizeof(rej), &rej);
-               }
-               break;
-       default:
-               conn->state = BT_CLOSED;
-               break;
-       }
-}
-
-static void abort_conn_complete(struct hci_dev *hdev, u8 status, u16 opcode)
-{
-       if (status)
-               bt_dev_dbg(hdev, "Failed to abort connection: status 0x%2.2x", status);
-}
-
-int hci_abort_conn(struct hci_conn *conn, u8 reason)
-{
-       struct hci_request req;
-       int err;
-
-       hci_req_init(&req, conn->hdev);
-
-       __hci_abort_conn(&req, conn, reason);
-
-       err = hci_req_run(&req, abort_conn_complete);
-       if (err && err != -ENODATA) {
-               bt_dev_err(conn->hdev, "failed to run HCI request: err %d", err);
-               return err;
-       }
-
-       return 0;
-}
-
 void hci_request_setup(struct hci_dev *hdev)
 {
        INIT_DELAYED_WORK(&hdev->interleave_scan, interleave_scan_work);
index 7e1de871fca4fdd3201190d346c67523c8643974..b9c5a98238374cccb4a59fbc3d41c7c465db1afd 100644 (file)
@@ -73,6 +73,5 @@ void hci_req_add_le_passive_scan(struct hci_request *req);
 
 void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next);
 
-int hci_abort_conn(struct hci_conn *conn, u8 reason);
 void hci_request_setup(struct hci_dev *hdev);
 void hci_request_cancel_all(struct hci_dev *hdev);
index 77e7aa63c0c08051f24a8ce8a76853837930405b..8d70f4a709d4eca23ffdffb2a11fd8c8ea606ee8 100644 (file)
@@ -3185,6 +3185,18 @@ unlock:
        return err;
 }
 
+static int abort_conn_sync(struct hci_dev *hdev, void *data)
+{
+       struct hci_conn *conn;
+       u16 handle = PTR_ERR(data);
+
+       conn = hci_conn_hash_lookup_handle(hdev, handle);
+       if (!conn)
+               return 0;
+
+       return hci_abort_conn_sync(hdev, conn, HCI_ERROR_REMOTE_USER_TERM);
+}
+
 static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
                              u16 len)
 {
@@ -3235,7 +3247,8 @@ static int cancel_pair_device(struct sock *sk, struct hci_dev *hdev, void *data,
                                              le_addr_type(addr->type));
 
        if (conn->conn_reason == CONN_REASON_PAIR_DEVICE)
-               hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
+               hci_cmd_sync_queue(hdev, abort_conn_sync, ERR_PTR(conn->handle),
+                                  NULL);
 
 unlock:
        hci_dev_unlock(hdev);