blob: 4f8a744c90b76837dab58c9b2bcbd8f18031f283 [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <linux/unistd.h>
39#include <linux/types.h>
40#include <linux/interrupt.h>
41#include <linux/moduleparam.h>
42
43#include <linux/slab.h>
44#include <linux/errno.h>
45#include <linux/string.h>
46#include <linux/skbuff.h>
47
48#include <linux/usb.h>
49
50#include <net/bluetooth/bluetooth.h>
51#include <net/bluetooth/hci_core.h>
52
53#include "hci_usb.h"
54
55#ifndef CONFIG_BT_HCIUSB_DEBUG
56#undef BT_DBG
57#define BT_DBG(D...)
Linus Torvalds1da177e2005-04-16 15:20:36 -070058#endif
59
60#ifndef CONFIG_BT_HCIUSB_ZERO_PACKET
61#undef URB_ZERO_PACKET
62#define URB_ZERO_PACKET 0
63#endif
64
65static int ignore = 0;
Marcel Holtmann7ef934b2005-11-08 09:57:05 -080066static int ignore_dga = 0;
Marcel Holtmann0915e882005-09-13 01:32:37 +020067static int ignore_csr = 0;
68static int ignore_sniffer = 0;
Marcel Holtmann520ca782006-07-14 16:01:52 +020069static int disable_scofix = 0;
70static int force_scofix = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070071static int reset = 0;
72
73#ifdef CONFIG_BT_HCIUSB_SCO
74static int isoc = 2;
75#endif
76
Marcel Holtmann0915e882005-09-13 01:32:37 +020077#define VERSION "2.9"
Linus Torvalds1da177e2005-04-16 15:20:36 -070078
79static struct usb_driver hci_usb_driver;
80
81static struct usb_device_id bluetooth_ids[] = {
82 /* Generic Bluetooth USB device */
83 { USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },
84
85 /* AVM BlueFRITZ! USB v2.0 */
86 { USB_DEVICE(0x057c, 0x3800) },
87
88 /* Bluetooth Ultraport Module from IBM */
89 { USB_DEVICE(0x04bf, 0x030a) },
90
91 /* ALPS Modules with non-standard id */
92 { USB_DEVICE(0x044e, 0x3001) },
93 { USB_DEVICE(0x044e, 0x3002) },
94
95 /* Ericsson with non-standard id */
96 { USB_DEVICE(0x0bdb, 0x1002) },
97
Marcel Holtmann62ae1592006-09-21 16:19:55 +020098 /* Canyon CN-BTU1 with HID interfaces */
99 { USB_DEVICE(0x0c10, 0x0000), .driver_info = HCI_RESET },
100
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101 { } /* Terminating entry */
102};
103
104MODULE_DEVICE_TABLE (usb, bluetooth_ids);
105
106static struct usb_device_id blacklist_ids[] = {
Marcel Holtmann0915e882005-09-13 01:32:37 +0200107 /* CSR BlueCore devices */
108 { USB_DEVICE(0x0a12, 0x0001), .driver_info = HCI_CSR },
109
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110 /* Broadcom BCM2033 without firmware */
111 { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE },
112
113 /* Broadcom BCM2035 */
Andy Shevchenko6e46c8c2008-02-05 03:10:02 -0800114 { USB_DEVICE(0x0a5c, 0x2035), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
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 Holtmann7bb078c2007-05-05 00:36:22 +0200118 /* Broadcom BCM2045 */
Marcel Holtmannfd184ab2007-05-24 14:26:15 +0200119 { USB_DEVICE(0x0a5c, 0x2101), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
Marcel Holtmann7bb078c2007-05-05 00:36:22 +0200120
Marcel Holtmann520ca782006-07-14 16:01:52 +0200121 /* IBM/Lenovo ThinkPad with Broadcom chip */
Marcel Holtmannfd184ab2007-05-24 14:26:15 +0200122 { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
123 { USB_DEVICE(0x0a5c, 0x2110), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
Marcel Holtmann520ca782006-07-14 16:01:52 +0200124
Marcel Holtmannc51bd3d2007-05-05 00:36:17 +0200125 /* Targus ACB10US */
126 { USB_DEVICE(0x0a5c, 0x2100), .driver_info = HCI_RESET },
127
Marcel Holtmann0eab9342006-10-20 08:55:29 +0200128 /* ANYCOM Bluetooth USB-200 and USB-250 */
129 { USB_DEVICE(0x0a5c, 0x2111), .driver_info = HCI_RESET },
130
Marcel Holtmannda942702007-01-08 02:16:50 +0100131 /* HP laptop with Broadcom chip */
Marcel Holtmannfd184ab2007-05-24 14:26:15 +0200132 { USB_DEVICE(0x03f0, 0x171d), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
Marcel Holtmannda942702007-01-08 02:16:50 +0100133
Marcel Holtmann86112ff2007-01-08 02:16:53 +0100134 /* Dell laptop with Broadcom chip */
Marcel Holtmannfd184ab2007-05-24 14:26:15 +0200135 { USB_DEVICE(0x413c, 0x8126), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
Marcel Holtmann86112ff2007-01-08 02:16:53 +0100136
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 /* Microsoft Wireless Transceiver for Bluetooth 2.0 */
138 { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
139
Marcel Holtmanncad0f622005-08-06 12:36:36 +0200140 /* Kensington Bluetooth USB adapter */
141 { USB_DEVICE(0x047d, 0x105d), .driver_info = HCI_RESET },
Marcel Holtmannfd184ab2007-05-24 14:26:15 +0200142 { USB_DEVICE(0x047d, 0x105e), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
Marcel Holtmanncad0f622005-08-06 12:36:36 +0200143
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 /* ISSC Bluetooth Adapter v3.1 */
145 { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
146
Marcel Holtmann8e4f7232006-07-18 18:04:59 +0200147 /* RTX Telecom based adapters with buggy SCO support */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
Marcel Holtmann8e4f7232006-07-18 18:04:59 +0200149 { USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150
SDiZ09a76032008-03-05 18:43:50 -0800151 /* CONWISE Technology based adapters with buggy SCO support */
152 { USB_DEVICE(0x0e5e, 0x6622), .driver_info = HCI_BROKEN_ISOC },
153
Marcel Holtmannea9727f2006-07-18 17:47:40 +0200154 /* Belkin F8T012 and F8T013 devices */
Marcel Holtmannfd184ab2007-05-24 14:26:15 +0200155 { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
156 { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
Marcel Holtmannda1f5192006-07-03 10:02:29 +0200157
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 /* Digianswer devices */
159 { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
160 { USB_DEVICE(0x08fd, 0x0002), .driver_info = HCI_IGNORE },
161
162 /* CSR BlueCore Bluetooth Sniffer */
163 { USB_DEVICE(0x0a12, 0x0002), .driver_info = HCI_SNIFFER },
164
Marcel Holtmann2b86ad22006-07-03 10:02:18 +0200165 /* Frontline ComProbe Bluetooth Sniffer */
166 { USB_DEVICE(0x16d3, 0x0002), .driver_info = HCI_SNIFFER },
167
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168 { } /* Terminating entry */
169};
170
Al Virodd0fc662005-10-07 07:46:04 +0100171static struct _urb *_urb_alloc(int isoc, gfp_t gfp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172{
173 struct _urb *_urb = kmalloc(sizeof(struct _urb) +
174 sizeof(struct usb_iso_packet_descriptor) * isoc, gfp);
175 if (_urb) {
176 memset(_urb, 0, sizeof(*_urb));
177 usb_init_urb(&_urb->urb);
178 }
179 return _urb;
180}
181
182static struct _urb *_urb_dequeue(struct _urb_queue *q)
183{
184 struct _urb *_urb = NULL;
185 unsigned long flags;
186 spin_lock_irqsave(&q->lock, flags);
187 {
188 struct list_head *head = &q->head;
189 struct list_head *next = head->next;
190 if (next != head) {
191 _urb = list_entry(next, struct _urb, list);
192 list_del(next); _urb->queue = NULL;
193 }
194 }
195 spin_unlock_irqrestore(&q->lock, flags);
196 return _urb;
197}
198
David Howells7d12e782006-10-05 14:55:46 +0100199static void hci_usb_rx_complete(struct urb *urb);
200static void hci_usb_tx_complete(struct urb *urb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201
202#define __pending_tx(husb, type) (&husb->pending_tx[type-1])
203#define __pending_q(husb, type) (&husb->pending_q[type-1])
204#define __completed_q(husb, type) (&husb->completed_q[type-1])
205#define __transmit_q(husb, type) (&husb->transmit_q[type-1])
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206
207static inline struct _urb *__get_completed(struct hci_usb *husb, int type)
208{
209 return _urb_dequeue(__completed_q(husb, type));
210}
211
212#ifdef CONFIG_BT_HCIUSB_SCO
213static void __fill_isoc_desc(struct urb *urb, int len, int mtu)
214{
215 int offset = 0, i;
216
217 BT_DBG("len %d mtu %d", len, mtu);
218
219 for (i=0; i < HCI_MAX_ISOC_FRAMES && len >= mtu; i++, offset += mtu, len -= mtu) {
220 urb->iso_frame_desc[i].offset = offset;
221 urb->iso_frame_desc[i].length = mtu;
222 BT_DBG("desc %d offset %d len %d", i, offset, mtu);
223 }
224 if (len && i < HCI_MAX_ISOC_FRAMES) {
225 urb->iso_frame_desc[i].offset = offset;
226 urb->iso_frame_desc[i].length = len;
227 BT_DBG("desc %d offset %d len %d", i, offset, len);
228 i++;
229 }
230 urb->number_of_packets = i;
231}
232#endif
233
234static int hci_usb_intr_rx_submit(struct hci_usb *husb)
235{
236 struct _urb *_urb;
237 struct urb *urb;
238 int err, pipe, interval, size;
239 void *buf;
240
241 BT_DBG("%s", husb->hdev->name);
242
243 size = le16_to_cpu(husb->intr_in_ep->desc.wMaxPacketSize);
244
245 buf = kmalloc(size, GFP_ATOMIC);
246 if (!buf)
247 return -ENOMEM;
248
249 _urb = _urb_alloc(0, GFP_ATOMIC);
250 if (!_urb) {
251 kfree(buf);
252 return -ENOMEM;
253 }
254 _urb->type = HCI_EVENT_PKT;
255 _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
256
257 urb = &_urb->urb;
258 pipe = usb_rcvintpipe(husb->udev, husb->intr_in_ep->desc.bEndpointAddress);
259 interval = husb->intr_in_ep->desc.bInterval;
260 usb_fill_int_urb(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb, interval);
261
262 err = usb_submit_urb(urb, GFP_ATOMIC);
263 if (err) {
264 BT_ERR("%s intr rx submit failed urb %p err %d",
265 husb->hdev->name, urb, err);
266 _urb_unlink(_urb);
267 _urb_free(_urb);
268 kfree(buf);
269 }
270 return err;
271}
272
273static int hci_usb_bulk_rx_submit(struct hci_usb *husb)
274{
275 struct _urb *_urb;
276 struct urb *urb;
277 int err, pipe, size = HCI_MAX_FRAME_SIZE;
278 void *buf;
279
280 buf = kmalloc(size, GFP_ATOMIC);
281 if (!buf)
282 return -ENOMEM;
283
284 _urb = _urb_alloc(0, GFP_ATOMIC);
285 if (!_urb) {
286 kfree(buf);
287 return -ENOMEM;
288 }
289 _urb->type = HCI_ACLDATA_PKT;
290 _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
291
292 urb = &_urb->urb;
293 pipe = usb_rcvbulkpipe(husb->udev, husb->bulk_in_ep->desc.bEndpointAddress);
294 usb_fill_bulk_urb(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb);
295 urb->transfer_flags = 0;
296
297 BT_DBG("%s urb %p", husb->hdev->name, urb);
298
299 err = usb_submit_urb(urb, GFP_ATOMIC);
300 if (err) {
301 BT_ERR("%s bulk rx submit failed urb %p err %d",
302 husb->hdev->name, urb, err);
303 _urb_unlink(_urb);
304 _urb_free(_urb);
305 kfree(buf);
306 }
307 return err;
308}
309
310#ifdef CONFIG_BT_HCIUSB_SCO
311static int hci_usb_isoc_rx_submit(struct hci_usb *husb)
312{
313 struct _urb *_urb;
314 struct urb *urb;
315 int err, mtu, size;
316 void *buf;
317
318 mtu = le16_to_cpu(husb->isoc_in_ep->desc.wMaxPacketSize);
319 size = mtu * HCI_MAX_ISOC_FRAMES;
320
321 buf = kmalloc(size, GFP_ATOMIC);
322 if (!buf)
323 return -ENOMEM;
324
325 _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
326 if (!_urb) {
327 kfree(buf);
328 return -ENOMEM;
329 }
330 _urb->type = HCI_SCODATA_PKT;
331 _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
332
333 urb = &_urb->urb;
334
335 urb->context = husb;
336 urb->dev = husb->udev;
337 urb->pipe = usb_rcvisocpipe(husb->udev, husb->isoc_in_ep->desc.bEndpointAddress);
338 urb->complete = hci_usb_rx_complete;
339
340 urb->interval = husb->isoc_in_ep->desc.bInterval;
341
342 urb->transfer_buffer_length = size;
343 urb->transfer_buffer = buf;
344 urb->transfer_flags = URB_ISO_ASAP;
345
346 __fill_isoc_desc(urb, size, mtu);
347
348 BT_DBG("%s urb %p", husb->hdev->name, urb);
349
350 err = usb_submit_urb(urb, GFP_ATOMIC);
351 if (err) {
352 BT_ERR("%s isoc rx submit failed urb %p err %d",
353 husb->hdev->name, urb, err);
354 _urb_unlink(_urb);
355 _urb_free(_urb);
356 kfree(buf);
357 }
358 return err;
359}
360#endif
361
362/* Initialize device */
363static int hci_usb_open(struct hci_dev *hdev)
364{
365 struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
366 int i, err;
367 unsigned long flags;
368
369 BT_DBG("%s", hdev->name);
370
371 if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
372 return 0;
373
374 write_lock_irqsave(&husb->completion_lock, flags);
375
376 err = hci_usb_intr_rx_submit(husb);
377 if (!err) {
378 for (i = 0; i < HCI_MAX_BULK_RX; i++)
379 hci_usb_bulk_rx_submit(husb);
380
381#ifdef CONFIG_BT_HCIUSB_SCO
382 if (husb->isoc_iface)
383 for (i = 0; i < HCI_MAX_ISOC_RX; i++)
384 hci_usb_isoc_rx_submit(husb);
385#endif
386 } else {
387 clear_bit(HCI_RUNNING, &hdev->flags);
388 }
389
390 write_unlock_irqrestore(&husb->completion_lock, flags);
391 return err;
392}
393
394/* Reset device */
395static int hci_usb_flush(struct hci_dev *hdev)
396{
397 struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
398 int i;
399
400 BT_DBG("%s", hdev->name);
401
402 for (i = 0; i < 4; i++)
403 skb_queue_purge(&husb->transmit_q[i]);
404 return 0;
405}
406
407static void hci_usb_unlink_urbs(struct hci_usb *husb)
408{
409 int i;
410
411 BT_DBG("%s", husb->hdev->name);
412
413 for (i = 0; i < 4; i++) {
414 struct _urb *_urb;
415 struct urb *urb;
416
417 /* Kill pending requests */
418 while ((_urb = _urb_dequeue(&husb->pending_q[i]))) {
419 urb = &_urb->urb;
420 BT_DBG("%s unlinking _urb %p type %d urb %p",
421 husb->hdev->name, _urb, _urb->type, urb);
422 usb_kill_urb(urb);
423 _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
424 }
425
426 /* Release completed requests */
427 while ((_urb = _urb_dequeue(&husb->completed_q[i]))) {
428 urb = &_urb->urb;
429 BT_DBG("%s freeing _urb %p type %d urb %p",
430 husb->hdev->name, _urb, _urb->type, urb);
Marcel Holtmanne9a3e672005-08-06 12:36:47 +0200431 kfree(urb->setup_packet);
432 kfree(urb->transfer_buffer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433 _urb_free(_urb);
434 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435 }
436}
437
438/* Close device */
439static int hci_usb_close(struct hci_dev *hdev)
440{
441 struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
442 unsigned long flags;
443
444 if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
445 return 0;
446
447 BT_DBG("%s", hdev->name);
448
449 /* Synchronize with completion handlers */
450 write_lock_irqsave(&husb->completion_lock, flags);
451 write_unlock_irqrestore(&husb->completion_lock, flags);
452
453 hci_usb_unlink_urbs(husb);
454 hci_usb_flush(hdev);
455 return 0;
456}
457
458static int __tx_submit(struct hci_usb *husb, struct _urb *_urb)
459{
460 struct urb *urb = &_urb->urb;
461 int err;
462
463 BT_DBG("%s urb %p type %d", husb->hdev->name, urb, _urb->type);
464
465 _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
466 err = usb_submit_urb(urb, GFP_ATOMIC);
467 if (err) {
468 BT_ERR("%s tx submit failed urb %p type %d err %d",
469 husb->hdev->name, urb, _urb->type, err);
470 _urb_unlink(_urb);
471 _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
472 } else
473 atomic_inc(__pending_tx(husb, _urb->type));
474
475 return err;
476}
477
478static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
479{
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700480 struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 struct usb_ctrlrequest *dr;
482 struct urb *urb;
483
484 if (!_urb) {
485 _urb = _urb_alloc(0, GFP_ATOMIC);
486 if (!_urb)
487 return -ENOMEM;
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700488 _urb->type = bt_cb(skb)->pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489
490 dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
491 if (!dr) {
492 _urb_free(_urb);
493 return -ENOMEM;
494 }
495 } else
496 dr = (void *) _urb->urb.setup_packet;
497
498 dr->bRequestType = husb->ctrl_req;
499 dr->bRequest = 0;
500 dr->wIndex = 0;
501 dr->wValue = 0;
502 dr->wLength = __cpu_to_le16(skb->len);
503
504 urb = &_urb->urb;
505 usb_fill_control_urb(urb, husb->udev, usb_sndctrlpipe(husb->udev, 0),
506 (void *) dr, skb->data, skb->len, hci_usb_tx_complete, husb);
507
508 BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len);
509
510 _urb->priv = skb;
511 return __tx_submit(husb, _urb);
512}
513
514static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
515{
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700516 struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 struct urb *urb;
518 int pipe;
519
520 if (!_urb) {
521 _urb = _urb_alloc(0, GFP_ATOMIC);
522 if (!_urb)
523 return -ENOMEM;
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700524 _urb->type = bt_cb(skb)->pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 }
526
527 urb = &_urb->urb;
528 pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep->desc.bEndpointAddress);
529 usb_fill_bulk_urb(urb, husb->udev, pipe, skb->data, skb->len,
530 hci_usb_tx_complete, husb);
531 urb->transfer_flags = URB_ZERO_PACKET;
532
533 BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len);
534
535 _urb->priv = skb;
536 return __tx_submit(husb, _urb);
537}
538
539#ifdef CONFIG_BT_HCIUSB_SCO
540static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
541{
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700542 struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 struct urb *urb;
544
545 if (!_urb) {
546 _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
547 if (!_urb)
548 return -ENOMEM;
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700549 _urb->type = bt_cb(skb)->pkt_type;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 }
551
552 BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len);
553
554 urb = &_urb->urb;
555
556 urb->context = husb;
557 urb->dev = husb->udev;
558 urb->pipe = usb_sndisocpipe(husb->udev, husb->isoc_out_ep->desc.bEndpointAddress);
559 urb->complete = hci_usb_tx_complete;
560 urb->transfer_flags = URB_ISO_ASAP;
561
562 urb->interval = husb->isoc_out_ep->desc.bInterval;
563
564 urb->transfer_buffer = skb->data;
565 urb->transfer_buffer_length = skb->len;
566
567 __fill_isoc_desc(urb, skb->len, le16_to_cpu(husb->isoc_out_ep->desc.wMaxPacketSize));
568
569 _urb->priv = skb;
570 return __tx_submit(husb, _urb);
571}
572#endif
573
574static void hci_usb_tx_process(struct hci_usb *husb)
575{
576 struct sk_buff_head *q;
577 struct sk_buff *skb;
578
579 BT_DBG("%s", husb->hdev->name);
580
581 do {
582 clear_bit(HCI_USB_TX_WAKEUP, &husb->state);
583
584 /* Process command queue */
585 q = __transmit_q(husb, HCI_COMMAND_PKT);
586 if (!atomic_read(__pending_tx(husb, HCI_COMMAND_PKT)) &&
587 (skb = skb_dequeue(q))) {
588 if (hci_usb_send_ctrl(husb, skb) < 0)
589 skb_queue_head(q, skb);
590 }
591
592#ifdef CONFIG_BT_HCIUSB_SCO
593 /* Process SCO queue */
594 q = __transmit_q(husb, HCI_SCODATA_PKT);
595 if (atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) < HCI_MAX_ISOC_TX &&
596 (skb = skb_dequeue(q))) {
597 if (hci_usb_send_isoc(husb, skb) < 0)
598 skb_queue_head(q, skb);
599 }
600#endif
601
602 /* Process ACL queue */
603 q = __transmit_q(husb, HCI_ACLDATA_PKT);
604 while (atomic_read(__pending_tx(husb, HCI_ACLDATA_PKT)) < HCI_MAX_BULK_TX &&
605 (skb = skb_dequeue(q))) {
606 if (hci_usb_send_bulk(husb, skb) < 0) {
607 skb_queue_head(q, skb);
608 break;
609 }
610 }
611 } while(test_bit(HCI_USB_TX_WAKEUP, &husb->state));
612}
613
614static inline void hci_usb_tx_wakeup(struct hci_usb *husb)
615{
616 /* Serialize TX queue processing to avoid data reordering */
617 if (!test_and_set_bit(HCI_USB_TX_PROCESS, &husb->state)) {
618 hci_usb_tx_process(husb);
619 clear_bit(HCI_USB_TX_PROCESS, &husb->state);
620 } else
621 set_bit(HCI_USB_TX_WAKEUP, &husb->state);
622}
623
624/* Send frames from HCI layer */
625static int hci_usb_send_frame(struct sk_buff *skb)
626{
627 struct hci_dev *hdev = (struct hci_dev *) skb->dev;
628 struct hci_usb *husb;
629
630 if (!hdev) {
631 BT_ERR("frame for uknown device (hdev=NULL)");
632 return -ENODEV;
633 }
634
635 if (!test_bit(HCI_RUNNING, &hdev->flags))
636 return -EBUSY;
637
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700638 BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639
640 husb = (struct hci_usb *) hdev->driver_data;
641
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700642 switch (bt_cb(skb)->pkt_type) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643 case HCI_COMMAND_PKT:
644 hdev->stat.cmd_tx++;
645 break;
646
647 case HCI_ACLDATA_PKT:
648 hdev->stat.acl_tx++;
649 break;
650
651#ifdef CONFIG_BT_HCIUSB_SCO
652 case HCI_SCODATA_PKT:
653 hdev->stat.sco_tx++;
654 break;
655#endif
656
657 default:
658 kfree_skb(skb);
659 return 0;
660 }
661
662 read_lock(&husb->completion_lock);
663
Marcel Holtmann0d48d932005-08-09 20:30:28 -0700664 skb_queue_tail(__transmit_q(husb, bt_cb(skb)->pkt_type), skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 hci_usb_tx_wakeup(husb);
666
667 read_unlock(&husb->completion_lock);
668 return 0;
669}
670
David Howells7d12e782006-10-05 14:55:46 +0100671static void hci_usb_rx_complete(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672{
673 struct _urb *_urb = container_of(urb, struct _urb, urb);
674 struct hci_usb *husb = (void *) urb->context;
675 struct hci_dev *hdev = husb->hdev;
676 int err, count = urb->actual_length;
677
678 BT_DBG("%s urb %p type %d status %d count %d flags %x", hdev->name, urb,
679 _urb->type, urb->status, count, urb->transfer_flags);
680
681 read_lock(&husb->completion_lock);
682
683 if (!test_bit(HCI_RUNNING, &hdev->flags))
684 goto unlock;
685
686 if (urb->status || !count)
687 goto resubmit;
688
689 if (_urb->type == HCI_SCODATA_PKT) {
690#ifdef CONFIG_BT_HCIUSB_SCO
691 int i;
692 for (i=0; i < urb->number_of_packets; i++) {
693 BT_DBG("desc %d status %d offset %d len %d", i,
694 urb->iso_frame_desc[i].status,
695 urb->iso_frame_desc[i].offset,
696 urb->iso_frame_desc[i].actual_length);
697
Marcel Holtmann26a4a062007-09-09 08:39:27 +0200698 if (!urb->iso_frame_desc[i].status) {
699 husb->hdev->stat.byte_rx += urb->iso_frame_desc[i].actual_length;
Marcel Holtmannbabf4d42007-07-11 06:42:35 +0200700 hci_recv_fragment(husb->hdev, _urb->type,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701 urb->transfer_buffer + urb->iso_frame_desc[i].offset,
702 urb->iso_frame_desc[i].actual_length);
Marcel Holtmann26a4a062007-09-09 08:39:27 +0200703 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700704 }
705#else
706 ;
707#endif
708 } else {
Marcel Holtmann26a4a062007-09-09 08:39:27 +0200709 husb->hdev->stat.byte_rx += count;
Marcel Holtmannbabf4d42007-07-11 06:42:35 +0200710 err = hci_recv_fragment(husb->hdev, _urb->type, urb->transfer_buffer, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 if (err < 0) {
712 BT_ERR("%s corrupted packet: type %d count %d",
713 husb->hdev->name, _urb->type, count);
714 hdev->stat.err_rx++;
715 }
716 }
717
718resubmit:
719 urb->dev = husb->udev;
720 err = usb_submit_urb(urb, GFP_ATOMIC);
721 BT_DBG("%s urb %p type %d resubmit status %d", hdev->name, urb,
722 _urb->type, err);
723
724unlock:
725 read_unlock(&husb->completion_lock);
726}
727
David Howells7d12e782006-10-05 14:55:46 +0100728static void hci_usb_tx_complete(struct urb *urb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729{
730 struct _urb *_urb = container_of(urb, struct _urb, urb);
731 struct hci_usb *husb = (void *) urb->context;
732 struct hci_dev *hdev = husb->hdev;
733
734 BT_DBG("%s urb %p status %d flags %x", hdev->name, urb,
735 urb->status, urb->transfer_flags);
736
737 atomic_dec(__pending_tx(husb, _urb->type));
738
739 urb->transfer_buffer = NULL;
740 kfree_skb((struct sk_buff *) _urb->priv);
741
742 if (!test_bit(HCI_RUNNING, &hdev->flags))
743 return;
744
745 if (!urb->status)
746 hdev->stat.byte_tx += urb->transfer_buffer_length;
747 else
748 hdev->stat.err_tx++;
749
750 read_lock(&husb->completion_lock);
751
752 _urb_unlink(_urb);
753 _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
754
755 hci_usb_tx_wakeup(husb);
756
757 read_unlock(&husb->completion_lock);
758}
759
760static void hci_usb_destruct(struct hci_dev *hdev)
761{
762 struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
763
764 BT_DBG("%s", hdev->name);
765
766 kfree(husb);
767}
768
769static void hci_usb_notify(struct hci_dev *hdev, unsigned int evt)
770{
771 BT_DBG("%s evt %d", hdev->name, evt);
772}
773
774static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
775{
776 struct usb_device *udev = interface_to_usbdev(intf);
777 struct usb_host_endpoint *bulk_out_ep = NULL;
778 struct usb_host_endpoint *bulk_in_ep = NULL;
779 struct usb_host_endpoint *intr_in_ep = NULL;
780 struct usb_host_endpoint *ep;
781 struct usb_host_interface *uif;
782 struct usb_interface *isoc_iface;
783 struct hci_usb *husb;
784 struct hci_dev *hdev;
785 int i, e, size, isoc_ifnum, isoc_alts;
786
787 BT_DBG("udev %p intf %p", udev, intf);
788
789 if (!id->driver_info) {
790 const struct usb_device_id *match;
791 match = usb_match_id(intf, blacklist_ids);
792 if (match)
793 id = match;
794 }
795
796 if (ignore || id->driver_info & HCI_IGNORE)
797 return -ENODEV;
798
Marcel Holtmann7ef934b2005-11-08 09:57:05 -0800799 if (ignore_dga && id->driver_info & HCI_DIGIANSWER)
800 return -ENODEV;
801
Marcel Holtmann0915e882005-09-13 01:32:37 +0200802 if (ignore_csr && id->driver_info & HCI_CSR)
803 return -ENODEV;
804
805 if (ignore_sniffer && id->driver_info & HCI_SNIFFER)
806 return -ENODEV;
807
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808 if (intf->cur_altsetting->desc.bInterfaceNumber > 0)
809 return -ENODEV;
810
811 /* Find endpoints that we need */
812 uif = intf->cur_altsetting;
813 for (e = 0; e < uif->desc.bNumEndpoints; e++) {
814 ep = &uif->endpoint[e];
815
816 switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
817 case USB_ENDPOINT_XFER_INT:
818 if (ep->desc.bEndpointAddress & USB_DIR_IN)
819 intr_in_ep = ep;
820 break;
821
822 case USB_ENDPOINT_XFER_BULK:
823 if (ep->desc.bEndpointAddress & USB_DIR_IN)
824 bulk_in_ep = ep;
825 else
826 bulk_out_ep = ep;
827 break;
828 }
829 }
830
831 if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) {
832 BT_DBG("Bulk endpoints not found");
833 goto done;
834 }
835
Deepak Saxena089b1db2005-11-07 01:01:26 -0800836 if (!(husb = kzalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 BT_ERR("Can't allocate: control structure");
838 goto done;
839 }
840
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 husb->udev = udev;
842 husb->bulk_out_ep = bulk_out_ep;
843 husb->bulk_in_ep = bulk_in_ep;
844 husb->intr_in_ep = intr_in_ep;
845
846 if (id->driver_info & HCI_DIGIANSWER)
847 husb->ctrl_req = USB_TYPE_VENDOR;
848 else
849 husb->ctrl_req = USB_TYPE_CLASS;
850
851 /* Find isochronous endpoints that we can use */
852 size = 0;
853 isoc_iface = NULL;
854 isoc_alts = 0;
855 isoc_ifnum = 1;
856
857#ifdef CONFIG_BT_HCIUSB_SCO
858 if (isoc && !(id->driver_info & (HCI_BROKEN_ISOC | HCI_SNIFFER)))
859 isoc_iface = usb_ifnum_to_if(udev, isoc_ifnum);
860
861 if (isoc_iface) {
862 int a;
863 struct usb_host_endpoint *isoc_out_ep = NULL;
864 struct usb_host_endpoint *isoc_in_ep = NULL;
865
866 for (a = 0; a < isoc_iface->num_altsetting; a++) {
867 uif = &isoc_iface->altsetting[a];
868 for (e = 0; e < uif->desc.bNumEndpoints; e++) {
869 ep = &uif->endpoint[e];
870
871 switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
872 case USB_ENDPOINT_XFER_ISOC:
873 if (le16_to_cpu(ep->desc.wMaxPacketSize) < size ||
874 uif->desc.bAlternateSetting != isoc)
875 break;
876 size = le16_to_cpu(ep->desc.wMaxPacketSize);
877
878 isoc_alts = uif->desc.bAlternateSetting;
879
880 if (ep->desc.bEndpointAddress & USB_DIR_IN)
881 isoc_in_ep = ep;
882 else
883 isoc_out_ep = ep;
884 break;
885 }
886 }
887 }
888
889 if (!isoc_in_ep || !isoc_out_ep)
890 BT_DBG("Isoc endpoints not found");
891 else {
892 BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts);
893 if (usb_driver_claim_interface(&hci_usb_driver, isoc_iface, husb) != 0)
894 BT_ERR("Can't claim isoc interface");
895 else if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
896 BT_ERR("Can't set isoc interface settings");
897 husb->isoc_iface = isoc_iface;
898 usb_driver_release_interface(&hci_usb_driver, isoc_iface);
899 husb->isoc_iface = NULL;
900 } else {
901 husb->isoc_iface = isoc_iface;
902 husb->isoc_in_ep = isoc_in_ep;
903 husb->isoc_out_ep = isoc_out_ep;
904 }
905 }
906 }
907#endif
908
909 rwlock_init(&husb->completion_lock);
910
911 for (i = 0; i < 4; i++) {
912 skb_queue_head_init(&husb->transmit_q[i]);
913 _urb_queue_init(&husb->pending_q[i]);
914 _urb_queue_init(&husb->completed_q[i]);
915 }
916
917 /* Initialize and register HCI device */
918 hdev = hci_alloc_dev();
919 if (!hdev) {
920 BT_ERR("Can't allocate HCI device");
921 goto probe_error;
922 }
923
924 husb->hdev = hdev;
925
926 hdev->type = HCI_USB;
927 hdev->driver_data = husb;
928 SET_HCIDEV_DEV(hdev, &intf->dev);
929
930 hdev->open = hci_usb_open;
931 hdev->close = hci_usb_close;
932 hdev->flush = hci_usb_flush;
933 hdev->send = hci_usb_send_frame;
934 hdev->destruct = hci_usb_destruct;
935 hdev->notify = hci_usb_notify;
936
937 hdev->owner = THIS_MODULE;
938
939 if (reset || id->driver_info & HCI_RESET)
940 set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
941
Marcel Holtmann520ca782006-07-14 16:01:52 +0200942 if (force_scofix || id->driver_info & HCI_WRONG_SCO_MTU) {
943 if (!disable_scofix)
944 set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
945 }
Marcel Holtmannda1f5192006-07-03 10:02:29 +0200946
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947 if (id->driver_info & HCI_SNIFFER) {
948 if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
949 set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
950 }
951
952 if (id->driver_info & HCI_BCM92035) {
953 unsigned char cmd[] = { 0x3b, 0xfc, 0x01, 0x00 };
954 struct sk_buff *skb;
955
956 skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
957 if (skb) {
958 memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
959 skb_queue_tail(&hdev->driver_init, skb);
960 }
961 }
962
963 if (hci_register_dev(hdev) < 0) {
964 BT_ERR("Can't register HCI device");
965 hci_free_dev(hdev);
966 goto probe_error;
967 }
968
969 usb_set_intfdata(intf, husb);
970 return 0;
971
972probe_error:
973 if (husb->isoc_iface)
974 usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
975 kfree(husb);
976
977done:
978 return -EIO;
979}
980
981static void hci_usb_disconnect(struct usb_interface *intf)
982{
983 struct hci_usb *husb = usb_get_intfdata(intf);
984 struct hci_dev *hdev;
985
986 if (!husb || intf == husb->isoc_iface)
987 return;
988
989 usb_set_intfdata(intf, NULL);
990 hdev = husb->hdev;
991
992 BT_DBG("%s", hdev->name);
993
994 hci_usb_close(hdev);
995
996 if (husb->isoc_iface)
997 usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
998
999 if (hci_unregister_dev(hdev) < 0)
1000 BT_ERR("Can't unregister HCI device %s", hdev->name);
1001
1002 hci_free_dev(hdev);
1003}
1004
Marcel Holtmanndcdcf632006-07-03 10:02:24 +02001005static int hci_usb_suspend(struct usb_interface *intf, pm_message_t message)
1006{
1007 struct hci_usb *husb = usb_get_intfdata(intf);
1008 struct list_head killed;
1009 unsigned long flags;
1010 int i;
1011
1012 if (!husb || intf == husb->isoc_iface)
1013 return 0;
1014
1015 hci_suspend_dev(husb->hdev);
1016
1017 INIT_LIST_HEAD(&killed);
1018
1019 for (i = 0; i < 4; i++) {
1020 struct _urb_queue *q = &husb->pending_q[i];
1021 struct _urb *_urb, *_tmp;
1022
1023 while ((_urb = _urb_dequeue(q))) {
1024 /* reset queue since _urb_dequeue sets it to NULL */
1025 _urb->queue = q;
1026 usb_kill_urb(&_urb->urb);
1027 list_add(&_urb->list, &killed);
1028 }
1029
1030 spin_lock_irqsave(&q->lock, flags);
1031
1032 list_for_each_entry_safe(_urb, _tmp, &killed, list) {
1033 list_move_tail(&_urb->list, &q->head);
1034 }
1035
1036 spin_unlock_irqrestore(&q->lock, flags);
1037 }
1038
1039 return 0;
1040}
1041
1042static int hci_usb_resume(struct usb_interface *intf)
1043{
1044 struct hci_usb *husb = usb_get_intfdata(intf);
1045 unsigned long flags;
1046 int i, err = 0;
1047
1048 if (!husb || intf == husb->isoc_iface)
1049 return 0;
1050
1051 for (i = 0; i < 4; i++) {
1052 struct _urb_queue *q = &husb->pending_q[i];
1053 struct _urb *_urb;
1054
1055 spin_lock_irqsave(&q->lock, flags);
1056
1057 list_for_each_entry(_urb, &q->head, list) {
1058 err = usb_submit_urb(&_urb->urb, GFP_ATOMIC);
1059 if (err)
1060 break;
1061 }
1062
1063 spin_unlock_irqrestore(&q->lock, flags);
1064
1065 if (err)
1066 return -EIO;
1067 }
1068
1069 hci_resume_dev(husb->hdev);
1070
1071 return 0;
1072}
1073
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074static struct usb_driver hci_usb_driver = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 .name = "hci_usb",
1076 .probe = hci_usb_probe,
1077 .disconnect = hci_usb_disconnect,
Marcel Holtmanndcdcf632006-07-03 10:02:24 +02001078 .suspend = hci_usb_suspend,
1079 .resume = hci_usb_resume,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 .id_table = bluetooth_ids,
1081};
1082
1083static int __init hci_usb_init(void)
1084{
1085 int err;
1086
1087 BT_INFO("HCI USB driver ver %s", VERSION);
1088
1089 if ((err = usb_register(&hci_usb_driver)) < 0)
1090 BT_ERR("Failed to register HCI USB driver");
1091
1092 return err;
1093}
1094
1095static void __exit hci_usb_exit(void)
1096{
1097 usb_deregister(&hci_usb_driver);
1098}
1099
1100module_init(hci_usb_init);
1101module_exit(hci_usb_exit);
1102
1103module_param(ignore, bool, 0644);
1104MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");
1105
Marcel Holtmann7ef934b2005-11-08 09:57:05 -08001106module_param(ignore_dga, bool, 0644);
1107MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
1108
Marcel Holtmann0915e882005-09-13 01:32:37 +02001109module_param(ignore_csr, bool, 0644);
1110MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
1111
1112module_param(ignore_sniffer, bool, 0644);
1113MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
1114
Marcel Holtmann520ca782006-07-14 16:01:52 +02001115module_param(disable_scofix, bool, 0644);
1116MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");
1117
1118module_param(force_scofix, bool, 0644);
1119MODULE_PARM_DESC(force_scofix, "Force fixup of wrong SCO buffers size");
1120
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121module_param(reset, bool, 0644);
1122MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
1123
1124#ifdef CONFIG_BT_HCIUSB_SCO
1125module_param(isoc, int, 0644);
1126MODULE_PARM_DESC(isoc, "Set isochronous transfers for SCO over HCI support");
1127#endif
1128
1129MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
1130MODULE_DESCRIPTION("Bluetooth HCI USB driver ver " VERSION);
1131MODULE_VERSION(VERSION);
1132MODULE_LICENSE("GPL");