diff options
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/bcm203x.c | 1 | ||||
-rw-r--r-- | drivers/bluetooth/bluecard_cs.c | 1 | ||||
-rw-r--r-- | drivers/bluetooth/bt3c_cs.c | 1 | ||||
-rw-r--r-- | drivers/bluetooth/btuart_cs.c | 1 | ||||
-rw-r--r-- | drivers/bluetooth/dtl1_cs.c | 1 | ||||
-rw-r--r-- | drivers/bluetooth/hci_ldisc.c | 4 | ||||
-rw-r--r-- | drivers/bluetooth/hci_usb.c | 99 | ||||
-rw-r--r-- | drivers/bluetooth/hci_usb.h | 1 | ||||
-rw-r--r-- | drivers/bluetooth/hci_vhci.c | 1 |
9 files changed, 105 insertions, 5 deletions
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c index 6f67141f4de0..13ba729cdd57 100644 --- a/drivers/bluetooth/bcm203x.c +++ b/drivers/bluetooth/bcm203x.c @@ -234,6 +234,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id data->fw_data = kmalloc(firmware->size, GFP_KERNEL); if (!data->fw_data) { BT_ERR("Can't allocate memory for firmware image"); + release_firmware(firmware); usb_free_urb(data->urb); kfree(data->buffer); kfree(data); diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index 2830f58d6f77..8eebf9ca3786 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -739,6 +739,7 @@ static int bluecard_open(bluecard_info_t *info) hdev->type = HCI_PCCARD; hdev->driver_data = info; + SET_HCIDEV_DEV(hdev, &info->p_dev->dev); hdev->open = bluecard_hci_open; hdev->close = bluecard_hci_close; diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index c9dba5565cac..df7bb016df49 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -582,6 +582,7 @@ static int bt3c_open(bt3c_info_t *info) hdev->type = HCI_PCCARD; hdev->driver_data = info; + SET_HCIDEV_DEV(hdev, &info->p_dev->dev); hdev->open = bt3c_hci_open; hdev->close = bt3c_hci_close; diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index c889bf8109a1..746ccca97f6f 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -502,6 +502,7 @@ static int btuart_open(btuart_info_t *info) hdev->type = HCI_PCCARD; hdev->driver_data = info; + SET_HCIDEV_DEV(hdev, &info->p_dev->dev); hdev->open = btuart_hci_open; hdev->close = btuart_hci_close; diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index be6eed175aa3..0e99def8a1e3 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -484,6 +484,7 @@ static int dtl1_open(dtl1_info_t *info) hdev->type = HCI_PCCARD; hdev->driver_data = info; + SET_HCIDEV_DEV(hdev, &info->p_dev->dev); hdev->open = dtl1_hci_open; hdev->close = dtl1_hci_close; diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 1994270c16e1..93ba25b7ea32 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -191,7 +191,7 @@ static int hci_uart_flush(struct hci_dev *hdev) /* Flush any pending characters in the driver and discipline. */ tty_ldisc_flush(tty); - if (tty->driver->flush_buffer) + if (tty->driver && tty->driver->flush_buffer) tty->driver->flush_buffer(tty); if (test_bit(HCI_UART_PROTO_SET, &hu->flags)) @@ -290,7 +290,7 @@ static int hci_uart_tty_open(struct tty_struct *tty) if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty); - if (tty->driver->flush_buffer) + if (tty->driver && tty->driver->flush_buffer) tty->driver->flush_buffer(tty); return 0; diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index a7d9d7e99e72..e2d4beac7420 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c @@ -67,6 +67,8 @@ static int ignore = 0; static int ignore_dga = 0; static int ignore_csr = 0; static int ignore_sniffer = 0; +static int disable_scofix = 0; +static int force_scofix = 0; static int reset = 0; #ifdef CONFIG_BT_HCIUSB_SCO @@ -107,9 +109,12 @@ static struct usb_device_id blacklist_ids[] = { { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE }, /* Broadcom BCM2035 */ - { USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_BROKEN_ISOC }, + { USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, { USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 }, + /* IBM/Lenovo ThinkPad with Broadcom chip */ + { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU }, + /* Microsoft Wireless Transceiver for Bluetooth 2.0 */ { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET }, @@ -119,8 +124,13 @@ static struct usb_device_id blacklist_ids[] = { /* ISSC Bluetooth Adapter v3.1 */ { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET }, - /* RTX Telecom based adapter with buggy SCO support */ + /* RTX Telecom based adapters with buggy SCO support */ { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC }, + { USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC }, + + /* Belkin F8T012 and F8T013 devices */ + { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU }, + { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_WRONG_SCO_MTU }, /* Digianswer devices */ { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER }, @@ -129,6 +139,9 @@ static struct usb_device_id blacklist_ids[] = { /* CSR BlueCore Bluetooth Sniffer */ { USB_DEVICE(0x0a12, 0x0002), .driver_info = HCI_SNIFFER }, + /* Frontline ComProbe Bluetooth Sniffer */ + { USB_DEVICE(0x16d3, 0x0002), .driver_info = HCI_SNIFFER }, + { } /* Terminating entry */ }; @@ -984,6 +997,11 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id if (reset || id->driver_info & HCI_RESET) set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks); + if (force_scofix || id->driver_info & HCI_WRONG_SCO_MTU) { + if (!disable_scofix) + set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks); + } + if (id->driver_info & HCI_SNIFFER) { if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997) set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); @@ -1042,10 +1060,81 @@ static void hci_usb_disconnect(struct usb_interface *intf) hci_free_dev(hdev); } +static int hci_usb_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct hci_usb *husb = usb_get_intfdata(intf); + struct list_head killed; + unsigned long flags; + int i; + + if (!husb || intf == husb->isoc_iface) + return 0; + + hci_suspend_dev(husb->hdev); + + INIT_LIST_HEAD(&killed); + + for (i = 0; i < 4; i++) { + struct _urb_queue *q = &husb->pending_q[i]; + struct _urb *_urb, *_tmp; + + while ((_urb = _urb_dequeue(q))) { + /* reset queue since _urb_dequeue sets it to NULL */ + _urb->queue = q; + usb_kill_urb(&_urb->urb); + list_add(&_urb->list, &killed); + } + + spin_lock_irqsave(&q->lock, flags); + + list_for_each_entry_safe(_urb, _tmp, &killed, list) { + list_move_tail(&_urb->list, &q->head); + } + + spin_unlock_irqrestore(&q->lock, flags); + } + + return 0; +} + +static int hci_usb_resume(struct usb_interface *intf) +{ + struct hci_usb *husb = usb_get_intfdata(intf); + unsigned long flags; + int i, err = 0; + + if (!husb || intf == husb->isoc_iface) + return 0; + + for (i = 0; i < 4; i++) { + struct _urb_queue *q = &husb->pending_q[i]; + struct _urb *_urb; + + spin_lock_irqsave(&q->lock, flags); + + list_for_each_entry(_urb, &q->head, list) { + err = usb_submit_urb(&_urb->urb, GFP_ATOMIC); + if (err) + break; + } + + spin_unlock_irqrestore(&q->lock, flags); + + if (err) + return -EIO; + } + + hci_resume_dev(husb->hdev); + + return 0; +} + static struct usb_driver hci_usb_driver = { .name = "hci_usb", .probe = hci_usb_probe, .disconnect = hci_usb_disconnect, + .suspend = hci_usb_suspend, + .resume = hci_usb_resume, .id_table = bluetooth_ids, }; @@ -1081,6 +1170,12 @@ MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001"); module_param(ignore_sniffer, bool, 0644); MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002"); +module_param(disable_scofix, bool, 0644); +MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size"); + +module_param(force_scofix, bool, 0644); +MODULE_PARM_DESC(force_scofix, "Force fixup of wrong SCO buffers size"); + module_param(reset, bool, 0644); MODULE_PARM_DESC(reset, "Send HCI reset command on initialization"); diff --git a/drivers/bluetooth/hci_usb.h b/drivers/bluetooth/hci_usb.h index 37100a6ea1a8..963fc55cdc85 100644 --- a/drivers/bluetooth/hci_usb.h +++ b/drivers/bluetooth/hci_usb.h @@ -35,6 +35,7 @@ #define HCI_SNIFFER 0x10 #define HCI_BCM92035 0x20 #define HCI_BROKEN_ISOC 0x40 +#define HCI_WRONG_SCO_MTU 0x80 #define HCI_MAX_IFACE_NUM 3 diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index ea589007fa26..aac67a3a6019 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -277,7 +277,6 @@ static int vhci_open(struct inode *inode, struct file *file) hdev->type = HCI_VHCI; hdev->driver_data = vhci; - SET_HCIDEV_DEV(hdev, vhci_miscdev.dev); hdev->open = vhci_open_dev; hdev->close = vhci_close_dev; |