#define URB_ZERO_PACKET 0
#endif
+static int ignore = 0;
+static int reset = 0;
+
#ifdef CONFIG_BT_HCIUSB_SCO
static int isoc = 2;
#endif
-#define VERSION "2.7"
+#define VERSION "2.8"
static struct usb_driver hci_usb_driver;
{ USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE },
/* Broadcom BCM2035 */
- { USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_RESET | HCI_BROKEN_ISOC },
{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_BROKEN_ISOC },
+ { USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 },
/* Microsoft Wireless Transceiver for Bluetooth 2.0 */
- { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET | HCI_BROKEN_ISOC },
+ { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
/* ISSC Bluetooth Adapter v3.1 */
{ USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
+ /* RTX Telecom based adapter with buggy SCO support */
+ { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
+
/* Digianswer devices */
{ USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
{ USB_DEVICE(0x08fd, 0x0002), .driver_info = HCI_IGNORE },
- /* RTX Telecom based adapter with buggy SCO support */
- { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
+ /* CSR BlueCore Bluetooth Sniffer */
+ { USB_DEVICE(0x0a12, 0x0002), .driver_info = HCI_SNIFFER },
{ } /* Terminating entry */
};
BT_DBG("%s", husb->hdev->name);
- size = husb->intr_in_ep->desc.wMaxPacketSize;
+ size = le16_to_cpu(husb->intr_in_ep->desc.wMaxPacketSize);
buf = kmalloc(size, GFP_ATOMIC);
if (!buf)
int err, mtu, size;
void *buf;
- mtu = husb->isoc_in_ep->desc.wMaxPacketSize;
+ mtu = le16_to_cpu(husb->isoc_in_ep->desc.wMaxPacketSize);
size = mtu * HCI_MAX_ISOC_FRAMES;
buf = kmalloc(size, GFP_ATOMIC);
urb->transfer_buffer = skb->data;
urb->transfer_buffer_length = skb->len;
- __fill_isoc_desc(urb, skb->len, husb->isoc_out_ep->desc.wMaxPacketSize);
+ __fill_isoc_desc(urb, skb->len, le16_to_cpu(husb->isoc_out_ep->desc.wMaxPacketSize));
_urb->priv = skb;
return __tx_submit(husb, _urb);
id = match;
}
- if (id->driver_info & HCI_IGNORE)
+ if (ignore || id->driver_info & HCI_IGNORE)
return -ENODEV;
if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
isoc_ifnum = 1;
#ifdef CONFIG_BT_HCIUSB_SCO
- if (isoc && !(id->driver_info & HCI_BROKEN_ISOC))
+ if (isoc && !(id->driver_info & (HCI_BROKEN_ISOC | HCI_SNIFFER)))
isoc_iface = usb_ifnum_to_if(udev, isoc_ifnum);
if (isoc_iface) {
switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
case USB_ENDPOINT_XFER_ISOC:
- if (ep->desc.wMaxPacketSize < size ||
+ if (le16_to_cpu(ep->desc.wMaxPacketSize) < size ||
uif->desc.bAlternateSetting != isoc)
break;
- size = ep->desc.wMaxPacketSize;
+ size = le16_to_cpu(ep->desc.wMaxPacketSize);
isoc_alts = uif->desc.bAlternateSetting;
hdev->owner = THIS_MODULE;
- if (id->driver_info & HCI_RESET)
+ if (reset || id->driver_info & HCI_RESET)
set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
+ if (id->driver_info & HCI_SNIFFER) {
+ if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
+ set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
+ }
+
+ if (id->driver_info & HCI_BCM92035) {
+ unsigned char cmd[] = { 0x3b, 0xfc, 0x01, 0x00 };
+ struct sk_buff *skb;
+
+ skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
+ if (skb) {
+ memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
+ skb_queue_tail(&hdev->driver_init, skb);
+ }
+ }
+
if (hci_register_dev(hdev) < 0) {
BT_ERR("Can't register HCI device");
hci_free_dev(hdev);
module_init(hci_usb_init);
module_exit(hci_usb_exit);
+module_param(ignore, bool, 0644);
+MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
+
+module_param(reset, bool, 0644);
+MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
+
#ifdef CONFIG_BT_HCIUSB_SCO
module_param(isoc, int, 0644);
MODULE_PARM_DESC(isoc, "Set isochronous transfers for SCO over HCI support");