Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Bluetooth: hci_sync: Add a new quirk to skip HCI_FLT_CLEAR_ALL

Some controllers have problems with being sent a command to clear
all filtering. While the HCI code does not unconditionally
send a clear-all anymore at BR/EDR setup (after the state machine
refactor), there might be more ways of hitting these codepaths
in the future as the kernel develops.

Cc: stable@vger.kernel.org
Cc: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Ismael Ferreras Morezuelas <swyterzone@gmail.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>

authored by

Ismael Ferreras Morezuelas and committed by
Marcel Holtmann
0eaecfb2 6ac034a7

+26
+10
include/net/bluetooth/hci.h
··· 255 255 * during the hdev->setup vendor callback. 256 256 */ 257 257 HCI_QUIRK_BROKEN_READ_TRANSMIT_POWER, 258 + 259 + /* When this quirk is set, HCI_OP_SET_EVENT_FLT requests with 260 + * HCI_FLT_CLEAR_ALL are ignored and event filtering is 261 + * completely avoided. A subset of the CSR controller 262 + * clones struggle with this and instantly lock up. 263 + * 264 + * Note that devices using this must (separately) disable 265 + * runtime suspend, because event filtering takes place there. 266 + */ 267 + HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, 258 268 }; 259 269 260 270 /* HCI device flags */
+16
net/bluetooth/hci_sync.c
··· 2809 2809 if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) 2810 2810 return 0; 2811 2811 2812 + if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks)) 2813 + return 0; 2814 + 2812 2815 memset(&cp, 0, sizeof(cp)); 2813 2816 cp.flt_type = flt_type; 2814 2817 ··· 2830 2827 static int hci_clear_event_filter_sync(struct hci_dev *hdev) 2831 2828 { 2832 2829 if (!hci_dev_test_flag(hdev, HCI_EVENT_FILTER_CONFIGURED)) 2830 + return 0; 2831 + 2832 + /* In theory the state machine should not reach here unless 2833 + * a hci_set_event_filter_sync() call succeeds, but we do 2834 + * the check both for parity and as a future reminder. 2835 + */ 2836 + if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks)) 2833 2837 return 0; 2834 2838 2835 2839 return hci_set_event_filter_sync(hdev, HCI_FLT_CLEAR_ALL, 0x00, ··· 4836 4826 int err; 4837 4827 4838 4828 if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) 4829 + return 0; 4830 + 4831 + /* Some fake CSR controllers lock up after setting this type of 4832 + * filter, so avoid sending the request altogether. 4833 + */ 4834 + if (test_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks)) 4839 4835 return 0; 4840 4836 4841 4837 /* Always clear event filter when starting */