From e9087e828827e5a5c85e124ce77503f2b81c3491 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 15 Jan 2025 19:36:36 -0800 Subject: [PATCH 1/5] Bluetooth: btusb: mediatek: Add locks for usb_driver_claim_interface() The documentation for usb_driver_claim_interface() says that "the device lock" is needed when the function is called from places other than probe(). This appears to be the lock for the USB interface device. The Mediatek btusb code gets called via this path: Workqueue: hci0 hci_power_on [bluetooth] Call trace: usb_driver_claim_interface btusb_mtk_claim_iso_intf btusb_mtk_setup hci_dev_open_sync hci_power_on process_scheduled_works worker_thread kthread With the above call trace the device lock hasn't been claimed. Claim it. Without this fix, we'd sometimes see the error "Failed to claim iso interface". Sometimes we'd even see worse errors, like a NULL pointer dereference (where `intf->dev.driver` was NULL) with a trace like: Call trace: usb_suspend_both usb_runtime_suspend __rpm_callback rpm_suspend pm_runtime_work process_scheduled_works Both errors appear to be fixed with the proper locking. Fixes: ceac1cb0259d ("Bluetooth: btusb: mediatek: add ISO data transmission functions") Signed-off-by: Douglas Anderson Signed-off-by: Luiz Augusto von Dentz --- drivers/bluetooth/btusb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 9aa018d4f6f50..145b3fbfff550 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2639,8 +2639,15 @@ static void btusb_mtk_claim_iso_intf(struct btusb_data *data) struct btmtk_data *btmtk_data = hci_get_priv(data->hdev); int err; + /* + * The function usb_driver_claim_interface() is documented to need + * locks held if it's not called from a probe routine. The code here + * is called from the hci_power_on workqueue, so grab the lock. + */ + device_lock(&btmtk_data->isopkt_intf->dev); err = usb_driver_claim_interface(&btusb_driver, btmtk_data->isopkt_intf, data); + device_unlock(&btmtk_data->isopkt_intf->dev); if (err < 0) { btmtk_data->isopkt_intf = NULL; bt_dev_err(data->hdev, "Failed to claim iso interface"); From 0983fb4799e78b1783eb5ed0dfe324649c491bb7 Mon Sep 17 00:00:00 2001 From: Hsin-chen Chuang Date: Mon, 20 Jan 2025 18:39:39 +0800 Subject: [PATCH 2/5] Bluetooth: Fix possible infinite recursion of btusb_reset The function enters infinite recursion if the HCI device doesn't support GPIO reset: btusb_reset -> hdev->reset -> vendor_reset -> btusb_reset... btusb_reset shouldn't call hdev->reset after commit f07d478090b0 ("Bluetooth: Get rid of cmd_timeout and use the reset callback") Fixes: f07d478090b0 ("Bluetooth: Get rid of cmd_timeout and use the reset callback") Signed-off-by: Hsin-chen Chuang Signed-off-by: Luiz Augusto von Dentz --- drivers/bluetooth/btusb.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 145b3fbfff550..90966dfbd2781 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -899,11 +899,6 @@ static void btusb_reset(struct hci_dev *hdev) struct btusb_data *data; int err; - if (hdev->reset) { - hdev->reset(hdev); - return; - } - data = hci_get_drvdata(hdev); /* This is not an unbalanced PM reference since the device will reset */ err = usb_autopm_get_interface(data->intf); From 514a8e6d6152a418da95db942827d5e3ce58613a Mon Sep 17 00:00:00 2001 From: Hsin-chen Chuang Date: Mon, 20 Jan 2025 16:47:36 +0800 Subject: [PATCH 3/5] Bluetooth: Add ABI doc for sysfs reset The functionality was implemented in commit 0f8a00137411 ("Bluetooth: Allow reset via sysfs") Fixes: 0f8a00137411 ("Bluetooth: Allow reset via sysfs") Signed-off-by: Hsin-chen Chuang Signed-off-by: Luiz Augusto von Dentz --- Documentation/ABI/stable/sysfs-class-bluetooth | 9 +++++++++ MAINTAINERS | 1 + 2 files changed, 10 insertions(+) create mode 100644 Documentation/ABI/stable/sysfs-class-bluetooth diff --git a/Documentation/ABI/stable/sysfs-class-bluetooth b/Documentation/ABI/stable/sysfs-class-bluetooth new file mode 100644 index 0000000000000..36be024711747 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-class-bluetooth @@ -0,0 +1,9 @@ +What: /sys/class/bluetooth/hci/reset +Date: 14-Jan-2025 +KernelVersion: 6.13 +Contact: linux-bluetooth@vger.kernel.org +Description: This write-only attribute allows users to trigger the vendor reset + method on the Bluetooth device when arbitrary data is written. + The reset may or may not be done through the device transport + (e.g., UART/USB), and can also be done through an out-of-band + approach such as GPIO. diff --git a/MAINTAINERS b/MAINTAINERS index 5bcc78c0be70b..d996f393fcf42 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4078,6 +4078,7 @@ S: Supported W: http://www.bluez.org/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git +F: Documentation/ABI/stable/sysfs-class-bluetooth F: include/net/bluetooth/ F: net/bluetooth/ From 7de119bb79a63f6a1959b83117a98734914fb0b0 Mon Sep 17 00:00:00 2001 From: Neeraj Sanjay Kale Date: Mon, 20 Jan 2025 19:49:46 +0530 Subject: [PATCH 4/5] Bluetooth: btnxpuart: Fix glitches seen in dual A2DP streaming This fixes a regression caused by previous commit for fixing truncated ACL data, which is causing some intermittent glitches when running two A2DP streams. serdev_device_write_buf() is the root cause of the glitch, which is reverted, and the TX work will continue to write until the queue is empty. This change fixes both issues. No A2DP streaming glitches or truncated ACL data issue observed. Fixes: 8023dd220425 ("Bluetooth: btnxpuart: Fix driver sending truncated data") Fixes: 689ca16e5232 ("Bluetooth: NXP: Add protocol support for NXP Bluetooth chipsets") Signed-off-by: Neeraj Sanjay Kale Signed-off-by: Luiz Augusto von Dentz --- drivers/bluetooth/btnxpuart.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/bluetooth/btnxpuart.c b/drivers/bluetooth/btnxpuart.c index 1230045d78a5f..aa5ec1d444a9d 100644 --- a/drivers/bluetooth/btnxpuart.c +++ b/drivers/bluetooth/btnxpuart.c @@ -1381,13 +1381,12 @@ static void btnxpuart_tx_work(struct work_struct *work) while ((skb = nxp_dequeue(nxpdev))) { len = serdev_device_write_buf(serdev, skb->data, skb->len); - serdev_device_wait_until_sent(serdev, 0); hdev->stat.byte_tx += len; skb_pull(skb, len); if (skb->len > 0) { skb_queue_head(&nxpdev->txq, skb); - break; + continue; } switch (hci_skb_pkt_type(skb)) { From 5c61419e02033eaf01733d66e2fcd4044808f482 Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin Date: Wed, 29 Jan 2025 00:08:14 +0300 Subject: [PATCH 5/5] Bluetooth: L2CAP: accept zero as a special value for MTU auto-selection One of the possible ways to enable the input MTU auto-selection for L2CAP connections is supposed to be through passing a special "0" value for it as a socket option. Commit [1] added one of those into avdtp. However, it simply wouldn't work because the kernel still treats the specified value as invalid and denies the setting attempt. Recorded BlueZ logs include the following: bluetoothd[496]: profiles/audio/avdtp.c:l2cap_connect() setsockopt(L2CAP_OPTIONS): Invalid argument (22) [1]: https://github.com/bluez/bluez/commit/ae5be371a9f53fed33d2b34748a95a5498fd4b77 Found by Linux Verification Center (linuxtesting.org). Fixes: 4b6e228e297b ("Bluetooth: Auto tune if input MTU is set to 0") Cc: stable@vger.kernel.org Signed-off-by: Fedor Pchelkin Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/l2cap_sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 49f97d4138ea7..46ea0bee2259f 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -710,12 +710,12 @@ static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu) { switch (chan->scid) { case L2CAP_CID_ATT: - if (mtu < L2CAP_LE_MIN_MTU) + if (mtu && mtu < L2CAP_LE_MIN_MTU) return false; break; default: - if (mtu < L2CAP_DEFAULT_MIN_MTU) + if (mtu && mtu < L2CAP_DEFAULT_MIN_MTU) return false; }