Blame view

drivers/bluetooth/btusb.c 29 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
23
24
25
26
27
28
29
30
31
32
33
34
35
36
   *
   *
   *  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
   *
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/slab.h>
  #include <linux/types.h>
  #include <linux/sched.h>
  #include <linux/errno.h>
  #include <linux/skbuff.h>
  
  #include <linux/usb.h>
  
  #include <net/bluetooth/bluetooth.h>
  #include <net/bluetooth/hci_core.h>
7bee549e1   Oliver Neukum   Bluetooth: Add US...
37
  #define VERSION "0.6"
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
38

90ab5ee94   Rusty Russell   module_param: mak...
39
40
41
42
43
  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...
44

90ab5ee94   Rusty Russell   module_param: mak...
45
  static bool reset = 1;
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
46
47
48
49
  
  static struct usb_driver btusb_driver;
  
  #define BTUSB_IGNORE		0x01
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
50
51
52
53
54
55
  #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...
56
  #define BTUSB_ATH3012		0x80
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
57
58
59
60
  
  static struct usb_device_id btusb_table[] = {
  	/* Generic Bluetooth USB device */
  	{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
c510eae37   Oliver Neukum   btusb: add device...
61
62
  	/* Broadcom SoftSailing reporting vendor specific */
  	{ USB_DEVICE(0x05ac, 0x21e1) },
3cd01976e   Nobuhiro Iwamatsu   Bluetooth: Add su...
63
64
  	/* Apple MacBookPro 7,1 */
  	{ USB_DEVICE(0x05ac, 0x8213) },
0a79f6744   Cyril Lacoux   Bluetooth: Added ...
65
66
  	/* Apple iMac11,1 */
  	{ USB_DEVICE(0x05ac, 0x8215) },
9c047157a   Nobuhiro Iwamatsu   Bluetooth: Add su...
67
68
  	/* Apple MacBookPro6,2 */
  	{ USB_DEVICE(0x05ac, 0x8218) },
3e3ede7dd   Edgar (gimli) Hucek   Bluetooth: Add Ma...
69
70
  	/* Apple MacBookAir3,1, MacBookAir3,2 */
  	{ USB_DEVICE(0x05ac, 0x821b) },
a63b723d0   Pieter-Augustijn Van Malleghem   Bluetooth: Add Ma...
71
72
  	/* Apple MacBookAir4,1 */
  	{ USB_DEVICE(0x05ac, 0x821f) },
88d377b6c   Marc-Antoine Perennou   Bluetooth: add su...
73
74
  	/* Apple MacBookPro8,2 */
  	{ USB_DEVICE(0x05ac, 0x821a) },
f78b68261   Jurgen Kramer   Bluetooth: add su...
75
76
  	/* Apple MacMini5,1 */
  	{ USB_DEVICE(0x05ac, 0x8281) },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
77
78
79
80
81
82
83
84
85
86
87
88
89
90
  	/* 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...
91
  	{ USB_DEVICE(0x0c10, 0x0000) },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
92

d13431ca3   Wen-chien Jesse Sung   Bluetooth: Add su...
93
  	/* Broadcom BCM20702A0 */
c0190925d   Jesse Sung   Bluetooth: Add su...
94
  	{ USB_DEVICE(0x0a5c, 0x21e3) },
d13431ca3   Wen-chien Jesse Sung   Bluetooth: Add su...
95
  	{ USB_DEVICE(0x413c, 0x8197) },
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
96
97
98
99
100
101
  	{ }	/* Terminating entry */
  };
  
  MODULE_DEVICE_TABLE(usb, btusb_table);
  
  static struct usb_device_id blacklist_table[] = {
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
102
103
104
105
106
  	/* 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...
107
108
  	/* Atheros 3011 with sflash firmware */
  	{ USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
2a7bccccd   Andy Ross   Bluetooth: Device...
109
  	{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
8e7c3d2e4   Ricardo Mendoza   Bluetooth: Add To...
110
  	{ USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE },
be93112ac   Bala Shanmugam   Bluetooth: Add ne...
111

509e7861d   Cho, Yu-Chen   Bluetooth: add At...
112
113
  	/* Atheros AR9285 Malbec with sflash firmware */
  	{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
d9f51b51d   Bala Shanmugam   Bluetooth: Add fi...
114
  	/* Atheros 3012 with sflash firmware */
2d25f8b46   Steven.Li   Bluetooth: Add At...
115
  	{ USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 },
d9f51b51d   Bala Shanmugam   Bluetooth: Add fi...
116

e9036e336   Cho, Yu-Chen   Bluetooth: Add At...
117
118
  	/* Atheros AR5BBU12 with sflash firmware */
  	{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
119
  	/* Broadcom BCM2035 */
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
120
121
122
  	{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
  	{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
  	{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
123
124
  
  	/* Broadcom BCM2045 */
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
125
126
  	{ 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...
127

cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
128
  	/* IBM/Lenovo ThinkPad with Broadcom chip */
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
129
130
  	{ 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...
131
132
  
  	/* HP laptop with Broadcom chip */
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
133
  	{ USB_DEVICE(0x03f0, 0x171d), .driver_info = BTUSB_WRONG_SCO_MTU },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
134
135
  
  	/* Dell laptop with Broadcom chip */
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
136
  	{ USB_DEVICE(0x413c, 0x8126), .driver_info = BTUSB_WRONG_SCO_MTU },
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
137

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

7a9d40205   Marcel Holtmann   Bluetooth: Send H...
142
143
144
  	/* 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...
145

5ddd4a606   Marcel Holtmann   Bluetooth: Allow ...
146
147
148
149
150
  	/* 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...
151
152
153
154
155
156
  	/* 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...
157
158
159
160
161
162
163
164
165
  	/* 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 },
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
166
167
  	{ }	/* Terminating entry */
  };
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
168
  #define BTUSB_MAX_ISOC_FRAMES	10
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
169
170
  #define BTUSB_INTR_RUNNING	0
  #define BTUSB_BULK_RUNNING	1
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
171
  #define BTUSB_ISOC_RUNNING	2
7bee549e1   Oliver Neukum   Bluetooth: Add US...
172
  #define BTUSB_SUSPENDING	3
08b8b6c45   Gustavo F. Padovan   Bluetooth: Move b...
173
  #define BTUSB_DID_ISO_RESUME	4
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
174
175
176
177
  
  struct btusb_data {
  	struct hci_dev       *hdev;
  	struct usb_device    *udev;
5fbcd260c   Marcel Holtmann   [Bluetooth] Fix U...
178
  	struct usb_interface *intf;
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
179
  	struct usb_interface *isoc;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
180
181
182
183
184
185
  
  	spinlock_t lock;
  
  	unsigned long flags;
  
  	struct work_struct work;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
186
  	struct work_struct waker;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
187
188
189
190
  
  	struct usb_anchor tx_anchor;
  	struct usb_anchor intr_anchor;
  	struct usb_anchor bulk_anchor;
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
191
  	struct usb_anchor isoc_anchor;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
192
193
194
  	struct usb_anchor deferred;
  	int tx_in_flight;
  	spinlock_t txlock;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
195
196
197
198
  
  	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...
199
200
  	struct usb_endpoint_descriptor *isoc_tx_ep;
  	struct usb_endpoint_descriptor *isoc_rx_ep;
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
201
  	__u8 cmdreq_type;
43c2e57f9   Marcel Holtmann   Bluetooth: Submit...
202
  	unsigned int sco_num;
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
203
  	int isoc_altsetting;
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
204
  	int suspend_count;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
205
  };
7bee549e1   Oliver Neukum   Bluetooth: Add US...
206
207
208
209
210
211
212
213
214
215
216
217
218
  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...
219
220
221
222
223
224
225
226
227
228
229
230
231
  static void btusb_intr_complete(struct urb *urb)
  {
  	struct hci_dev *hdev = urb->context;
  	struct btusb_data *data = hdev->driver_data;
  	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...
232
  		hdev->stat.byte_rx += urb->actual_length;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
233
234
235
236
237
238
239
240
241
242
  		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...
243
  	usb_mark_last_busy(data->udev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
244
245
246
247
  	usb_anchor_urb(urb, &data->intr_anchor);
  
  	err = usb_submit_urb(urb, GFP_ATOMIC);
  	if (err < 0) {
4935f1c16   Paul Bolle   Bluetooth: btusb:...
248
249
250
  		/* -EPERM: urb is being killed;
  		 * -ENODEV: device got disconnected */
  		if (err != -EPERM && err != -ENODEV)
61faddf66   Stefan Seyfried   Bluetooth: Fix lo...
251
  			BT_ERR("%s urb %p failed to resubmit (%d)",
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
252
253
254
255
  						hdev->name, urb, -err);
  		usb_unanchor_urb(urb);
  	}
  }
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
256
  static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
257
258
259
260
261
262
263
264
  {
  	struct btusb_data *data = hdev->driver_data;
  	struct urb *urb;
  	unsigned char *buf;
  	unsigned int pipe;
  	int err, size;
  
  	BT_DBG("%s", hdev->name);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
265
266
  	if (!data->intr_ep)
  		return -ENODEV;
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
267
  	urb = usb_alloc_urb(0, mem_flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
268
269
270
271
  	if (!urb)
  		return -ENOMEM;
  
  	size = le16_to_cpu(data->intr_ep->wMaxPacketSize);
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
272
  	buf = kmalloc(size, mem_flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
273
274
275
276
277
278
279
280
281
282
283
284
285
286
  	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...
287
  	err = usb_submit_urb(urb, mem_flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
288
  	if (err < 0) {
d4b8d1c9c   Paul Bolle   Bluetooth: btusb:...
289
290
  		if (err != -EPERM && err != -ENODEV)
  			BT_ERR("%s urb %p submission failed (%d)",
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
291
292
  						hdev->name, urb, -err);
  		usb_unanchor_urb(urb);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
  	}
  
  	usb_free_urb(urb);
  
  	return err;
  }
  
  static void btusb_bulk_complete(struct urb *urb)
  {
  	struct hci_dev *hdev = urb->context;
  	struct btusb_data *data = hdev->driver_data;
  	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...
313
  		hdev->stat.byte_rx += urb->actual_length;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
314
315
316
317
318
319
320
321
322
323
324
325
  		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...
326
  	usb_mark_last_busy(data->udev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
327
328
329
  
  	err = usb_submit_urb(urb, GFP_ATOMIC);
  	if (err < 0) {
4935f1c16   Paul Bolle   Bluetooth: btusb:...
330
331
332
  		/* -EPERM: urb is being killed;
  		 * -ENODEV: device got disconnected */
  		if (err != -EPERM && err != -ENODEV)
61faddf66   Stefan Seyfried   Bluetooth: Fix lo...
333
  			BT_ERR("%s urb %p failed to resubmit (%d)",
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
334
335
336
337
  						hdev->name, urb, -err);
  		usb_unanchor_urb(urb);
  	}
  }
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
338
  static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags)
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
339
340
341
342
343
  {
  	struct btusb_data *data = hdev->driver_data;
  	struct urb *urb;
  	unsigned char *buf;
  	unsigned int pipe;
290ba2008   Vikram Kandukuri   Bluetooth: Improv...
344
  	int err, size = HCI_MAX_FRAME_SIZE;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
345
346
  
  	BT_DBG("%s", hdev->name);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
347
348
  	if (!data->bulk_rx_ep)
  		return -ENODEV;
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
349
  	urb = usb_alloc_urb(0, mem_flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
350
351
  	if (!urb)
  		return -ENOMEM;
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
352
  	buf = kmalloc(size, mem_flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
353
354
355
356
357
358
359
360
361
362
363
  	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...
364
  	usb_mark_last_busy(data->udev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
365
  	usb_anchor_urb(urb, &data->bulk_anchor);
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
366
  	err = usb_submit_urb(urb, mem_flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
367
  	if (err < 0) {
d4b8d1c9c   Paul Bolle   Bluetooth: btusb:...
368
369
  		if (err != -EPERM && err != -ENODEV)
  			BT_ERR("%s urb %p submission failed (%d)",
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
370
371
  						hdev->name, urb, -err);
  		usb_unanchor_urb(urb);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
372
373
374
375
376
377
  	}
  
  	usb_free_urb(urb);
  
  	return err;
  }
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
  static void btusb_isoc_complete(struct urb *urb)
  {
  	struct hci_dev *hdev = urb->context;
  	struct btusb_data *data = hdev->driver_data;
  	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:...
416
417
418
  		/* -EPERM: urb is being killed;
  		 * -ENODEV: device got disconnected */
  		if (err != -EPERM && err != -ENODEV)
61faddf66   Stefan Seyfried   Bluetooth: Fix lo...
419
  			BT_ERR("%s urb %p failed to resubmit (%d)",
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
420
421
422
423
  						hdev->name, urb, -err);
  		usb_unanchor_urb(urb);
  	}
  }
42b16b3fb   Jesper Juhl   Kill off warning:...
424
  static inline void __fill_isoc_descriptor(struct urb *urb, int len, int mtu)
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
  {
  	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...
444
  static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags)
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
445
446
447
448
449
450
451
452
453
454
455
  {
  	struct btusb_data *data = hdev->driver_data;
  	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...
456
  	urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, mem_flags);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
457
458
459
460
461
  	if (!urb)
  		return -ENOMEM;
  
  	size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) *
  						BTUSB_MAX_ISOC_FRAMES;
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
462
  	buf = kmalloc(size, mem_flags);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
463
464
465
466
467
468
  	if (!buf) {
  		usb_free_urb(urb);
  		return -ENOMEM;
  	}
  
  	pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress);
fa0fb93f2   Bing Zhao   Bluetooth: btusb:...
469
470
  	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...
471
472
  
  	urb->transfer_flags  = URB_FREE_BUFFER | URB_ISO_ASAP;
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
473
474
475
476
477
  
  	__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...
478
  	err = usb_submit_urb(urb, mem_flags);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
479
  	if (err < 0) {
d4b8d1c9c   Paul Bolle   Bluetooth: btusb:...
480
481
  		if (err != -EPERM && err != -ENODEV)
  			BT_ERR("%s urb %p submission failed (%d)",
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
482
483
  						hdev->name, urb, -err);
  		usb_unanchor_urb(urb);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
484
485
486
487
488
489
  	}
  
  	usb_free_urb(urb);
  
  	return err;
  }
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
490
491
492
493
  static void btusb_tx_complete(struct urb *urb)
  {
  	struct sk_buff *skb = urb->context;
  	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
  	struct btusb_data *data = hdev->driver_data;
  
  	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...
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
  
  	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)
  {
  	struct btusb_data *data = hdev->driver_data;
  	int err;
  
  	BT_DBG("%s", hdev->name);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
545
546
547
548
549
  	err = usb_autopm_get_interface(data->intf);
  	if (err < 0)
  		return err;
  
  	data->intf->needs_remote_wakeup = 1;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
550
  	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
7bee549e1   Oliver Neukum   Bluetooth: Add US...
551
  		goto done;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
552
553
  
  	if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
7bee549e1   Oliver Neukum   Bluetooth: Add US...
554
  		goto done;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
555

2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
556
  	err = btusb_submit_intr_urb(hdev, GFP_KERNEL);
43c2e57f9   Marcel Holtmann   Bluetooth: Submit...
557
558
559
560
  	if (err < 0)
  		goto failed;
  
  	err = btusb_submit_bulk_urb(hdev, GFP_KERNEL);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
561
  	if (err < 0) {
43c2e57f9   Marcel Holtmann   Bluetooth: Submit...
562
563
  		usb_kill_anchored_urbs(&data->intr_anchor);
  		goto failed;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
564
  	}
43c2e57f9   Marcel Holtmann   Bluetooth: Submit...
565
566
  	set_bit(BTUSB_BULK_RUNNING, &data->flags);
  	btusb_submit_bulk_urb(hdev, GFP_KERNEL);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
567
568
  done:
  	usb_autopm_put_interface(data->intf);
43c2e57f9   Marcel Holtmann   Bluetooth: Submit...
569
570
571
572
573
  	return 0;
  
  failed:
  	clear_bit(BTUSB_INTR_RUNNING, &data->flags);
  	clear_bit(HCI_RUNNING, &hdev->flags);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
574
  	usb_autopm_put_interface(data->intf);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
575
576
  	return err;
  }
7bee549e1   Oliver Neukum   Bluetooth: Add US...
577
578
579
580
581
582
  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...
583
584
585
  static int btusb_close(struct hci_dev *hdev)
  {
  	struct btusb_data *data = hdev->driver_data;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
586
  	int err;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
587
588
589
590
591
  
  	BT_DBG("%s", hdev->name);
  
  	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
  		return 0;
e8c3c3d22   Marcel Holtmann   [Bluetooth] Fix w...
592
  	cancel_work_sync(&data->work);
404291ac9   Linus Torvalds   btusb bluetooth d...
593
  	cancel_work_sync(&data->waker);
e8c3c3d22   Marcel Holtmann   [Bluetooth] Fix w...
594

9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
595
  	clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
596
  	clear_bit(BTUSB_BULK_RUNNING, &data->flags);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
597
  	clear_bit(BTUSB_INTR_RUNNING, &data->flags);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
598
599
600
601
  
  	btusb_stop_traffic(data);
  	err = usb_autopm_get_interface(data->intf);
  	if (err < 0)
7b8e2c1db   Oliver Neukum   fix memory leak i...
602
  		goto failed;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
603
604
605
  
  	data->intf->needs_remote_wakeup = 0;
  	usb_autopm_put_interface(data->intf);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
606

7b8e2c1db   Oliver Neukum   fix memory leak i...
607
608
  failed:
  	usb_scuttle_anchored_urbs(&data->deferred);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
  	return 0;
  }
  
  static int btusb_flush(struct hci_dev *hdev)
  {
  	struct btusb_data *data = hdev->driver_data;
  
  	BT_DBG("%s", hdev->name);
  
  	usb_kill_anchored_urbs(&data->tx_anchor);
  
  	return 0;
  }
  
  static int btusb_send_frame(struct sk_buff *skb)
  {
  	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
  	struct btusb_data *data = hdev->driver_data;
  	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;
  
  	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...
648
  		dr->bRequestType = data->cmdreq_type;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
649
650
651
652
653
654
655
656
657
658
659
660
661
662
  		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 ...
663
  		if (!data->bulk_tx_ep)
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
664
  			return -ENODEV;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
665
666
667
668
669
670
671
672
673
  		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);
b8aabfc92   Luiz Augusto von Dentz   Bluetooth: use bu...
674
675
  		if (skb->priority >= HCI_PRIO_MAX - 1)
  			urb->transfer_flags  = URB_ISO_ASAP;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
676
677
678
679
  		hdev->stat.acl_tx++;
  		break;
  
  	case HCI_SCODATA_PKT:
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
680
681
682
683
684
685
686
687
688
  		if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1)
  			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 F. Padovan   Bluetooth: Use us...
689
690
691
  		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...
692
693
  
  		urb->transfer_flags  = URB_ISO_ASAP;
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
694
695
696
  
  		__fill_isoc_descriptor(urb, skb->len,
  				le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize));
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
697
  		hdev->stat.sco_tx++;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
698
  		goto skip_waking;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
699
700
701
702
  
  	default:
  		return -EILSEQ;
  	}
7bee549e1   Oliver Neukum   Bluetooth: Add US...
703
704
705
706
707
708
709
710
711
  	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...
712
713
714
715
  	usb_anchor_urb(urb, &data->tx_anchor);
  
  	err = usb_submit_urb(urb, GFP_ATOMIC);
  	if (err < 0) {
5a9b80e2c   Paul Bolle   Bluetooth: btusb:...
716
717
718
  		if (err != -EPERM && err != -ENODEV)
  			BT_ERR("%s urb %p submission failed (%d)",
  						hdev->name, urb, -err);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
719
720
  		kfree(urb->setup_packet);
  		usb_unanchor_urb(urb);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
721
722
  	} else {
  		usb_mark_last_busy(data->udev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
723
  	}
7bee549e1   Oliver Neukum   Bluetooth: Add US...
724
  done:
54a8a79c5   Cong Wang   btusb: fix a memo...
725
  	usb_free_urb(urb);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
  	return err;
  }
  
  static void btusb_destruct(struct hci_dev *hdev)
  {
  	struct btusb_data *data = hdev->driver_data;
  
  	BT_DBG("%s", hdev->name);
  
  	kfree(data);
  }
  
  static void btusb_notify(struct hci_dev *hdev, unsigned int evt)
  {
  	struct btusb_data *data = hdev->driver_data;
  
  	BT_DBG("%s evt %d", hdev->name, evt);
43c2e57f9   Marcel Holtmann   Bluetooth: Submit...
743
744
745
  	if (hdev->conn_hash.sco_num != data->sco_num) {
  		data->sco_num = hdev->conn_hash.sco_num;
  		schedule_work(&data->work);
a780efa81   Marcel Holtmann   Bluetooth: Handle...
746
  	}
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
747
  }
42b16b3fb   Jesper Juhl   Kill off warning:...
748
  static inline int __set_isoc_interface(struct hci_dev *hdev, int altsetting)
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
  {
  	struct btusb_data *data = hdev->driver_data;
  	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...
790
791
792
793
  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;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
794
  	int err;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
795

9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
796
  	if (hdev->conn_hash.sco_num > 0) {
08b8b6c45   Gustavo F. Padovan   Bluetooth: Move b...
797
  		if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
8efdd0cdc   Oliver Neukum   Bluetooth: fix cr...
798
  			err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
799
800
801
802
803
  			if (err < 0) {
  				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
  				usb_kill_anchored_urbs(&data->isoc_anchor);
  				return;
  			}
08b8b6c45   Gustavo F. Padovan   Bluetooth: Move b...
804
  			set_bit(BTUSB_DID_ISO_RESUME, &data->flags);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
805
  		}
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
806
807
808
809
810
811
812
813
814
  		if (data->isoc_altsetting != 2) {
  			clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
  			usb_kill_anchored_urbs(&data->isoc_anchor);
  
  			if (__set_isoc_interface(hdev, 2) < 0)
  				return;
  		}
  
  		if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) {
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
815
  			if (btusb_submit_isoc_urb(hdev, GFP_KERNEL) < 0)
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
816
817
  				clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
  			else
2eda66f4a   Marcel Holtmann   Bluetooth: Add fi...
818
  				btusb_submit_isoc_urb(hdev, GFP_KERNEL);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
819
820
821
822
823
824
  		}
  	} else {
  		clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
  		usb_kill_anchored_urbs(&data->isoc_anchor);
  
  		__set_isoc_interface(hdev, 0);
08b8b6c45   Gustavo F. Padovan   Bluetooth: Move b...
825
  		if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
8efdd0cdc   Oliver Neukum   Bluetooth: fix cr...
826
  			usb_autopm_put_interface(data->isoc ? data->isoc : data->intf);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
827
828
  	}
  }
7bee549e1   Oliver Neukum   Bluetooth: Add US...
829
830
831
832
833
834
835
836
837
838
839
  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);
  }
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
840
841
842
843
844
845
846
847
848
  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...
849
  	/* interface numbers are hardcoded in the spec */
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
850
851
852
853
854
855
856
857
858
  	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...
859
860
861
862
863
864
865
866
867
868
869
  	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...
870
871
872
873
874
875
876
877
  	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;
  	}
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
  	data = kzalloc(sizeof(*data), GFP_KERNEL);
  	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;
  		}
  	}
  
  	if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) {
  		kfree(data);
  		return -ENODEV;
  	}
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
905
  	data->cmdreq_type = USB_TYPE_CLASS;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
906
  	data->udev = interface_to_usbdev(intf);
5fbcd260c   Marcel Holtmann   [Bluetooth] Fix U...
907
  	data->intf = intf;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
908
909
910
911
  
  	spin_lock_init(&data->lock);
  
  	INIT_WORK(&data->work, btusb_work);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
912
913
  	INIT_WORK(&data->waker, btusb_waker);
  	spin_lock_init(&data->txlock);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
914
915
916
917
  
  	init_usb_anchor(&data->tx_anchor);
  	init_usb_anchor(&data->intr_anchor);
  	init_usb_anchor(&data->bulk_anchor);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
918
  	init_usb_anchor(&data->isoc_anchor);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
919
  	init_usb_anchor(&data->deferred);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
920
921
922
923
924
925
  
  	hdev = hci_alloc_dev();
  	if (!hdev) {
  		kfree(data);
  		return -ENOMEM;
  	}
c13854cef   Marcel Holtmann   Bluetooth: Conver...
926
  	hdev->bus = HCI_USB;
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
927
928
929
930
931
932
933
934
935
936
937
938
939
940
  	hdev->driver_data = data;
  
  	data->hdev = hdev;
  
  	SET_HCIDEV_DEV(hdev, &intf->dev);
  
  	hdev->open     = btusb_open;
  	hdev->close    = btusb_close;
  	hdev->flush    = btusb_flush;
  	hdev->send     = btusb_send_frame;
  	hdev->destruct = btusb_destruct;
  	hdev->notify   = btusb_notify;
  
  	hdev->owner = THIS_MODULE;
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
941
  	/* Interface numbers are hardcoded in the specification */
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
942
  	data->isoc = usb_ifnum_to_if(data->udev, 1);
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
943
944
  	if (!reset)
  		set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
945
946
947
948
949
  
  	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...
950
951
  	if (id->driver_info & BTUSB_BROKEN_ISOC)
  		data->isoc = NULL;
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
952
953
954
955
956
957
958
959
960
961
962
963
  	if (id->driver_info & BTUSB_DIGIANSWER) {
  		data->cmdreq_type = USB_TYPE_VENDOR;
  		set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
  	}
  
  	if (id->driver_info & BTUSB_CSR) {
  		struct usb_device *udev = data->udev;
  
  		/* Old firmware would otherwise execute USB reset */
  		if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x117)
  			set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
  	}
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
964
  	if (id->driver_info & BTUSB_SNIFFER) {
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
965
  		struct usb_device *udev = data->udev;
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
966

7a9d40205   Marcel Holtmann   Bluetooth: Send H...
967
  		/* New sniffer firmware has crippled HCI interface */
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
968
969
  		if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
  			set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
970
971
  
  		data->isoc = NULL;
cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
972
973
974
975
976
977
978
979
980
981
982
983
  	}
  
  	if (id->driver_info & BTUSB_BCM92035) {
  		unsigned char cmd[] = { 0x3b, 0xfc, 0x01, 0x00 };
  		struct sk_buff *skb;
  
  		skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
  		if (skb) {
  			memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
  			skb_queue_tail(&hdev->driver_init, skb);
  		}
  	}
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
984

9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
985
986
  	if (data->isoc) {
  		err = usb_driver_claim_interface(&btusb_driver,
5fbcd260c   Marcel Holtmann   [Bluetooth] Fix U...
987
  							data->isoc, data);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
988
989
990
991
992
993
  		if (err < 0) {
  			hci_free_dev(hdev);
  			kfree(data);
  			return err;
  		}
  	}
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
  	err = hci_register_dev(hdev);
  	if (err < 0) {
  		hci_free_dev(hdev);
  		kfree(data);
  		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...
1017
  	__hci_dev_hold(hdev);
9bfa35fe4   Marcel Holtmann   [Bluetooth] Add S...
1018

5fbcd260c   Marcel Holtmann   [Bluetooth] Fix U...
1019
1020
1021
1022
  	usb_set_intfdata(data->intf, NULL);
  
  	if (data->isoc)
  		usb_set_intfdata(data->isoc, NULL);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1023
1024
  
  	hci_unregister_dev(hdev);
5fbcd260c   Marcel Holtmann   [Bluetooth] Fix U...
1025
1026
1027
1028
1029
1030
  	if (intf == data->isoc)
  		usb_driver_release_interface(&btusb_driver, data->intf);
  	else if (data->isoc)
  		usb_driver_release_interface(&btusb_driver, data->isoc);
  
  	__hci_dev_put(hdev);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1031
1032
  	hci_free_dev(hdev);
  }
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1033
  #ifdef CONFIG_PM
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1034
1035
1036
1037
1038
1039
1040
1041
  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...
1042
  	spin_lock_irq(&data->txlock);
5b1b0b812   Alan Stern   PM / Runtime: Add...
1043
  	if (!(PMSG_IS_AUTO(message) && data->tx_in_flight)) {
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1044
1045
1046
1047
1048
1049
1050
  		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...
1051
  	cancel_work_sync(&data->work);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1052
  	btusb_stop_traffic(data);
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1053
  	usb_kill_anchored_urbs(&data->tx_anchor);
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1054
1055
  	return 0;
  }
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
  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...
1070
1071
1072
1073
  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...
1074
  	int err = 0;
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1075
1076
1077
1078
1079
1080
1081
  
  	BT_DBG("intf %p", intf);
  
  	if (--data->suspend_count)
  		return 0;
  
  	if (!test_bit(HCI_RUNNING, &hdev->flags))
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1082
  		goto done;
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1083
1084
1085
1086
1087
  
  	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...
1088
  			goto failed;
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1089
1090
1091
1092
  		}
  	}
  
  	if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) {
43c2e57f9   Marcel Holtmann   Bluetooth: Submit...
1093
1094
  		err = btusb_submit_bulk_urb(hdev, GFP_NOIO);
  		if (err < 0) {
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1095
  			clear_bit(BTUSB_BULK_RUNNING, &data->flags);
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1096
1097
1098
1099
  			goto failed;
  		}
  
  		btusb_submit_bulk_urb(hdev, GFP_NOIO);
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1100
1101
1102
1103
1104
1105
1106
1107
  	}
  
  	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...
