Skip to content

Commit f4292e2

Browse files
Swyterholtmann
authored andcommitted
Bluetooth: btusb: Make the CSR clone chip force-suspend workaround more generic
Turns out Hans de Goede completed the work I started last year trying to improve Chinese-clone detection of CSR controller chips. Quirk after quirk these Bluetooth dongles are more usable now. Even after a few BlueZ regressions; these clones are so fickle that some days they stop working altogether. Except on Windows, they work fine. But this force-suspend initialization quirk seems to mostly do the trick, after a lot of testing Bluetooth now seems to work *all* the time. The only problem is that the solution ended up being masked under a very stringent check; when there are probably hundreds of fake dongle models out there that benefit from a good reset. Make it so. Fixes: 81cac64 ("Bluetooth: Deal with USB devices that are faking CSR vendor") Fixes: cde1a8a ("Bluetooth: btusb: Fix and detect most of the Chinese Bluetooth controllers") Fixes: d74e0ae ("Bluetooth: btusb: Fix detection of some fake CSR controllers with a bcdDevice val of 0x0134") Fixes: 0671c06 ("Bluetooth: btusb: Add workaround for remote-wakeup issues with Barrot 8041a02 fake CSR controllers") Cc: [email protected] Cc: Hans de Goede <[email protected]> Tested-by: Ismael Ferreras Morezuelas <[email protected]> Signed-off-by: Ismael Ferreras Morezuelas <[email protected]> Reviewed-by: Hans de Goede <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent f283f47 commit f4292e2

File tree

1 file changed

+30
-25
lines changed

1 file changed

+30
-25
lines changed

drivers/bluetooth/btusb.c

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1900,7 +1900,7 @@ static int btusb_setup_csr(struct hci_dev *hdev)
19001900
is_fake = true;
19011901

19021902
if (is_fake) {
1903-
bt_dev_warn(hdev, "CSR: Unbranded CSR clone detected; adding workarounds...");
1903+
bt_dev_warn(hdev, "CSR: Unbranded CSR clone detected; adding workarounds and force-suspending once...");
19041904

19051905
/* Generally these clones have big discrepancies between
19061906
* advertised features and what's actually supported.
@@ -1917,41 +1917,46 @@ static int btusb_setup_csr(struct hci_dev *hdev)
19171917
clear_bit(HCI_QUIRK_SIMULTANEOUS_DISCOVERY, &hdev->quirks);
19181918

19191919
/*
1920-
* Special workaround for clones with a Barrot 8041a02 chip,
1921-
* these clones are really messed-up:
1922-
* 1. Their bulk rx endpoint will never report any data unless
1923-
* the device was suspended at least once (yes really).
1920+
* Special workaround for these BT 4.0 chip clones, and potentially more:
1921+
*
1922+
* - 0x0134: a Barrot 8041a02 (HCI rev: 0x1012 sub: 0x0810)
1923+
* - 0x7558: IC markings FR3191AHAL 749H15143 (HCI rev/sub-version: 0x0709)
1924+
*
1925+
* These controllers are really messed-up.
1926+
*
1927+
* 1. Their bulk RX endpoint will never report any data unless
1928+
* the device was suspended at least once (yes, really).
19241929
* 2. They will not wakeup when autosuspended and receiving data
1925-
* on their bulk rx endpoint from e.g. a keyboard or mouse
1930+
* on their bulk RX endpoint from e.g. a keyboard or mouse
19261931
* (IOW remote-wakeup support is broken for the bulk endpoint).
19271932
*
19281933
* To fix 1. enable runtime-suspend, force-suspend the
1929-
* hci and then wake-it up by disabling runtime-suspend.
1934+
* HCI and then wake-it up by disabling runtime-suspend.
19301935
*
1931-
* To fix 2. clear the hci's can_wake flag, this way the hci
1936+
* To fix 2. clear the HCI's can_wake flag, this way the HCI
19321937
* will still be autosuspended when it is not open.
1938+
*
1939+
* --
1940+
*
1941+
* Because these are widespread problems we prefer generic solutions; so
1942+
* apply this initialization quirk to every controller that gets here,
1943+
* it should be harmless. The alternative is to not work at all.
19331944
*/
1934-
if (bcdDevice == 0x8891 &&
1935-
le16_to_cpu(rp->lmp_subver) == 0x1012 &&
1936-
le16_to_cpu(rp->hci_rev) == 0x0810 &&
1937-
le16_to_cpu(rp->hci_ver) == BLUETOOTH_VER_4_0) {
1938-
bt_dev_warn(hdev, "CSR: detected a fake CSR dongle using a Barrot 8041a02 chip, this chip is very buggy and may have issues");
1945+
pm_runtime_allow(&data->udev->dev);
19391946

1940-
pm_runtime_allow(&data->udev->dev);
1947+
ret = pm_runtime_suspend(&data->udev->dev);
1948+
if (ret >= 0)
1949+
msleep(200);
1950+
else
1951+
bt_dev_err(hdev, "CSR: Failed to suspend the device for our Barrot 8041a02 receive-issue workaround");
19411952

1942-
ret = pm_runtime_suspend(&data->udev->dev);
1943-
if (ret >= 0)
1944-
msleep(200);
1945-
else
1946-
bt_dev_err(hdev, "Failed to suspend the device for Barrot 8041a02 receive-issue workaround");
1953+
pm_runtime_forbid(&data->udev->dev);
19471954

1948-
pm_runtime_forbid(&data->udev->dev);
1955+
device_set_wakeup_capable(&data->udev->dev, false);
19491956

1950-
device_set_wakeup_capable(&data->udev->dev, false);
1951-
/* Re-enable autosuspend if this was requested */
1952-
if (enable_autosuspend)
1953-
usb_enable_autosuspend(data->udev);
1954-
}
1957+
/* Re-enable autosuspend if this was requested */
1958+
if (enable_autosuspend)
1959+
usb_enable_autosuspend(data->udev);
19551960
}
19561961

19571962
kfree_skb(skb);

0 commit comments

Comments
 (0)