Blame view

drivers/bluetooth/btusb.c 43.7 KB
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1
2
3
4
  /*
   *
   *  Generic Bluetooth USB driver
   *
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
5
   *  Copyright (C) 2005-2008  Marcel Holtmann <marcel@holtmann.org>
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
   *
   *
   *  This program is free software; you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation; either version 2 of the License, or
   *  (at your option) any later version.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License
   *  along with this program; if not, write to the Free Software
   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   *
   */
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
23
  #include <linux/module.h>
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
24
  #include <linux/usb.h>
dffd30ee9   Tedd Ho-Jeong An   Bluetooth: Add su...
25
  #include <linux/firmware.h>
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
26
27
28
  
  #include <net/bluetooth/bluetooth.h>
  #include <net/bluetooth/hci_core.h>
7bee549e1   Oliver Neukum   Bluetooth: Add US...
29
  #define VERSION "0.6"
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
30

90ab5ee94   Rusty Russell   module_param: mak...
31
32
33
34
35
  static bool ignore_dga;
  static bool ignore_csr;
  static bool ignore_sniffer;
  static bool disable_scofix;
  static bool force_scofix;
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
36

90ab5ee94   Rusty Russell   module_param: mak...
37
  static bool reset = 1;
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
38
39
40
41
  
  static struct usb_driver btusb_driver;
  
  #define BTUSB_IGNORE		0x01
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
42
43
44
45
46
47
  #define BTUSB_DIGIANSWER	0x02
  #define BTUSB_CSR		0x04
  #define BTUSB_SNIFFER		0x08
  #define BTUSB_BCM92035		0x10
  #define BTUSB_BROKEN_ISOC	0x20
  #define BTUSB_WRONG_SCO_MTU	0x40
2d25f8b46   Steven.Li   Bluetooth: Add At...
48
  #define BTUSB_ATH3012		0x80
dffd30ee9   Tedd Ho-Jeong An   Bluetooth: Add su...
49
  #define BTUSB_INTEL		0x100
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
50

54265202f   Marcel Holtmann   Bluetooth: Declar...
51
  static const struct usb_device_id btusb_table[] = {
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
52
53
  	/* Generic Bluetooth USB device */
  	{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
1fa6535fa   Henrik Rydberg   Bluetooth: Add su...
54
55
  	/* Apple-specific (Broadcom) devices */
  	{ USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) },
178c059e7   Cho, Yu-Chen   Bluetooth: Add su...
56
57
  	/* MediaTek MT76x0E */
  	{ USB_DEVICE(0x0e8d, 0x763f) },
c510eae37   Oliver Neukum   btusb: add device...
58
  	/* Broadcom SoftSailing reporting vendor specific */
2e8b50631   Don Zickus   Bluetooth: btusb:...
59
  	{ USB_DEVICE(0x0a5c, 0x21e1) },
c510eae37   Oliver Neukum   btusb: add device...
60

3cd01976e   Nobuhiro Iwamatsu   Bluetooth: Add su...
61
62
  	/* Apple MacBookPro 7,1 */
  	{ USB_DEVICE(0x05ac, 0x8213) },
0a79f6744   Cyril Lacoux   Bluetooth: Added ...
63
64
  	/* Apple iMac11,1 */
  	{ USB_DEVICE(0x05ac, 0x8215) },
9c047157a   Nobuhiro Iwamatsu   Bluetooth: Add su...
65
66
  	/* Apple MacBookPro6,2 */
  	{ USB_DEVICE(0x05ac, 0x8218) },
3e3ede7dd   Edgar (gimli) Hucek   Bluetooth: Add Ma...
67
68
  	/* Apple MacBookAir3,1, MacBookAir3,2 */
  	{ USB_DEVICE(0x05ac, 0x821b) },
a63b723d0   Pieter-Augustijn Van Malleghem   Bluetooth: Add Ma...
69
70
  	/* Apple MacBookAir4,1 */
  	{ USB_DEVICE(0x05ac, 0x821f) },
88d377b6c   Marc-Antoine Perennou   Bluetooth: add su...
71
72
  	/* Apple MacBookPro8,2 */
  	{ USB_DEVICE(0x05ac, 0x821a) },
f78b68261   Jurgen Kramer   Bluetooth: add su...
73
74
  	/* Apple MacMini5,1 */
  	{ USB_DEVICE(0x05ac, 0x8281) },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  	/* AVM BlueFRITZ! USB v2.0 */
  	{ USB_DEVICE(0x057c, 0x3800) },
  
  	/* Bluetooth Ultraport Module from IBM */
  	{ USB_DEVICE(0x04bf, 0x030a) },
  
  	/* ALPS Modules with non-standard id */
  	{ USB_DEVICE(0x044e, 0x3001) },
  	{ USB_DEVICE(0x044e, 0x3002) },
  
  	/* Ericsson with non-standard id */
  	{ USB_DEVICE(0x0bdb, 0x1002) },
  
  	/* Canyon CN-BTU1 with HID interfaces */
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
89
  	{ USB_DEVICE(0x0c10, 0x0000) },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
90

d13431ca3   Wen-chien Jesse Sung   Bluetooth: Add su...
91
  	/* Broadcom BCM20702A0 */
0b8800623   Andy Shevchenko   Bluetooth: sort t...
92
93
  	{ USB_DEVICE(0x0489, 0xe042) },
  	{ USB_DEVICE(0x04ca, 0x2003) },
1ee3ff611   Jeff Cook   Bluetooth: Add su...
94
  	{ USB_DEVICE(0x0b05, 0x17b5) },
38a172bef   Raphael Kubo da Costa   Bluetooth: Add su...
95
  	{ USB_DEVICE(0x0b05, 0x17cb) },
d13431ca3   Wen-chien Jesse Sung   Bluetooth: Add su...
96
  	{ USB_DEVICE(0x413c, 0x8197) },
985140369   Steven Harms   Add Foxconn / Hon...
97
  	/* Foxconn - Hon Hai */
ee66401bb   Gustavo Padovan   Bluetooth: Add US...
98
  	{ USB_VENDOR_AND_INTERFACE_INFO(0x0489, 0xff, 0x01, 0x01) },
985140369   Steven Harms   Add Foxconn / Hon...
99

0b8800623   Andy Shevchenko   Bluetooth: sort t...
100
  	/* Broadcom devices with vendor specific id */
92c385f46   Gustavo Padovan   Bluetooth: Use US...
101
  	{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) },
5bcecf325   Ken O'Brien   Bluetooth: btusb:...
102
103
  	/* Belkin F8065bf - Broadcom based */
  	{ USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01) },
9113bfd82   Jurgen Kramer   Bluetooth: btusb:...
104
105
  	/* IMC Networks - Broadcom based */
  	{ USB_VENDOR_AND_INTERFACE_INFO(0x13d3, 0xff, 0x01, 0x01) },
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
106
107
108
109
  	{ }	/* Terminating entry */
  };
  
  MODULE_DEVICE_TABLE(usb, btusb_table);
