@@ -1739,9 +1739,22 @@ static int btusb_setup_csr(struct hci_dev *hdev)
rp = (struct hci_rp_read_local_version *)skb->data;
- /* Detect controllers which aren't real CSR ones. */
+ /* Detect a wide host of Chinese controllers that aren't CSR. Some of these clones even
+ * respond with the correct HCI manufacturer, and their bcdDevice tags are all over the place,
+ * which may be another good angle to look into if we really want to have really long quirk lists.
+ *
+ * Known fake bcdDevices: 0x0100, 0x0134, 0x1915, 0x2520, 0x7558, 0x8891
+ * IC markings on 0x7558: FR3191AHAL 749H15143 (???)
+ *
+ * But the main thing they have in common is that these are really popular low-cost
+ * options that support newer Bluetooth versions but rely on heavy VID/PID
+ * squatting of this poor old Bluetooth 1.1 device. Even sold as such.
+ */
if (le16_to_cpu(rp->manufacturer) != 10 ||
- le16_to_cpu(rp->lmp_subver) == 0x0c5c) {
+ le16_to_cpu(rp->lmp_subver) == 0x0c5c ||
+ le16_to_cpu(rp->hci_ver) >= BLUETOOTH_VER_1_2) {
+ bt_dev_info(hdev, "CSR: Unbranded CSR clone detected; adding workaround");
+
/* Clear the reset quirk since this is not an actual
* early Bluetooth 1.1 device from CSR.
*/
@@ -1751,6 +1764,9 @@ static int btusb_setup_csr(struct hci_dev *hdev)
* stored link key handling and so just disable it.
*/
set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
+ } else {
+ /* Only apply these quirks to the actual, old CSR devices */
+ set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
}
kfree_skb(skb);
@@ -3995,17 +4011,13 @@ static int btusb_probe(struct usb_interface *intf,
if (id->driver_info & BTUSB_CSR) {
struct usb_device *udev = data->udev;
- u16 bcdDevice = le16_to_cpu(udev->descriptor.bcdDevice);
/* Old firmware would otherwise execute USB reset */
- if (bcdDevice < 0x117)
+ if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x117)
set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
/* Fake CSR devices with broken commands */
- if (bcdDevice <= 0x100 || bcdDevice == 0x134)
- hdev->setup = btusb_setup_csr;
-
- set_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
+ hdev->setup = btusb_setup_csr;
}
if (id->driver_info & BTUSB_SNIFFER) {