summaryrefslogtreecommitdiff
path: root/net/bluetooth/hci_sync.c
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2023-06-27 03:25:06 +0300
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2023-08-11 21:42:15 +0300
commita13f316e90fdb1fb6df6582e845aa9b3270f3581 (patch)
tree214fc9ee8640cfb772df562f8baaec9ec9f78935 /net/bluetooth/hci_sync.c
parent0b70151328781a89c89e4cf3fae21fc0e98d869e (diff)
downloadlinux-a13f316e90fdb1fb6df6582e845aa9b3270f3581.tar.xz
Bluetooth: hci_conn: Consolidate code for aborting connections
This consolidates code for aborting connections using hci_cmd_sync_queue so it is synchronized with other threads, but because of the fact that some commands may block the cmd_sync_queue while waiting specific events this attempt to cancel those requests by using hci_cmd_sync_cancel. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Diffstat (limited to 'net/bluetooth/hci_sync.c')
-rw-r--r--net/bluetooth/hci_sync.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 73b49d0c1e11..5f7a901709b5 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -5274,22 +5274,27 @@ static int hci_disconnect_sync(struct hci_dev *hdev, struct hci_conn *conn,
}
static int hci_le_connect_cancel_sync(struct hci_dev *hdev,
- struct hci_conn *conn)
+ struct hci_conn *conn, u8 reason)
{
+ /* Return reason if scanning since the connection shall probably be
+ * cleanup directly.
+ */
if (test_bit(HCI_CONN_SCANNING, &conn->flags))
- return 0;
+ return reason;
- if (test_and_set_bit(HCI_CONN_CANCEL, &conn->flags))
+ if (conn->role == HCI_ROLE_SLAVE ||
+ test_and_set_bit(HCI_CONN_CANCEL, &conn->flags))
return 0;
return __hci_cmd_sync_status(hdev, HCI_OP_LE_CREATE_CONN_CANCEL,
0, NULL, HCI_CMD_TIMEOUT);
}
-static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn)
+static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn,
+ u8 reason)
{
if (conn->type == LE_LINK)
- return hci_le_connect_cancel_sync(hdev, conn);
+ return hci_le_connect_cancel_sync(hdev, conn, reason);
if (hdev->hci_ver < BLUETOOTH_VER_1_2)
return 0;
@@ -5342,9 +5347,11 @@ int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, u8 reason)
case BT_CONFIG:
return hci_disconnect_sync(hdev, conn, reason);
case BT_CONNECT:
- err = hci_connect_cancel_sync(hdev, conn);
+ err = hci_connect_cancel_sync(hdev, conn, reason);
/* Cleanup hci_conn object if it cannot be cancelled as it
- * likelly means the controller and host stack are out of sync.
+ * likelly means the controller and host stack are out of sync
+ * or in case of LE it was still scanning so it can be cleanup
+ * safely.
*/
if (err) {
hci_dev_lock(hdev);
@@ -6258,7 +6265,7 @@ int hci_le_create_conn_sync(struct hci_dev *hdev, struct hci_conn *conn)
done:
if (err == -ETIMEDOUT)
- hci_le_connect_cancel_sync(hdev, conn);
+ hci_le_connect_cancel_sync(hdev, conn, 0x00);
/* Re-enable advertising after the connection attempt is finished. */
hci_resume_advertising_sync(hdev);