diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2008-08-07 16:26:56 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2008-08-07 16:26:56 -0400 |
commit | cfeb414537b1d7c23ba202f198fa4154cd5a4856 (patch) | |
tree | a17238dd44e778c07aa3aeac6c545893d259e8b1 | |
parent | 943d56b0a578cfc10e0340c6f8d6b8795d380e67 (diff) |
[Bluetooth] Add full quirk implementation for btusb driver
This implements all the quirk handling from the hci_usb driver to the
new btusb driver.
Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r-- | drivers/bluetooth/btusb.c | 163 |
1 files changed, 161 insertions, 2 deletions
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 12e108914f19..95ae9ba5661e 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -41,18 +41,122 @@ | |||
41 | #define BT_DBG(D...) | 41 | #define BT_DBG(D...) |
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | #define VERSION "0.1" | 44 | #define VERSION "0.2" |
45 | |||
46 | static int ignore_dga; | ||
47 | static int ignore_csr; | ||
48 | static int ignore_sniffer; | ||
49 | static int disable_scofix; | ||
50 | static int force_scofix; | ||
51 | static int reset; | ||
52 | |||
53 | static struct usb_driver btusb_driver; | ||
54 | |||
55 | #define BTUSB_IGNORE 0x01 | ||
56 | #define BTUSB_RESET 0x02 | ||
57 | #define BTUSB_DIGIANSWER 0x04 | ||
58 | #define BTUSB_CSR 0x08 | ||
59 | #define BTUSB_SNIFFER 0x10 | ||
60 | #define BTUSB_BCM92035 0x20 | ||
61 | #define BTUSB_BROKEN_ISOC 0x40 | ||
62 | #define BTUSB_WRONG_SCO_MTU 0x80 | ||
45 | 63 | ||
46 | static struct usb_device_id btusb_table[] = { | 64 | static struct usb_device_id btusb_table[] = { |
47 | /* Generic Bluetooth USB device */ | 65 | /* Generic Bluetooth USB device */ |
48 | { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, | 66 | { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, |
49 | 67 | ||
68 | /* AVM BlueFRITZ! USB v2.0 */ | ||
69 | { USB_DEVICE(0x057c, 0x3800) }, | ||
70 | |||
71 | /* Bluetooth Ultraport Module from IBM */ | ||
72 | { USB_DEVICE(0x04bf, 0x030a) }, | ||
73 | |||
74 | /* ALPS Modules with non-standard id */ | ||
75 | { USB_DEVICE(0x044e, 0x3001) }, | ||
76 | { USB_DEVICE(0x044e, 0x3002) }, | ||
77 | |||
78 | /* Ericsson with non-standard id */ | ||
79 | { USB_DEVICE(0x0bdb, 0x1002) }, | ||
80 | |||
81 | /* Canyon CN-BTU1 with HID interfaces */ | ||
82 | { USB_DEVICE(0x0c10, 0x0000), .driver_info = BTUSB_RESET }, | ||
83 | |||
50 | { } /* Terminating entry */ | 84 | { } /* Terminating entry */ |
51 | }; | 85 | }; |
52 | 86 | ||
53 | MODULE_DEVICE_TABLE(usb, btusb_table); | 87 | MODULE_DEVICE_TABLE(usb, btusb_table); |
54 | 88 | ||
55 | static struct usb_device_id blacklist_table[] = { | 89 | static struct usb_device_id blacklist_table[] = { |
90 | /* CSR BlueCore devices */ | ||
91 | { USB_DEVICE(0x0a12, 0x0001), .driver_info = BTUSB_CSR }, | ||
92 | |||
93 | /* Broadcom BCM2033 without firmware */ | ||
94 | { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE }, | ||
95 | |||
96 | /* Broadcom BCM2035 */ | ||
97 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||
98 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||
99 | |||
100 | /* Broadcom BCM2045 */ | ||
101 | { USB_DEVICE(0x0a5c, 0x2039), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||
102 | { USB_DEVICE(0x0a5c, 0x2101), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||
103 | |||
104 | /* Broadcom BCM2046 */ | ||
105 | { USB_DEVICE(0x0a5c, 0x2151), .driver_info = BTUSB_RESET }, | ||
106 | |||
107 | /* IBM/Lenovo ThinkPad with Broadcom chip */ | ||
108 | { USB_DEVICE(0x0a5c, 0x201e), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||
109 | { USB_DEVICE(0x0a5c, 0x2110), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||
110 | |||
111 | /* Targus ACB10US */ | ||
112 | { USB_DEVICE(0x0a5c, 0x2100), .driver_info = BTUSB_RESET }, | ||
113 | |||
114 | /* ANYCOM Bluetooth USB-200 and USB-250 */ | ||
115 | { USB_DEVICE(0x0a5c, 0x2111), .driver_info = BTUSB_RESET }, | ||
116 | |||
117 | /* HP laptop with Broadcom chip */ | ||
118 | { USB_DEVICE(0x03f0, 0x171d), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||
119 | |||
120 | /* Dell laptop with Broadcom chip */ | ||
121 | { USB_DEVICE(0x413c, 0x8126), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||
122 | |||
123 | /* Dell Wireless 370 */ | ||
124 | { USB_DEVICE(0x413c, 0x8156), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||
125 | |||
126 | /* Dell Wireless 410 */ | ||
127 | { USB_DEVICE(0x413c, 0x8152), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||
128 | |||
129 | /* Microsoft Wireless Transceiver for Bluetooth 2.0 */ | ||
130 | { USB_DEVICE(0x045e, 0x009c), .driver_info = BTUSB_RESET }, | ||
131 | |||
132 | /* Kensington Bluetooth USB adapter */ | ||
133 | { USB_DEVICE(0x047d, 0x105d), .driver_info = BTUSB_RESET }, | ||
134 | { USB_DEVICE(0x047d, 0x105e), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||
135 | |||
136 | /* ISSC Bluetooth Adapter v3.1 */ | ||
137 | { USB_DEVICE(0x1131, 0x1001), .driver_info = BTUSB_RESET }, | ||
138 | |||
139 | /* RTX Telecom based adapters with buggy SCO support */ | ||
140 | { USB_DEVICE(0x0400, 0x0807), .driver_info = BTUSB_BROKEN_ISOC }, | ||
141 | { USB_DEVICE(0x0400, 0x080a), .driver_info = BTUSB_BROKEN_ISOC }, | ||
142 | |||
143 | /* CONWISE Technology based adapters with buggy SCO support */ | ||
144 | { USB_DEVICE(0x0e5e, 0x6622), .driver_info = BTUSB_BROKEN_ISOC }, | ||
145 | |||
146 | /* Belkin F8T012 and F8T013 devices */ | ||
147 | { USB_DEVICE(0x050d, 0x0012), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||
148 | { USB_DEVICE(0x050d, 0x0013), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, | ||
149 | |||
150 | /* Digianswer devices */ | ||
151 | { USB_DEVICE(0x08fd, 0x0001), .driver_info = BTUSB_DIGIANSWER }, | ||
152 | { USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE }, | ||
153 | |||
154 | /* CSR BlueCore Bluetooth Sniffer */ | ||
155 | { USB_DEVICE(0x0a12, 0x0002), .driver_info = BTUSB_SNIFFER }, | ||
156 | |||
157 | /* Frontline ComProbe Bluetooth Sniffer */ | ||
158 | { USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER }, | ||
159 | |||
56 | { } /* Terminating entry */ | 160 | { } /* Terminating entry */ |
57 | }; | 161 | }; |
58 | 162 | ||
@@ -433,6 +537,7 @@ static int btusb_probe(struct usb_interface *intf, | |||
433 | 537 | ||
434 | BT_DBG("intf %p id %p", intf, id); | 538 | BT_DBG("intf %p id %p", intf, id); |
435 | 539 | ||
540 | /* interface numbers are hardcoded in the spec */ | ||
436 | if (intf->cur_altsetting->desc.bInterfaceNumber != 0) | 541 | if (intf->cur_altsetting->desc.bInterfaceNumber != 0) |
437 | return -ENODEV; | 542 | return -ENODEV; |
438 | 543 | ||
@@ -443,6 +548,18 @@ static int btusb_probe(struct usb_interface *intf, | |||
443 | id = match; | 548 | id = match; |
444 | } | 549 | } |
445 | 550 | ||
551 | if (id->driver_info == BTUSB_IGNORE) | ||
552 | return -ENODEV; | ||
553 | |||
554 | if (ignore_dga && id->driver_info & BTUSB_DIGIANSWER) | ||
555 | return -ENODEV; | ||
556 | |||
557 | if (ignore_csr && id->driver_info & BTUSB_CSR) | ||
558 | return -ENODEV; | ||
559 | |||
560 | if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER) | ||
561 | return -ENODEV; | ||
562 | |||
446 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 563 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
447 | if (!data) | 564 | if (!data) |
448 | return -ENOMEM; | 565 | return -ENOMEM; |
@@ -503,7 +620,31 @@ static int btusb_probe(struct usb_interface *intf, | |||
503 | 620 | ||
504 | hdev->owner = THIS_MODULE; | 621 | hdev->owner = THIS_MODULE; |
505 | 622 | ||
506 | set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks); | 623 | if (reset || id->driver_info & BTUSB_RESET) |
624 | set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks); | ||
625 | |||
626 | if (force_scofix || id->driver_info & BTUSB_WRONG_SCO_MTU) { | ||
627 | if (!disable_scofix) | ||
628 | set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks); | ||
629 | } | ||
630 | |||
631 | if (id->driver_info & BTUSB_SNIFFER) { | ||
632 | struct usb_device *udev = interface_to_usbdev(intf); | ||
633 | |||
634 | if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997) | ||
635 | set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); | ||
636 | } | ||
637 | |||
638 | if (id->driver_info & BTUSB_BCM92035) { | ||
639 | unsigned char cmd[] = { 0x3b, 0xfc, 0x01, 0x00 }; | ||
640 | struct sk_buff *skb; | ||
641 | |||
642 | skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL); | ||
643 | if (skb) { | ||
644 | memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd)); | ||
645 | skb_queue_tail(&hdev->driver_init, skb); | ||
646 | } | ||
647 | } | ||
507 | 648 | ||
508 | err = hci_register_dev(hdev); | 649 | err = hci_register_dev(hdev); |
509 | if (err < 0) { | 650 | if (err < 0) { |
@@ -558,6 +699,24 @@ static void __exit btusb_exit(void) | |||
558 | module_init(btusb_init); | 699 | module_init(btusb_init); |
559 | module_exit(btusb_exit); | 700 | module_exit(btusb_exit); |
560 | 701 | ||
702 | module_param(ignore_dga, bool, 0644); | ||
703 | MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001"); | ||
704 | |||
705 | module_param(ignore_csr, bool, 0644); | ||
706 | MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001"); | ||
707 | |||
708 | module_param(ignore_sniffer, bool, 0644); | ||
709 | MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002"); | ||
710 | |||
711 | module_param(disable_scofix, bool, 0644); | ||
712 | MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size"); | ||
713 | |||
714 | module_param(force_scofix, bool, 0644); | ||
715 | MODULE_PARM_DESC(force_scofix, "Force fixup of wrong SCO buffers size"); | ||
716 | |||
717 | module_param(reset, bool, 0644); | ||
718 | MODULE_PARM_DESC(reset, "Send HCI reset command on initialization"); | ||
719 | |||
561 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); | 720 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); |
562 | MODULE_DESCRIPTION("Generic Bluetooth USB driver ver " VERSION); | 721 | MODULE_DESCRIPTION("Generic Bluetooth USB driver ver " VERSION); |
563 | MODULE_VERSION(VERSION); | 722 | MODULE_VERSION(VERSION); |