aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/hci_usb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth/hci_usb.c')
-rw-r--r--drivers/bluetooth/hci_usb.c103
1 files changed, 100 insertions, 3 deletions
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c
index 92382e82328..0801af4ad2b 100644
--- a/drivers/bluetooth/hci_usb.c
+++ b/drivers/bluetooth/hci_usb.c
@@ -31,7 +31,6 @@
31 * 31 *
32 */ 32 */
33 33
34#include <linux/config.h>
35#include <linux/module.h> 34#include <linux/module.h>
36 35
37#include <linux/kernel.h> 36#include <linux/kernel.h>
@@ -68,6 +67,8 @@ static int ignore = 0;
68static int ignore_dga = 0; 67static int ignore_dga = 0;
69static int ignore_csr = 0; 68static int ignore_csr = 0;
70static int ignore_sniffer = 0; 69static int ignore_sniffer = 0;
70static int disable_scofix = 0;
71static int force_scofix = 0;
71static int reset = 0; 72static int reset = 0;
72 73
73#ifdef CONFIG_BT_HCIUSB_SCO 74#ifdef CONFIG_BT_HCIUSB_SCO
@@ -95,6 +96,9 @@ static struct usb_device_id bluetooth_ids[] = {
95 /* Ericsson with non-standard id */ 96 /* Ericsson with non-standard id */
96 { USB_DEVICE(0x0bdb, 0x1002) }, 97 { USB_DEVICE(0x0bdb, 0x1002) },
97 98
99 /* Canyon CN-BTU1 with HID interfaces */
100 { USB_DEVICE(0x0c10, 0x0000), .driver_info = HCI_RESET },
101
98 { } /* Terminating entry */ 102 { } /* Terminating entry */
99}; 103};
100 104
@@ -108,9 +112,12 @@ static struct usb_device_id blacklist_ids[] = {
108 { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE }, 112 { USB_DEVICE(0x0a5c, 0x2033), .driver_info = HCI_IGNORE },
109 113
110 /* Broadcom BCM2035 */ 114 /* Broadcom BCM2035 */
111 { USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_BROKEN_ISOC }, 115 { USB_DEVICE(0x0a5c, 0x200a), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU },
112 { USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 }, 116 { USB_DEVICE(0x0a5c, 0x2009), .driver_info = HCI_BCM92035 },
113 117
118 /* IBM/Lenovo ThinkPad with Broadcom chip */
119 { USB_DEVICE(0x0a5c, 0x201e), .driver_info = HCI_WRONG_SCO_MTU },
120
114 /* Microsoft Wireless Transceiver for Bluetooth 2.0 */ 121 /* Microsoft Wireless Transceiver for Bluetooth 2.0 */
115 { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET }, 122 { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET },
116 123
@@ -120,8 +127,13 @@ static struct usb_device_id blacklist_ids[] = {
120 /* ISSC Bluetooth Adapter v3.1 */ 127 /* ISSC Bluetooth Adapter v3.1 */
121 { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET }, 128 { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET },
122 129
123 /* RTX Telecom based adapter with buggy SCO support */ 130 /* RTX Telecom based adapters with buggy SCO support */
124 { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC }, 131 { USB_DEVICE(0x0400, 0x0807), .driver_info = HCI_BROKEN_ISOC },
132 { USB_DEVICE(0x0400, 0x080a), .driver_info = HCI_BROKEN_ISOC },
133
134 /* Belkin F8T012 and F8T013 devices */
135 { USB_DEVICE(0x050d, 0x0012), .driver_info = HCI_WRONG_SCO_MTU },
136 { USB_DEVICE(0x050d, 0x0013), .driver_info = HCI_WRONG_SCO_MTU },
125 137
126 /* Digianswer devices */ 138 /* Digianswer devices */
127 { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER }, 139 { USB_DEVICE(0x08fd, 0x0001), .driver_info = HCI_DIGIANSWER },
@@ -130,6 +142,9 @@ static struct usb_device_id blacklist_ids[] = {
130 /* CSR BlueCore Bluetooth Sniffer */ 142 /* CSR BlueCore Bluetooth Sniffer */
131 { USB_DEVICE(0x0a12, 0x0002), .driver_info = HCI_SNIFFER }, 143 { USB_DEVICE(0x0a12, 0x0002), .driver_info = HCI_SNIFFER },
132 144
145 /* Frontline ComProbe Bluetooth Sniffer */
146 { USB_DEVICE(0x16d3, 0x0002), .driver_info = HCI_SNIFFER },
147
133 { } /* Terminating entry */ 148 { } /* Terminating entry */
134}; 149};
135 150
@@ -985,6 +1000,11 @@ static int hci_usb_probe(struct usb_interface *intf, const struct usb_device_id
985 if (reset || id->driver_info & HCI_RESET) 1000 if (reset || id->driver_info & HCI_RESET)
986 set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks); 1001 set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
987 1002
1003 if (force_scofix || id->driver_info & HCI_WRONG_SCO_MTU) {
1004 if (!disable_scofix)
1005 set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
1006 }
1007
988 if (id->driver_info & HCI_SNIFFER) { 1008 if (id->driver_info & HCI_SNIFFER) {
989 if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997) 1009 if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
990 set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); 1010 set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
@@ -1043,10 +1063,81 @@ static void hci_usb_disconnect(struct usb_interface *intf)
1043 hci_free_dev(hdev); 1063 hci_free_dev(hdev);
1044} 1064}
1045 1065
1066static int hci_usb_suspend(struct usb_interface *intf, pm_message_t message)
1067{
1068 struct hci_usb *husb = usb_get_intfdata(intf);
1069 struct list_head killed;
1070 unsigned long flags;
1071 int i;
1072
1073 if (!husb || intf == husb->isoc_iface)
1074 return 0;
1075
1076 hci_suspend_dev(husb->hdev);
1077
1078 INIT_LIST_HEAD(&killed);
1079
1080 for (i = 0; i < 4; i++) {
1081 struct _urb_queue *q = &husb->pending_q[i];
1082 struct _urb *_urb, *_tmp;
1083
1084 while ((_urb = _urb_dequeue(q))) {
1085 /* reset queue since _urb_dequeue sets it to NULL */
1086 _urb->queue = q;
1087 usb_kill_urb(&_urb->urb);
1088 list_add(&_urb->list, &killed);
1089 }
1090
1091 spin_lock_irqsave(&q->lock, flags);
1092
1093 list_for_each_entry_safe(_urb, _tmp, &killed, list) {
1094 list_move_tail(&_urb->list, &q->head);
1095 }
1096
1097 spin_unlock_irqrestore(&q->lock, flags);
1098 }
1099
1100 return 0;
1101}
1102
1103static int hci_usb_resume(struct usb_interface *intf)
1104{
1105 struct hci_usb *husb = usb_get_intfdata(intf);
1106 unsigned long flags;
1107 int i, err = 0;
1108
1109 if (!husb || intf == husb->isoc_iface)
1110 return 0;
1111
1112 for (i = 0; i < 4; i++) {
1113 struct _urb_queue *q = &husb->pending_q[i];
1114 struct _urb *_urb;
1115
1116 spin_lock_irqsave(&q->lock, flags);
1117
1118 list_for_each_entry(_urb, &q->head, list) {
1119 err = usb_submit_urb(&_urb->urb, GFP_ATOMIC);
1120 if (err)
1121 break;
1122 }
1123
1124 spin_unlock_irqrestore(&q->lock, flags);
1125
1126 if (err)
1127 return -EIO;
1128 }
1129
1130 hci_resume_dev(husb->hdev);
1131
1132 return 0;
1133}
1134
1046static struct usb_driver hci_usb_driver = { 1135static struct usb_driver hci_usb_driver = {
1047 .name = "hci_usb", 1136 .name = "hci_usb",
1048 .probe = hci_usb_probe, 1137 .probe = hci_usb_probe,
1049 .disconnect = hci_usb_disconnect, 1138 .disconnect = hci_usb_disconnect,
1139 .suspend = hci_usb_suspend,
1140 .resume = hci_usb_resume,
1050 .id_table = bluetooth_ids, 1141 .id_table = bluetooth_ids,
1051}; 1142};
1052 1143
@@ -1082,6 +1173,12 @@ MODULE_PARM_DESC(ignore_csr, "Ignore devices with id 0a12:0001");
1082module_param(ignore_sniffer, bool, 0644); 1173module_param(ignore_sniffer, bool, 0644);
1083MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002"); 1174MODULE_PARM_DESC(ignore_sniffer, "Ignore devices with id 0a12:0002");
1084 1175
1176module_param(disable_scofix, bool, 0644);
1177MODULE_PARM_DESC(disable_scofix, "Disable fixup of wrong SCO buffer size");
1178
1179module_param(force_scofix, bool, 0644);
1180MODULE_PARM_DESC(force_scofix, "Force fixup of wrong SCO buffers size");
1181
1085module_param(reset, bool, 0644); 1182module_param(reset, bool, 0644);
1086MODULE_PARM_DESC(reset, "Send HCI reset command on initialization"); 1183MODULE_PARM_DESC(reset, "Send HCI reset command on initialization");
1087 1184