Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pabigot/617f680a6ab89b3c7c643044ae9c758e to your computer and use it in GitHub Desktop.
Save pabigot/617f680a6ab89b3c7c643044ae9c758e to your computer and use it in GitHub Desktop.
Linux btusb patch to avoid validation checks for Zephyr USB HCI
From 5e9ccd2e720f5d01fad5e2b89ec3b3a205a15c0b Mon Sep 17 00:00:00 2001
From: "Peter A. Bigot" <pab@pabigot.com>
Date: Sat, 26 Sep 2020 09:56:07 -0500
Subject: [PATCH] Bluetooth: btusb: support Zephyr HCI devices
The Bluetooth specification requires that a USB HCI primary controller
provide the bulk and interrupt endpoints as interface 1, and a
scalable isochronous endpoint at interface 2. The latter supports the
synchronous connection oriented capability required for Bluetooth
audio.
Zephyr doesn't have the ability to specify which interface the BT HCI
controller ends up at, and it doesn't provide an SCO endpoint at all.
There's existing code for Apple devices to bypass the interface
validation, but this only works when the device is found in
btusb_table. The Zephyr USB HCI device is not found there, but it is
found if placed in the blacklist table which is checked (via a yocto
patch) after the validation occurs.
So first, we move the check for blacklist up above the validation, so
we use what'll be used in the rest of the code.
Then we extend the blacklist table to include an entry for the default
Zephyr vendor ID (0x2f3d) with the default sample USB HCI product ID
(0x000b) and mark it as a Zephyr device with a broken ISOC.
Finally we completely bypass the interface number check for Zephyr
devices.
Upstream-Status: Inappropriate [Zephyr-specific]
Signed-off-by: Peter A. Bigot <pab@pabigot.com>
---
drivers/bluetooth/btusb.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index f3f0529564da..b8d309271d5a 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -58,6 +58,8 @@ static struct usb_driver btusb_driver;
#define BTUSB_CW6622 0x100000
#define BTUSB_MEDIATEK 0x200000
+#define BTUSB_ZEPHYR 0x10000000
+
static const struct usb_device_id btusb_table[] = {
/* Generic Bluetooth USB device */
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
@@ -390,6 +392,10 @@ static const struct usb_device_id blacklist_table[] = {
/* Silicon Wave based devices */
{ USB_DEVICE(0x0c10, 0x0000), .driver_info = BTUSB_SWAVE },
+ /* Zephyr RTOS */
+ { USB_DEVICE(0x2fe3, 0x000b),
+ .driver_info = BTUSB_BROKEN_ISOC | BTUSB_ZEPHYR },
+
{ } /* Terminating entry */
};
@@ -3596,8 +3602,17 @@ static int btusb_probe(struct usb_interface *intf,
BT_DBG("intf %p id %p", intf, id);
+ if (!id->driver_info) {
+ const struct usb_device_id *match;
+
+ match = usb_match_id(intf, blacklist_table);
+ if (match)
+ id = match;
+ }
+
/* interface numbers are hardcoded in the spec */
- if (intf->cur_altsetting->desc.bInterfaceNumber != 0) {
+ if ((intf->cur_altsetting->desc.bInterfaceNumber != 0)
+ && !(id->driver_info & BTUSB_ZEPHYR)) {
if (!(id->driver_info & BTUSB_IFNUM_2))
return -ENODEV;
if (intf->cur_altsetting->desc.bInterfaceNumber != 2)
@@ -3606,14 +3621,6 @@ static int btusb_probe(struct usb_interface *intf,
ifnum_base = intf->cur_altsetting->desc.bInterfaceNumber;
- if (!id->driver_info) {
- const struct usb_device_id *match;
-
- match = usb_match_id(intf, blacklist_table);
- if (match)
- id = match;
- }
-
if (id->driver_info == BTUSB_IGNORE)
return -ENODEV;
--
2.25.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment