|
From: Fredrik S. <fre...@us...> - 2002-02-12 11:02:23
|
The following files were modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
bnep.c 1.4 1.5=20=20=20=20=20=20=20=20=20=20=20=20=20
hci.c 1.191 1.192=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
Fixed a problem with running out of ACL buffers when a client disconnects u=
ngracefully.
The diff of the modified file(s):
--- bnep.c 11 Feb 2002 17:52:38 -0000 1.4
+++ bnep.c 12 Feb 2002 11:02:21 -0000 1.5
@@ -1407,10 +1407,11 @@
/* acknowledge the disconnect */
if (l2ca_disconnect_rsp(l2cap)) {
D_ERR("ether_disconnect_ind: l2ca_disconnect_rsp failed\n");
- return;
+ //return;
}
local =3D dev->priv;
local->l2cap =3D NULL;
+ local->state =3D DISCONNECTED;
}
=20
static void=20
--- hci.c 6 Feb 2002 11:23:15 -0000 1.191
+++ hci.c 12 Feb 2002 11:02:21 -0000 1.192
@@ -714,6 +714,8 @@
update_ncp(u8 nbr_of_hdl, u8 *pkt)
{
s32 i;
+ u16 hci_hdl;
+ u16 count;
#ifdef __KERNEL__
unsigned long flags;
=20
@@ -729,7 +731,18 @@
that have been sent */
=20
for (i =3D 0; i < 4 * nbr_of_hdl; i +=3D 4) {
- hci_ctrl.hc_buf.acl_num +=3D le16_to_cpuu(&pkt[i+2]);
+ hci_hdl =3D hci_handle(&pkt[i]);
+ count =3D le16_to_cpuu(&pkt[i+2]);
+ hci_ctrl.hc_buf.acl_num +=3D count;
+
+ D_REC(__FUNCTION__ ": free %d for handle %d\n", count, hci_hdl);
+
+ if (hci_ctrl.acl_buf_count[hci_hdl] < count) {
+ D_ERR(__FUNCTION__ ": completed packets > pending, hdl %d\n", hci_hdl);
+ hci_ctrl.acl_buf_count[hci_hdl] =3D 0;
+ } else {
+ hci_ctrl.acl_buf_count[hci_hdl] -=3D count;
+ }
}
=20=09
D_QUEUE("<NCP:%d>\n", hci_ctrl.hc_buf.acl_num);
@@ -836,6 +849,7 @@
if (lp_connect_cfm(buf + 3, (u32) buf[0], hci_hdl)) {
hci_ctrl.nbr_of_connections++;
hci_update_load_factor();
+ hci_ctrl.acl_buf_count[hci_hdl] =3D 0;
}
=20
#ifndef HCI_EMULATION
@@ -897,27 +911,37 @@
break;
=20
case DISCONNECTION_COMPLETE:
+ {
+ u16 hci_hdl =3D hci_handle(&buf[1]);
DSYS(__FUNCTION__ ": DISCONNECTION_COMPLETE %s\n", get_err_msg(buf[3]));
=20
release_cmd_timer();
wake_up_interruptible(&hci_wq);
=20
- if (lp_disconnect_ind(hci_handle(&buf[1])))
+ if (lp_disconnect_ind(hci_hdl))
if (hci_ctrl.nbr_of_connections > 0) {
hci_ctrl.nbr_of_connections--;
hci_update_load_factor();
}
=20
+ if (hci_ctrl.acl_buf_count[hci_hdl] > 0) {
+ DSYS(__FUNCTION__ ": Reset %d pending packets for handle %d\n",=20
+ hci_ctrl.acl_buf_count[hci_hdl], hci_hdl);
+ hci_ctrl.hc_buf.acl_num +=3D hci_ctrl.acl_buf_count[hci_hdl];
+ hci_ctrl.acl_buf_count[hci_hdl] =3D 0;
+ }
+
/* FIXME: No more NBR_OF_COMPLETE_PACKETS will arrive for this
connection handle, if we only support point-to-point
connections we can acl_num by reading the buffersizes again,
but this will not work in a multipoint connection. */
=20
- reset_hci_con_bd(hci_handle(&buf[1]));
+ reset_hci_con_bd(hci_hdl);
=20=09=09
if (hci_ctrl.nbr_of_connections <=3D 0) {
hci_read_buffer_size(HCI_NON_BLOCK);
}
+ }
break;
=20
case AUTHENTICATION_COMPLETE:
@@ -3423,6 +3447,7 @@
if (sent_bytes !=3D 0) {
bytes2send -=3D sent_bytes;
cli();
+ hci_ctrl.acl_buf_count[tx_buf->hci_hdl]++;
hci_ctrl.hc_buf.acl_num--;
sti();
} else {
|