54265202f   Marcel Holtmann   Bluetooth: Declar...
110
  static const struct usb_device_id blacklist_table[] = {
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
111
112
113
114
115
  	/* CSR BlueCore devices */
  	{ USB_DEVICE(0x0a12, 0x0001), .driver_info = BTUSB_CSR },
  
  	/* Broadcom BCM2033 without firmware */
  	{ USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE },
be93112ac   Bala Shanmugam   Bluetooth: Add ne...
116
  	/* Atheros 3011 with sflash firmware */
0b8800623   Andy Shevchenko   Bluetooth: sort t...
117
118
119
  	{ USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE },
  	{ USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE },
  	{ USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
be93112ac   Bala Shanmugam   Bluetooth: Add ne...
120
  	{ USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
6eda541d1   Marek Vasut   Bluetooth: Suppor...
121
  	{ USB_DEVICE(0x0cf3, 0xe019), .driver_info = BTUSB_IGNORE },
2a7bccccd   Andy Ross   Bluetooth: Device...
122
  	{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
be93112ac   Bala Shanmugam   Bluetooth: Add ne...
123

509e7861d   Cho, Yu-Chen   Bluetooth: add At...
124
125
  	/* Atheros AR9285 Malbec with sflash firmware */
  	{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
d9f51b51d   Bala Shanmugam   Bluetooth: Add fi...
126
  	/* Atheros 3012 with sflash firmware */
0b8800623   Andy Shevchenko   Bluetooth: sort t...
127
128
129
130
131
132
133
134
135
136
137
138
139
  	{ USB_DEVICE(0x0489, 0xe04d), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 },
a735f9e22   Andy Shevchenko   Bluetooth: append...
140
  	{ USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 },
d66629c13   Ming Lei   Bluetooth: Add su...
141
  	{ USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 },
2d25f8b46   Steven.Li   Bluetooth: Add At...
142
  	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
ca58e594d   Peng Chen   Bluetooth: Add a ...
143
  	{ USB_DEVICE(0x0cf3, 0x3005), .driver_info = BTUSB_ATH3012 },
94a32d10f   Sunguk Lee   Bluetooth: Device...
144
  	{ USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 },
07c0ea874   Cho, Yu-Chen   Bluetooth: Add At...
145
  	{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
b131237ca   Oliver Neukum   Bluetooth: Enable...
146
  	{ USB_DEVICE(0x0cf3, 0x311e), .driver_info = BTUSB_ATH3012 },
1e56f1eb2   Oliver Neukum   Bluetooth: Add fi...
147
  	{ USB_DEVICE(0x0cf3, 0x311f), .driver_info = BTUSB_ATH3012 },
0b8800623   Andy Shevchenko   Bluetooth: sort t...
148
  	{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
ebaf5795e   Ming Lei   Bluetooth: Add su...
149
  	{ USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 },
0b8800623   Andy Shevchenko   Bluetooth: sort t...
150
  	{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
ac71311e6   AceLan Kao   Bluetooth: Add su...
151
  	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
0a3658ccc   Peng Chen   Bluetooth: Add a ...
152
  	{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
0b8800623   Andy Shevchenko   Bluetooth: sort t...
153
154
  	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
  	{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
eed307e29   AceLan Kao   Bluetooth: Add su...
155
  	{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
5b77a1f3d   Sujith Manoharan   Bluetooth: ath3k:...
156
  	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
d9f51b51d   Bala Shanmugam   Bluetooth: Add fi...
157

e9036e336   Cho, Yu-Chen   Bluetooth: Add At...
158
159
  	/* Atheros AR5BBU12 with sflash firmware */
  	{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
85d59726c   Michael Gruetzner   Bluetooth: Add su...
160
  	/* Atheros AR5BBU12 with sflash firmware */
bc21fde2d   Yevgeniy Melnichuk   Bluetooth: Add su...
161
  	{ USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 },
0b8800623   Andy Shevchenko   Bluetooth: sort t...
162
  	{ USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
85d59726c   Michael Gruetzner   Bluetooth: Add su...
163

cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
164
  	/* Broadcom BCM2035 */
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
165
  	{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
0b8800623   Andy Shevchenko   Bluetooth: sort t...
166
167
  	{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
  	{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
168
169
  
  	/* Broadcom BCM2045 */
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
170
171
  	{ USB_DEVICE(0x0a5c, 0x2039), .driver_info = BTUSB_WRONG_SCO_MTU },
  	{ USB_DEVICE(0x0a5c, 0x2101), .driver_info = BTUSB_WRONG_SCO_MTU },
bdbef3d69   Marcel Holtmann   [Bluetooth] Fix I...
172

cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
173
  	/* IBM/Lenovo ThinkPad with Broadcom chip */
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
174
175
  	{ USB_DEVICE(0x0a5c, 0x201e), .driver_info = BTUSB_WRONG_SCO_MTU },
  	{ USB_DEVICE(0x0a5c, 0x2110), .driver_info = BTUSB_WRONG_SCO_MTU },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
176
177
  
  	/* HP laptop with Broadcom chip */
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
178
  	{ USB_DEVICE(0x03f0, 0x171d), .driver_info = BTUSB_WRONG_SCO_MTU },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
179
180
  
  	/* Dell laptop with Broadcom chip */
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
181
  	{ USB_DEVICE(0x413c, 0x8126), .driver_info = BTUSB_WRONG_SCO_MTU },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
182

5ddd4a606   Marcel Holtmann   Bluetooth: Allow ...
183
  	/* Dell Wireless 370 and 410 devices */
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
184
  	{ USB_DEVICE(0x413c, 0x8152), .driver_info = BTUSB_WRONG_SCO_MTU },
5ddd4a606   Marcel Holtmann   Bluetooth: Allow ...
185
  	{ USB_DEVICE(0x413c, 0x8156), .driver_info = BTUSB_WRONG_SCO_MTU },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
186

7a9d40205   Marcel Holtmann   Bluetooth: Send H...
187
188
189
  	/* Belkin F8T012 and F8T013 devices */
  	{ USB_DEVICE(0x050d, 0x0012), .driver_info = BTUSB_WRONG_SCO_MTU },
  	{ USB_DEVICE(0x050d, 0x0013), .driver_info = BTUSB_WRONG_SCO_MTU },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
190

5ddd4a606   Marcel Holtmann   Bluetooth: Allow ...
191
192
193
194
195
  	/* Asus WL-BTD202 device */
  	{ USB_DEVICE(0x0b05, 0x1715), .driver_info = BTUSB_WRONG_SCO_MTU },
  
  	/* Kensington Bluetooth USB adapter */
  	{ USB_DEVICE(0x047d, 0x105e), .driver_info = BTUSB_WRONG_SCO_MTU },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
196
197
198
199
200
201
  	/* RTX Telecom based adapters with buggy SCO support */
  	{ USB_DEVICE(0x0400, 0x0807), .driver_info = BTUSB_BROKEN_ISOC },
  	{ USB_DEVICE(0x0400, 0x080a), .driver_info = BTUSB_BROKEN_ISOC },
  
  	/* CONWISE Technology based adapters with buggy SCO support */
  	{ USB_DEVICE(0x0e5e, 0x6622), .driver_info = BTUSB_BROKEN_ISOC },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
202
203
204
205
206
207
208
209
210
  	/* Digianswer devices */
  	{ USB_DEVICE(0x08fd, 0x0001), .driver_info = BTUSB_DIGIANSWER },
  	{ USB_DEVICE(0x08fd, 0x0002), .driver_info = BTUSB_IGNORE },
  
  	/* CSR BlueCore Bluetooth Sniffer */
  	{ USB_DEVICE(0x0a12, 0x0002), .driver_info = BTUSB_SNIFFER },
  
  	/* Frontline ComProbe Bluetooth Sniffer */
  	{ USB_DEVICE(0x16d3, 0x0002), .driver_info = BTUSB_SNIFFER },
dffd30ee9   Tedd Ho-Jeong An   Bluetooth: Add su...
211
212
  	/* Intel Bluetooth device */
  	{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
ef4e5e4a7   Tedd Ho-Jeong An   Bluetooth: Add su...
213
  	{ USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
dffd30ee9   Tedd Ho-Jeong An   Bluetooth: Add su...
214

5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
215
216
  	{ }	/* Terminating entry */
  };
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
217
  #define BTUSB_MAX_ISOC_FRAMES	10
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
218
219
  #define BTUSB_INTR_RUNNING	0
  #define BTUSB_BULK_RUNNING	1
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
220
  #define BTUSB_ISOC_RUNNING	2
7bee549e1   Oliver Neukum   Bluetooth: Add US...
221
  #define BTUSB_SUSPENDING	3
08b8b6c45   Gustavo Padovan   Bluetooth: Move b...
222
  #define BTUSB_DID_ISO_RESUME	4
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
223
224
225
226
  
  struct btusb_data {
  	struct hci_dev       *hdev;
  	struct usb_device    *udev;
5fbcd260c   Marcel Holtmann   [Bluetooth] Fix U...
227
  	struct usb_interface *intf;
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
228
  	struct usb_interface *isoc;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
229
230
231
232
233
234
  
  	spinlock_t lock;
  
  	unsigned long flags;
  
  	struct work_struct work;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
235
  	struct work_struct waker;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
236
237
238
239
  
  	struct usb_anchor tx_anchor;
  	struct usb_anchor intr_anchor;
  	struct usb_anchor bulk_anchor;
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
240
  	struct usb_anchor isoc_anchor;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
241
242
243
  	struct usb_anchor deferred;
  	int tx_in_flight;
  	spinlock_t txlock;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
244
245
246
247
  
  	struct usb_endpoint_descriptor *intr_ep;
  	struct usb_endpoint_descriptor *bulk_tx_ep;
  	struct usb_endpoint_descriptor *bulk_rx_ep;
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
248
249
  	struct usb_endpoint_descriptor *isoc_tx_ep;
  	struct usb_endpoint_descriptor *isoc_rx_ep;
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
250
  	__u8 cmdreq_type;
43c2e57f9   Marcel Holtmann   Bluetooth: Submit...
251
  	unsigned int sco_num;
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
252
  	int isoc_altsetting;
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
253
  	int suspend_count;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
254
  };
7bee549e1   Oliver Neukum   Bluetooth: Add US...
255
256
257
258
259
260
261
262
263
264
265
266
267
  static int inc_tx(struct btusb_data *data)
  {
  	unsigned long flags;
  	int rv;
  
  	spin_lock_irqsave(&data->txlock, flags);
  	rv = test_bit(BTUSB_SUSPENDING, &data->flags);
  	if (!rv)
  		data->tx_in_flight++;
  	spin_unlock_irqrestore(&data->txlock, flags);
  
  	return rv;
  }
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
268
269
270
  static void btusb_intr_complete(struct urb *urb)
  {
  	struct hci_dev *hdev = urb->context;
155961e80   David Herrmann   Bluetooth: Remove...
271
  	struct btusb_data *data = hci_get_drvdata(hdev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
272
273
274
275
276
277
278
279
280
  	int err;
  
  	BT_DBG("%s urb %p status %d count %d", hdev->name,
  					urb, urb->status, urb->actual_length);
  
  	if (!test_bit(HCI_RUNNING, &hdev->flags))
  		return;
  
  	if (urb->status == 0) {
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
281
  		hdev->stat.byte_rx += urb->actual_length;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
282
283
284
285
286
287
288
289
290
291
  		if (hci_recv_fragment(hdev, HCI_EVENT_PKT,
  						urb->transfer_buffer,
  						urb->actual_length) < 0) {
  			BT_ERR("%s corrupted event packet", hdev->name);
  			hdev->stat.err_rx++;
  		}
  	}
  
  	if (!test_bit(BTUSB_INTR_RUNNING, &data->flags))
  		return;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
292
  	usb_mark_last_busy(data->udev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
293
294
295
296
  	usb_anchor_urb(urb, &data->intr_anchor);
  
  	err = usb_submit_urb(urb, GFP_ATOMIC);
  	if (err < 0) {
4935f1c16   Paul Bolle   Bluetooth: btusb:...
297
298
299
  		/* -EPERM: urb is being killed;
  		 * -ENODEV: device got disconnected */
  		if (err != -EPERM && err != -ENODEV)
61faddf66   Stefan Seyfried   Bluetooth: Fix lo...
300
  			BT_ERR("%s urb %p failed to resubmit (%d)",
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
301
302
303
304
  						hdev->name, urb, -err);
  		usb_unanchor_urb(urb);
  	}
  }
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
305
  static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
306
  {
155961e80   David Herrmann   Bluetooth: Remove...
307
  	struct btusb_data *data = hci_get_drvdata(hdev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
308
309
310
311
312
313
  	struct urb *urb;
  	unsigned char *buf;
  	unsigned int pipe;
  	int err, size;
  
  	BT_DBG("%s", hdev->name);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
314
315
  	if (!data->intr_ep)
  		return -ENODEV;
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
316
  	urb = usb_alloc_urb(0, mem_flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
317
318
319
320
  	if (!urb)
  		return -ENOMEM;
  
  	size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
321
  	buf = kmalloc(size, mem_flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
322
323
324
325
326
327
328
329
330
331
332
333
334
335
  	if (!buf) {
  		usb_free_urb(urb);
  		return -ENOMEM;
  	}
  
  	pipe = usb_rcvintpipe(data->udev, data->intr_ep->bEndpointAddress);
  
  	usb_fill_int_urb(urb, data->udev, pipe, buf, size,
  						btusb_intr_complete, hdev,
  						data->intr_ep->bInterval);
  
  	urb->transfer_flags |= URB_FREE_BUFFER;
  
  	usb_anchor_urb(urb, &data->intr_anchor);
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
336
  	err = usb_submit_urb(urb, mem_flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
337
  	if (err < 0) {
d4b8d1c9c   Paul Bolle   Bluetooth: btusb:...
338
339
  		if (err != -EPERM && err != -ENODEV)
  			BT_ERR("%s urb %p submission failed (%d)",
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
340
341
  						hdev->name, urb, -err);
  		usb_unanchor_urb(urb);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
342
343
344
345
346
347
348
349
350
351
  	}
  
  	usb_free_urb(urb);
  
  	return err;
  }
  
  static void btusb_bulk_complete(struct urb *urb)
  {
  	struct hci_dev *hdev = urb->context;
155961e80   David Herrmann   Bluetooth: Remove...
352
  	struct btusb_data *data = hci_get_drvdata(hdev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
353
354
355
356
357
358
359
360
361
  	int err;
  
  	BT_DBG("%s urb %p status %d count %d", hdev->name,
  					urb, urb->status, urb->actual_length);
  
  	if (!test_bit(HCI_RUNNING, &hdev->flags))
  		return;
  
  	if (urb->status == 0) {
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
362
  		hdev->stat.byte_rx += urb->actual_length;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
363
364
365
366
367
368
369
370
371
372
373
374
  		if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT,
  						urb->transfer_buffer,
  						urb->actual_length) < 0) {
  			BT_ERR("%s corrupted ACL packet", hdev->name);
  			hdev->stat.err_rx++;
  		}
  	}
  
  	if (!test_bit(BTUSB_BULK_RUNNING, &data->flags))
  		return;
  
  	usb_anchor_urb(urb, &data->bulk_anchor);
652fd781a   Oliver Neukum   Bluetooth: Preven...
375
  	usb_mark_last_busy(data->udev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
376
377
378
  
  	err = usb_submit_urb(urb, GFP_ATOMIC);
  	if (err < 0) {
4935f1c16   Paul Bolle   Bluetooth: btusb:...
379
380
381
  		/* -EPERM: urb is being killed;
  		 * -ENODEV: device got disconnected */
  		if (err != -EPERM && err != -ENODEV)
61faddf66   Stefan Seyfried   Bluetooth: Fix lo...
382
  			BT_ERR("%s urb %p failed to resubmit (%d)",
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
383
384
385
386
  						hdev->name, urb, -err);
  		usb_unanchor_urb(urb);
  	}
  }
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
387
  static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
388
  {
155961e80   David Herrmann   Bluetooth: Remove...
389
  	struct btusb_data *data = hci_get_drvdata(hdev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
390
391
392
  	struct urb *urb;
  	unsigned char *buf;
  	unsigned int pipe;
290ba2008   Vikram Kandukuri   Bluetooth: Improv...
393
  	int err, size = HCI_MAX_FRAME_SIZE;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
394
395
  
  	BT_DBG("%s", hdev->name);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
396
397
  	if (!data->bulk_rx_ep)
  		return -ENODEV;
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
398
  	urb = usb_alloc_urb(0, mem_flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
399
400
  	if (!urb)
  		return -ENOMEM;
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
401
  	buf = kmalloc(size, mem_flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
402
403
404
405
406
407
408
409
410
411
412
  	if (!buf) {
  		usb_free_urb(urb);
  		return -ENOMEM;
  	}
  
  	pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress);
  
  	usb_fill_bulk_urb(urb, data->udev, pipe,
  					buf, size, btusb_bulk_complete, hdev);
  
  	urb->transfer_flags |= URB_FREE_BUFFER;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
413
  	usb_mark_last_busy(data->udev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
414
  	usb_anchor_urb(urb, &data->bulk_anchor);
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
415
  	err = usb_submit_urb(urb, mem_flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
416
  	if (err < 0) {
d4b8d1c9c   Paul Bolle   Bluetooth: btusb:...
417
418
  		if (err != -EPERM && err != -ENODEV)
  			BT_ERR("%s urb %p submission failed (%d)",
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
419
420
  						hdev->name, urb, -err);
  		usb_unanchor_urb(urb);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
421
422
423
424
425
426
  	}
  
  	usb_free_urb(urb);
  
  	return err;
  }
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
427
428
429
  static void btusb_isoc_complete(struct urb *urb)
  {
  	struct hci_dev *hdev = urb->context;
155961e80   David Herrmann   Bluetooth: Remove...
430
  	struct btusb_data *data = hci_get_drvdata(hdev);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
  	int i, err;
  
  	BT_DBG("%s urb %p status %d count %d", hdev->name,
  					urb, urb->status, urb->actual_length);
  
  	if (!test_bit(HCI_RUNNING, &hdev->flags))
  		return;
  
  	if (urb->status == 0) {
  		for (i = 0; i < urb->number_of_packets; i++) {
  			unsigned int offset = urb->iso_frame_desc[i].offset;
  			unsigned int length = urb->iso_frame_desc[i].actual_length;
  
  			if (urb->iso_frame_desc[i].status)
  				continue;
  
  			hdev->stat.byte_rx += length;
  
  			if (hci_recv_fragment(hdev, HCI_SCODATA_PKT,
  						urb->transfer_buffer + offset,
  								length) < 0) {
  				BT_ERR("%s corrupted SCO packet", hdev->name);
  				hdev->stat.err_rx++;
  			}
  		}
  	}
  
  	if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags))
  		return;
  
  	usb_anchor_urb(urb, &data->isoc_anchor);
  
  	err = usb_submit_urb(urb, GFP_ATOMIC);
  	if (err < 0) {
4935f1c16   Paul Bolle   Bluetooth: btusb:...
465
466
467
  		/* -EPERM: urb is being killed;
  		 * -ENODEV: device got disconnected */
  		if (err != -EPERM && err != -ENODEV)
61faddf66   Stefan Seyfried   Bluetooth: Fix lo...
468
  			BT_ERR("%s urb %p failed to resubmit (%d)",
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
469
470
471
472
  						hdev->name, urb, -err);
  		usb_unanchor_urb(urb);
  	}
  }
42b16b3fb   Jesper Juhl   Kill off warning:...
473
  static inline void __fill_isoc_descriptor(struct urb *urb, int len, int mtu)
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
  {
  	int i, offset = 0;
  
  	BT_DBG("len %d mtu %d", len, mtu);
  
  	for (i = 0; i < BTUSB_MAX_ISOC_FRAMES && len >= mtu;
  					i++, offset += mtu, len -= mtu) {
  		urb->iso_frame_desc[i].offset = offset;
  		urb->iso_frame_desc[i].length = mtu;
  	}
  
  	if (len && i < BTUSB_MAX_ISOC_FRAMES) {
  		urb->iso_frame_desc[i].offset = offset;
  		urb->iso_frame_desc[i].length = len;
  		i++;
  	}
  
  	urb->number_of_packets = i;
  }
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
493
  static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
494
  {
155961e80   David Herrmann   Bluetooth: Remove...
495
  	struct btusb_data *data = hci_get_drvdata(hdev);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
496
497
498
499
500
501
502
503
504
  	struct urb *urb;
  	unsigned char *buf;
  	unsigned int pipe;
  	int err, size;
  
  	BT_DBG("%s", hdev->name);
  
  	if (!data->isoc_rx_ep)
  		return -ENODEV;
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
505
  	urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, mem_flags);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
506
507
508
509
510
  	if (!urb)
  		return -ENOMEM;
  
  	size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) *
  						BTUSB_MAX_ISOC_FRAMES;
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
511
  	buf = kmalloc(size, mem_flags);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
512
513
514
515
516
517
  	if (!buf) {
  		usb_free_urb(urb);
  		return -ENOMEM;
  	}
  
  	pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);
fa0fb93f2   Bing Zhao   Bluetooth: btusb:...
518
519
  	usb_fill_int_urb(urb, data->udev, pipe, buf, size, btusb_isoc_complete,
  				hdev, data->isoc_rx_ep->bInterval);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
520
521
  
  	urb->transfer_flags  = URB_FREE_BUFFER | URB_ISO_ASAP;
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
522
523
524
525
526
  
  	__fill_isoc_descriptor(urb, size,
  			le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize));
  
  	usb_anchor_urb(urb, &data->isoc_anchor);
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
527
  	err = usb_submit_urb(urb, mem_flags);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
528
  	if (err < 0) {
d4b8d1c9c   Paul Bolle   Bluetooth: btusb:...
529
530
  		if (err != -EPERM && err != -ENODEV)
  			BT_ERR("%s urb %p submission failed (%d)",
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
531
532
  						hdev->name, urb, -err);
  		usb_unanchor_urb(urb);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
533
534
535
536
537
538
  	}
  
  	usb_free_urb(urb);
  
  	return err;
  }
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
539
540
541
542
  static void btusb_tx_complete(struct urb *urb)
  {
  	struct sk_buff *skb = urb->context;
  	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
155961e80   David Herrmann   Bluetooth: Remove...
543
  	struct btusb_data *data = hci_get_drvdata(hdev);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
  
  	BT_DBG("%s urb %p status %d count %d", hdev->name,
  					urb, urb->status, urb->actual_length);
  
  	if (!test_bit(HCI_RUNNING, &hdev->flags))
  		goto done;
  
  	if (!urb->status)
  		hdev->stat.byte_tx += urb->transfer_buffer_length;
  	else
  		hdev->stat.err_tx++;
  
  done:
  	spin_lock(&data->txlock);
  	data->tx_in_flight--;
  	spin_unlock(&data->txlock);
  
  	kfree(urb->setup_packet);
  
  	kfree_skb(skb);
  }
  
  static void btusb_isoc_tx_complete(struct urb *urb)
  {
  	struct sk_buff *skb = urb->context;
  	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
  
  	BT_DBG("%s urb %p status %d count %d", hdev->name,
  					urb, urb->status, urb->actual_length);
  
  	if (!test_bit(HCI_RUNNING, &hdev->flags))
  		goto done;
  
  	if (!urb->status)
  		hdev->stat.byte_tx += urb->transfer_buffer_length;
  	else
  		hdev->stat.err_tx++;
  
  done:
  	kfree(urb->setup_packet);
  
  	kfree_skb(skb);
  }
  
  static int btusb_open(struct hci_dev *hdev)
  {
155961e80   David Herrmann   Bluetooth: Remove...
590
  	struct btusb_data *data = hci_get_drvdata(hdev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
591
592
593
  	int err;
  
  	BT_DBG("%s", hdev->name);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
594
595
596
597
598
  	err = usb_autopm_get_interface(data->intf);
  	if (err < 0)
  		return err;
  
  	data->intf->needs_remote_wakeup = 1;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
599
  	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
7bee549e1   Oliver Neukum   Bluetooth: Add US...
600
  		goto done;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
601
602
  
  	if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
7bee549e1   Oliver Neukum   Bluetooth: Add US...
603
  		goto done;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
604

2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
605
  	err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
43c2e57f9   Marcel Holtmann   Bluetooth: Submit...
606
607
608
609
  	if (err < 0)
  		goto failed;
  
  	err = btusb_submit_bulk_urb(hdev, GFP_KERNEL);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
610
  	if (err < 0) {
43c2e57f9   Marcel Holtmann   Bluetooth: Submit...
611
612
  		usb_kill_anchored_urbs(&data->intr_anchor);
  		goto failed;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
613
  	}
43c2e57f9   Marcel Holtmann   Bluetooth: Submit...
614
615
  	set_bit(BTUSB_BULK_RUNNING, &data->flags);
  	btusb_submit_bulk_urb(hdev, GFP_KERNEL);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
616
617
  done:
  	usb_autopm_put_interface(data->intf);
43c2e57f9   Marcel Holtmann   Bluetooth: Submit...
618
619
620
621
622
  	return 0;
  
  failed:
  	clear_bit(BTUSB_INTR_RUNNING, &data->flags);
  	clear_bit(HCI_RUNNING, &hdev->flags);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
623
  	usb_autopm_put_interface(data->intf);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
624
625
  	return err;
  }
7bee549e1   Oliver Neukum   Bluetooth: Add US...
626
627
628
629
630
631
  static void btusb_stop_traffic(struct btusb_data *data)
  {
  	usb_kill_anchored_urbs(&data->intr_anchor);
  	usb_kill_anchored_urbs(&data->bulk_anchor);
  	usb_kill_anchored_urbs(&data->isoc_anchor);
  }
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
632
633
  static int btusb_close(struct hci_dev *hdev)
  {
155961e80   David Herrmann   Bluetooth: Remove...
634
  	struct btusb_data *data = hci_get_drvdata(hdev);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
635
  	int err;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
636
637
638
639
640
  
  	BT_DBG("%s", hdev->name);
  
  	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
  		return 0;
e8c3c3d22   Marcel Holtmann   [Bluetooth] Fix w...
641
  	cancel_work_sync(&data->work);
404291ac9   Linus Torvalds   btusb bluetooth d...
642
  	cancel_work_sync(&data->waker);
e8c3c3d22   Marcel Holtmann   [Bluetooth] Fix w...
643

9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
644
  	clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
645
  	clear_bit(BTUSB_BULK_RUNNING, &data->flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
646
  	clear_bit(BTUSB_INTR_RUNNING, &data->flags);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
647
648
649
650
  
  	btusb_stop_traffic(data);
  	err = usb_autopm_get_interface(data->intf);
  	if (err < 0)
7b8e2c1db   Oliver Neukum   fix memory leak i...
651
  		goto failed;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
652
653
654
  
  	data->intf->needs_remote_wakeup = 0;
  	usb_autopm_put_interface(data->intf);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
655

7b8e2c1db   Oliver Neukum   fix memory leak i...
656
657
  failed:
  	usb_scuttle_anchored_urbs(&data->deferred);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
658
659
660
661
662
  	return 0;
  }
  
  static int btusb_flush(struct hci_dev *hdev)
  {
155961e80   David Herrmann   Bluetooth: Remove...
663
  	struct btusb_data *data = hci_get_drvdata(hdev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
664
665
666
667
668
669
670
  
  	BT_DBG("%s", hdev->name);
  
  	usb_kill_anchored_urbs(&data->tx_anchor);
  
  	return 0;
  }
7bd8f09f6   Marcel Holtmann   Bluetooth: Add hd...
671
  static int btusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
672
  {
155961e80   David Herrmann   Bluetooth: Remove...
673
  	struct btusb_data *data = hci_get_drvdata(hdev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
674
675
676
677
678
679
680
681
682
  	struct usb_ctrlrequest *dr;
  	struct urb *urb;
  	unsigned int pipe;
  	int err;
  
  	BT_DBG("%s", hdev->name);
  
  	if (!test_bit(HCI_RUNNING, &hdev->flags))
  		return -EBUSY;
7bd8f09f6   Marcel Holtmann   Bluetooth: Add hd...
683
  	skb->dev = (void *) hdev;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
684
685
686
687
688
689
690
691
692
693
694
  	switch (bt_cb(skb)->pkt_type) {
  	case HCI_COMMAND_PKT:
  		urb = usb_alloc_urb(0, GFP_ATOMIC);
  		if (!urb)
  			return -ENOMEM;
  
  		dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
  		if (!dr) {
  			usb_free_urb(urb);
  			return -ENOMEM;
  		}
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
695
  		dr->bRequestType = data->cmdreq_type;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
696
697
698
699
700
701
702
703
704
705
706
707
708
709
  		dr->bRequest     = 0;
  		dr->wIndex       = 0;
  		dr->wValue       = 0;
  		dr->wLength      = __cpu_to_le16(skb->len);
  
  		pipe = usb_sndctrlpipe(data->udev, 0x00);
  
  		usb_fill_control_urb(urb, data->udev, pipe, (void *) dr,
  				skb->data, skb->len, btusb_tx_complete, skb);
  
  		hdev->stat.cmd_tx++;
  		break;
  
  	case HCI_ACLDATA_PKT:
9fd481e03   Peter Hurley   Bluetooth: Allow ...
710
  		if (!data->bulk_tx_ep)
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
711
  			return -ENODEV;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
712
713
714
715
716
717
718
719
720
721
722
723
724
725
  		urb = usb_alloc_urb(0, GFP_ATOMIC);
  		if (!urb)
  			return -ENOMEM;
  
  		pipe = usb_sndbulkpipe(data->udev,
  					data->bulk_tx_ep->bEndpointAddress);
  
  		usb_fill_bulk_urb(urb, data->udev, pipe,
  				skb->data, skb->len, btusb_tx_complete, skb);
  
  		hdev->stat.acl_tx++;
  		break;
  
  	case HCI_SCODATA_PKT:
014f7bc78   Marcel Holtmann   Bluetooth: Use hc...
726
  		if (!data->isoc_tx_ep || hci_conn_num(hdev, SCO_LINK) < 1)
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
727
728
729
730
731
732
733
734
  			return -ENODEV;
  
  		urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC);
  		if (!urb)
  			return -ENOMEM;
  
  		pipe = usb_sndisocpipe(data->udev,
  					data->isoc_tx_ep->bEndpointAddress);
03c2d0e89   Gustavo Padovan   Bluetooth: Use us...
735
736
737
  		usb_fill_int_urb(urb, data->udev, pipe,
  				skb->data, skb->len, btusb_isoc_tx_complete,
  				skb, data->isoc_tx_ep->bInterval);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
738
739
  
  		urb->transfer_flags  = URB_ISO_ASAP;
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
740
741
742
  
  		__fill_isoc_descriptor(urb, skb->len,
  				le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
743
  		hdev->stat.sco_tx++;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
744
  		goto skip_waking;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
745
746
747
748
  
  	default:
  		return -EILSEQ;
  	}
7bee549e1   Oliver Neukum   Bluetooth: Add US...
749
750
751
752
753
754
755
756
757
  	err = inc_tx(data);
  	if (err) {
  		usb_anchor_urb(urb, &data->deferred);
  		schedule_work(&data->waker);
  		err = 0;
  		goto done;
  	}
  
  skip_waking:
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
758
759
760
761
  	usb_anchor_urb(urb, &data->tx_anchor);
  
  	err = usb_submit_urb(urb, GFP_ATOMIC);
  	if (err < 0) {
5a9b80e2c   Paul Bolle   Bluetooth: btusb:...
762
763
764
  		if (err != -EPERM && err != -ENODEV)
  			BT_ERR("%s urb %p submission failed (%d)",
  						hdev->name, urb, -err);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
765
766
  		kfree(urb->setup_packet);
  		usb_unanchor_urb(urb);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
767
768
  	} else {
  		usb_mark_last_busy(data->udev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
769
  	}
7bee549e1   Oliver Neukum   Bluetooth: Add US...
770
  done:
54a8a79c5   Cong Wang   btusb: fix a memo...
771
  	usb_free_urb(urb);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
772
773
  	return err;
  }
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
774
775
  static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
  {
155961e80   David Herrmann   Bluetooth: Remove...
776
  	struct btusb_data *data = hci_get_drvdata(hdev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
777
778
  
  	BT_DBG("%s evt %d", hdev->name, evt);
014f7bc78   Marcel Holtmann   Bluetooth: Use hc...
779
780
  	if (hci_conn_num(hdev, SCO_LINK) != data->sco_num) {
  		data->sco_num = hci_conn_num(hdev, SCO_LINK);
43c2e57f9   Marcel Holtmann   Bluetooth: Submit...
781
  		schedule_work(&data->work);
a780efa81   Marcel Holtmann   Bluetooth: Handle...
782
  	}
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
783
  }
42b16b3fb   Jesper Juhl   Kill off warning:...
784
  static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting)
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
785
  {
155961e80   David Herrmann   Bluetooth: Remove...
786
  	struct btusb_data *data = hci_get_drvdata(hdev);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
  	struct usb_interface *intf = data->isoc;
  	struct usb_endpoint_descriptor *ep_desc;
  	int i, err;
  
  	if (!data->isoc)
  		return -ENODEV;
  
  	err = usb_set_interface(data->udev, 1, altsetting);
  	if (err < 0) {
  		BT_ERR("%s setting interface failed (%d)", hdev->name, -err);
  		return err;
  	}
  
  	data->isoc_altsetting = altsetting;
  
  	data->isoc_tx_ep = NULL;
  	data->isoc_rx_ep = NULL;
  
  	for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
  		ep_desc = &intf->cur_altsetting->endpoint[i].desc;
  
  		if (!data->isoc_tx_ep && usb_endpoint_is_isoc_out(ep_desc)) {
  			data->isoc_tx_ep = ep_desc;
  			continue;
  		}
  
  		if (!data->isoc_rx_ep && usb_endpoint_is_isoc_in(ep_desc)) {
  			data->isoc_rx_ep = ep_desc;
  			continue;
  		}
  	}
  
  	if (!data->isoc_tx_ep || !data->isoc_rx_ep) {
  		BT_ERR("%s invalid SCO descriptors", hdev->name);
  		return -ENODEV;
  	}
  
  	return 0;
  }
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
826
827
828
829
  static void btusb_work(struct work_struct *work)
  {
  	struct btusb_data *data = container_of(work, struct btusb_data, work);
  	struct hci_dev *hdev = data->hdev;
f4001d284   Mikel Astiz   Bluetooth: btusb:...
830
  	int new_alts;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
831
  	int err;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
832

014f7bc78   Marcel Holtmann   Bluetooth: Use hc...
833
  	if (data->sco_num > 0) {
08b8b6c45   Gustavo Padovan   Bluetooth: Move b...
834
  		if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
8efdd0cdc   Oliver Neukum   Bluetooth: fix cr...
835
  			err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
836
837
838
839
840
  			if (err < 0) {
  				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
  				usb_kill_anchored_urbs(&data->isoc_anchor);
  				return;
  			}
08b8b6c45   Gustavo Padovan   Bluetooth: Move b...
841
  			set_bit(BTUSB_DID_ISO_RESUME, &data->flags);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
842
  		}
f4001d284   Mikel Astiz   Bluetooth: btusb:...
843
844
845
  
  		if (hdev->voice_setting & 0x0020) {
  			static const int alts[3] = { 2, 4, 5 };
014f7bc78   Marcel Holtmann   Bluetooth: Use hc...
846
  			new_alts = alts[data->sco_num - 1];
f4001d284   Mikel Astiz   Bluetooth: btusb:...
847
  		} else {
014f7bc78   Marcel Holtmann   Bluetooth: Use hc...
848
  			new_alts = data->sco_num;
f4001d284   Mikel Astiz   Bluetooth: btusb:...
849
850
851
  		}
  
  		if (data->isoc_altsetting != new_alts) {
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
852
853
  			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
  			usb_kill_anchored_urbs(&data->isoc_anchor);
f4001d284   Mikel Astiz   Bluetooth: btusb:...
854
  			if (__set_isoc_interface(hdev, new_alts) < 0)
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
855
856
857
858
  				return;
  		}
  
  		if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
859
  			if (btusb_submit_isoc_urb(hdev, GFP_KERNEL) < 0)
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
860
861
  				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
  			else
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
862
  				btusb_submit_isoc_urb(hdev, GFP_KERNEL);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
863
864
865
866
867
868
  		}
  	} else {
  		clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
  		usb_kill_anchored_urbs(&data->isoc_anchor);
  
  		__set_isoc_interface(hdev, 0);
08b8b6c45   Gustavo Padovan   Bluetooth: Move b...
869
  		if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
8efdd0cdc   Oliver Neukum   Bluetooth: fix cr...
870
  			usb_autopm_put_interface(data->isoc ? data->isoc : data->intf);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
871
872
  	}
  }
7bee549e1   Oliver Neukum   Bluetooth: Add US...
873
874
875
876
877
878
879
880
881
882
883
  static void btusb_waker(struct work_struct *work)
  {
  	struct btusb_data *data = container_of(work, struct btusb_data, waker);
  	int err;
  
  	err = usb_autopm_get_interface(data->intf);
  	if (err < 0)
  		return;
  
  	usb_autopm_put_interface(data->intf);
  }
9f8f962c8   Marcel Holtmann   Bluetooth: Use se...
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
  static int btusb_setup_bcm92035(struct hci_dev *hdev)
  {
  	struct sk_buff *skb;
  	u8 val = 0x00;
  
  	BT_DBG("%s", hdev->name);
  
  	skb = __hci_cmd_sync(hdev, 0xfc3b, 1, &val, HCI_INIT_TIMEOUT);
  	if (IS_ERR(skb))
  		BT_ERR("BCM92035 command failed (%ld)", -PTR_ERR(skb));
  	else
  		kfree_skb(skb);
  
  	return 0;
  }
81cac64ba   Marcel Holtmann   Bluetooth: Deal w...
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
  static int btusb_setup_csr(struct hci_dev *hdev)
  {
  	struct hci_rp_read_local_version *rp;
  	struct sk_buff *skb;
  	int ret;
  
  	BT_DBG("%s", hdev->name);
  
  	skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
  			     HCI_INIT_TIMEOUT);
  	if (IS_ERR(skb)) {
  		BT_ERR("Reading local version failed (%ld)", -PTR_ERR(skb));
  		return -PTR_ERR(skb);
  	}
  
  	rp = (struct hci_rp_read_local_version *) skb->data;
  
  	if (!rp->status) {
  		if (le16_to_cpu(rp->manufacturer) != 10) {
  			/* Clear the reset quirk since this is not an actual
  			 * early Bluetooth 1.1 device from CSR.
  			 */
  			clear_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
  
  			/* These fake CSR controllers have all a broken
  			 * stored link key handling and so just disable it.
  			 */
  			set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY,
  				&hdev->quirks);
  		}
  	}
  
  	ret = -bt_to_errno(rp->status);
  
  	kfree_skb(skb);
  
  	return ret;
  }
dffd30ee9   Tedd Ho-Jeong An   Bluetooth: Add su...
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
  struct intel_version {
  	u8 status;
  	u8 hw_platform;
  	u8 hw_variant;
  	u8 hw_revision;
  	u8 fw_variant;
  	u8 fw_revision;
  	u8 fw_build_num;
  	u8 fw_build_ww;
  	u8 fw_build_yy;
  	u8 fw_patch_num;
  } __packed;
  
  static const struct firmware *btusb_setup_intel_get_fw(struct hci_dev *hdev,
  						struct intel_version *ver)
  {
  	const struct firmware *fw;
  	char fwname[64];
  	int ret;
  
  	snprintf(fwname, sizeof(fwname),
  		 "intel/ibt-hw-%x.%x.%x-fw-%x.%x.%x.%x.%x.bseq",
  		 ver->hw_platform, ver->hw_variant, ver->hw_revision,
  		 ver->fw_variant,  ver->fw_revision, ver->fw_build_num,
  		 ver->fw_build_ww, ver->fw_build_yy);
  
  	ret = request_firmware(&fw, fwname, &hdev->dev);
  	if (ret < 0) {
  		if (ret == -EINVAL) {
  			BT_ERR("%s Intel firmware file request failed (%d)",
  			       hdev->name, ret);
  			return NULL;
  		}
  
  		BT_ERR("%s failed to open Intel firmware file: %s(%d)",
  		       hdev->name, fwname, ret);
  
  		/* If the correct firmware patch file is not found, use the
  		 * default firmware patch file instead
  		 */
  		snprintf(fwname, sizeof(fwname), "intel/ibt-hw-%x.%x.bseq",
  			 ver->hw_platform, ver->hw_variant);
  		if (request_firmware(&fw, fwname, &hdev->dev) < 0) {
  			BT_ERR("%s failed to open default Intel fw file: %s",
  			       hdev->name, fwname);
  			return NULL;
  		}
  	}
  
  	BT_INFO("%s: Intel Bluetooth firmware file: %s", hdev->name, fwname);
  
  	return fw;
  }
  
  static int btusb_setup_intel_patching(struct hci_dev *hdev,
  				      const struct firmware *fw,
  				      const u8 **fw_ptr, int *disable_patch)
  {
  	struct sk_buff *skb;
  	struct hci_command_hdr *cmd;
  	const u8 *cmd_param;
  	struct hci_event_hdr *evt = NULL;
  	const u8 *evt_param = NULL;
  	int remain = fw->size - (*fw_ptr - fw->data);
  
  	/* The first byte indicates the types of the patch command or event.
  	 * 0x01 means HCI command and 0x02 is HCI event. If the first bytes
  	 * in the current firmware buffer doesn't start with 0x01 or
  	 * the size of remain buffer is smaller than HCI command header,
  	 * the firmware file is corrupted and it should stop the patching
  	 * process.
  	 */
  	if (remain > HCI_COMMAND_HDR_SIZE && *fw_ptr[0] != 0x01) {
  		BT_ERR("%s Intel fw corrupted: invalid cmd read", hdev->name);
  		return -EINVAL;
  	}
  	(*fw_ptr)++;
  	remain--;
  
  	cmd = (struct hci_command_hdr *)(*fw_ptr);
  	*fw_ptr += sizeof(*cmd);
  	remain -= sizeof(*cmd);
  
  	/* Ensure that the remain firmware data is long enough than the length
  	 * of command parameter. If not, the firmware file is corrupted.
  	 */
  	if (remain < cmd->plen) {
  		BT_ERR("%s Intel fw corrupted: invalid cmd len", hdev->name);
  		return -EFAULT;
  	}
  
  	/* If there is a command that loads a patch in the firmware
  	 * file, then enable the patch upon success, otherwise just
  	 * disable the manufacturer mode, for example patch activation
  	 * is not required when the default firmware patch file is used
  	 * because there are no patch data to load.
  	 */
  	if (*disable_patch && le16_to_cpu(cmd->opcode) == 0xfc8e)
  		*disable_patch = 0;
  
  	cmd_param = *fw_ptr;
  	*fw_ptr += cmd->plen;
  	remain -= cmd->plen;
  
  	/* This reads the expected events when the above command is sent to the
  	 * device. Some vendor commands expects more than one events, for
  	 * example command status event followed by vendor specific event.
  	 * For this case, it only keeps the last expected event. so the command
  	 * can be sent with __hci_cmd_sync_ev() which returns the sk_buff of
  	 * last expected event.
  	 */
  	while (remain > HCI_EVENT_HDR_SIZE && *fw_ptr[0] == 0x02) {
  		(*fw_ptr)++;
  		remain--;
  
  		evt = (struct hci_event_hdr *)(*fw_ptr);
  		*fw_ptr += sizeof(*evt);
  		remain -= sizeof(*evt);
  
  		if (remain < evt->plen) {
  			BT_ERR("%s Intel fw corrupted: invalid evt len",
  			       hdev->name);
  			return -EFAULT;
  		}
  
  		evt_param = *fw_ptr;
  		*fw_ptr += evt->plen;
  		remain -= evt->plen;
  	}
  
  	/* Every HCI commands in the firmware file has its correspond event.
  	 * If event is not found or remain is smaller than zero, the firmware
  	 * file is corrupted.
  	 */
  	if (!evt || !evt_param || remain < 0) {
  		BT_ERR("%s Intel fw corrupted: invalid evt read", hdev->name);
  		return -EFAULT;
  	}
  
  	skb = __hci_cmd_sync_ev(hdev, le16_to_cpu(cmd->opcode), cmd->plen,
  				cmd_param, evt->evt, HCI_INIT_TIMEOUT);
  	if (IS_ERR(skb)) {
  		BT_ERR("%s sending Intel patch command (0x%4.4x) failed (%ld)",
  		       hdev->name, cmd->opcode, PTR_ERR(skb));
d9c78e973   Adam Lee   Bluetooth: fix wr...
1081
  		return PTR_ERR(skb);
dffd30ee9   Tedd Ho-Jeong An   Bluetooth: Add su...
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
  	}
  
  	/* It ensures that the returned event matches the event data read from
  	 * the firmware file. At fist, it checks the length and then
  	 * the contents of the event.
  	 */
  	if (skb->len != evt->plen) {
  		BT_ERR("%s mismatch event length (opcode 0x%4.4x)", hdev->name,
  		       le16_to_cpu(cmd->opcode));
  		kfree_skb(skb);
  		return -EFAULT;
  	}
  
  	if (memcmp(skb->data, evt_param, evt->plen)) {
  		BT_ERR("%s mismatch event parameter (opcode 0x%4.4x)",
  		       hdev->name, le16_to_cpu(cmd->opcode));
  		kfree_skb(skb);
  		return -EFAULT;
  	}
  	kfree_skb(skb);
  
  	return 0;
  }
  
  static int btusb_setup_intel(struct hci_dev *hdev)
  {
  	struct sk_buff *skb;
  	const struct firmware *fw;
  	const u8 *fw_ptr;
  	int disable_patch;
  	struct intel_version *ver;
  
  	const u8 mfg_enable[] = { 0x01, 0x00 };
  	const u8 mfg_disable[] = { 0x00, 0x00 };
  	const u8 mfg_reset_deactivate[] = { 0x00, 0x01 };
  	const u8 mfg_reset_activate[] = { 0x00, 0x02 };
  
  	BT_DBG("%s", hdev->name);
  
  	/* The controller has a bug with the first HCI command sent to it
  	 * returning number of completed commands as zero. This would stall the
  	 * command processing in the Bluetooth core.
  	 *
  	 * As a workaround, send HCI Reset command first which will reset the
  	 * number of completed commands and allow normal command processing
  	 * from now on.
  	 */
  	skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
  	if (IS_ERR(skb)) {
  		BT_ERR("%s sending initial HCI reset command failed (%ld)",
  		       hdev->name, PTR_ERR(skb));
d9c78e973   Adam Lee   Bluetooth: fix wr...
1133
  		return PTR_ERR(skb);
dffd30ee9   Tedd Ho-Jeong An   Bluetooth: Add su...
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
  	}
  	kfree_skb(skb);
  
  	/* Read Intel specific controller version first to allow selection of
  	 * which firmware file to load.
  	 *
  	 * The returned information are hardware variant and revision plus
  	 * firmware variant, revision and build number.
  	 */
  	skb = __hci_cmd_sync(hdev, 0xfc05, 0, NULL, HCI_INIT_TIMEOUT);
  	if (IS_ERR(skb)) {
  		BT_ERR("%s reading Intel fw version command failed (%ld)",
  		       hdev->name, PTR_ERR(skb));
d9c78e973   Adam Lee   Bluetooth: fix wr...
1147
  		return PTR_ERR(skb);
dffd30ee9   Tedd Ho-Jeong An   Bluetooth: Add su...
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
  	}
  
  	if (skb->len != sizeof(*ver)) {
  		BT_ERR("%s Intel version event length mismatch", hdev->name);
  		kfree_skb(skb);
  		return -EIO;
  	}
  
  	ver = (struct intel_version *)skb->data;
  	if (ver->status) {
  		BT_ERR("%s Intel fw version event failed (%02x)", hdev->name,
  		       ver->status);
  		kfree_skb(skb);
  		return -bt_to_errno(ver->status);
  	}
  
  	BT_INFO("%s: read Intel version: %02x%02x%02x%02x%02x%02x%02x%02x%02x",
  		hdev->name, ver->hw_platform, ver->hw_variant,
  		ver->hw_revision, ver->fw_variant,  ver->fw_revision,
  		ver->fw_build_num, ver->fw_build_ww, ver->fw_build_yy,
  		ver->fw_patch_num);
  
  	/* fw_patch_num indicates the version of patch the device currently
  	 * have. If there is no patch data in the device, it is always 0x00.
  	 * So, if it is other than 0x00, no need to patch the deivce again.
  	 */
  	if (ver->fw_patch_num) {
  		BT_INFO("%s: Intel device is already patched. patch num: %02x",
  			hdev->name, ver->fw_patch_num);
  		kfree_skb(skb);
  		return 0;
  	}
  
  	/* Opens the firmware patch file based on the firmware version read
  	 * from the controller. If it fails to open the matching firmware
  	 * patch file, it tries to open the default firmware patch file.
  	 * If no patch file is found, allow the device to operate without
  	 * a patch.
  	 */
  	fw = btusb_setup_intel_get_fw(hdev, ver);
  	if (!fw) {
  		kfree_skb(skb);
  		return 0;
  	}
  	fw_ptr = fw->data;
  
  	/* This Intel specific command enables the manufacturer mode of the
  	 * controller.
  	 *
  	 * Only while this mode is enabled, the driver can download the
  	 * firmware patch data and configuration parameters.
  	 */
  	skb = __hci_cmd_sync(hdev, 0xfc11, 2, mfg_enable, HCI_INIT_TIMEOUT);
  	if (IS_ERR(skb)) {
  		BT_ERR("%s entering Intel manufacturer mode failed (%ld)",
  		       hdev->name, PTR_ERR(skb));
  		release_firmware(fw);
d9c78e973   Adam Lee   Bluetooth: fix wr...
1205
  		return PTR_ERR(skb);
dffd30ee9   Tedd Ho-Jeong An   Bluetooth: Add su...
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
  	}
  
  	if (skb->data[0]) {
  		u8 evt_status = skb->data[0];
  		BT_ERR("%s enable Intel manufacturer mode event failed (%02x)",
  		       hdev->name, evt_status);
  		kfree_skb(skb);
  		release_firmware(fw);
  		return -bt_to_errno(evt_status);
  	}
  	kfree_skb(skb);
  
  	disable_patch = 1;
  
  	/* The firmware data file consists of list of Intel specific HCI
  	 * commands and its expected events. The first byte indicates the
  	 * type of the message, either HCI command or HCI event.
  	 *
  	 * It reads the command and its expected event from the firmware file,
  	 * and send to the controller. Once __hci_cmd_sync_ev() returns,
  	 * the returned event is compared with the event read from the firmware
  	 * file and it will continue until all the messages are downloaded to
  	 * the controller.
  	 *
  	 * Once the firmware patching is completed successfully,
  	 * the manufacturer mode is disabled with reset and activating the
  	 * downloaded patch.
  	 *
  	 * If the firmware patching fails, the manufacturer mode is
  	 * disabled with reset and deactivating the patch.
  	 *
  	 * If the default patch file is used, no reset is done when disabling
  	 * the manufacturer.
  	 */
  	while (fw->size > fw_ptr - fw->data) {
  		int ret;
  
  		ret = btusb_setup_intel_patching(hdev, fw, &fw_ptr,
  						 &disable_patch);
  		if (ret < 0)
  			goto exit_mfg_deactivate;
  	}
  
  	release_firmware(fw);
  
  	if (disable_patch)
  		goto exit_mfg_disable;
  
  	/* Patching completed successfully and disable the manufacturer mode
  	 * with reset and activate the downloaded firmware patches.
  	 */
  	skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_reset_activate),
  			     mfg_reset_activate, HCI_INIT_TIMEOUT);
  	if (IS_ERR(skb)) {
  		BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
  		       hdev->name, PTR_ERR(skb));
d9c78e973   Adam Lee   Bluetooth: fix wr...
1262
  		return PTR_ERR(skb);
dffd30ee9   Tedd Ho-Jeong An   Bluetooth: Add su...
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
  	}
  	kfree_skb(skb);
  
  	BT_INFO("%s: Intel Bluetooth firmware patch completed and activated",
  		hdev->name);
  
  	return 0;
  
  exit_mfg_disable:
  	/* Disable the manufacturer mode without reset */
  	skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_disable), mfg_disable,
  			     HCI_INIT_TIMEOUT);
  	if (IS_ERR(skb)) {
  		BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
  		       hdev->name, PTR_ERR(skb));
d9c78e973   Adam Lee   Bluetooth: fix wr...
1278
  		return PTR_ERR(skb);
dffd30ee9   Tedd Ho-Jeong An   Bluetooth: Add su...
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
  	}
  	kfree_skb(skb);
  
  	BT_INFO("%s: Intel Bluetooth firmware patch completed", hdev->name);
  	return 0;
  
  exit_mfg_deactivate:
  	release_firmware(fw);
  
  	/* Patching failed. Disable the manufacturer mode with reset and
  	 * deactivate the downloaded firmware patches.
  	 */
  	skb = __hci_cmd_sync(hdev, 0xfc11, sizeof(mfg_reset_deactivate),
  			     mfg_reset_deactivate, HCI_INIT_TIMEOUT);
  	if (IS_ERR(skb)) {
  		BT_ERR("%s exiting Intel manufacturer mode failed (%ld)",
  		       hdev->name, PTR_ERR(skb));
d9c78e973   Adam Lee   Bluetooth: fix wr...
1296
  		return PTR_ERR(skb);
dffd30ee9   Tedd Ho-Jeong An   Bluetooth: Add su...
1297
1298
1299
1300
1301
1302
1303
1304
  	}
  	kfree_skb(skb);
  
  	BT_INFO("%s: Intel Bluetooth firmware patch completed and deactivated",
  		hdev->name);
  
  	return 0;
  }
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1305
1306
1307
1308
1309
1310
1311
1312
1313
  static int btusb_probe(struct usb_interface *intf,
  				const struct usb_device_id *id)
  {
  	struct usb_endpoint_descriptor *ep_desc;
  	struct btusb_data *data;
  	struct hci_dev *hdev;
  	int i, err;
  
  	BT_DBG("intf %p id %p", intf, id);
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
1314
  	/* interface numbers are hardcoded in the spec */
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1315
1316
1317
1318
1319
1320
1321
1322
1323
  	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
  		return -ENODEV;
  
  	if (!id->driver_info) {
  		const struct usb_device_id *match;
  		match = usb_match_id(intf, blacklist_table);
  		if (match)
  			id = match;
  	}
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
  	if (id->driver_info == BTUSB_IGNORE)
  		return -ENODEV;
  
  	if (ignore_dga && id->driver_info & BTUSB_DIGIANSWER)
  		return -ENODEV;
  
  	if (ignore_csr && id->driver_info & BTUSB_CSR)
  		return -ENODEV;
  
  	if (ignore_sniffer && id->driver_info & BTUSB_SNIFFER)
  		return -ENODEV;
2d25f8b46   Steven.Li   Bluetooth: Add At...
1335
1336
1337
1338
1339
1340
1341
1342
  	if (id->driver_info & BTUSB_ATH3012) {
  		struct usb_device *udev = interface_to_usbdev(intf);
  
  		/* Old firmware would otherwise let ath3k driver load
  		 * patch and sysconfig files */
  		if (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x0001)
  			return -ENODEV;
  	}
98921dbd0   Sachin Kamat   Bluetooth: Use de...
1343
  	data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
  	if (!data)
  		return -ENOMEM;
  
  	for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
  		ep_desc = &intf->cur_altsetting->endpoint[i].desc;
  
  		if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) {
  			data->intr_ep = ep_desc;
  			continue;
  		}
  
  		if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) {
  			data->bulk_tx_ep = ep_desc;
  			continue;
  		}
  
  		if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) {
  			data->bulk_rx_ep = ep_desc;
  			continue;
  		}
  	}
98921dbd0   Sachin Kamat   Bluetooth: Use de...
1365
  	if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep)
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1366
  		return -ENODEV;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1367

7a9d40205   Marcel Holtmann   Bluetooth: Send H...
1368
  	data->cmdreq_type = USB_TYPE_CLASS;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1369
  	data->udev = interface_to_usbdev(intf);
5fbcd260c   Marcel Holtmann   [Bluetooth] Fix U...
1370
  	data->intf = intf;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1371
1372
1373
1374
  
  	spin_lock_init(&data->lock);
  
  	INIT_WORK(&data->work, btusb_work);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1375
1376
  	INIT_WORK(&data->waker, btusb_waker);
  	spin_lock_init(&data->txlock);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1377
1378
1379
1380
  
  	init_usb_anchor(&data->tx_anchor);
  	init_usb_anchor(&data->intr_anchor);
  	init_usb_anchor(&data->bulk_anchor);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
1381
  	init_usb_anchor(&data->isoc_anchor);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1382
  	init_usb_anchor(&data->deferred);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1383
1384
  
  	hdev = hci_alloc_dev();
98921dbd0   Sachin Kamat   Bluetooth: Use de...
1385
  	if (!hdev)
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1386
  		return -ENOMEM;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1387

c13854cef   Marcel Holtmann   Bluetooth: Conver...
1388
  	hdev->bus = HCI_USB;
155961e80   David Herrmann   Bluetooth: Remove...
1389
  	hci_set_drvdata(hdev, data);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1390
1391
1392
1393
  
  	data->hdev = hdev;
  
  	SET_HCIDEV_DEV(hdev, &intf->dev);
9f8f962c8   Marcel Holtmann   Bluetooth: Use se...
1394
1395
1396
1397
1398
1399
1400
1401
  	hdev->open   = btusb_open;
  	hdev->close  = btusb_close;
  	hdev->flush  = btusb_flush;
  	hdev->send   = btusb_send_frame;
  	hdev->notify = btusb_notify;
  
  	if (id->driver_info & BTUSB_BCM92035)
  		hdev->setup = btusb_setup_bcm92035;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1402

d2bee8fb6   Tedd Ho-Jeong An   Bluetooth: Enable...
1403
1404
  	if (id->driver_info & BTUSB_INTEL) {
  		usb_enable_autosuspend(data->udev);
dffd30ee9   Tedd Ho-Jeong An   Bluetooth: Add su...
1405
  		hdev->setup = btusb_setup_intel;
d2bee8fb6   Tedd Ho-Jeong An   Bluetooth: Enable...
1406
  	}
dffd30ee9   Tedd Ho-Jeong An   Bluetooth: Add su...
1407

7a9d40205   Marcel Holtmann   Bluetooth: Send H...
1408
  	/* Interface numbers are hardcoded in the specification */
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
1409
  	data->isoc = usb_ifnum_to_if(data->udev, 1);
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
1410
  	if (!reset)
a6c511c63   Szymon Janc   Bluetooth: Rename...
1411
  		set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
1412
1413
1414
1415
1416
  
  	if (force_scofix || id->driver_info & BTUSB_WRONG_SCO_MTU) {
  		if (!disable_scofix)
  			set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
  	}
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
1417
1418
  	if (id->driver_info & BTUSB_BROKEN_ISOC)
  		data->isoc = NULL;
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
1419
1420
  	if (id->driver_info & BTUSB_DIGIANSWER) {
  		data->cmdreq_type = USB_TYPE_VENDOR;
a6c511c63   Szymon Janc   Bluetooth: Rename...
1421
  		set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
1422
1423
1424
1425
  	}
  
  	if (id->driver_info & BTUSB_CSR) {
  		struct usb_device *udev = data->udev;
81cac64ba   Marcel Holtmann   Bluetooth: Deal w...
1426
  		u16 bcdDevice = le16_to_cpu(udev->descriptor.bcdDevice);
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
1427
1428
  
  		/* Old firmware would otherwise execute USB reset */
81cac64ba   Marcel Holtmann   Bluetooth: Deal w...
1429
  		if (bcdDevice < 0x117)
a6c511c63   Szymon Janc   Bluetooth: Rename...
1430
  			set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
81cac64ba   Marcel Holtmann   Bluetooth: Deal w...
1431
1432
1433
1434
  
  		/* Fake CSR devices with broken commands */
  		if (bcdDevice <= 0x100)
  			hdev->setup = btusb_setup_csr;
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
1435
  	}
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
1436
  	if (id->driver_info & BTUSB_SNIFFER) {
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
1437
  		struct usb_device *udev = data->udev;
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
1438

7a9d40205   Marcel Holtmann   Bluetooth: Send H...
1439
  		/* New sniffer firmware has crippled HCI interface */
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
1440
1441
  		if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
  			set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
1442
1443
  
  		data->isoc = NULL;
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
1444
  	}
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
1445
1446
  	if (data->isoc) {
  		err = usb_driver_claim_interface(&btusb_driver,
5fbcd260c   Marcel Holtmann   [Bluetooth] Fix U...
1447
  							data->isoc, data);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
1448
1449
  		if (err < 0) {
  			hci_free_dev(hdev);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
1450
1451
1452
  			return err;
  		}
  	}
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1453
1454
1455
  	err = hci_register_dev(hdev);
  	if (err < 0) {
  		hci_free_dev(hdev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
  		return err;
  	}
  
  	usb_set_intfdata(intf, data);
  
  	return 0;
  }
  
  static void btusb_disconnect(struct usb_interface *intf)
  {
  	struct btusb_data *data = usb_get_intfdata(intf);
  	struct hci_dev *hdev;
  
  	BT_DBG("intf %p", intf);
  
  	if (!data)
  		return;
  
  	hdev = data->hdev;
5fbcd260c   Marcel Holtmann   [Bluetooth] Fix U...
1475
1476
1477
1478
  	usb_set_intfdata(data->intf, NULL);
  
  	if (data->isoc)
  		usb_set_intfdata(data->isoc, NULL);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1479
1480
  
  	hci_unregister_dev(hdev);
5fbcd260c   Marcel Holtmann   [Bluetooth] Fix U...
1481
1482
1483
1484
  	if (intf == data->isoc)
  		usb_driver_release_interface(&btusb_driver, data->intf);
  	else if (data->isoc)
  		usb_driver_release_interface(&btusb_driver, data->isoc);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1485
1486
  	hci_free_dev(hdev);
  }
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1487
  #ifdef CONFIG_PM
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1488
1489
1490
1491
1492
1493
1494
1495
  static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
  {
  	struct btusb_data *data = usb_get_intfdata(intf);
  
  	BT_DBG("intf %p", intf);
  
  	if (data->suspend_count++)
  		return 0;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1496
  	spin_lock_irq(&data->txlock);
5b1b0b812   Alan Stern   PM / Runtime: Add...
1497
  	if (!(PMSG_IS_AUTO(message) && data->tx_in_flight)) {
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1498
1499
1500
1501
1502
1503
1504
  		set_bit(BTUSB_SUSPENDING, &data->flags);
  		spin_unlock_irq(&data->txlock);
  	} else {
  		spin_unlock_irq(&data->txlock);
  		data->suspend_count--;
  		return -EBUSY;
  	}
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1505
  	cancel_work_sync(&data->work);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1506
  	btusb_stop_traffic(data);
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1507
  	usb_kill_anchored_urbs(&data->tx_anchor);
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1508
1509
  	return 0;
  }
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
  static void play_deferred(struct btusb_data *data)
  {
  	struct urb *urb;
  	int err;
  
  	while ((urb = usb_get_from_anchor(&data->deferred))) {
  		err = usb_submit_urb(urb, GFP_ATOMIC);
  		if (err < 0)
  			break;
  
  		data->tx_in_flight++;
  	}
  	usb_scuttle_anchored_urbs(&data->deferred);
  }
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1524
1525
1526
1527
  static int btusb_resume(struct usb_interface *intf)
  {
  	struct btusb_data *data = usb_get_intfdata(intf);
  	struct hci_dev *hdev = data->hdev;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1528
  	int err = 0;
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1529
1530
1531
1532
1533
1534
1535
  
  	BT_DBG("intf %p", intf);
  
  	if (--data->suspend_count)
  		return 0;
  
  	if (!test_bit(HCI_RUNNING, &hdev->flags))
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1536
  		goto done;
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1537
1538
1539
1540
1541
  
  	if (test_bit(BTUSB_INTR_RUNNING, &data->flags)) {
  		err = btusb_submit_intr_urb(hdev, GFP_NOIO);
  		if (err < 0) {
  			clear_bit(BTUSB_INTR_RUNNING, &data->flags);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1542
  			goto failed;
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1543
1544
1545
1546
  		}
  	}
  
  	if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
43c2e57f9   Marcel Holtmann   Bluetooth: Submit...
1547
1548
  		err = btusb_submit_bulk_urb(hdev, GFP_NOIO);
  		if (err < 0) {
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1549
  			clear_bit(BTUSB_BULK_RUNNING, &data->flags);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1550
1551
1552
1553
  			goto failed;
  		}
  
  		btusb_submit_bulk_urb(hdev, GFP_NOIO);
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1554
1555
1556
1557
1558
1559
1560
1561
  	}
  
  	if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
  		if (btusb_submit_isoc_urb(hdev, GFP_NOIO) < 0)
  			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
  		else
  			btusb_submit_isoc_urb(hdev, GFP_NOIO);
  	}
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1562
1563
1564
1565
1566
  	spin_lock_irq(&data->txlock);
  	play_deferred(data);
  	clear_bit(BTUSB_SUSPENDING, &data->flags);
  	spin_unlock_irq(&data->txlock);
  	schedule_work(&data->work);
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1567
  	return 0;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1568
1569
1570
1571
1572
1573
1574
1575
1576
  
  failed:
  	usb_scuttle_anchored_urbs(&data->deferred);
  done:
  	spin_lock_irq(&data->txlock);
  	clear_bit(BTUSB_SUSPENDING, &data->flags);
  	spin_unlock_irq(&data->txlock);
  
  	return err;
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1577
  }
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1578
  #endif
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1579

5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1580
1581
1582
1583
  static struct usb_driver btusb_driver = {
  	.name		= "btusb",
  	.probe		= btusb_probe,
  	.disconnect	= btusb_disconnect,
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1584
  #ifdef CONFIG_PM
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1585
1586
  	.suspend	= btusb_suspend,
  	.resume		= btusb_resume,
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1587
  #endif
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1588
  	.id_table	= btusb_table,
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1589
  	.supports_autosuspend = 1,
e1f12eb6b   Sarah Sharp   USB: Disable hub-...
1590
  	.disable_hub_initiated_lpm = 1,
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1591
  };
93f1508cf   Greg Kroah-Hartman   USB: convert driv...
1592
  module_usb_driver(btusb_driver);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1593

cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
  module_param(ignore_dga, bool, 0644);
  MODULE_PARM_DESC(ignore_dga, "Ignore devices with id 08fd:0001");
  
  module_param(ignore_csr, bool, 0644);
  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");
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1611
1612
1613
1614
  MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
  MODULE_DESCRIPTION("Generic Bluetooth USB driver ver " VERSION);
  MODULE_VERSION(VERSION);
  MODULE_LICENSE("GPL");