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