linux5.15: add patch to fix bluetooth dongle
The patch is taken verbatim from this particular comment: https://gist.github.com/nevack/6b36b82d715dc025163d9e9124840a07#gistcomment-3818325 Note that there are several fake variants of this CSR dongle (usb id 0a12:0001) that need different workarounds. The gist itself mentions a workaround (force-suspend) that is already included in 5.15 and fixes some dongles but not mine. The issue is also mentioned in kernel bugzilla at https://bugzilla.kernel.org/show_bug.cgi?id=60824#c187 Starting at comment 187 there are several reports of dongles fixed by that patch (or a variation / rediscovery of the workaround).
This commit is contained in:
parent
53db226aa2
commit
625fd0cf93
1 changed files with 96 additions and 0 deletions
|
@ -0,0 +1,96 @@
|
|||
From 4d5b0262d30dd6227d9bef96c2a2259bf1162350 Mon Sep 17 00:00:00 2001
|
||||
From: Ismael Ferreras Morezuelas <swyterzone@gmail.com>
|
||||
Date: Mon, 19 Jul 2021 12:39:11 +0200
|
||||
Subject: [PATCH] Bluetooth: Add a new quirk to skip HCI_FLT_CLEAR_ALL
|
||||
|
||||
Signed-off-by: Ismael Ferreras Morezuelas <swyterzone@gmail.com>
|
||||
---
|
||||
drivers/bluetooth/btusb.c | 1 +
|
||||
include/net/bluetooth/hci.h | 6 ++++++
|
||||
net/bluetooth/hci_core.c | 12 +++++++++---
|
||||
net/bluetooth/hci_request.c | 8 ++++++--
|
||||
4 files changed, 22 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
|
||||
index 197cafe75..8fa07f9e3 100644
|
||||
--- a/drivers/bluetooth/btusb.c
|
||||
+++ b/drivers/bluetooth/btusb.c
|
||||
@@ -1899,6 +1899,7 @@ static int btusb_setup_csr(struct hci_dev *hdev)
|
||||
*/
|
||||
set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
|
||||
+ set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks);
|
||||
|
||||
/* Clear the reset quirk since this is not an actual
|
||||
* early Bluetooth 1.1 device from CSR.
|
||||
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
|
||||
index b80415011..a12178387 100644
|
||||
--- a/include/net/bluetooth/hci.h
|
||||
+++ b/include/net/bluetooth/hci.h
|
||||
@@ -246,6 +246,12 @@ enum {
|
||||
* HCI after resume.
|
||||
*/
|
||||
HCI_QUIRK_NO_SUSPEND_NOTIFIER,
|
||||
+
|
||||
+ /* When this quirk is set, HCI_OP_SET_EVENT_FLT requests with
|
||||
+ * HCI_FLT_CLEAR_ALL are ignored. A subset of the CSR controller
|
||||
+ * clones struggle with this and instantly lock up.
|
||||
+ */
|
||||
+ HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL,
|
||||
};
|
||||
|
||||
/* HCI device flags */
|
||||
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
|
||||
index 2560ed2f1..7ed355c3e 100644
|
||||
--- a/net/bluetooth/hci_core.c
|
||||
+++ b/net/bluetooth/hci_core.c
|
||||
@@ -273,6 +273,7 @@ static void bredr_setup(struct hci_request *req)
|
||||
{
|
||||
__le16 param;
|
||||
__u8 flt_type;
|
||||
+ struct hci_dev *hdev = req->hdev;
|
||||
|
||||
/* Read Buffer Size (ACL mtu, max pkt, etc.) */
|
||||
hci_req_add(req, HCI_OP_READ_BUFFER_SIZE, 0, NULL);
|
||||
@@ -292,9 +293,14 @@ static void bredr_setup(struct hci_request *req)
|
||||
/* Read Current IAC LAP */
|
||||
hci_req_add(req, HCI_OP_READ_CURRENT_IAC_LAP, 0, NULL);
|
||||
|
||||
- /* Clear Event Filters */
|
||||
- flt_type = HCI_FLT_CLEAR_ALL;
|
||||
- hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
|
||||
+ /* Clear Event Filters; some fake CSR controllers lock up after setting
|
||||
+ * this type of filter, so avoid sending the request altogether.
|
||||
+ */
|
||||
+ if (!test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
|
||||
+ {
|
||||
+ flt_type = HCI_FLT_CLEAR_ALL;
|
||||
+ hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &flt_type);
|
||||
+ }
|
||||
|
||||
/* Connection accept timeout ~20 secs */
|
||||
param = cpu_to_le16(0x7d00);
|
||||
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
|
||||
index 1d14adc02..90a88539b 100644
|
||||
--- a/net/bluetooth/hci_request.c
|
||||
+++ b/net/bluetooth/hci_request.c
|
||||
@@ -1156,11 +1156,15 @@ static bool adv_instance_is_scannable(struct hci_dev *hdev, u8 instance)
|
||||
static void hci_req_clear_event_filter(struct hci_request *req)
|
||||
{
|
||||
struct hci_cp_set_event_filter f;
|
||||
+ struct hci_dev *hdev = req->hdev;
|
||||
+
|
||||
+ if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED))
|
||||
+ return;
|
||||
|
||||
- if (!hci_dev_test_flag(req->hdev, HCI_BREDR_ENABLED))
|
||||
+ if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks))
|
||||
return;
|
||||
|
||||
- if (hci_dev_test_flag(req->hdev, HCI_EVENT_FILTER_CONFIGURED)) {
|
||||
+ if (hci_dev_test_flag(hdev, HCI_EVENT_FILTER_CONFIGURED)) {
|
||||
memset(&f, 0, sizeof(f));
|
||||
f.flt_type = HCI_FLT_CLEAR_ALL;
|
||||
hci_req_add(req, HCI_OP_SET_EVENT_FLT, 1, &f);
|
||||
--
|
||||
2.32.0
|
Loading…
Reference in a new issue