diff --git a/sys/netgraph/bluetooth/include/ng_l2cap.h b/sys/netgraph/bluetooth/include/ng_l2cap.h index 094aad38b56d..f57b5cbe3d20 100644 --- a/sys/netgraph/bluetooth/include/ng_l2cap.h +++ b/sys/netgraph/bluetooth/include/ng_l2cap.h @@ -623,6 +623,7 @@ typedef struct { #define NG_L2CAP_CON_OUTGOING (1 << 2) /* outgoing connection */ #define NG_L2CAP_CON_LP_TIMO (1 << 3) /* LP timeout */ #define NG_L2CAP_CON_AUTO_DISCON_TIMO (1 << 4) /* auto discon. timeout */ +#define NG_L2CAP_CON_DYING (1 << 5) /* connection is dying */ typedef struct { u_int8_t state; /* connection state */ diff --git a/sys/netgraph/bluetooth/l2cap/ng_l2cap_cmds.c b/sys/netgraph/bluetooth/l2cap/ng_l2cap_cmds.c index 06c19f613a8f..2e0efe392ef8 100644 --- a/sys/netgraph/bluetooth/l2cap/ng_l2cap_cmds.c +++ b/sys/netgraph/bluetooth/l2cap/ng_l2cap_cmds.c @@ -226,6 +226,9 @@ ng_l2cap_con_fail(ng_l2cap_con_p con, u_int16_t result) "%s: %s - ACL connection failed, result=%d\n", __func__, NG_NODE_NAME(l2cap->node), result); + /* Connection is dying */ + con->flags |= NG_L2CAP_CON_DYING; + /* Clean command queue */ while (!TAILQ_EMPTY(&con->cmd_list)) { cmd = TAILQ_FIRST(&con->cmd_list); diff --git a/sys/netgraph/bluetooth/l2cap/ng_l2cap_misc.c b/sys/netgraph/bluetooth/l2cap/ng_l2cap_misc.c index 10eb89eea5d1..635298a4e3d3 100644 --- a/sys/netgraph/bluetooth/l2cap/ng_l2cap_misc.c +++ b/sys/netgraph/bluetooth/l2cap/ng_l2cap_misc.c @@ -182,12 +182,14 @@ ng_l2cap_con_unref(ng_l2cap_con_p con) * 2) connection is in OPEN state * 3) it is an outgoing connection * 4) disconnect timeout > 0 + * 5) connection is not dying */ if ((con->refcnt == 0) && (con->state == NG_L2CAP_CON_OPEN) && (con->flags & NG_L2CAP_CON_OUTGOING) && - (con->l2cap->discon_timo > 0)) + (con->l2cap->discon_timo > 0) && + ((con->flags & NG_L2CAP_CON_DYING) == 0)) ng_l2cap_discon_timeout(con); } /* ng_l2cap_con_unref */ @@ -273,11 +275,14 @@ ng_l2cap_free_con(ng_l2cap_con_p con) ng_l2cap_free_cmd(cmd); } + if (con->flags & (NG_L2CAP_CON_AUTO_DISCON_TIMO|NG_L2CAP_CON_LP_TIMO)) + panic( +"%s: %s - timeout pending! state=%d, flags=%#x\n", + __func__, NG_NODE_NAME(con->l2cap->node), + con->state, con->flags); + LIST_REMOVE(con, next); - if (con->flags & NG_L2CAP_CON_AUTO_DISCON_TIMO) - ng_l2cap_discon_untimeout(con); - if (con->flags & NG_L2CAP_CON_LP_TIMO) - ng_l2cap_lp_untimeout(con); + bzero(con, sizeof(*con)); FREE(con, M_NETGRAPH_L2CAP); } /* ng_l2cap_free_con */