@@ -149,8 +149,6 @@ static void hci_conn_cleanup(struct hci_conn *conn)
149
149
150
150
hci_chan_list_flush (conn );
151
151
152
- hci_conn_hash_del (hdev , conn );
153
-
154
152
if (HCI_CONN_HANDLE_UNSET (conn -> handle ))
155
153
ida_free (& hdev -> unset_handle_ida , conn -> handle );
156
154
@@ -1152,28 +1150,54 @@ void hci_conn_del(struct hci_conn *conn)
1152
1150
disable_delayed_work_sync (& conn -> auto_accept_work );
1153
1151
disable_delayed_work_sync (& conn -> idle_work );
1154
1152
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 );
1160
1157
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 ;
1163
1171
else
1164
1172
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
1173
1182
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 ;
1174
1188
else
1175
1189
hdev -> acl_cnt += conn -> sent ;
1176
1190
}
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 ;
1177
1201
}
1178
1202
1179
1203
skb_queue_purge (& conn -> data_q );
0 commit comments