aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/netgraph/bluetooth/include/ng_l2cap.h1
-rw-r--r--sys/netgraph/bluetooth/l2cap/ng_l2cap_cmds.c3
-rw-r--r--sys/netgraph/bluetooth/l2cap/ng_l2cap_misc.c15
3 files changed, 14 insertions, 5 deletions
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 */