[PATCH v2 3/4] Bluetooth: hci_sync: disconnect linked connections before parents

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

 



SCO/ISO connections are disconnected implicitly if the ACL connection is
gone.  If we disconnect ACL first, controller may error disconnecting
ISO/SCO, which in hci_disconnect_all_sync fails powering off.  With ISO
connections present, powering off usually fails because of this.

Fix by aborting linked connections first in hci_disconnect_all_sync.

Signed-off-by: Pauli Virtanen <pav@xxxxxx>
---

Notes:
    v2: new patch

 net/bluetooth/hci_sync.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index 228259f44815..a476594ecd2a 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -5435,10 +5435,26 @@ static int hci_disconnect_all_sync(struct hci_dev *hdev, u8 reason)
 	do {
 		conn = NULL;
 		list_for_each_entry_rcu(c, &hdev->conn_hash.list, list) {
+			struct hci_link *link;
+
 			if (c->abort_reason == reason)
 				continue;
 
 			conn = c;
+
+			/* Abort linked connections first. Disconnecting ACL
+			 * implicitly disconnects SCO/ISO, and controller may
+			 * error commands disconnecting them after ACL.
+			 * (See Core v5.4 Vol 4 Part E Sec 7.1.6)
+			 */
+			if (conn->parent)
+				break;
+			list_for_each_entry_rcu(link, &conn->link_list, list) {
+				if (link->conn->abort_reason != reason) {
+					conn = link->conn;
+					break;
+				}
+			}
 			break;
 		}
 		if (!conn)
-- 
2.41.0




[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