btusb: support for more CSR clones.

This commit is contained in:
Sorgelig
2021-08-19 06:33:06 +08:00
parent c5066763cf
commit b02a4a011a

View File

@@ -1891,6 +1891,11 @@ static int btusb_setup_csr(struct hci_dev *hdev)
le16_to_cpu(rp->hci_ver) == BLUETOOTH_VER_2_0)
is_fake = true;
else if (le16_to_cpu(rp->lmp_subver) == 0x2512)
is_fake = true;
bt_dev_err(hdev, "lmp_subver = %X, hci_ver = %X, bcdDevice = %X is_fake = %d", le16_to_cpu(rp->lmp_subver), le16_to_cpu(rp->hci_ver), bcdDevice, is_fake);
if (is_fake) {
bt_dev_warn(hdev, "CSR: Unbranded CSR clone detected; adding workarounds and force-suspending once...");
@@ -1909,46 +1914,42 @@ static int btusb_setup_csr(struct hci_dev *hdev)
clear_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
/*
* Special workaround for these BT 4.0 chip clones, and potentially more:
*
* - 0x0134: a Barrot 8041a02 (HCI rev: 0x1012 sub: 0x0810)
* - 0x7558: IC markings FR3191AHAL 749H15143 (HCI rev/sub-version: 0x0709)
*
* These controllers are really messed-up.
*
* 1. Their bulk RX endpoint will never report any data unless
* the device was suspended at least once (yes, really).
* Special workaround for clones with a Barrot 8041a02 chip,
* these clones are really messed-up:
* 1. Their bulk rx endpoint will never report any data unless
* the device was suspended at least once (yes really).
* 2. They will not wakeup when autosuspended and receiving data
* on their bulk RX endpoint from e.g. a keyboard or mouse
* on their bulk rx endpoint from e.g. a keyboard or mouse
* (IOW remote-wakeup support is broken for the bulk endpoint).
*
* To fix 1. enable runtime-suspend, force-suspend the
* HCI and then wake-it up by disabling runtime-suspend.
* hci and then wake-it up by disabling runtime-suspend.
*
* To fix 2. clear the HCI's can_wake flag, this way the HCI
* To fix 2. clear the hci's can_wake flag, this way the hci
* will still be autosuspended when it is not open.
*
* --
*
* Because these are widespread problems we prefer generic solutions; so
* apply this initialization quirk to every controller that gets here,
* it should be harmless. The alternative is to not work at all.
*/
pm_runtime_allow(&data->udev->dev);
if (bcdDevice == 0x8891 &&
((le16_to_cpu(rp->lmp_subver) == 0x2512) ||
(le16_to_cpu(rp->lmp_subver) == 0x1012 &&
le16_to_cpu(rp->hci_rev) == 0x0810 &&
le16_to_cpu(rp->hci_ver) == BLUETOOTH_VER_4_0))) {
bt_dev_err(hdev, "CSR: detected a fake CSR dongle using a Barrot 8041a02 chip, this chip is very buggy and may have issues");
ret = pm_runtime_suspend(&data->udev->dev);
if (ret >= 0)
msleep(200);
else
bt_dev_err(hdev, "CSR: Failed to suspend the device for our Barrot 8041a02 receive-issue workaround");
pm_runtime_allow(&data->udev->dev);
pm_runtime_forbid(&data->udev->dev);
ret = pm_runtime_suspend(&data->udev->dev);
if (ret >= 0)
msleep(200);
else
bt_dev_err(hdev, "Failed to suspend the device for Barrot 8041a02 receive-issue workaround");
device_set_wakeup_capable(&data->udev->dev, false);
pm_runtime_forbid(&data->udev->dev);
/* Re-enable autosuspend if this was requested */
if (enable_autosuspend)
usb_enable_autosuspend(data->udev);
device_set_wakeup_capable(&data->udev->dev, false);
/* Re-enable autosuspend if this was requested */
if (enable_autosuspend)
usb_enable_autosuspend(data->udev);
}
}
kfree_skb(skb);