[PATCH v7 9/9] Bluetooth: Convert hci_abort_conn to hci_sync

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The prior hci_abort_conn() used the deprecated hci_request mechanism.
This version has been rewritten to use hci_sync.c

Signed-off-by: Brian Gix <brian.gix@xxxxxxxxx>
---
 include/net/bluetooth/hci_sync.h |   1 +
 net/bluetooth/hci_conn.c         |   6 +-
 net/bluetooth/hci_request.c      |  93 ----------------------
 net/bluetooth/hci_request.h      |   1 -
 net/bluetooth/hci_sync.c         | 130 +++++++++++++++++++++++++++++++
 net/bluetooth/mgmt.c             |   2 +-
 6 files changed, 135 insertions(+), 98 deletions(-)

diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
index 17f5a4c32f36..1816222c8fbc 100644
--- a/include/net/bluetooth/hci_sync.h
+++ b/include/net/bluetooth/hci_sync.h
@@ -129,3 +129,4 @@ int hci_le_terminate_big_sync(struct hci_dev *hdev, u8 handle, u8 reason);
 int hci_le_big_terminate_sync(struct hci_dev *hdev, u8 handle);
 
 int hci_le_pa_terminate_sync(struct hci_dev *hdev, u16 handle);
+int hci_abort_conn(struct hci_conn *conn, u8 reason, bool async);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 337e74d0f8b1..e61cb5aa3eb1 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -286,7 +286,7 @@ int hci_disconnect(struct hci_conn *conn, __u8 reason)
 			     &clkoff_cp);
 	}
 
-	return hci_abort_conn(conn, reason);
+	return hci_abort_conn(conn, reason, true);
 }
 
 static void hci_add_sco(struct hci_conn *conn, __u16 handle)
@@ -662,7 +662,7 @@ static void hci_conn_timeout(struct work_struct *work)
 		return;
 	}
 
-	hci_abort_conn(conn, hci_proto_disconn_ind(conn));
+	hci_abort_conn(conn, hci_proto_disconn_ind(conn), false);
 }
 
 /* Enter sniff mode */
@@ -748,7 +748,7 @@ static void le_conn_timeout(struct work_struct *work)
 		return;
 	}
 
-	hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM);
+	hci_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM, false);
 }
 
 struct iso_list_data {
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index 2e19a271d7a1..5a0296a4352e 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -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);
diff --git a/net/bluetooth/hci_request.h b/net/bluetooth/hci_request.h
index 7e1de871fca4..b9c5a9823837 100644
--- a/net/bluetooth/hci_request.h
+++ b/net/bluetooth/hci_request.h
@@ -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);
diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 6de2ad730995..0523e60a379b 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -6085,3 +6085,133 @@ int hci_update_adv_data(struct hci_dev *hdev, u8 instance)
 	*inst_ptr = instance;
 	return hci_cmd_sync_queue(hdev, _update_adv_data_sync, inst_ptr, NULL);
 }
+
+struct conn_reason {
+	struct hci_conn *conn;
+	u8 reason;
+};
+
+static int _abort_conn_sync(struct hci_dev *hdev, void *data)
+{
+	struct hci_conn *conn = ((struct conn_reason *)data)->conn;
+	u8 reason = ((struct conn_reason *)data)->reason;
+	int err = 0;
+
+	kfree(data);
+
+	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;
+			err = __hci_cmd_sync_status(hdev,
+						    HCI_OP_DISCONN_PHY_LINK,
+						    sizeof(cp), &cp,
+						    HCI_CMD_TIMEOUT);
+		} else {
+			struct hci_cp_disconnect dc;
+
+			dc.handle = cpu_to_le16(conn->handle);
+			dc.reason = reason;
+			err = __hci_cmd_sync_status(hdev,
+						    HCI_OP_DISCONNECT,
+						    sizeof(dc), &dc,
+						    HCI_CMD_TIMEOUT);
+		}
+		conn->state = BT_DISCONN;
+		break;
+	case BT_CONNECT:
+		if (conn->type == LE_LINK) {
+			if (test_bit(HCI_CONN_SCANNING, &conn->flags))
+				break;
+
+			err = __hci_cmd_sync_status(hdev,
+						    HCI_OP_LE_CREATE_CONN_CANCEL,
+						    0, NULL, HCI_CMD_TIMEOUT);
+		} else if (conn->type == ACL_LINK) {
+			if (hdev->hci_ver < BLUETOOTH_VER_1_2)
+				break;
+
+			err = __hci_cmd_sync_status(hdev,
+						    HCI_OP_CREATE_CONN_CANCEL,
+						    6, &conn->dst,
+						    HCI_CMD_TIMEOUT);
+		}
+		break;
+	case BT_CONNECT2:
+		if (conn->type == ACL_LINK) {
+			struct hci_cp_reject_conn_req rej;
+
+			bacpy(&rej.bdaddr, &conn->dst);
+			rej.reason = reason;
+
+			err = __hci_cmd_sync_status(hdev,
+						    HCI_OP_REJECT_CONN_REQ,
+						    sizeof(rej), &rej,
+						    HCI_CMD_TIMEOUT);
+
+		} 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;
+
+			err = __hci_cmd_sync_status(hdev,
+						    HCI_OP_REJECT_SYNC_CONN_REQ,
+						    sizeof(rej), &rej,
+						    HCI_CMD_TIMEOUT);
+		}
+		break;
+	default:
+		conn->state = BT_CLOSED;
+		break;
+	}
+
+	return err;
+}
+
+static void abort_conn_complete(struct hci_dev *hdev, void *data, int err)
+{
+	if (err)
+		bt_dev_dbg(hdev, "Failed to abort connection: err %d", err);
+}
+
+int hci_abort_conn(struct hci_conn *conn, u8 reason, bool async)
+{
+	struct conn_reason *conn_reason = kmalloc(sizeof(*conn_reason),
+						  GFP_KERNEL);
+	int err;
+
+	if (!conn_reason)
+		return -ENOMEM;
+
+	conn_reason->conn = conn;
+	conn_reason->reason = reason;
+
+	if (async) {
+		err = hci_cmd_sync_queue(conn->hdev, _abort_conn_sync,
+					 conn_reason, abort_conn_complete);
+
+		if (err)
+			kfree(conn_reason);
+	} else {
+		err = _abort_conn_sync(conn->hdev, conn_reason);
+	}
+
+	if (err && err != -ENODATA) {
+		bt_dev_err(conn->hdev, "failed to run HCI req: err %d", err);
+		return err;
+	}
+
+	return 0;
+}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 11eb6e538518..a63c778d18f1 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -3235,7 +3235,7 @@ 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_abort_conn(conn, HCI_ERROR_REMOTE_USER_TERM, true);
 
 unlock:
 	hci_dev_unlock(hdev);
-- 
2.37.1




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux