diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2014-08-18 00:41:44 +0300 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-09-08 19:07:53 +0200 |
commit | f94b665dcf15324f5ac8aa639e47be0829b6409d (patch) | |
tree | d510060cd994c4b9cd9e0e543f01a2024eadf524 | |
parent | b3ff670a44cc34c01e78900c42255511e4f232e6 (diff) | |
download | op-kernel-dev-f94b665dcf15324f5ac8aa639e47be0829b6409d.zip op-kernel-dev-f94b665dcf15324f5ac8aa639e47be0829b6409d.tar.gz |
Bluetooth: Ignore incoming data after initiating disconnection
When hci_chan_del is called the disconnection routines get scheduled
through a workqueue. If there's any incoming ACL data before the
routines get executed there's a chance that a new hci_chan is created
and the disconnection never happens. This patch adds a new hci_conn flag
to indicate that we're in the process of driving the connection down. We
set the flag in hci_chan_del and check for it in hci_chan_create so that
no new channels are created for the same connection.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r-- | include/net/bluetooth/hci_core.h | 1 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 6 |
2 files changed, 7 insertions, 0 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 18c24f6..dbe7364 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -553,6 +553,7 @@ enum { HCI_CONN_FIPS, HCI_CONN_STK_ENCRYPT, HCI_CONN_AUTH_INITIATOR, + HCI_CONN_DROP, }; static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index cb04a4e..aaa7e38 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -1291,6 +1291,11 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn) BT_DBG("%s hcon %p", hdev->name, conn); + if (test_bit(HCI_CONN_DROP, &conn->flags)) { + BT_DBG("Refusing to create new hci_chan"); + return NULL; + } + chan = kzalloc(sizeof(*chan), GFP_KERNEL); if (!chan) return NULL; @@ -1318,6 +1323,7 @@ void hci_chan_del(struct hci_chan *chan) /* Force the connection to be immediately dropped */ conn->disc_timeout = 0; + set_bit(HCI_CONN_DROP, &conn->flags); hci_conn_drop(conn); hci_conn_put(conn); |