mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
bluetooth pull request for net:
- hci_conn: Make unacked packet handling more robust - hci_event: Treat UNKNOWN_CONN_ID on disconnect as success - hci_event: Mark connection as closed during suspend disconnect - hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced - hci_event: Disconnect device when BIG sync is lost - hci_sync: fix set_local_name race condition -----BEGIN PGP SIGNATURE----- iQJNBAABCgA3FiEE7E6oRXp8w05ovYr/9JCA4xAyCykFAmiosHUZHGx1aXoudm9u LmRlbnR6QGludGVsLmNvbQAKCRD0kIDjEDILKXtCD/92xuS5xvFhqhzexyXPyHa8 rNB8Gl9EpXlSkftmKwguRxo6LzM8U2R4zOx49MwCVFpcTdWYCP1WvDuWWKcmfuDg qyFIUyZWb8u02nRbscwN/yF0YcHwPXpAcWt8XmQvPu9sZ3i0dmJBSrabdZ+OI4oa Lqi4frdfWVFr46dpj9U61bWtY34lR+1BxWiOHtLT8+xGlgiugnXwkcwDY7bzmK6s hMabAoMCWv5iuWwE8LXubPYHg4M8PPrQORBQ/iNwJYtan7YD6f/sDd3rHlCF8cuU uvoCVXDx1UI7LrYsocb9iNHFsyvZD93W5xmK+8PAZKsMZgEcdfs3jLlT6zek/GI/ ab5nr6q+XVas3Z0tq3MblpAzRmlOZaLM97LqotQC4EBVyIH3JXhwN41nBDKycmM4 WBPWHZIsJ6ZIV+++tZIIuKAaZHSCiYcEwEiQyV06QdHoDfw9Wc39sr13IOqThXfv AOCwjnjUTuqZ6HnmogOcN87tYXQghJ12XJgNgFbxeoAtxqL1TDWtZKJkHB7oHY3l gGeN2ffRP+yoXPT7GWQoGAydKylf6fIPkRo64gbEoYmPy56djUZ2lnRMbrYm1MWR Yy4SaZhu84jLKdOsLxhRzZR2FxO3E568t2nDDA5xz2F4FkrP8/ih+fOO18+5UVK9 302cU7sOXc+aSt8LHP4lRQ== =4eUN -----END PGP SIGNATURE----- Merge tag 'for-net-2025-08-22' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth Luiz Augusto von Dentz says: ==================== bluetooth pull request for net: * tag 'for-net-2025-08-22' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth: Bluetooth: hci_sync: fix set_local_name race condition Bluetooth: hci_event: Disconnect device when BIG sync is lost Bluetooth: hci_event: Detect if HCI_EV_NUM_COMP_PKTS is unbalanced Bluetooth: hci_event: Mark connection as closed during suspend disconnect Bluetooth: hci_event: Treat UNKNOWN_CONN_ID on disconnect as success Bluetooth: hci_conn: Make unacked packet handling more robust ==================== Link: https://patch.msgid.link/20250822180230.345979-1-luiz.dentz@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
1559c9c231
@ -93,7 +93,7 @@ int hci_update_class_sync(struct hci_dev *hdev);
|
||||
|
||||
int hci_update_eir_sync(struct hci_dev *hdev);
|
||||
int hci_update_class_sync(struct hci_dev *hdev);
|
||||
int hci_update_name_sync(struct hci_dev *hdev);
|
||||
int hci_update_name_sync(struct hci_dev *hdev, const u8 *name);
|
||||
int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode);
|
||||
|
||||
int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
|
||||
|
@ -149,8 +149,6 @@ static void hci_conn_cleanup(struct hci_conn *conn)
|
||||
|
||||
hci_chan_list_flush(conn);
|
||||
|
||||
hci_conn_hash_del(hdev, conn);
|
||||
|
||||
if (HCI_CONN_HANDLE_UNSET(conn->handle))
|
||||
ida_free(&hdev->unset_handle_ida, conn->handle);
|
||||
|
||||
@ -1152,28 +1150,54 @@ void hci_conn_del(struct hci_conn *conn)
|
||||
disable_delayed_work_sync(&conn->auto_accept_work);
|
||||
disable_delayed_work_sync(&conn->idle_work);
|
||||
|
||||
if (conn->type == ACL_LINK) {
|
||||
/* Unacked frames */
|
||||
hdev->acl_cnt += conn->sent;
|
||||
} else if (conn->type == LE_LINK) {
|
||||
cancel_delayed_work(&conn->le_conn_timeout);
|
||||
/* Remove the connection from the list so unacked logic can detect when
|
||||
* a certain pool is not being utilized.
|
||||
*/
|
||||
hci_conn_hash_del(hdev, conn);
|
||||
|
||||
if (hdev->le_pkts)
|
||||
hdev->le_cnt += conn->sent;
|
||||
/* Handle unacked frames:
|
||||
*
|
||||
* - In case there are no connection, or if restoring the buffers
|
||||
* considered in transist would overflow, restore all buffers to the
|
||||
* pool.
|
||||
* - Otherwise restore just the buffers considered in transit for the
|
||||
* hci_conn
|
||||
*/
|
||||
switch (conn->type) {
|
||||
case ACL_LINK:
|
||||
if (!hci_conn_num(hdev, ACL_LINK) ||
|
||||
hdev->acl_cnt + conn->sent > hdev->acl_pkts)
|
||||
hdev->acl_cnt = hdev->acl_pkts;
|
||||
else
|
||||
hdev->acl_cnt += conn->sent;
|
||||
} else {
|
||||
/* Unacked ISO frames */
|
||||
if (conn->type == CIS_LINK ||
|
||||
conn->type == BIS_LINK ||
|
||||
conn->type == PA_LINK) {
|
||||
if (hdev->iso_pkts)
|
||||
hdev->iso_cnt += conn->sent;
|
||||
else if (hdev->le_pkts)
|
||||
break;
|
||||
case LE_LINK:
|
||||
cancel_delayed_work(&conn->le_conn_timeout);
|
||||
|
||||
if (hdev->le_pkts) {
|
||||
if (!hci_conn_num(hdev, LE_LINK) ||
|
||||
hdev->le_cnt + conn->sent > hdev->le_pkts)
|
||||
hdev->le_cnt = hdev->le_pkts;
|
||||
else
|
||||
hdev->le_cnt += conn->sent;
|
||||
} else {
|
||||
if ((!hci_conn_num(hdev, LE_LINK) &&
|
||||
!hci_conn_num(hdev, ACL_LINK)) ||
|
||||
hdev->acl_cnt + conn->sent > hdev->acl_pkts)
|
||||
hdev->acl_cnt = hdev->acl_pkts;
|
||||
else
|
||||
hdev->acl_cnt += conn->sent;
|
||||
}
|
||||
break;
|
||||
case CIS_LINK:
|
||||
case BIS_LINK:
|
||||
case PA_LINK:
|
||||
if (!hci_iso_count(hdev) ||
|
||||
hdev->iso_cnt + conn->sent > hdev->iso_pkts)
|
||||
hdev->iso_cnt = hdev->iso_pkts;
|
||||
else
|
||||
hdev->iso_cnt += conn->sent;
|
||||
break;
|
||||
}
|
||||
|
||||
skb_queue_purge(&conn->data_q);
|
||||
|
@ -2703,7 +2703,7 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
|
||||
if (!conn)
|
||||
goto unlock;
|
||||
|
||||
if (status) {
|
||||
if (status && status != HCI_ERROR_UNKNOWN_CONN_ID) {
|
||||
mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
|
||||
conn->dst_type, status);
|
||||
|
||||
@ -2718,6 +2718,12 @@ static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* During suspend, mark connection as closed immediately
|
||||
* since we might not receive HCI_EV_DISCONN_COMPLETE
|
||||
*/
|
||||
if (hdev->suspended)
|
||||
conn->state = BT_CLOSED;
|
||||
|
||||
mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags);
|
||||
|
||||
if (conn->type == ACL_LINK) {
|
||||
@ -4398,7 +4404,17 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,
|
||||
if (!conn)
|
||||
continue;
|
||||
|
||||
/* Check if there is really enough packets outstanding before
|
||||
* attempting to decrease the sent counter otherwise it could
|
||||
* underflow..
|
||||
*/
|
||||
if (conn->sent >= count) {
|
||||
conn->sent -= count;
|
||||
} else {
|
||||
bt_dev_warn(hdev, "hcon %p sent %u < count %u",
|
||||
conn, conn->sent, count);
|
||||
conn->sent = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; ++i)
|
||||
hci_conn_tx_dequeue(conn);
|
||||
@ -7008,6 +7024,7 @@ static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data,
|
||||
{
|
||||
struct hci_evt_le_big_sync_lost *ev = data;
|
||||
struct hci_conn *bis, *conn;
|
||||
bool mgmt_conn;
|
||||
|
||||
bt_dev_dbg(hdev, "big handle 0x%2.2x", ev->handle);
|
||||
|
||||
@ -7026,6 +7043,10 @@ static void hci_le_big_sync_lost_evt(struct hci_dev *hdev, void *data,
|
||||
while ((bis = hci_conn_hash_lookup_big_state(hdev, ev->handle,
|
||||
BT_CONNECTED,
|
||||
HCI_ROLE_SLAVE))) {
|
||||
mgmt_conn = test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &bis->flags);
|
||||
mgmt_device_disconnected(hdev, &bis->dst, bis->type, bis->dst_type,
|
||||
ev->reason, mgmt_conn);
|
||||
|
||||
clear_bit(HCI_CONN_BIG_SYNC, &bis->flags);
|
||||
hci_disconn_cfm(bis, ev->reason);
|
||||
hci_conn_del(bis);
|
||||
|
@ -3481,13 +3481,13 @@ int hci_update_scan_sync(struct hci_dev *hdev)
|
||||
return hci_write_scan_enable_sync(hdev, scan);
|
||||
}
|
||||
|
||||
int hci_update_name_sync(struct hci_dev *hdev)
|
||||
int hci_update_name_sync(struct hci_dev *hdev, const u8 *name)
|
||||
{
|
||||
struct hci_cp_write_local_name cp;
|
||||
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
|
||||
memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
|
||||
memcpy(cp.name, name, sizeof(cp.name));
|
||||
|
||||
return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME,
|
||||
sizeof(cp), &cp,
|
||||
@ -3540,7 +3540,7 @@ int hci_powered_update_sync(struct hci_dev *hdev)
|
||||
hci_write_fast_connectable_sync(hdev, false);
|
||||
hci_update_scan_sync(hdev);
|
||||
hci_update_class_sync(hdev);
|
||||
hci_update_name_sync(hdev);
|
||||
hci_update_name_sync(hdev, hdev->dev_name);
|
||||
hci_update_eir_sync(hdev);
|
||||
}
|
||||
|
||||
|
@ -3892,8 +3892,11 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
|
||||
|
||||
static int set_name_sync(struct hci_dev *hdev, void *data)
|
||||
{
|
||||
struct mgmt_pending_cmd *cmd = data;
|
||||
struct mgmt_cp_set_local_name *cp = cmd->param;
|
||||
|
||||
if (lmp_bredr_capable(hdev)) {
|
||||
hci_update_name_sync(hdev);
|
||||
hci_update_name_sync(hdev, cp->name);
|
||||
hci_update_eir_sync(hdev);
|
||||
}
|
||||
|
||||
@ -9705,7 +9708,9 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
|
||||
if (!mgmt_connected)
|
||||
return;
|
||||
|
||||
if (link_type != ACL_LINK && link_type != LE_LINK)
|
||||
if (link_type != ACL_LINK &&
|
||||
link_type != LE_LINK &&
|
||||
link_type != BIS_LINK)
|
||||
return;
|
||||
|
||||
bacpy(&ev.addr.bdaddr, bdaddr);
|
||||
|
Loading…
Reference in New Issue
Block a user