Blame view

drivers/bluetooth/bpa10x.c 8.83 KB
1a59d1b8e   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
  /*
   *
   *  Digianswer Bluetooth USB driver
   *
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
6
   *  Copyright (C) 2004-2007  Marcel Holtmann <marcel@holtmann.org>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
  #include <linux/kernel.h>
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
9
  #include <linux/module.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
10
11
12
  #include <linux/init.h>
  #include <linux/slab.h>
  #include <linux/types.h>
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
13
  #include <linux/sched.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
  #include <linux/errno.h>
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
15
  #include <linux/skbuff.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
17
18
19
20
  
  #include <linux/usb.h>
  
  #include <net/bluetooth/bluetooth.h>
  #include <net/bluetooth/hci_core.h>
07eb96a5a   Marcel Holtmann   Bluetooth: bpa10x...
21
  #include "h4_recv.h"
943cc5921   Marcel Holtmann   Bluetooth: bpa10x...
22
23
  
  #define VERSION "0.11"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24

e8549384d   Marcel Holtmann   Bluetooth: Declar...
25
  static const struct usb_device_id bpa10x_table[] = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
28
29
30
31
32
  	/* Tektronix BPA 100/105 (Digianswer) */
  	{ USB_DEVICE(0x08fd, 0x0002) },
  
  	{ }	/* Terminating entry */
  };
  
  MODULE_DEVICE_TABLE(usb, bpa10x_table);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
  struct bpa10x_data {
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
34
35
  	struct hci_dev    *hdev;
  	struct usb_device *udev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
37
38
  	struct usb_anchor tx_anchor;
  	struct usb_anchor rx_anchor;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
40
  	struct sk_buff *rx_skb[2];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
  };
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
42
  static void bpa10x_tx_complete(struct urb *urb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
  {
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
44
45
  	struct sk_buff *skb = urb->context;
  	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
47
48
  	BT_DBG("%s urb %p status %d count %d", hdev->name,
  					urb, urb->status, urb->actual_length);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
50
51
52
53
54
  	if (!test_bit(HCI_RUNNING, &hdev->flags))
  		goto done;
  
  	if (!urb->status)
  		hdev->stat.byte_tx += urb->transfer_buffer_length;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
  	else
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
56
  		hdev->stat.err_tx++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
58
59
  done:
  	kfree(urb->setup_packet);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
61
62
  	kfree_skb(skb);
  }
943cc5921   Marcel Holtmann   Bluetooth: bpa10x...
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  #define HCI_VENDOR_HDR_SIZE 5
  
  #define HCI_RECV_VENDOR \
  	.type = HCI_VENDOR_PKT, \
  	.hlen = HCI_VENDOR_HDR_SIZE, \
  	.loff = 3, \
  	.lsize = 2, \
  	.maxlen = HCI_MAX_FRAME_SIZE
  
  static const struct h4_recv_pkt bpa10x_recv_pkts[] = {
  	{ H4_RECV_ACL,     .recv = hci_recv_frame },
  	{ H4_RECV_SCO,     .recv = hci_recv_frame },
  	{ H4_RECV_EVENT,   .recv = hci_recv_frame },
  	{ HCI_RECV_VENDOR, .recv = hci_recv_diag  },
  };
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
78
79
80
  static void bpa10x_rx_complete(struct urb *urb)
  {
  	struct hci_dev *hdev = urb->context;
155961e80   David Herrmann   Bluetooth: Remove...
81
  	struct bpa10x_data *data = hci_get_drvdata(hdev);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
82
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
84
85
  	BT_DBG("%s urb %p status %d count %d", hdev->name,
  					urb, urb->status, urb->actual_length);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
87
88
  	if (!test_bit(HCI_RUNNING, &hdev->flags))
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
90
  	if (urb->status == 0) {
943cc5921   Marcel Holtmann   Bluetooth: bpa10x...
91
92
93
  		bool idx = usb_pipebulk(urb->pipe);
  
  		data->rx_skb[idx] = h4_recv_buf(hdev, data->rx_skb[idx],
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
94
  						urb->transfer_buffer,
943cc5921   Marcel Holtmann   Bluetooth: bpa10x...
95
96
97
98
  						urb->actual_length,
  						bpa10x_recv_pkts,
  						ARRAY_SIZE(bpa10x_recv_pkts));
  		if (IS_ERR(data->rx_skb[idx])) {
2064ee332   Marcel Holtmann   Bluetooth: Use bt...
99
  			bt_dev_err(hdev, "corrupted event packet");
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
100
  			hdev->stat.err_rx++;
943cc5921   Marcel Holtmann   Bluetooth: bpa10x...
101
  			data->rx_skb[idx] = NULL;
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
102
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
  	}
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
104
105
106
107
  	usb_anchor_urb(urb, &data->rx_anchor);
  
  	err = usb_submit_urb(urb, GFP_ATOMIC);
  	if (err < 0) {
2064ee332   Marcel Holtmann   Bluetooth: Use bt...
108
  		bt_dev_err(hdev, "urb %p failed to resubmit (%d)", urb, -err);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
109
  		usb_unanchor_urb(urb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
111
  	}
  }
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
112
  static inline int bpa10x_submit_intr_urb(struct hci_dev *hdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
  {
155961e80   David Herrmann   Bluetooth: Remove...
114
  	struct bpa10x_data *data = hci_get_drvdata(hdev);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
115
116
117
118
  	struct urb *urb;
  	unsigned char *buf;
  	unsigned int pipe;
  	int err, size = 16;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
119

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
120
  	BT_DBG("%s", hdev->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
122
123
124
  	urb = usb_alloc_urb(0, GFP_KERNEL);
  	if (!urb)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
126
127
128
129
130
  	buf = kmalloc(size, GFP_KERNEL);
  	if (!buf) {
  		usb_free_urb(urb);
  		return -ENOMEM;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
132
  	pipe = usb_rcvintpipe(data->udev, 0x81);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
134
135
  	usb_fill_int_urb(urb, data->udev, pipe, buf, size,
  						bpa10x_rx_complete, hdev, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
136

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
137
  	urb->transfer_flags |= URB_FREE_BUFFER;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
139
  	usb_anchor_urb(urb, &data->rx_anchor);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
141
142
  	err = usb_submit_urb(urb, GFP_KERNEL);
  	if (err < 0) {
2064ee332   Marcel Holtmann   Bluetooth: Use bt...
143
  		bt_dev_err(hdev, "urb %p submission failed (%d)", urb, -err);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
144
  		usb_unanchor_urb(urb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
  	}
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
146
  	usb_free_urb(urb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
148
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
  }
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
150
  static inline int bpa10x_submit_bulk_urb(struct hci_dev *hdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
  {
155961e80   David Herrmann   Bluetooth: Remove...
152
  	struct bpa10x_data *data = hci_get_drvdata(hdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153
  	struct urb *urb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
  	unsigned char *buf;
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
155
156
  	unsigned int pipe;
  	int err, size = 64;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
158
  	BT_DBG("%s", hdev->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
160
  	urb = usb_alloc_urb(0, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
  	if (!urb)
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
162
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
164
  	buf = kmalloc(size, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165
166
  	if (!buf) {
  		usb_free_urb(urb);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
167
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
  	}
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
169
  	pipe = usb_rcvbulkpipe(data->udev, 0x82);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
171
172
  	usb_fill_bulk_urb(urb, data->udev, pipe,
  					buf, size, bpa10x_rx_complete, hdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
174
  	urb->transfer_flags |= URB_FREE_BUFFER;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
175

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
176
  	usb_anchor_urb(urb, &data->rx_anchor);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
178
179
  	err = usb_submit_urb(urb, GFP_KERNEL);
  	if (err < 0) {
2064ee332   Marcel Holtmann   Bluetooth: Use bt...
180
  		bt_dev_err(hdev, "urb %p submission failed (%d)", urb, -err);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
181
  		usb_unanchor_urb(urb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
  	usb_free_urb(urb);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
184
185
  
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
187
188
189
  }
  
  static int bpa10x_open(struct hci_dev *hdev)
  {
155961e80   David Herrmann   Bluetooth: Remove...
190
  	struct bpa10x_data *data = hci_get_drvdata(hdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
  	int err;
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
192
  	BT_DBG("%s", hdev->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
193

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
194
195
196
  	err = bpa10x_submit_intr_urb(hdev);
  	if (err < 0)
  		goto error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
198
199
200
  	err = bpa10x_submit_bulk_urb(hdev);
  	if (err < 0)
  		goto error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
202
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
204
205
  error:
  	usb_kill_anchored_urbs(&data->rx_anchor);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207
208
209
210
211
  	return err;
  }
  
  static int bpa10x_close(struct hci_dev *hdev)
  {
155961e80   David Herrmann   Bluetooth: Remove...
212
  	struct bpa10x_data *data = hci_get_drvdata(hdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
214
  	BT_DBG("%s", hdev->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
215

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
216
  	usb_kill_anchored_urbs(&data->rx_anchor);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
218
219
220
221
222
  
  	return 0;
  }
  
  static int bpa10x_flush(struct hci_dev *hdev)
  {
155961e80   David Herrmann   Bluetooth: Remove...
223
  	struct bpa10x_data *data = hci_get_drvdata(hdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
225
  	BT_DBG("%s", hdev->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
227
  	usb_kill_anchored_urbs(&data->tx_anchor);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
229
230
  
  	return 0;
  }
ddd68ec8f   Marcel Holtmann   Bluetooth: bpa10x...
231
232
  static int bpa10x_setup(struct hci_dev *hdev)
  {
cca32837f   Colin Ian King   Bluetooth: bpa10x...
233
  	static const u8 req[] = { 0x07 };
ddd68ec8f   Marcel Holtmann   Bluetooth: bpa10x...
234
235
236
237
238
239
240
241
  	struct sk_buff *skb;
  
  	BT_DBG("%s", hdev->name);
  
  	/* Read revision string */
  	skb = __hci_cmd_sync(hdev, 0xfc0e, sizeof(req), req, HCI_INIT_TIMEOUT);
  	if (IS_ERR(skb))
  		return PTR_ERR(skb);
2064ee332   Marcel Holtmann   Bluetooth: Use bt...
242
  	bt_dev_info(hdev, "%s", (char *)(skb->data + 1));
ddd68ec8f   Marcel Holtmann   Bluetooth: bpa10x...
243

b2999c195   Marcel Holtmann   Bluetooth: bpa10x...
244
  	hci_set_fw_info(hdev, "%s", skb->data + 1);
ddd68ec8f   Marcel Holtmann   Bluetooth: bpa10x...
245
246
247
  	kfree_skb(skb);
  	return 0;
  }
7bd8f09f6   Marcel Holtmann   Bluetooth: Add hd...
248
  static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249
  {
155961e80   David Herrmann   Bluetooth: Remove...
250
  	struct bpa10x_data *data = hci_get_drvdata(hdev);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
251
252
253
254
  	struct usb_ctrlrequest *dr;
  	struct urb *urb;
  	unsigned int pipe;
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
255

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
256
  	BT_DBG("%s", hdev->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257

7bd8f09f6   Marcel Holtmann   Bluetooth: Add hd...
258
  	skb->dev = (void *) hdev;
478113e43   Jia-Ju Bai   bluetooth: bpa10x...
259
  	urb = usb_alloc_urb(0, GFP_KERNEL);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
260
261
  	if (!urb)
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
263
  
  	/* Prepend skb with frame type */
d58ff3512   Johannes Berg   networking: make ...
264
  	*(u8 *)skb_push(skb, 1) = hci_skb_pkt_type(skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265

618e8bc22   Marcel Holtmann   Bluetooth: Use ne...
266
  	switch (hci_skb_pkt_type(skb)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
267
  	case HCI_COMMAND_PKT:
478113e43   Jia-Ju Bai   bluetooth: bpa10x...
268
  		dr = kmalloc(sizeof(*dr), GFP_KERNEL);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
  		if (!dr) {
  			usb_free_urb(urb);
  			return -ENOMEM;
  		}
  
  		dr->bRequestType = USB_TYPE_VENDOR;
  		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, bpa10x_tx_complete, skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
  		hdev->stat.cmd_tx++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
286
287
  		break;
  
  	case HCI_ACLDATA_PKT:
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
288
289
290
291
  		pipe = usb_sndbulkpipe(data->udev, 0x02);
  
  		usb_fill_bulk_urb(urb, data->udev, pipe,
  				skb->data, skb->len, bpa10x_tx_complete, skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
  		hdev->stat.acl_tx++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293
294
295
  		break;
  
  	case HCI_SCODATA_PKT:
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
296
297
298
299
  		pipe = usb_sndbulkpipe(data->udev, 0x02);
  
  		usb_fill_bulk_urb(urb, data->udev, pipe,
  				skb->data, skb->len, bpa10x_tx_complete, skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
  		hdev->stat.sco_tx++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
303
  	default:
cb7cd4293   Adrian Bunk   drivers/bluetooth...
304
  		usb_free_urb(urb);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
305
306
307
308
  		return -EILSEQ;
  	}
  
  	usb_anchor_urb(urb, &data->tx_anchor);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309

478113e43   Jia-Ju Bai   bluetooth: bpa10x...
310
  	err = usb_submit_urb(urb, GFP_KERNEL);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
311
  	if (err < 0) {
2064ee332   Marcel Holtmann   Bluetooth: Use bt...
312
  		bt_dev_err(hdev, "urb %p submission failed", urb);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
313
314
315
  		kfree(urb->setup_packet);
  		usb_unanchor_urb(urb);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
316

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
317
  	usb_free_urb(urb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318

d94dfd798   Navid Emamdoost   Bluetooth: bpa10x...
319
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
  }
881f7e86a   Marcel Holtmann   Bluetooth: bpa10x...
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
  static int bpa10x_set_diag(struct hci_dev *hdev, bool enable)
  {
  	const u8 req[] = { 0x00, enable };
  	struct sk_buff *skb;
  
  	BT_DBG("%s", hdev->name);
  
  	if (!test_bit(HCI_RUNNING, &hdev->flags))
  		return -ENETDOWN;
  
  	/* Enable sniffer operation */
  	skb = __hci_cmd_sync(hdev, 0xfc0e, sizeof(req), req, HCI_INIT_TIMEOUT);
  	if (IS_ERR(skb))
  		return PTR_ERR(skb);
  
  	kfree_skb(skb);
  	return 0;
  }
82b7d8566   Fabian Schindlatz   Bluetooth: Cleanu...
339
340
  static int bpa10x_probe(struct usb_interface *intf,
  			const struct usb_device_id *id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
341
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342
  	struct bpa10x_data *data;
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
343
  	struct hci_dev *hdev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344
345
346
  	int err;
  
  	BT_DBG("intf %p id %p", intf, id);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
347
  	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
348
  		return -ENODEV;
704687ce1   Sachin Kamat   Bluetooth: Use de...
349
  	data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
350
  	if (!data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
351
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
353
  	data->udev = interface_to_usbdev(intf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
355
356
  	init_usb_anchor(&data->tx_anchor);
  	init_usb_anchor(&data->rx_anchor);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
357
358
  
  	hdev = hci_alloc_dev();
704687ce1   Sachin Kamat   Bluetooth: Use de...
359
  	if (!hdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
361

c13854cef   Marcel Holtmann   Bluetooth: Conver...
362
  	hdev->bus = HCI_USB;
155961e80   David Herrmann   Bluetooth: Remove...
363
  	hci_set_drvdata(hdev, data);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
364
365
  
  	data->hdev = hdev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366
  	SET_HCIDEV_DEV(hdev, &intf->dev);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
367
368
369
  	hdev->open     = bpa10x_open;
  	hdev->close    = bpa10x_close;
  	hdev->flush    = bpa10x_flush;
ddd68ec8f   Marcel Holtmann   Bluetooth: bpa10x...
370
  	hdev->setup    = bpa10x_setup;
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
371
  	hdev->send     = bpa10x_send_frame;
881f7e86a   Marcel Holtmann   Bluetooth: bpa10x...
372
  	hdev->set_diag = bpa10x_set_diag;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373

a6c511c63   Szymon Janc   Bluetooth: Rename...
374
  	set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks);
7a9d40205   Marcel Holtmann   Bluetooth: Send H...
375

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
376
377
  	err = hci_register_dev(hdev);
  	if (err < 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378
379
380
381
382
383
384
385
386
387
388
389
  		hci_free_dev(hdev);
  		return err;
  	}
  
  	usb_set_intfdata(intf, data);
  
  	return 0;
  }
  
  static void bpa10x_disconnect(struct usb_interface *intf)
  {
  	struct bpa10x_data *data = usb_get_intfdata(intf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
391
  
  	BT_DBG("intf %p", intf);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
392
  	if (!data)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
394
395
  		return;
  
  	usb_set_intfdata(intf, NULL);
e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
396
  	hci_unregister_dev(data->hdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397

e24b21ec8   Marcel Holtmann   [Bluetooth] Chang...
398
  	hci_free_dev(data->hdev);
d25442ba4   David Herrmann   Bluetooth: bpa10x...
399
400
  	kfree_skb(data->rx_skb[0]);
  	kfree_skb(data->rx_skb[1]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
402
403
  }
  
  static struct usb_driver bpa10x_driver = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
404
405
406
407
  	.name		= "bpa10x",
  	.probe		= bpa10x_probe,
  	.disconnect	= bpa10x_disconnect,
  	.id_table	= bpa10x_table,
e1f12eb6b   Sarah Sharp   USB: Disable hub-...
408
  	.disable_hub_initiated_lpm = 1,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
409
  };
93f1508cf   Greg Kroah-Hartman   USB: convert driv...
410
  module_usb_driver(bpa10x_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
411

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
412
413
414
415
  MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
  MODULE_DESCRIPTION("Digianswer Bluetooth USB driver ver " VERSION);
  MODULE_VERSION(VERSION);
  MODULE_LICENSE("GPL");