blob: 01d6789b3eb7a951d6643824aa73667e2192f2af [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 HCI USB driver for Linux Bluetooth protocol stack (BlueZ)
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
5
6 Copyright (C) 2003 Maxim Krasnyansky <maxk@qualcomm.com>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as
10 published by the Free Software Foundation;
11
12 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
13 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
15 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
16 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
17 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
21 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
22 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
23 SOFTWARE IS DISCLAIMED.
24*/
25
26/*
27 * Bluetooth HCI USB driver.
28 * Based on original USB Bluetooth driver for Linux kernel
29 * Copyright (c) 2000 Greg Kroah-Hartman <greg@kroah.com>
30 * Copyright (c) 2000 Mark Douglas Corner <mcorner@umich.edu>
31 *
32 */
33
Linus Torvalds1da177e2005-04-16 15:20:36 -070034#include <linux/module.h>
35
36#include <linux/kernel.h>
37#include <linux/init.h>
38#include <linux/sched.h>
39#include <linux/unistd.h>
40#include <linux/types.h>
41#include <linux/interrupt.h>
42#include <linux/moduleparam.h>
43
44#include <linux/slab.h>
45#include <linux/errno.h>
46#include <linux/string.h>
47#include <linux/skbuff.h>
48
49#include <linux/usb.h>
50
51#include <net/bluetooth/bluetooth.h>
52#include <net/bluetooth/hci_core.h>
53
54#include "hci_usb.h"
55
56#ifndef CONFIG_BT_HCIUSB_DEBUG
57#undef BT_DBG
58#define BT_DBG(D...)
Linus Torvalds1da177e2005-04-16 15:20:36 -070059#endif
60
61#ifndef CONFIG_BT_HCIUSB_ZERO_PACKET
62#undef URB_ZERO_PACKET
63#define URB_ZERO_PACKET 0
64#endif
65
66static int ignore = 0;
Marcel Holtmann7ef934b2005-11-08 09:57:05 -080067static int ignore_dga = 0;
Marcel Holtmann0915e882005-09-13 01:32:37 +020068static int ignore_csr = 0;
69static int ignore_sniffer = 0;
Marcel Holtmann520ca782006-07-14 16:01:52 +020070static int disable_scofix = 0;
71static int force_scofix = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070072static int reset = 0;
73
74#ifdef CONFIG_BT_HCIUSB_SCO
75static int isoc = 2;
76#endif
77
Marcel Holtmann0915e882005-09-13 01:32:37 +020078#define VERSION "2.9"
Linus Torvalds1da177e2005-04-16 15:20:36 -070079
80static struct usb_driver hci_usb_driver;
81
82static struct usb_device_id bluetooth_ids[] = {
83 /* Generic Bluetooth USB device */
84 { USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },
85
86 /* AVM BlueFRITZ! USB v2.0 */
87 { USB_DEVICE(0x057c, 0x3800) },
88
89 /* Bluetooth Ultraport Module from IBM */
90 { USB_DEVICE(0x04bf, 0x030a) },
91
92 /* ALPS Modules with non-standard id */
93 { USB_DEVICE(0x044e, 0x3001) },
94 { USB_DEVICE(0x044e, 0x3002) },
95
96 /* Ericsson with non-standard id */
97 { USB_DEVICE(0x0bdb, 0x1002) },
98
Marcel Holtmann62ae1592006-09-21 16:19:55 +020099 /* Canyon CN-BTU1 with HID interfaces */
100 { USB_DEVICE(0x0c10, 0x0000), .driver_info = HCI_RESET },
101
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 { } /* Terminating entry */
103};
104
105MODULE_DEVICE_TABLE (usb, bluetooth_ids);
106
107static struct usb_device_id blacklist_ids[] = {
Marcel Holtmann0915e882005-09-13 01:32:37 +0200108 /* CSR BlueCore devices */
109 { USB_DEVICE(0x0a12, 0x0001), .driver_info = HCI_CSR },
110
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111 /* Broadcom BCM2033 without firmware */
112 { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE },
113
114 /* Broadcom BCM2035 */
Marcel Holtmanne9e92902006-07-18 18:32:33 +0200115 { USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 { USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 },
117
Marcel Holtmann520ca782006-07-14 16:01:52 +0200118 /* IBM/Lenovo ThinkPad with Broadcom chip */
119 { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU },
Marcel Holtmann5939be42007-01-08 02:16:46 +0100120 { USB_DEVICE(0x0a5c, 0x2110), .driver_info = HCI_WRONG_SCO_MTU },
Marcel Holtmann520ca782006-07-14 16:01:52 +0200121
Marcel Holtmann0eab9342006-10-20 08:55:29 +0200122 /* ANYCOM Bluetooth USB-200 and USB-250 */
123 { USB_DEVICE(0x0a5c, 0x2111), .driver_info = HCI_RESET },
124
Marcel Holtmannda942702007-01-08 02:16:50 +0100125 /* HP laptop with Broadcom chip */
126 { USB_DEVICE(0x03f0, 0x171d), .driver_info = HCI_WRONG_SCO_MTU },
127
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128 /* Microsoft Wireless Transceiver for Bluetooth 2.0 */
129 { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
130
Marcel Holtmanncad0f622005-08-06 12:36:36 +0200131 /* Kensington Bluetooth USB adapter */
132 { USB_DEVICE(0x047d, 0x105d), .driver_info = HCI_RESET },
Olivier Galibert71c83512006-12-19 13:15:25 -0800133 { USB_DEVICE(0x047d, 0x105e), .driver_info = HCI_WRONG_SCO_MTU },
Marcel Holtmanncad0f622005-08-06 12:36:36 +0200134
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135 /* ISSC Bluetooth Adapter v3.1 */
136 { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
137
Marcel Holtmann8e4f7232006-07-18 18:04:59 +0200138 /* RTX Telecom based adapters with buggy SCO support */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139 { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
Marcel Holtmann8e4f7232006-07-18 18:04:59 +0200140 { USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141
Marcel Holtmannea9727f2006-07-18 17:47:40 +0200142 /* Belkin F8T012 and F8T013 devices */
Marcel Holtmannda1f5192006-07-03 10:02:29 +0200143 { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU },
Marcel Holtmannea9727f2006-07-18 17:47:40 +0200144 { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_WRONG_SCO_MTU },
Marcel Holtmannda1f5192006-07-03 10:02:29 +0200145
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 /* Digianswer devices */
147 { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
148 { USB_DEVICE(0x08fd, 0x0002), .driver_info = HCI_IGNORE },
149
150 /* CSR BlueCore Bluetooth Sniffer */
151 { USB_DEVICE(0x0a12, 0x0002), .driver_info = HCI_SNIFFER },
152
Marcel Holtmann2b86ad22006-07-03 10:02:18 +0200153 /* Frontline ComProbe Bluetooth Sniffer */
154 { USB_DEVICE(0x16d3, 0x0002), .driver_info = HCI_SNIFFER },
155
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 { } /* Terminating entry */
157};
158
Al Virodd0fc662005-10-07 07:46:04 +0100159static struct _urb *_urb_alloc(int isoc, gfp_t gfp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160{
161 struct _urb *_urb = kmalloc(sizeof(struct _urb) +
162 sizeof(struct usb_iso_packet_descriptor) * isoc, gfp);
163 if (_urb) {
164 memset(_urb, 0, sizeof(*_urb));
165 usb_init_urb(&_urb->urb);
166 }
167 return _urb;
168}
169
170static struct _urb *_urb_dequeue(struct _urb_queue *q)
171{
172 struct _urb *_urb = NULL;
173 unsigned long flags;
174 spin_lock_irqsave(&q->lock, flags);
175 {
176 struct list_head *head = &q->head;
177 struct list_head *next = head->next;
178 if (next != head) {
179 _urb = list_entry(next, struct _urb, list);
180 list_del(next); _urb->queue = NULL;
181 }
182 }
183 spin_unlock_irqrestore(&q->lock, flags);
184 return _urb;
185}
186
David Howells7d12e782006-10-05 14:55:46 +0100187static void hci_usb_rx_complete(struct urb *urb);
188static void hci_usb_tx_complete(struct urb *urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189
190#define __pending_tx(husb, type) (&husb->pending_tx[type-1])
191#define __pending_q(husb, type) (&husb->pending_q[type-1])
192#define __completed_q(husb, type) (&husb->completed_q[type-1])
193#define __transmit_q(husb, type) (&husb->transmit_q[type-1])
194#define __reassembly(husb, type) (husb->reassembly[type-1])
195
196static inline struct _urb *__get_completed(struct hci_usb *husb, int type)
197{
198 return _urb_dequeue(__completed_q(husb, type));
199}
200
201#ifdef CONFIG_BT_HCIUSB_SCO
202static void __fill_isoc_desc(struct urb *urb, int len, int mtu)
203{
204 int offset = 0, i;
205
206 BT_DBG("len %d mtu %d", len, mtu);
207
208 for (i=0; i < HCI_MAX_ISOC_FRAMES && len >= mtu; i++, offset += mtu, len -= mtu) {
209 urb->iso_frame_desc[i].offset = offset;
210 urb->iso_frame_desc[i].length = mtu;
211 BT_DBG("desc %d offset %d len %d", i, offset, mtu);
212 }
213 if (len && i < HCI_MAX_ISOC_FRAMES) {
214 urb->iso_frame_desc[i].offset = offset;
215 urb->iso_frame_desc[i].length = len;
216 BT_DBG("desc %d offset %d len %d", i, offset, len);
217 i++;
218 }
219 urb->number_of_packets = i;
220}
221#endif
222
223static int hci_usb_intr_rx_submit(struct hci_usb *husb)
224{
225 struct _urb *_urb;
226 struct urb *urb;
227 int err, pipe, interval, size;
228 void *buf;
229
230 BT_DBG("%s", husb->hdev->name);
231
232 size = le16_to_cpu(husb->intr_in_ep->desc.wMaxPacketSize);
233
234 buf = kmalloc(size, GFP_ATOMIC);
235 if (!buf)
236 return -ENOMEM;
237
238 _urb = _urb_alloc(0, GFP_ATOMIC);
239 if (!_urb) {
240 kfree(buf);
241 return -ENOMEM;
242 }
243 _urb->type = HCI_EVENT_PKT;
244 _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
245
246 urb = &_urb->urb;
247 pipe = usb_rcvintpipe(husb->udev, husb->intr_in_ep->desc.bEndpointAddress);
248 interval = husb->intr_in_ep->desc.bInterval;
249 usb_fill_int_urb(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb, interval);
250
251 err = usb_submit_urb(urb, GFP_ATOMIC);
252 if (err) {
253 BT_ERR("%s intr rx submit failed urb %p err %d",
254 husb->hdev->name, urb, err);
255 _urb_unlink(_urb);
256 _urb_free(_urb);
257 kfree(buf);
258 }
259 return err;
260}
261
262static int hci_usb_bulk_rx_submit(struct hci_usb *husb)
263{
264 struct _urb *_urb;
265 struct urb *urb;
266 int err, pipe, size = HCI_MAX_FRAME_SIZE;
267 void *buf;
268
269 buf = kmalloc(size, GFP_ATOMIC);
270 if (!buf)
271 return -ENOMEM;
272
273 _urb = _urb_alloc(0, GFP_ATOMIC);
274 if (!_urb) {
275 kfree(buf);
276 return -ENOMEM;
277 }
278 _urb->type = HCI_ACLDATA_PKT;
279 _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
280
281 urb = &_urb->urb;
282 pipe = usb_rcvbulkpipe(husb->udev, husb->bulk_in_ep->desc.bEndpointAddress);
283 usb_fill_bulk_urb(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb);
284 urb->transfer_flags = 0;
285
286 BT_DBG("%s urb %p", husb->hdev->name, urb);
287
288 err = usb_submit_urb(urb, GFP_ATOMIC);
289 if (err) {
290 BT_ERR("%s bulk rx submit failed urb %p err %d",
291 husb->hdev->name, urb, err);
292 _urb_unlink(_urb);
293 _urb_free(_urb);
294 kfree(buf);
295 }
296 return err;
297}
298
299#ifdef CONFIG_BT_HCIUSB_SCO
300static int hci_usb_isoc_rx_submit(struct hci_usb *husb)
301{
302 struct _urb *_urb;
303 struct urb *urb;
304 int err, mtu, size;
305 void *buf;
306
307 mtu = le16_to_cpu(husb->isoc_in_ep->desc.wMaxPacketSize);
308 size = mtu * HCI_MAX_ISOC_FRAMES;
309
310 buf = kmalloc(size, GFP_ATOMIC);
311 if (!buf)
312 return -ENOMEM;
313
314 _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
315 if (!_urb) {
316 kfree(buf);
317 return -ENOMEM;
318 }
319 _urb->type = HCI_SCODATA_PKT;
320 _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
321
322 urb = &_urb->urb;
323
324 urb->context = husb;
325 urb->dev = husb->udev;
326 urb->pipe = usb_rcvisocpipe(husb->udev, husb->isoc_in_ep->desc.bEndpointAddress);
327 urb->complete = hci_usb_rx_complete;
328
329 urb->interval = husb->isoc_in_ep->desc.bInterval;
330
331 urb->transfer_buffer_length = size;
332 urb->transfer_buffer = buf;
333 urb->transfer_flags = URB_ISO_ASAP;
334
335 __fill_isoc_desc(urb, size, mtu);
336
337 BT_DBG("%s urb %p", husb->hdev->name, urb);
338
339 err = usb_submit_urb(urb, GFP_ATOMIC);
340 if (err) {
341 BT_ERR("%s isoc rx submit failed urb %p err %d",
342 husb->hdev->name, urb, err);
343 _urb_unlink(_urb);
344 _urb_free(_urb);
345 kfree(buf);
346 }
347 return err;
348}
349#endif
350
351/* Initialize device */
352static int hci_usb_open(struct hci_dev *hdev)
353{
354 struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
355 int i, err;
356 unsigned long flags;
357
358 BT_DBG("%s", hdev->name);
359
360 if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
361 return 0;
362
363 write_lock_irqsave(&husb->completion_lock, flags);
364
365 err = hci_usb_intr_rx_submit(husb);
366 if (!err) {
367 for (i = 0; i < HCI_MAX_BULK_RX; i++)
368 hci_usb_bulk_rx_submit(husb);
369
370#ifdef CONFIG_BT_HCIUSB_SCO
371 if (husb->isoc_iface)
372 for (i = 0; i < HCI_MAX_ISOC_RX; i++)
373 hci_usb_isoc_rx_submit(husb);
374#endif
375 } else {
376 clear_bit(HCI_RUNNING, &hdev->flags);
377 }
378
379 write_unlock_irqrestore(&husb->completion_lock, flags);
380 return err;
381}
382
383/* Reset device */
384static int hci_usb_flush(struct hci_dev *hdev)
385{
386 struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
387 int i;
388
389 BT_DBG("%s", hdev->name);
390
391 for (i = 0; i < 4; i++)
392 skb_queue_purge(&husb->transmit_q[i]);
393 return 0;
394}
395
396static void hci_usb_unlink_urbs(struct hci_usb *husb)
397{
398 int i;
399
400 BT_DBG("%s", husb->hdev->name);
401
402 for (i = 0; i < 4; i++) {
403 struct _urb *_urb;
404 struct urb *urb;
405
406 /* Kill pending requests */
407 while ((_urb = _urb_dequeue(&husb->pending_q[i]))) {
408 urb = &_urb->urb;
409 BT_DBG("%s unlinking _urb %p type %d urb %p",
410 husb->hdev->name, _urb, _urb->type, urb);
411 usb_kill_urb(urb);
412 _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
413 }
414
415 /* Release completed requests */
416 while ((_urb = _urb_dequeue(&husb->completed_q[i]))) {
417 urb = &_urb->urb;
418 BT_DBG("%s freeing _urb %p type %d urb %p",
419 husb->hdev->name, _urb, _urb->type, urb);
Marcel Holtmanne9a3e672005-08-06 12:36:47 +0200420 kfree(urb->setup_packet);
421 kfree(urb->transfer_buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 _urb_free(_urb);
423 }
424
425 /* Release reassembly buffers */
426 if (husb->reassembly[i]) {
427 kfree_skb(husb->reassembly[i]);
428 husb->reassembly[i] = NULL;
429 }
430 }
431}
432
433/* Close device */
434static int hci_usb_close(struct hci_dev *hdev)
435{
436 struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
437 unsigned long flags;
438
439 if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
440 return 0;
441
442 BT_DBG("%s", hdev->name);
443
444 /* Synchronize with completion handlers */
445 write_lock_irqsave(&husb->completion_lock, flags);
446 write_unlock_irqrestore(&husb->completion_lock, flags);
447
448 hci_usb_unlink_urbs(husb);
449 hci_usb_flush(hdev);
450 return 0;
451}
452
453static int __tx_submit(struct hci_usb *husb, struct _urb *_urb)
454{
455 struct urb *urb = &_urb->urb;
456 int err;
457
458 BT_DBG("%s urb %p type %d", husb->hdev->name, urb, _urb->type);
459
460 _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
461 err = usb_submit_urb(urb, GFP_ATOMIC);
462 if (err) {
463 BT_ERR("%s tx submit failed urb %p type %d err %d",
464 husb->hdev->name, urb, _urb->type, err);
465 _urb_unlink(_urb);
466 _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
467 } else
468 atomic_inc(__pending_tx(husb, _urb->type));
469
470 return err;
471}
472
473static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
474{
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700475 struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 struct usb_ctrlrequest *dr;
477 struct urb *urb;
478
479 if (!_urb) {
480 _urb = _urb_alloc(0, GFP_ATOMIC);
481 if (!_urb)
482 return -ENOMEM;
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700483 _urb->type = bt_cb(skb)->pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700484
485 dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
486 if (!dr) {
487 _urb_free(_urb);
488 return -ENOMEM;
489 }
490 } else
491 dr = (void *) _urb->urb.setup_packet;
492
493 dr->bRequestType = husb->ctrl_req;
494 dr->bRequest = 0;
495 dr->wIndex = 0;
496 dr->wValue = 0;
497 dr->wLength = __cpu_to_le16(skb->len);
498
499 urb = &_urb->urb;
500 usb_fill_control_urb(urb, husb->udev, usb_sndctrlpipe(husb->udev, 0),
501 (void *) dr, skb->data, skb->len, hci_usb_tx_complete, husb);
502
503 BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len);
504
505 _urb->priv = skb;
506 return __tx_submit(husb, _urb);
507}
508
509static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
510{
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700511 struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 struct urb *urb;
513 int pipe;
514
515 if (!_urb) {
516 _urb = _urb_alloc(0, GFP_ATOMIC);
517 if (!_urb)
518 return -ENOMEM;
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700519 _urb->type = bt_cb(skb)->pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700520 }
521
522 urb = &_urb->urb;
523 pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep->desc.bEndpointAddress);
524 usb_fill_bulk_urb(urb, husb->udev, pipe, skb->data, skb->len,
525 hci_usb_tx_complete, husb);
526 urb->transfer_flags = URB_ZERO_PACKET;
527
528 BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len);
529
530 _urb->priv = skb;
531 return __tx_submit(husb, _urb);
532}
533
534#ifdef CONFIG_BT_HCIUSB_SCO
535static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
536{
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700537 struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 struct urb *urb;
539
540 if (!_urb) {
541 _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
542 if (!_urb)
543 return -ENOMEM;
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700544 _urb->type = bt_cb(skb)->pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 }
546
547 BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len);
548
549 urb = &_urb->urb;
550
551 urb->context = husb;
552 urb->dev = husb->udev;
553 urb->pipe = usb_sndisocpipe(husb->udev, husb->isoc_out_ep->desc.bEndpointAddress);
554 urb->complete = hci_usb_tx_complete;
555 urb->transfer_flags = URB_ISO_ASAP;
556
557 urb->interval = husb->isoc_out_ep->desc.bInterval;
558
559 urb->transfer_buffer = skb->data;
560 urb->transfer_buffer_length = skb->len;
561
562 __fill_isoc_desc(urb, skb->len, le16_to_cpu(husb->isoc_out_ep->desc.wMaxPacketSize));
563
564 _urb->priv = skb;
565 return __tx_submit(husb, _urb);
566}
567#endif
568
569static void hci_usb_tx_process(struct hci_usb *husb)
570{
571 struct sk_buff_head *q;
572 struct sk_buff *skb;
573
574 BT_DBG("%s", husb->hdev->name);
575
576 do {
577 clear_bit(HCI_USB_TX_WAKEUP, &husb->state);
578
579 /* Process command queue */
580 q = __transmit_q(husb, HCI_COMMAND_PKT);
581 if (!atomic_read(__pending_tx(husb, HCI_COMMAND_PKT)) &&
582 (skb = skb_dequeue(q))) {
583 if (hci_usb_send_ctrl(husb, skb) < 0)
584 skb_queue_head(q, skb);
585 }
586
587#ifdef CONFIG_BT_HCIUSB_SCO
588 /* Process SCO queue */
589 q = __transmit_q(husb, HCI_SCODATA_PKT);
590 if (atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) < HCI_MAX_ISOC_TX &&
591 (skb = skb_dequeue(q))) {
592 if (hci_usb_send_isoc(husb, skb) < 0)
593 skb_queue_head(q, skb);
594 }
595#endif
596
597 /* Process ACL queue */
598 q = __transmit_q(husb, HCI_ACLDATA_PKT);
599 while (atomic_read(__pending_tx(husb, HCI_ACLDATA_PKT)) < HCI_MAX_BULK_TX &&
600 (skb = skb_dequeue(q))) {
601 if (hci_usb_send_bulk(husb, skb) < 0) {
602 skb_queue_head(q, skb);
603 break;
604 }
605 }
606 } while(test_bit(HCI_USB_TX_WAKEUP, &husb->state));
607}
608
609static inline void hci_usb_tx_wakeup(struct hci_usb *husb)
610{
611 /* Serialize TX queue processing to avoid data reordering */
612 if (!test_and_set_bit(HCI_USB_TX_PROCESS, &husb->state)) {
613 hci_usb_tx_process(husb);
614 clear_bit(HCI_USB_TX_PROCESS, &husb->state);
615 } else
616 set_bit(HCI_USB_TX_WAKEUP, &husb->state);
617}
618
619/* Send frames from HCI layer */
620static int hci_usb_send_frame(struct sk_buff *skb)
621{
622 struct hci_dev *hdev = (struct hci_dev *) skb->dev;
623 struct hci_usb *husb;
624
625 if (!hdev) {
626 BT_ERR("frame for uknown device (hdev=NULL)");
627 return -ENODEV;
628 }
629
630 if (!test_bit(HCI_RUNNING, &hdev->flags))
631 return -EBUSY;
632
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700633 BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634
635 husb = (struct hci_usb *) hdev->driver_data;
636
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700637 switch (bt_cb(skb)->pkt_type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638 case HCI_COMMAND_PKT:
639 hdev->stat.cmd_tx++;
640 break;
641
642 case HCI_ACLDATA_PKT:
643 hdev->stat.acl_tx++;
644 break;
645
646#ifdef CONFIG_BT_HCIUSB_SCO
647 case HCI_SCODATA_PKT:
648 hdev->stat.sco_tx++;
649 break;
650#endif
651
652 default:
653 kfree_skb(skb);
654 return 0;
655 }
656
657 read_lock(&husb->completion_lock);
658
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700659 skb_queue_tail(__transmit_q(husb, bt_cb(skb)->pkt_type), skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 hci_usb_tx_wakeup(husb);
661
662 read_unlock(&husb->completion_lock);
663 return 0;
664}
665
666static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int count)
667{
668 BT_DBG("%s type %d data %p count %d", husb->hdev->name, type, data, count);
669
670 husb->hdev->stat.byte_rx += count;
671
672 while (count) {
673 struct sk_buff *skb = __reassembly(husb, type);
674 struct { int expect; } *scb;
675 int len = 0;
676
677 if (!skb) {
678 /* Start of the frame */
679
680 switch (type) {
681 case HCI_EVENT_PKT:
682 if (count >= HCI_EVENT_HDR_SIZE) {
683 struct hci_event_hdr *h = data;
684 len = HCI_EVENT_HDR_SIZE + h->plen;
685 } else
686 return -EILSEQ;
687 break;
688
689 case HCI_ACLDATA_PKT:
690 if (count >= HCI_ACL_HDR_SIZE) {
691 struct hci_acl_hdr *h = data;
692 len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen);
693 } else
694 return -EILSEQ;
695 break;
696#ifdef CONFIG_BT_HCIUSB_SCO
697 case HCI_SCODATA_PKT:
698 if (count >= HCI_SCO_HDR_SIZE) {
699 struct hci_sco_hdr *h = data;
700 len = HCI_SCO_HDR_SIZE + h->dlen;
701 } else
702 return -EILSEQ;
703 break;
704#endif
705 }
706 BT_DBG("new packet len %d", len);
707
708 skb = bt_skb_alloc(len, GFP_ATOMIC);
709 if (!skb) {
710 BT_ERR("%s no memory for the packet", husb->hdev->name);
711 return -ENOMEM;
712 }
713 skb->dev = (void *) husb->hdev;
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700714 bt_cb(skb)->pkt_type = type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715
716 __reassembly(husb, type) = skb;
717
718 scb = (void *) skb->cb;
719 scb->expect = len;
720 } else {
721 /* Continuation */
722 scb = (void *) skb->cb;
723 len = scb->expect;
724 }
725
726 len = min(len, count);
727
728 memcpy(skb_put(skb, len), data, len);
729
730 scb->expect -= len;
731 if (!scb->expect) {
732 /* Complete frame */
733 __reassembly(husb, type) = NULL;
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700734 bt_cb(skb)->pkt_type = type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 hci_recv_frame(skb);
736 }
737
738 count -= len; data += len;
739 }
740 return 0;
741}
742
David Howells7d12e782006-10-05 14:55:46 +0100743static void hci_usb_rx_complete(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744{
745 struct _urb *_urb = container_of(urb, struct _urb, urb);
746 struct hci_usb *husb = (void *) urb->context;
747 struct hci_dev *hdev = husb->hdev;
748 int err, count = urb->actual_length;
749
750 BT_DBG("%s urb %p type %d status %d count %d flags %x", hdev->name, urb,
751 _urb->type, urb->status, count, urb->transfer_flags);
752
753 read_lock(&husb->completion_lock);
754
755 if (!test_bit(HCI_RUNNING, &hdev->flags))
756 goto unlock;
757
758 if (urb->status || !count)
759 goto resubmit;
760
761 if (_urb->type == HCI_SCODATA_PKT) {
762#ifdef CONFIG_BT_HCIUSB_SCO
763 int i;
764 for (i=0; i < urb->number_of_packets; i++) {
765 BT_DBG("desc %d status %d offset %d len %d", i,
766 urb->iso_frame_desc[i].status,
767 urb->iso_frame_desc[i].offset,
768 urb->iso_frame_desc[i].actual_length);
769
770 if (!urb->iso_frame_desc[i].status)
771 __recv_frame(husb, _urb->type,
772 urb->transfer_buffer + urb->iso_frame_desc[i].offset,
773 urb->iso_frame_desc[i].actual_length);
774 }
775#else
776 ;
777#endif
778 } else {
779 err = __recv_frame(husb, _urb->type, urb->transfer_buffer, count);
780 if (err < 0) {
781 BT_ERR("%s corrupted packet: type %d count %d",
782 husb->hdev->name, _urb->type, count);
783 hdev->stat.err_rx++;
784 }
785 }
786
787resubmit:
788 urb->dev = husb->udev;
789 err = usb_submit_urb(urb, GFP_ATOMIC);
790 BT_DBG("%s urb %p type %d resubmit status %d", hdev->name, urb,
791 _urb->type, err);
792
793unlock:
794 read_unlock(&husb->completion_lock);
795}
796
David Howells7d12e782006-10-05 14:55:46 +0100797static void hci_usb_tx_complete(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798{
799 struct _urb *_urb = container_of(urb, struct _urb, urb);
800 struct hci_usb *husb = (void *) urb->context;
801 struct hci_dev *hdev = husb->hdev;
802
803 BT_DBG("%s urb %p status %d flags %x", hdev->name, urb,
804 urb->status, urb->transfer_flags);
805
806 atomic_dec(__pending_tx(husb, _urb->type));
807
808 urb->transfer_buffer = NULL;
809 kfree_skb((struct sk_buff *) _urb->priv);
810
811 if (!test_bit(HCI_RUNNING, &hdev->flags))
812 return;
813
814 if (!urb->status)
815 hdev->stat.byte_tx += urb->transfer_buffer_length;
816 else
817 hdev->stat.err_tx++;
818
819 read_lock(&husb->completion_lock);
820
821 _urb_unlink(_urb);
822 _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
823
824 hci_usb_tx_wakeup(husb);
825
826 read_unlock(&husb->completion_lock);
827}
828
829static void hci_usb_destruct(struct hci_dev *hdev)
830{
831 struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
832
833 BT_DBG("%s", hdev->name);
834
835 kfree(husb);
836}
837
838static void hci_usb_notify(struct hci_dev *hdev, unsigned int evt)
839{
840 BT_DBG("%s evt %d", hdev->name, evt);
841}
842
843static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
844{
845 struct usb_device *udev = interface_to_usbdev(intf);
846 struct usb_host_endpoint *bulk_out_ep = NULL;
847 struct usb_host_endpoint *bulk_in_ep = NULL;
848 struct usb_host_endpoint *intr_in_ep = NULL;
849 struct usb_host_endpoint *ep;
850 struct usb_host_interface *uif;
851 struct usb_interface *isoc_iface;
852 struct hci_usb *husb;
853 struct hci_dev *hdev;
854 int i, e, size, isoc_ifnum, isoc_alts;
855
856 BT_DBG("udev %p intf %p", udev, intf);
857
858 if (!id->driver_info) {
859 const struct usb_device_id *match;
860 match = usb_match_id(intf, blacklist_ids);
861 if (match)
862 id = match;
863 }
864
865 if (ignore || id->driver_info & HCI_IGNORE)
866 return -ENODEV;
867
Marcel Holtmann7ef934b2005-11-08 09:57:05 -0800868 if (ignore_dga && id->driver_info & HCI_DIGIANSWER)
869 return -ENODEV;
870
Marcel Holtmann0915e882005-09-13 01:32:37 +0200871 if (ignore_csr && id->driver_info & HCI_CSR)
872 return -ENODEV;
873
874 if (ignore_sniffer && id->driver_info & HCI_SNIFFER)
875 return -ENODEV;
876
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877 if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
878 return -ENODEV;
879
880 /* Find endpoints that we need */
881 uif = intf->cur_altsetting;
882 for (e = 0; e < uif->desc.bNumEndpoints; e++) {
883 ep = &uif->endpoint[e];
884
885 switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
886 case USB_ENDPOINT_XFER_INT:
887 if (ep->desc.bEndpointAddress & USB_DIR_IN)
888 intr_in_ep = ep;
889 break;
890
891 case USB_ENDPOINT_XFER_BULK:
892 if (ep->desc.bEndpointAddress & USB_DIR_IN)
893 bulk_in_ep = ep;
894 else
895 bulk_out_ep = ep;
896 break;
897 }
898 }
899
900 if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) {
901 BT_DBG("Bulk endpoints not found");
902 goto done;
903 }
904
Deepak Saxena089b1db2005-11-07 01:01:26 -0800905 if (!(husb = kzalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906 BT_ERR("Can't allocate: control structure");
907 goto done;
908 }
909
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 husb->udev = udev;
911 husb->bulk_out_ep = bulk_out_ep;
912 husb->bulk_in_ep = bulk_in_ep;
913 husb->intr_in_ep = intr_in_ep;
914
915 if (id->driver_info & HCI_DIGIANSWER)
916 husb->ctrl_req = USB_TYPE_VENDOR;
917 else
918 husb->ctrl_req = USB_TYPE_CLASS;
919
920 /* Find isochronous endpoints that we can use */
921 size = 0;
922 isoc_iface = NULL;
923 isoc_alts = 0;
924 isoc_ifnum = 1;
925
926#ifdef CONFIG_BT_HCIUSB_SCO
927 if (isoc && !(id->driver_info & (HCI_BROKEN_ISOC | HCI_SNIFFER)))
928 isoc_iface = usb_ifnum_to_if(udev, isoc_ifnum);
929
930 if (isoc_iface) {
931 int a;
932 struct usb_host_endpoint *isoc_out_ep = NULL;
933 struct usb_host_endpoint *isoc_in_ep = NULL;
934
935 for (a = 0; a < isoc_iface->num_altsetting; a++) {
936 uif = &isoc_iface->altsetting[a];
937 for (e = 0; e < uif->desc.bNumEndpoints; e++) {
938 ep = &uif->endpoint[e];
939
940 switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
941 case USB_ENDPOINT_XFER_ISOC:
942 if (le16_to_cpu(ep->desc.wMaxPacketSize) < size ||
943 uif->desc.bAlternateSetting != isoc)
944 break;
945 size = le16_to_cpu(ep->desc.wMaxPacketSize);
946
947 isoc_alts = uif->desc.bAlternateSetting;
948
949 if (ep->desc.bEndpointAddress & USB_DIR_IN)
950 isoc_in_ep = ep;
951 else
952 isoc_out_ep = ep;
953 break;
954 }
955 }
956 }
957
958 if (!isoc_in_ep || !isoc_out_ep)
959 BT_DBG("Isoc endpoints not found");
960 else {
961 BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts);
962 if (usb_driver_claim_interface(&hci_usb_driver, isoc_iface, husb) != 0)
963 BT_ERR("Can't claim isoc interface");
964 else if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
965 BT_ERR("Can't set isoc interface settings");
966 husb->isoc_iface = isoc_iface;
967 usb_driver_release_interface(&hci_usb_driver, isoc_iface);
968 husb->isoc_iface = NULL;
969 } else {
970 husb->isoc_iface = isoc_iface;
971 husb->isoc_in_ep = isoc_in_ep;
972 husb->isoc_out_ep = isoc_out_ep;
973 }
974 }
975 }
976#endif
977
978 rwlock_init(&husb->completion_lock);
979
980 for (i = 0; i < 4; i++) {
981 skb_queue_head_init(&husb->transmit_q[i]);
982 _urb_queue_init(&husb->pending_q[i]);
983 _urb_queue_init(&husb->completed_q[i]);
984 }
985
986 /* Initialize and register HCI device */
987 hdev = hci_alloc_dev();
988 if (!hdev) {
989 BT_ERR("Can't allocate HCI device");
990 goto probe_error;
991 }
992
993 husb->hdev = hdev;
994
995 hdev->type = HCI_USB;
996 hdev->driver_data = husb;
997 SET_HCIDEV_DEV(hdev, &intf->dev);
998
999 hdev->open = hci_usb_open;
1000 hdev->close = hci_usb_close;
1001 hdev->flush = hci_usb_flush;
1002 hdev->send = hci_usb_send_frame;
1003 hdev->destruct = hci_usb_destruct;
1004 hdev->notify = hci_usb_notify;
1005
1006 hdev->owner = THIS_MODULE;
1007
1008 if (reset || id->driver_info & HCI_RESET)
1009 set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
1010
Marcel Holtmann520ca782006-07-14 16:01:52 +02001011 if (force_scofix || id->driver_info & HCI_WRONG_SCO_MTU) {
1012 if (!disable_scofix)
1013 set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
1014 }
Marcel Holtmannda1f5192006-07-03 10:02:29 +02001015
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 if (id->driver_info & HCI_SNIFFER) {
1017 if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
1018 set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
1019 }
1020
1021 if (id->driver_info & HCI_BCM92035) {
1022 unsigned char cmd[] = { 0x3b, 0xfc, 0x01, 0x00 };
1023 struct sk_buff *skb;
1024
1025 skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
1026 if (skb) {
1027 memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
1028 skb_queue_tail(&hdev->driver_init, skb);
1029 }
1030 }
1031
1032 if (hci_register_dev(hdev) < 0) {
1033 BT_ERR("Can't register HCI device");
1034 hci_free_dev(hdev);
1035 goto probe_error;
1036 }
1037
1038 usb_set_intfdata(intf, husb);
1039 return 0;
1040
1041probe_error:
1042 if (husb->isoc_iface)
1043 usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
1044 kfree(husb);
1045
1046done:
1047 return -EIO;
1048}
1049
1050static void hci_usb_disconnect(struct usb_interface *intf)
1051{
1052 struct hci_usb *husb = usb_get_intfdata(intf);
1053 struct hci_dev *hdev;
1054
1055 if (!husb || intf == husb->isoc_iface)
1056 return;
1057
1058 usb_set_intfdata(intf, NULL);
1059 hdev = husb->hdev;
1060
1061 BT_DBG("%s", hdev->name);
1062
1063 hci_usb_close(hdev);
1064
1065 if (husb->isoc_iface)
1066 usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
1067
1068 if (hci_unregister_dev(hdev) < 0)
1069 BT_ERR("Can't unregister HCI device %s", hdev->name);
1070
1071 hci_free_dev(hdev);
1072}
1073
Marcel Holtmanndcdcf632006-07-03 10:02:24 +02001074static int hci_usb_suspend(struct usb_interface *intf, pm_message_t message)
1075{
1076 struct hci_usb *husb = usb_get_intfdata(intf);
1077 struct list_head killed;
1078 unsigned long flags;
1079 int i;
1080
1081 if (!husb || intf == husb->isoc_iface)
1082 return 0;
1083
1084 hci_suspend_dev(husb->hdev);
1085
1086 INIT_LIST_HEAD(&killed);
1087
1088 for (i = 0; i < 4; i++) {
1089 struct _urb_queue *q = &husb->pending_q[i];
1090 struct _urb *_urb, *_tmp;
1091
1092 while ((_urb = _urb_dequeue(q))) {
1093 /* reset queue since _urb_dequeue sets it to NULL */
1094 _urb->queue = q;
1095 usb_kill_urb(&_urb->urb);
1096 list_add(&_urb->list, &killed);
1097 }
1098
1099 spin_lock_irqsave(&q->lock, flags);
1100
1101 list_for_each_entry_safe(_urb, _tmp, &killed, list) {
1102 list_move_tail(&_urb->list, &q->head);
1103 }
1104
1105 spin_unlock_irqrestore(&q->lock, flags);
1106 }
1107
1108 return 0;
1109}
1110
1111static int hci_usb_resume(struct usb_interface *intf)
1112{
1113 struct hci_usb *husb = usb_get_intfdata(intf);
1114 unsigned long flags;
1115 int i, err = 0;
1116
1117 if (!husb || intf == husb->isoc_iface)
1118 return 0;
1119
1120 for (i = 0; i < 4; i++) {
1121 struct _urb_queue *q = &husb->pending_q[i];
1122 struct _urb *_urb;
1123
1124 spin_lock_irqsave(&q->lock, flags);
1125
1126 list_for_each_entry(_urb, &q->head, list) {
1127 err = usb_submit_urb(&_urb->urb, GFP_ATOMIC);
1128 if (err)
1129 break;
1130 }
1131
1132 spin_unlock_irqrestore(&q->lock, flags);
1133
1134 if (err)
1135 return -EIO;
1136 }
1137
1138 hci_resume_dev(husb->hdev);
1139
1140 return 0;
1141}
1142
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143static struct usb_driver hci_usb_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 .name = "hci_usb",
1145 .probe = hci_usb_probe,
1146 .disconnect = hci_usb_disconnect,
Marcel Holtmanndcdcf632006-07-03 10:02:24 +02001147 .suspend = hci_usb_suspend,
1148 .resume = hci_usb_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 .id_table = bluetooth_ids,
1150};
1151
1152static int __init hci_usb_init(void)
1153{
1154 int err;
1155
1156 BT_INFO("HCI USB driver ver %s", VERSION);
1157
1158 if ((err = usb_register(&hci_usb_driver)) < 0)
1159 BT_ERR("Failed to register HCI USB driver");
1160
1161 return err;
1162}
1163
1164static void __exit hci_usb_exit(void)
1165{
1166 usb_deregister(&hci_usb_driver);
1167}
1168
1169module_init(hci_usb_init);
1170module_exit(hci_usb_exit);
1171
1172module_param(ignore, bool, 0644);
1173MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
1174
Marcel Holtmann7ef934b2005-11-08 09:57:05 -08001175module_param(ignore_dga, bool, 0644);
1176MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
1177
Marcel Holtmann0915e882005-09-13 01:32:37 +02001178module_param(ignore_csr, bool, 0644);
1179MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
1180
1181module_param(ignore_sniffer, bool, 0644);
1182MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
1183
Marcel Holtmann520ca782006-07-14 16:01:52 +02001184module_param(disable_scofix, bool, 0644);
1185MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");
1186
1187module_param(force_scofix, bool, 0644);
1188MODULE_PARM_DESC(force_scofix, "Force fixup of wrong SCO buffers size");
1189
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190module_param(reset, bool, 0644);
1191MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
1192
1193#ifdef CONFIG_BT_HCIUSB_SCO
1194module_param(isoc, int, 0644);
1195MODULE_PARM_DESC(isoc, "Set isochronous transfers for SCO over HCI support");
1196#endif
1197
1198MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
1199MODULE_DESCRIPTION("Bluetooth HCI USB driver ver " VERSION);
1200MODULE_VERSION(VERSION);
1201MODULE_LICENSE("GPL");