1108
1109
1110
1111
1112
  	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...
1113
  	return 0;
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1114
1115
1116
1117
1118
1119
1120
1121
1122
  
  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...
1123
  }
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1124
  #endif
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1125

5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1126
1127
1128
1129
  static struct usb_driver btusb_driver = {
  	.name		= "btusb",
  	.probe		= btusb_probe,
  	.disconnect	= btusb_disconnect,
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1130
  #ifdef CONFIG_PM
6a88adf2a   Marcel Holtmann   Bluetooth: Add su...
1131
1132
  	.suspend	= btusb_suspend,
  	.resume		= btusb_resume,
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1133
  #endif
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1134
  	.id_table	= btusb_table,
7bee549e1   Oliver Neukum   Bluetooth: Add US...
1135
  	.supports_autosuspend = 1,
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1136
  };
93f1508cf   Greg Kroah-Hartman   USB: convert driv...
1137
  module_usb_driver(btusb_driver);
5e23b923d   Marcel Holtmann   [Bluetooth] Add g...
1138

cfeb41453   Marcel Holtmann   [Bluetooth] Add f...
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
  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...
1156
1157
1158
1159
  MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
  MODULE_DESCRIPTION("Generic Bluetooth USB driver ver " VERSION);
  MODULE_VERSION(VERSION);
  MODULE_LICENSE("GPL");