@@ -149,8 +149,6 @@ static void hci_conn_cleanup(struct hci_conn *conn)
149149
150150 hci_chan_list_flush (conn );
151151
152- hci_conn_hash_del (hdev , conn );
153-
154152 if (HCI_CONN_HANDLE_UNSET (conn -> handle ))
155153 ida_free (& hdev -> unset_handle_ida , conn -> handle );
156154
@@ -1152,28 +1150,54 @@ void hci_conn_del(struct hci_conn *conn)
11521150 disable_delayed_work_sync (& conn -> auto_accept_work );
11531151 disable_delayed_work_sync (& conn -> idle_work );
11541152
1155- if (conn -> type == ACL_LINK ) {
1156- /* Unacked frames */
1157- hdev -> acl_cnt += conn -> sent ;
1158- } else if (conn -> type == LE_LINK ) {
1159- cancel_delayed_work (& conn -> le_conn_timeout );
1153+ /* Remove the connection from the list so unacked logic can detect when
1154+ * a certain pool is not being utilized.
1155+ */
1156+ hci_conn_hash_del (hdev , conn );
11601157
1161- if (hdev -> le_pkts )
1162- hdev -> le_cnt += conn -> sent ;
1158+ /* Handle unacked frames:
1159+ *
1160+ * - In case there are no connection, or if restoring the buffers
1161+ * considered in transist would overflow, restore all buffers to the
1162+ * pool.
1163+ * - Otherwise restore just the buffers considered in transit for the
1164+ * hci_conn
1165+ */
1166+ switch (conn -> type ) {
1167+ case ACL_LINK :
1168+ if (!hci_conn_num (hdev , ACL_LINK ) ||
1169+ hdev -> acl_cnt + conn -> sent > hdev -> acl_pkts )
1170+ hdev -> acl_cnt = hdev -> acl_pkts ;
11631171 else
11641172 hdev -> acl_cnt += conn -> sent ;
1165- } else {
1166- /* Unacked ISO frames */
1167- if (conn -> type == CIS_LINK ||
1168- conn -> type == BIS_LINK ||
1169- conn -> type == PA_LINK ) {
1170- if (hdev -> iso_pkts )
1171- hdev -> iso_cnt += conn -> sent ;
1172- else if (hdev -> le_pkts )
1173+ break ;
1174+ case LE_LINK :
1175+ cancel_delayed_work (& conn -> le_conn_timeout );
1176+
1177+ if (hdev -> le_pkts ) {
1178+ if (!hci_conn_num (hdev , LE_LINK ) ||
1179+ hdev -> le_cnt + conn -> sent > hdev -> le_pkts )
1180+ hdev -> le_cnt = hdev -> le_pkts ;
1181+ else
11731182 hdev -> le_cnt += conn -> sent ;
1183+ } else {
1184+ if ((!hci_conn_num (hdev , LE_LINK ) &&
1185+ !hci_conn_num (hdev , ACL_LINK )) ||
1186+ hdev -> acl_cnt + conn -> sent > hdev -> acl_pkts )
1187+ hdev -> acl_cnt = hdev -> acl_pkts ;
11741188 else
11751189 hdev -> acl_cnt += conn -> sent ;
11761190 }
1191+ break ;
1192+ case CIS_LINK :
1193+ case BIS_LINK :
1194+ case PA_LINK :
1195+ if (!hci_iso_count (hdev ) ||
1196+ hdev -> iso_cnt + conn -> sent > hdev -> iso_pkts )
1197+ hdev -> iso_cnt = hdev -> iso_pkts ;
1198+ else
1199+ hdev -> iso_cnt += conn -> sent ;
1200+ break ;
11771201 }
11781202
11791203 skb_queue_purge (& conn -> data_q );
0 commit comments