On Sat, Aug 7, 2021 at 6:22 AM Guenter Roeck linux@roeck-us.net wrote:
[ Greg asked me to submit a report to regressions@, so here it is. ]
The following error was observed on Chromebooks with MT8183 CPU (ASUS Chromebook Detachable CM3, HP Chromebook 11a, and others):
[ 224.735198] Bluetooth: qca_setup() hci0: setting up ROME/QCA6390 [ 225.205024] Bluetooth: qca_read_soc_version() hci0: QCA Product ID :0x00000008 [ 225.205040] Bluetooth: qca_read_soc_version() hci0: QCA SOC Version :0x00000044 [ 225.205045] Bluetooth: qca_read_soc_version() hci0: QCA ROM Version :0x00000302 [ 225.205049] Bluetooth: qca_read_soc_version() hci0: QCA Patch Version:0x000003e8 [ 225.205055] Bluetooth: qca_uart_setup() hci0: QCA controller version 0x00440302 [ 225.205061] Bluetooth: qca_download_firmware() hci0: QCA Downloading qca/rampatch_00440302.bin [ 227.252653] Bluetooth: hci_cmd_timeout() hci0: command 0xfc00 tx timeout ... [ 223.604971] Bluetooth: qca_recv() hci0: Frame reassembly failed (-84) [ 223.605027] Bluetooth: qca_recv() hci0: Frame reassembly failed (-84) (repeated several times) ...
The Bluetooth interface on those Chromebooks can not be enabled.
Bisect suggests that upstream commit 0ea9fd001a14 ("Bluetooth: Shutdown controller after workqueues are flushed or cancelled") introduced the problem. Reverting it fixes the problem.
The problem was also reported at [1] on a Mediatek Pumpkin board.
As of this writing, the problem is still present in the upstream kernel as well as in all stable releases which include commit 0ea9fd001a14.
Thanks. Can you please test the following patch:
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 2560ed2f144d4..131e69a9a66a0 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1757,6 +1757,14 @@ int hci_dev_do_close(struct hci_dev *hdev) cancel_delayed_work_sync(&adv_instance->rpa_expired_cb); }
+ if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) && + !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && + test_bit(HCI_UP, &hdev->flags)) { + /* Execute vendor specific shutdown routine */ + if (hdev->shutdown) + hdev->shutdown(hdev); + } + /* Avoid potential lockdep warnings from the *_flush() calls by * ensuring the workqueue is empty up front. */ @@ -1798,14 +1806,6 @@ int hci_dev_do_close(struct hci_dev *hdev) clear_bit(HCI_INIT, &hdev->flags); }
- if (!hci_dev_test_flag(hdev, HCI_UNREGISTER) && - !hci_dev_test_flag(hdev, HCI_USER_CHANNEL) && - test_bit(HCI_UP, &hdev->flags)) { - /* Execute vendor specific shutdown routine */ - if (hdev->shutdown) - hdev->shutdown(hdev); - } - /* flush cmd work */ flush_work(&hdev->cmd_work);
Thanks, Guenter