summaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorMattijs Korpershoek <mkorpershoek@baylibre.com>2019-10-16 20:20:39 -0700
committerMarcel Holtmann <marcel@holtmann.org>2019-10-17 07:10:49 +0200
commiteb8c101e28496888a0dcfe16ab86a1bee369e820 (patch)
treee39a9ec7367c74b1452ffeca48a59d5e9c49eb77 /net/bluetooth
parent4c371bb95cf06ded80df0e6139fdd77cee1d9a94 (diff)
downloadlinux-eb8c101e28496888a0dcfe16ab86a1bee369e820.tar.gz
linux-eb8c101e28496888a0dcfe16ab86a1bee369e820.tar.bz2
linux-eb8c101e28496888a0dcfe16ab86a1bee369e820.zip
Bluetooth: hci_core: fix init for HCI_USER_CHANNEL
During the setup() stage, HCI device drivers expect the chip to acknowledge its setup() completion via vendor specific frames. If userspace opens() such HCI device in HCI_USER_CHANNEL [1] mode, the vendor specific frames are never tranmitted to the driver, as they are filtered in hci_rx_work(). Allow HCI devices which operate in HCI_USER_CHANNEL mode to receive frames if the HCI device is is HCI_INIT state. [1] https://www.spinics.net/lists/linux-bluetooth/msg37345.html Fixes: 23500189d7e0 ("Bluetooth: Introduce new HCI socket channel for user operation") Signed-off-by: Mattijs Korpershoek <mkorpershoek@baylibre.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_core.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b2559d4bed81..0cc9ce917222 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -4440,7 +4440,14 @@ static void hci_rx_work(struct work_struct *work)
hci_send_to_sock(hdev, skb);
}
- if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
+ /* If the device has been opened in HCI_USER_CHANNEL,
+ * the userspace has exclusive access to device.
+ * When device is HCI_INIT, we still need to process
+ * the data packets to the driver in order
+ * to complete its setup().
+ */
+ if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL) &&
+ !test_bit(HCI_INIT, &hdev->flags)) {
kfree_skb(skb);
continue;
}