summaryrefslogtreecommitdiff
path: root/drivers/bluetooth
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>2024-10-16 11:47:00 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-10-22 15:46:31 +0200
commit885f8c873fedf3393c76827c4821071bf5fd16b1 (patch)
treec69acc7f890e2db06675e7eedb8d02a069ccb9b5 /drivers/bluetooth
parent8fb8e912afb4c47dec12ea9a5853e7a8db95816f (diff)
downloadlinux-885f8c873fedf3393c76827c4821071bf5fd16b1.tar.gz
linux-885f8c873fedf3393c76827c4821071bf5fd16b1.tar.bz2
linux-885f8c873fedf3393c76827c4821071bf5fd16b1.zip
Bluetooth: btusb: Fix regression with fake CSR controllers 0a12:0001
commit 2c1dda2acc4192d826e84008d963b528e24d12bc upstream. Fake CSR controllers don't seem to handle short-transfer properly which cause command to time out: kernel: usb 1-1: new full-speed USB device number 19 using xhci_hcd kernel: usb 1-1: New USB device found, idVendor=0a12, idProduct=0001, bcdDevice=88.91 kernel: usb 1-1: New USB device strings: Mfr=0, Product=2, SerialNumber=0 kernel: usb 1-1: Product: BT DONGLE10 ... Bluetooth: hci1: Opcode 0x1004 failed: -110 kernel: Bluetooth: hci1: command 0x1004 tx timeout According to USB Spec 2.0 Section 5.7.3 Interrupt Transfer Packet Size Constraints a interrupt transfer is considered complete when the size is 0 (ZPL) or < wMaxPacketSize: 'When an interrupt transfer involves more data than can fit in one data payload of the currently established maximum size, all data payloads are required to be maximum-sized except for the last data payload, which will contain the remaining data. An interrupt transfer is complete when the endpoint does one of the following: • Has transferred exactly the amount of data expected • Transfers a packet with a payload size less than wMaxPacketSize or transfers a zero-length packet' Link: https://bugzilla.kernel.org/show_bug.cgi?id=219365 Fixes: 7b05933340f4 ("Bluetooth: btusb: Fix not handling ZPL/short-transfer") Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r--drivers/bluetooth/btusb.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index bc53da383f85..b3a9b93f027a 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1354,10 +1354,15 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
if (!urb)
return -ENOMEM;
- /* Use maximum HCI Event size so the USB stack handles
- * ZPL/short-transfer automatically.
- */
- size = HCI_MAX_EVENT_SIZE;
+ if (le16_to_cpu(data->udev->descriptor.idVendor) == 0x0a12 &&
+ le16_to_cpu(data->udev->descriptor.idProduct) == 0x0001)
+ /* Fake CSR devices don't seem to support sort-transter */
+ size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
+ else
+ /* Use maximum HCI Event size so the USB stack handles
+ * ZPL/short-transfer automatically.
+ */
+ size = HCI_MAX_EVENT_SIZE;
buf = kmalloc(size, mem_flags);
if (!buf) {