blob: 93d2836cac004fed00424133752604c73e247bf2 [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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 /* Microsoft Wireless Transceiver for Bluetooth 2.0 */
126 { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
127
Marcel Holtmanncad0f622005-08-06 12:36:36 +0200128 /* Kensington Bluetooth USB adapter */
129 { USB_DEVICE(0x047d, 0x105d), .driver_info = HCI_RESET },
Olivier Galibert71c83512006-12-19 13:15:25 -0800130 { USB_DEVICE(0x047d, 0x105e), .driver_info = HCI_WRONG_SCO_MTU },
Marcel Holtmanncad0f622005-08-06 12:36:36 +0200131
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 /* ISSC Bluetooth Adapter v3.1 */
133 { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
134
Marcel Holtmann8e4f7232006-07-18 18:04:59 +0200135 /* RTX Telecom based adapters with buggy SCO support */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700136 { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
Marcel Holtmann8e4f7232006-07-18 18:04:59 +0200137 { USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138
Marcel Holtmannea9727f2006-07-18 17:47:40 +0200139 /* Belkin F8T012 and F8T013 devices */
Marcel Holtmannda1f5192006-07-03 10:02:29 +0200140 { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU },
Marcel Holtmannea9727f2006-07-18 17:47:40 +0200141 { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_WRONG_SCO_MTU },
Marcel Holtmannda1f5192006-07-03 10:02:29 +0200142
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143 /* Digianswer devices */
144 { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
145 { USB_DEVICE(0x08fd, 0x0002), .driver_info = HCI_IGNORE },
146
147 /* CSR BlueCore Bluetooth Sniffer */
148 { USB_DEVICE(0x0a12, 0x0002), .driver_info = HCI_SNIFFER },
149
Marcel Holtmann2b86ad22006-07-03 10:02:18 +0200150 /* Frontline ComProbe Bluetooth Sniffer */
151 { USB_DEVICE(0x16d3, 0x0002), .driver_info = HCI_SNIFFER },
152
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153 { } /* Terminating entry */
154};
155
Al Virodd0fc662005-10-07 07:46:04 +0100156static struct _urb *_urb_alloc(int isoc, gfp_t gfp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157{
158 struct _urb *_urb = kmalloc(sizeof(struct _urb) +
159 sizeof(struct usb_iso_packet_descriptor) * isoc, gfp);
160 if (_urb) {
161 memset(_urb, 0, sizeof(*_urb));
162 usb_init_urb(&_urb->urb);
163 }
164 return _urb;
165}
166
167static struct _urb *_urb_dequeue(struct _urb_queue *q)
168{
169 struct _urb *_urb = NULL;
170 unsigned long flags;
171 spin_lock_irqsave(&q->lock, flags);
172 {
173 struct list_head *head = &q->head;
174 struct list_head *next = head->next;
175 if (next != head) {
176 _urb = list_entry(next, struct _urb, list);
177 list_del(next); _urb->queue = NULL;
178 }
179 }
180 spin_unlock_irqrestore(&q->lock, flags);
181 return _urb;
182}
183
David Howells7d12e782006-10-05 14:55:46 +0100184static void hci_usb_rx_complete(struct urb *urb);
185static void hci_usb_tx_complete(struct urb *urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186
187#define __pending_tx(husb, type) (&husb->pending_tx[type-1])
188#define __pending_q(husb, type) (&husb->pending_q[type-1])
189#define __completed_q(husb, type) (&husb->completed_q[type-1])
190#define __transmit_q(husb, type) (&husb->transmit_q[type-1])
191#define __reassembly(husb, type) (husb->reassembly[type-1])
192
193static inline struct _urb *__get_completed(struct hci_usb *husb, int type)
194{
195 return _urb_dequeue(__completed_q(husb, type));
196}
197
198#ifdef CONFIG_BT_HCIUSB_SCO
199static void __fill_isoc_desc(struct urb *urb, int len, int mtu)
200{
201 int offset = 0, i;
202
203 BT_DBG("len %d mtu %d", len, mtu);
204
205 for (i=0; i < HCI_MAX_ISOC_FRAMES && len >= mtu; i++, offset += mtu, len -= mtu) {
206 urb->iso_frame_desc[i].offset = offset;
207 urb->iso_frame_desc[i].length = mtu;
208 BT_DBG("desc %d offset %d len %d", i, offset, mtu);
209 }
210 if (len && i < HCI_MAX_ISOC_FRAMES) {
211 urb->iso_frame_desc[i].offset = offset;
212 urb->iso_frame_desc[i].length = len;
213 BT_DBG("desc %d offset %d len %d", i, offset, len);
214 i++;
215 }
216 urb->number_of_packets = i;
217}
218#endif
219
220static int hci_usb_intr_rx_submit(struct hci_usb *husb)
221{
222 struct _urb *_urb;
223 struct urb *urb;
224 int err, pipe, interval, size;
225 void *buf;
226
227 BT_DBG("%s", husb->hdev->name);
228
229 size = le16_to_cpu(husb->intr_in_ep->desc.wMaxPacketSize);
230
231 buf = kmalloc(size, GFP_ATOMIC);
232 if (!buf)
233 return -ENOMEM;
234
235 _urb = _urb_alloc(0, GFP_ATOMIC);
236 if (!_urb) {
237 kfree(buf);
238 return -ENOMEM;
239 }
240 _urb->type = HCI_EVENT_PKT;
241 _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
242
243 urb = &_urb->urb;
244 pipe = usb_rcvintpipe(husb->udev, husb->intr_in_ep->desc.bEndpointAddress);
245 interval = husb->intr_in_ep->desc.bInterval;
246 usb_fill_int_urb(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb, interval);
247
248 err = usb_submit_urb(urb, GFP_ATOMIC);
249 if (err) {
250 BT_ERR("%s intr rx submit failed urb %p err %d",
251 husb->hdev->name, urb, err);
252 _urb_unlink(_urb);
253 _urb_free(_urb);
254 kfree(buf);
255 }
256 return err;
257}
258
259static int hci_usb_bulk_rx_submit(struct hci_usb *husb)
260{
261 struct _urb *_urb;
262 struct urb *urb;
263 int err, pipe, size = HCI_MAX_FRAME_SIZE;
264 void *buf;
265
266 buf = kmalloc(size, GFP_ATOMIC);
267 if (!buf)
268 return -ENOMEM;
269
270 _urb = _urb_alloc(0, GFP_ATOMIC);
271 if (!_urb) {
272 kfree(buf);
273 return -ENOMEM;
274 }
275 _urb->type = HCI_ACLDATA_PKT;
276 _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
277
278 urb = &_urb->urb;
279 pipe = usb_rcvbulkpipe(husb->udev, husb->bulk_in_ep->desc.bEndpointAddress);
280 usb_fill_bulk_urb(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb);
281 urb->transfer_flags = 0;
282
283 BT_DBG("%s urb %p", husb->hdev->name, urb);
284
285 err = usb_submit_urb(urb, GFP_ATOMIC);
286 if (err) {
287 BT_ERR("%s bulk rx submit failed urb %p err %d",
288 husb->hdev->name, urb, err);
289 _urb_unlink(_urb);
290 _urb_free(_urb);
291 kfree(buf);
292 }
293 return err;
294}
295
296#ifdef CONFIG_BT_HCIUSB_SCO
297static int hci_usb_isoc_rx_submit(struct hci_usb *husb)
298{
299 struct _urb *_urb;
300 struct urb *urb;
301 int err, mtu, size;
302 void *buf;
303
304 mtu = le16_to_cpu(husb->isoc_in_ep->desc.wMaxPacketSize);
305 size = mtu * HCI_MAX_ISOC_FRAMES;
306
307 buf = kmalloc(size, GFP_ATOMIC);
308 if (!buf)
309 return -ENOMEM;
310
311 _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
312 if (!_urb) {
313 kfree(buf);
314 return -ENOMEM;
315 }
316 _urb->type = HCI_SCODATA_PKT;
317 _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
318
319 urb = &_urb->urb;
320
321 urb->context = husb;
322 urb->dev = husb->udev;
323 urb->pipe = usb_rcvisocpipe(husb->udev, husb->isoc_in_ep->desc.bEndpointAddress);
324 urb->complete = hci_usb_rx_complete;
325
326 urb->interval = husb->isoc_in_ep->desc.bInterval;
327
328 urb->transfer_buffer_length = size;
329 urb->transfer_buffer = buf;
330 urb->transfer_flags = URB_ISO_ASAP;
331
332 __fill_isoc_desc(urb, size, mtu);
333
334 BT_DBG("%s urb %p", husb->hdev->name, urb);
335
336 err = usb_submit_urb(urb, GFP_ATOMIC);
337 if (err) {
338 BT_ERR("%s isoc rx submit failed urb %p err %d",
339 husb->hdev->name, urb, err);
340 _urb_unlink(_urb);
341 _urb_free(_urb);
342 kfree(buf);
343 }
344 return err;
345}
346#endif
347
348/* Initialize device */
349static int hci_usb_open(struct hci_dev *hdev)
350{
351 struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
352 int i, err;
353 unsigned long flags;
354
355 BT_DBG("%s", hdev->name);
356
357 if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
358 return 0;
359
360 write_lock_irqsave(&husb->completion_lock, flags);
361
362 err = hci_usb_intr_rx_submit(husb);
363 if (!err) {
364 for (i = 0; i < HCI_MAX_BULK_RX; i++)
365 hci_usb_bulk_rx_submit(husb);
366
367#ifdef CONFIG_BT_HCIUSB_SCO
368 if (husb->isoc_iface)
369 for (i = 0; i < HCI_MAX_ISOC_RX; i++)
370 hci_usb_isoc_rx_submit(husb);
371#endif
372 } else {
373 clear_bit(HCI_RUNNING, &hdev->flags);
374 }
375
376 write_unlock_irqrestore(&husb->completion_lock, flags);
377 return err;
378}
379
380/* Reset device */
381static int hci_usb_flush(struct hci_dev *hdev)
382{
383 struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
384 int i;
385
386 BT_DBG("%s", hdev->name);
387
388 for (i = 0; i < 4; i++)
389 skb_queue_purge(&husb->transmit_q[i]);
390 return 0;
391}
392
393static void hci_usb_unlink_urbs(struct hci_usb *husb)
394{
395 int i;
396
397 BT_DBG("%s", husb->hdev->name);
398
399 for (i = 0; i < 4; i++) {
400 struct _urb *_urb;
401 struct urb *urb;
402
403 /* Kill pending requests */
404 while ((_urb = _urb_dequeue(&husb->pending_q[i]))) {
405 urb = &_urb->urb;
406 BT_DBG("%s unlinking _urb %p type %d urb %p",
407 husb->hdev->name, _urb, _urb->type, urb);
408 usb_kill_urb(urb);
409 _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
410 }
411
412 /* Release completed requests */
413 while ((_urb = _urb_dequeue(&husb->completed_q[i]))) {
414 urb = &_urb->urb;
415 BT_DBG("%s freeing _urb %p type %d urb %p",
416 husb->hdev->name, _urb, _urb->type, urb);
Marcel Holtmanne9a3e672005-08-06 12:36:47 +0200417 kfree(urb->setup_packet);
418 kfree(urb->transfer_buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 _urb_free(_urb);
420 }
421
422 /* Release reassembly buffers */
423 if (husb->reassembly[i]) {
424 kfree_skb(husb->reassembly[i]);
425 husb->reassembly[i] = NULL;
426 }
427 }
428}
429
430/* Close device */
431static int hci_usb_close(struct hci_dev *hdev)
432{
433 struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
434 unsigned long flags;
435
436 if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
437 return 0;
438
439 BT_DBG("%s", hdev->name);
440
441 /* Synchronize with completion handlers */
442 write_lock_irqsave(&husb->completion_lock, flags);
443 write_unlock_irqrestore(&husb->completion_lock, flags);
444
445 hci_usb_unlink_urbs(husb);
446 hci_usb_flush(hdev);
447 return 0;
448}
449
450static int __tx_submit(struct hci_usb *husb, struct _urb *_urb)
451{
452 struct urb *urb = &_urb->urb;
453 int err;
454
455 BT_DBG("%s urb %p type %d", husb->hdev->name, urb, _urb->type);
456
457 _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
458 err = usb_submit_urb(urb, GFP_ATOMIC);
459 if (err) {
460 BT_ERR("%s tx submit failed urb %p type %d err %d",
461 husb->hdev->name, urb, _urb->type, err);
462 _urb_unlink(_urb);
463 _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
464 } else
465 atomic_inc(__pending_tx(husb, _urb->type));
466
467 return err;
468}
469
470static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
471{
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700472 struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 struct usb_ctrlrequest *dr;
474 struct urb *urb;
475
476 if (!_urb) {
477 _urb = _urb_alloc(0, GFP_ATOMIC);
478 if (!_urb)
479 return -ENOMEM;
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700480 _urb->type = bt_cb(skb)->pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481
482 dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
483 if (!dr) {
484 _urb_free(_urb);
485 return -ENOMEM;
486 }
487 } else
488 dr = (void *) _urb->urb.setup_packet;
489
490 dr->bRequestType = husb->ctrl_req;
491 dr->bRequest = 0;
492 dr->wIndex = 0;
493 dr->wValue = 0;
494 dr->wLength = __cpu_to_le16(skb->len);
495
496 urb = &_urb->urb;
497 usb_fill_control_urb(urb, husb->udev, usb_sndctrlpipe(husb->udev, 0),
498 (void *) dr, skb->data, skb->len, hci_usb_tx_complete, husb);
499
500 BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len);
501
502 _urb->priv = skb;
503 return __tx_submit(husb, _urb);
504}
505
506static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
507{
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700508 struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 struct urb *urb;
510 int pipe;
511
512 if (!_urb) {
513 _urb = _urb_alloc(0, GFP_ATOMIC);
514 if (!_urb)
515 return -ENOMEM;
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700516 _urb->type = bt_cb(skb)->pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 }
518
519 urb = &_urb->urb;
520 pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep->desc.bEndpointAddress);
521 usb_fill_bulk_urb(urb, husb->udev, pipe, skb->data, skb->len,
522 hci_usb_tx_complete, husb);
523 urb->transfer_flags = URB_ZERO_PACKET;
524
525 BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len);
526
527 _urb->priv = skb;
528 return __tx_submit(husb, _urb);
529}
530
531#ifdef CONFIG_BT_HCIUSB_SCO
532static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
533{
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700534 struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 struct urb *urb;
536
537 if (!_urb) {
538 _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
539 if (!_urb)
540 return -ENOMEM;
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700541 _urb->type = bt_cb(skb)->pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 }
543
544 BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len);
545
546 urb = &_urb->urb;
547
548 urb->context = husb;
549 urb->dev = husb->udev;
550 urb->pipe = usb_sndisocpipe(husb->udev, husb->isoc_out_ep->desc.bEndpointAddress);
551 urb->complete = hci_usb_tx_complete;
552 urb->transfer_flags = URB_ISO_ASAP;
553
554 urb->interval = husb->isoc_out_ep->desc.bInterval;
555
556 urb->transfer_buffer = skb->data;
557 urb->transfer_buffer_length = skb->len;
558
559 __fill_isoc_desc(urb, skb->len, le16_to_cpu(husb->isoc_out_ep->desc.wMaxPacketSize));
560
561 _urb->priv = skb;
562 return __tx_submit(husb, _urb);
563}
564#endif
565
566static void hci_usb_tx_process(struct hci_usb *husb)
567{
568 struct sk_buff_head *q;
569 struct sk_buff *skb;
570
571 BT_DBG("%s", husb->hdev->name);
572
573 do {
574 clear_bit(HCI_USB_TX_WAKEUP, &husb->state);
575
576 /* Process command queue */
577 q = __transmit_q(husb, HCI_COMMAND_PKT);
578 if (!atomic_read(__pending_tx(husb, HCI_COMMAND_PKT)) &&
579 (skb = skb_dequeue(q))) {
580 if (hci_usb_send_ctrl(husb, skb) < 0)
581 skb_queue_head(q, skb);
582 }
583
584#ifdef CONFIG_BT_HCIUSB_SCO
585 /* Process SCO queue */
586 q = __transmit_q(husb, HCI_SCODATA_PKT);
587 if (atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) < HCI_MAX_ISOC_TX &&
588 (skb = skb_dequeue(q))) {
589 if (hci_usb_send_isoc(husb, skb) < 0)
590 skb_queue_head(q, skb);
591 }
592#endif
593
594 /* Process ACL queue */
595 q = __transmit_q(husb, HCI_ACLDATA_PKT);
596 while (atomic_read(__pending_tx(husb, HCI_ACLDATA_PKT)) < HCI_MAX_BULK_TX &&
597 (skb = skb_dequeue(q))) {
598 if (hci_usb_send_bulk(husb, skb) < 0) {
599 skb_queue_head(q, skb);
600 break;
601 }
602 }
603 } while(test_bit(HCI_USB_TX_WAKEUP, &husb->state));
604}
605
606static inline void hci_usb_tx_wakeup(struct hci_usb *husb)
607{
608 /* Serialize TX queue processing to avoid data reordering */
609 if (!test_and_set_bit(HCI_USB_TX_PROCESS, &husb->state)) {
610 hci_usb_tx_process(husb);
611 clear_bit(HCI_USB_TX_PROCESS, &husb->state);
612 } else
613 set_bit(HCI_USB_TX_WAKEUP, &husb->state);
614}
615
616/* Send frames from HCI layer */
617static int hci_usb_send_frame(struct sk_buff *skb)
618{
619 struct hci_dev *hdev = (struct hci_dev *) skb->dev;
620 struct hci_usb *husb;
621
622 if (!hdev) {
623 BT_ERR("frame for uknown device (hdev=NULL)");
624 return -ENODEV;
625 }
626
627 if (!test_bit(HCI_RUNNING, &hdev->flags))
628 return -EBUSY;
629
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700630 BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631
632 husb = (struct hci_usb *) hdev->driver_data;
633
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700634 switch (bt_cb(skb)->pkt_type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 case HCI_COMMAND_PKT:
636 hdev->stat.cmd_tx++;
637 break;
638
639 case HCI_ACLDATA_PKT:
640 hdev->stat.acl_tx++;
641 break;
642
643#ifdef CONFIG_BT_HCIUSB_SCO
644 case HCI_SCODATA_PKT:
645 hdev->stat.sco_tx++;
646 break;
647#endif
648
649 default:
650 kfree_skb(skb);
651 return 0;
652 }
653
654 read_lock(&husb->completion_lock);
655
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700656 skb_queue_tail(__transmit_q(husb, bt_cb(skb)->pkt_type), skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 hci_usb_tx_wakeup(husb);
658
659 read_unlock(&husb->completion_lock);
660 return 0;
661}
662
663static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int count)
664{
665 BT_DBG("%s type %d data %p count %d", husb->hdev->name, type, data, count);
666
667 husb->hdev->stat.byte_rx += count;
668
669 while (count) {
670 struct sk_buff *skb = __reassembly(husb, type);
671 struct { int expect; } *scb;
672 int len = 0;
673
674 if (!skb) {
675 /* Start of the frame */
676
677 switch (type) {
678 case HCI_EVENT_PKT:
679 if (count >= HCI_EVENT_HDR_SIZE) {
680 struct hci_event_hdr *h = data;
681 len = HCI_EVENT_HDR_SIZE + h->plen;
682 } else
683 return -EILSEQ;
684 break;
685
686 case HCI_ACLDATA_PKT:
687 if (count >= HCI_ACL_HDR_SIZE) {
688 struct hci_acl_hdr *h = data;
689 len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen);
690 } else
691 return -EILSEQ;
692 break;
693#ifdef CONFIG_BT_HCIUSB_SCO
694 case HCI_SCODATA_PKT:
695 if (count >= HCI_SCO_HDR_SIZE) {
696 struct hci_sco_hdr *h = data;
697 len = HCI_SCO_HDR_SIZE + h->dlen;
698 } else
699 return -EILSEQ;
700 break;
701#endif
702 }
703 BT_DBG("new packet len %d", len);
704
705 skb = bt_skb_alloc(len, GFP_ATOMIC);
706 if (!skb) {
707 BT_ERR("%s no memory for the packet", husb->hdev->name);
708 return -ENOMEM;
709 }
710 skb->dev = (void *) husb->hdev;
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700711 bt_cb(skb)->pkt_type = type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712
713 __reassembly(husb, type) = skb;
714
715 scb = (void *) skb->cb;
716 scb->expect = len;
717 } else {
718 /* Continuation */
719 scb = (void *) skb->cb;
720 len = scb->expect;
721 }
722
723 len = min(len, count);
724
725 memcpy(skb_put(skb, len), data, len);
726
727 scb->expect -= len;
728 if (!scb->expect) {
729 /* Complete frame */
730 __reassembly(husb, type) = NULL;
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700731 bt_cb(skb)->pkt_type = type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700732 hci_recv_frame(skb);
733 }
734
735 count -= len; data += len;
736 }
737 return 0;
738}
739
David Howells7d12e782006-10-05 14:55:46 +0100740static void hci_usb_rx_complete(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741{
742 struct _urb *_urb = container_of(urb, struct _urb, urb);
743 struct hci_usb *husb = (void *) urb->context;
744 struct hci_dev *hdev = husb->hdev;
745 int err, count = urb->actual_length;
746
747 BT_DBG("%s urb %p type %d status %d count %d flags %x", hdev->name, urb,
748 _urb->type, urb->status, count, urb->transfer_flags);
749
750 read_lock(&husb->completion_lock);
751
752 if (!test_bit(HCI_RUNNING, &hdev->flags))
753 goto unlock;
754
755 if (urb->status || !count)
756 goto resubmit;
757
758 if (_urb->type == HCI_SCODATA_PKT) {
759#ifdef CONFIG_BT_HCIUSB_SCO
760 int i;
761 for (i=0; i < urb->number_of_packets; i++) {
762 BT_DBG("desc %d status %d offset %d len %d", i,
763 urb->iso_frame_desc[i].status,
764 urb->iso_frame_desc[i].offset,
765 urb->iso_frame_desc[i].actual_length);
766
767 if (!urb->iso_frame_desc[i].status)
768 __recv_frame(husb, _urb->type,
769 urb->transfer_buffer + urb->iso_frame_desc[i].offset,
770 urb->iso_frame_desc[i].actual_length);
771 }
772#else
773 ;
774#endif
775 } else {
776 err = __recv_frame(husb, _urb->type, urb->transfer_buffer, count);
777 if (err < 0) {
778 BT_ERR("%s corrupted packet: type %d count %d",
779 husb->hdev->name, _urb->type, count);
780 hdev->stat.err_rx++;
781 }
782 }
783
784resubmit:
785 urb->dev = husb->udev;
786 err = usb_submit_urb(urb, GFP_ATOMIC);
787 BT_DBG("%s urb %p type %d resubmit status %d", hdev->name, urb,
788 _urb->type, err);
789
790unlock:
791 read_unlock(&husb->completion_lock);
792}
793
David Howells7d12e782006-10-05 14:55:46 +0100794static void hci_usb_tx_complete(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795{
796 struct _urb *_urb = container_of(urb, struct _urb, urb);
797 struct hci_usb *husb = (void *) urb->context;
798 struct hci_dev *hdev = husb->hdev;
799
800 BT_DBG("%s urb %p status %d flags %x", hdev->name, urb,
801 urb->status, urb->transfer_flags);
802
803 atomic_dec(__pending_tx(husb, _urb->type));
804
805 urb->transfer_buffer = NULL;
806 kfree_skb((struct sk_buff *) _urb->priv);
807
808 if (!test_bit(HCI_RUNNING, &hdev->flags))
809 return;
810
811 if (!urb->status)
812 hdev->stat.byte_tx += urb->transfer_buffer_length;
813 else
814 hdev->stat.err_tx++;
815
816 read_lock(&husb->completion_lock);
817
818 _urb_unlink(_urb);
819 _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
820
821 hci_usb_tx_wakeup(husb);
822
823 read_unlock(&husb->completion_lock);
824}
825
826static void hci_usb_destruct(struct hci_dev *hdev)
827{
828 struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
829
830 BT_DBG("%s", hdev->name);
831
832 kfree(husb);
833}
834
835static void hci_usb_notify(struct hci_dev *hdev, unsigned int evt)
836{
837 BT_DBG("%s evt %d", hdev->name, evt);
838}
839
840static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
841{
842 struct usb_device *udev = interface_to_usbdev(intf);
843 struct usb_host_endpoint *bulk_out_ep = NULL;
844 struct usb_host_endpoint *bulk_in_ep = NULL;
845 struct usb_host_endpoint *intr_in_ep = NULL;
846 struct usb_host_endpoint *ep;
847 struct usb_host_interface *uif;
848 struct usb_interface *isoc_iface;
849 struct hci_usb *husb;
850 struct hci_dev *hdev;
851 int i, e, size, isoc_ifnum, isoc_alts;
852
853 BT_DBG("udev %p intf %p", udev, intf);
854
855 if (!id->driver_info) {
856 const struct usb_device_id *match;
857 match = usb_match_id(intf, blacklist_ids);
858 if (match)
859 id = match;
860 }
861
862 if (ignore || id->driver_info & HCI_IGNORE)
863 return -ENODEV;
864
Marcel Holtmann7ef934b2005-11-08 09:57:05 -0800865 if (ignore_dga && id->driver_info & HCI_DIGIANSWER)
866 return -ENODEV;
867
Marcel Holtmann0915e882005-09-13 01:32:37 +0200868 if (ignore_csr && id->driver_info & HCI_CSR)
869 return -ENODEV;
870
871 if (ignore_sniffer && id->driver_info & HCI_SNIFFER)
872 return -ENODEV;
873
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
875 return -ENODEV;
876
877 /* Find endpoints that we need */
878 uif = intf->cur_altsetting;
879 for (e = 0; e < uif->desc.bNumEndpoints; e++) {
880 ep = &uif->endpoint[e];
881
882 switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
883 case USB_ENDPOINT_XFER_INT:
884 if (ep->desc.bEndpointAddress & USB_DIR_IN)
885 intr_in_ep = ep;
886 break;
887
888 case USB_ENDPOINT_XFER_BULK:
889 if (ep->desc.bEndpointAddress & USB_DIR_IN)
890 bulk_in_ep = ep;
891 else
892 bulk_out_ep = ep;
893 break;
894 }
895 }
896
897 if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) {
898 BT_DBG("Bulk endpoints not found");
899 goto done;
900 }
901
Deepak Saxena089b1db2005-11-07 01:01:26 -0800902 if (!(husb = kzalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 BT_ERR("Can't allocate: control structure");
904 goto done;
905 }
906
Linus Torvalds1da177e2005-04-16 15:20:36 -0700907 husb->udev = udev;
908 husb->bulk_out_ep = bulk_out_ep;
909 husb->bulk_in_ep = bulk_in_ep;
910 husb->intr_in_ep = intr_in_ep;
911
912 if (id->driver_info & HCI_DIGIANSWER)
913 husb->ctrl_req = USB_TYPE_VENDOR;
914 else
915 husb->ctrl_req = USB_TYPE_CLASS;
916
917 /* Find isochronous endpoints that we can use */
918 size = 0;
919 isoc_iface = NULL;
920 isoc_alts = 0;
921 isoc_ifnum = 1;
922
923#ifdef CONFIG_BT_HCIUSB_SCO
924 if (isoc && !(id->driver_info & (HCI_BROKEN_ISOC | HCI_SNIFFER)))
925 isoc_iface = usb_ifnum_to_if(udev, isoc_ifnum);
926
927 if (isoc_iface) {
928 int a;
929 struct usb_host_endpoint *isoc_out_ep = NULL;
930 struct usb_host_endpoint *isoc_in_ep = NULL;
931
932 for (a = 0; a < isoc_iface->num_altsetting; a++) {
933 uif = &isoc_iface->altsetting[a];
934 for (e = 0; e < uif->desc.bNumEndpoints; e++) {
935 ep = &uif->endpoint[e];
936
937 switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
938 case USB_ENDPOINT_XFER_ISOC:
939 if (le16_to_cpu(ep->desc.wMaxPacketSize) < size ||
940 uif->desc.bAlternateSetting != isoc)
941 break;
942 size = le16_to_cpu(ep->desc.wMaxPacketSize);
943
944 isoc_alts = uif->desc.bAlternateSetting;
945
946 if (ep->desc.bEndpointAddress & USB_DIR_IN)
947 isoc_in_ep = ep;
948 else
949 isoc_out_ep = ep;
950 break;
951 }
952 }
953 }
954
955 if (!isoc_in_ep || !isoc_out_ep)
956 BT_DBG("Isoc endpoints not found");
957 else {
958 BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts);
959 if (usb_driver_claim_interface(&hci_usb_driver, isoc_iface, husb) != 0)
960 BT_ERR("Can't claim isoc interface");
961 else if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
962 BT_ERR("Can't set isoc interface settings");
963 husb->isoc_iface = isoc_iface;
964 usb_driver_release_interface(&hci_usb_driver, isoc_iface);
965 husb->isoc_iface = NULL;
966 } else {
967 husb->isoc_iface = isoc_iface;
968 husb->isoc_in_ep = isoc_in_ep;
969 husb->isoc_out_ep = isoc_out_ep;
970 }
971 }
972 }
973#endif
974
975 rwlock_init(&husb->completion_lock);
976
977 for (i = 0; i < 4; i++) {
978 skb_queue_head_init(&husb->transmit_q[i]);
979 _urb_queue_init(&husb->pending_q[i]);
980 _urb_queue_init(&husb->completed_q[i]);
981 }
982
983 /* Initialize and register HCI device */
984 hdev = hci_alloc_dev();
985 if (!hdev) {
986 BT_ERR("Can't allocate HCI device");
987 goto probe_error;
988 }
989
990 husb->hdev = hdev;
991
992 hdev->type = HCI_USB;
993 hdev->driver_data = husb;
994 SET_HCIDEV_DEV(hdev, &intf->dev);
995
996 hdev->open = hci_usb_open;
997 hdev->close = hci_usb_close;
998 hdev->flush = hci_usb_flush;
999 hdev->send = hci_usb_send_frame;
1000 hdev->destruct = hci_usb_destruct;
1001 hdev->notify = hci_usb_notify;
1002
1003 hdev->owner = THIS_MODULE;
1004
1005 if (reset || id->driver_info & HCI_RESET)
1006 set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
1007
Marcel Holtmann520ca782006-07-14 16:01:52 +02001008 if (force_scofix || id->driver_info & HCI_WRONG_SCO_MTU) {
1009 if (!disable_scofix)
1010 set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
1011 }
Marcel Holtmannda1f5192006-07-03 10:02:29 +02001012
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 if (id->driver_info & HCI_SNIFFER) {
1014 if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
1015 set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
1016 }
1017
1018 if (id->driver_info & HCI_BCM92035) {
1019 unsigned char cmd[] = { 0x3b, 0xfc, 0x01, 0x00 };
1020 struct sk_buff *skb;
1021
1022 skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
1023 if (skb) {
1024 memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
1025 skb_queue_tail(&hdev->driver_init, skb);
1026 }
1027 }
1028
1029 if (hci_register_dev(hdev) < 0) {
1030 BT_ERR("Can't register HCI device");
1031 hci_free_dev(hdev);
1032 goto probe_error;
1033 }
1034
1035 usb_set_intfdata(intf, husb);
1036 return 0;
1037
1038probe_error:
1039 if (husb->isoc_iface)
1040 usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
1041 kfree(husb);
1042
1043done:
1044 return -EIO;
1045}
1046
1047static void hci_usb_disconnect(struct usb_interface *intf)
1048{
1049 struct hci_usb *husb = usb_get_intfdata(intf);
1050 struct hci_dev *hdev;
1051
1052 if (!husb || intf == husb->isoc_iface)
1053 return;
1054
1055 usb_set_intfdata(intf, NULL);
1056 hdev = husb->hdev;
1057
1058 BT_DBG("%s", hdev->name);
1059
1060 hci_usb_close(hdev);
1061
1062 if (husb->isoc_iface)
1063 usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
1064
1065 if (hci_unregister_dev(hdev) < 0)
1066 BT_ERR("Can't unregister HCI device %s", hdev->name);
1067
1068 hci_free_dev(hdev);
1069}
1070
Marcel Holtmanndcdcf632006-07-03 10:02:24 +02001071static int hci_usb_suspend(struct usb_interface *intf, pm_message_t message)
1072{
1073 struct hci_usb *husb = usb_get_intfdata(intf);
1074 struct list_head killed;
1075 unsigned long flags;
1076 int i;
1077
1078 if (!husb || intf == husb->isoc_iface)
1079 return 0;
1080
1081 hci_suspend_dev(husb->hdev);
1082
1083 INIT_LIST_HEAD(&killed);
1084
1085 for (i = 0; i < 4; i++) {
1086 struct _urb_queue *q = &husb->pending_q[i];
1087 struct _urb *_urb, *_tmp;
1088
1089 while ((_urb = _urb_dequeue(q))) {
1090 /* reset queue since _urb_dequeue sets it to NULL */
1091 _urb->queue = q;
1092 usb_kill_urb(&_urb->urb);
1093 list_add(&_urb->list, &killed);
1094 }
1095
1096 spin_lock_irqsave(&q->lock, flags);
1097
1098 list_for_each_entry_safe(_urb, _tmp, &killed, list) {
1099 list_move_tail(&_urb->list, &q->head);
1100 }
1101
1102 spin_unlock_irqrestore(&q->lock, flags);
1103 }
1104
1105 return 0;
1106}
1107
1108static int hci_usb_resume(struct usb_interface *intf)
1109{
1110 struct hci_usb *husb = usb_get_intfdata(intf);
1111 unsigned long flags;
1112 int i, err = 0;
1113
1114 if (!husb || intf == husb->isoc_iface)
1115 return 0;
1116
1117 for (i = 0; i < 4; i++) {
1118 struct _urb_queue *q = &husb->pending_q[i];
1119 struct _urb *_urb;
1120
1121 spin_lock_irqsave(&q->lock, flags);
1122
1123 list_for_each_entry(_urb, &q->head, list) {
1124 err = usb_submit_urb(&_urb->urb, GFP_ATOMIC);
1125 if (err)
1126 break;
1127 }
1128
1129 spin_unlock_irqrestore(&q->lock, flags);
1130
1131 if (err)
1132 return -EIO;
1133 }
1134
1135 hci_resume_dev(husb->hdev);
1136
1137 return 0;
1138}
1139
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140static struct usb_driver hci_usb_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 .name = "hci_usb",
1142 .probe = hci_usb_probe,
1143 .disconnect = hci_usb_disconnect,
Marcel Holtmanndcdcf632006-07-03 10:02:24 +02001144 .suspend = hci_usb_suspend,
1145 .resume = hci_usb_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001146 .id_table = bluetooth_ids,
1147};
1148
1149static int __init hci_usb_init(void)
1150{
1151 int err;
1152
1153 BT_INFO("HCI USB driver ver %s", VERSION);
1154
1155 if ((err = usb_register(&hci_usb_driver)) < 0)
1156 BT_ERR("Failed to register HCI USB driver");
1157
1158 return err;
1159}
1160
1161static void __exit hci_usb_exit(void)
1162{
1163 usb_deregister(&hci_usb_driver);
1164}
1165
1166module_init(hci_usb_init);
1167module_exit(hci_usb_exit);
1168
1169module_param(ignore, bool, 0644);
1170MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
1171
Marcel Holtmann7ef934b2005-11-08 09:57:05 -08001172module_param(ignore_dga, bool, 0644);
1173MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
1174
Marcel Holtmann0915e882005-09-13 01:32:37 +02001175module_param(ignore_csr, bool, 0644);
1176MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
1177
1178module_param(ignore_sniffer, bool, 0644);
1179MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
1180
Marcel Holtmann520ca782006-07-14 16:01:52 +02001181module_param(disable_scofix, bool, 0644);
1182MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");
1183
1184module_param(force_scofix, bool, 0644);
1185MODULE_PARM_DESC(force_scofix, "Force fixup of wrong SCO buffers size");
1186
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187module_param(reset, bool, 0644);
1188MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
1189
1190#ifdef CONFIG_BT_HCIUSB_SCO
1191module_param(isoc, int, 0644);
1192MODULE_PARM_DESC(isoc, "Set isochronous transfers for SCO over HCI support");
1193#endif
1194
1195MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
1196MODULE_DESCRIPTION("Bluetooth HCI USB driver ver " VERSION);
1197MODULE_VERSION(VERSION);
1198MODULE_LICENSE("GPL");