bpa10x.c 10.7 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4
/*
 *
 *  Digianswer Bluetooth USB driver
 *
5
 *  Copyright (C) 2004-2007  Marcel Holtmann <marcel@holtmann.org>
L
Linus Torvalds 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 *
 *  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>
25
#include <linux/module.h>
L
Linus Torvalds 已提交
26 27 28
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/types.h>
29
#include <linux/sched.h>
L
Linus Torvalds 已提交
30
#include <linux/errno.h>
31
#include <linux/skbuff.h>
L
Linus Torvalds 已提交
32 33 34 35 36 37 38 39 40 41 42

#include <linux/usb.h>

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>

#ifndef CONFIG_BT_HCIBPA10X_DEBUG
#undef  BT_DBG
#define BT_DBG(D...)
#endif

43
#define VERSION "0.10"
L
Linus Torvalds 已提交
44 45 46 47 48 49 50 51 52 53 54

static struct usb_device_id bpa10x_table[] = {
	/* Tektronix BPA 100/105 (Digianswer) */
	{ USB_DEVICE(0x08fd, 0x0002) },

	{ }	/* Terminating entry */
};

MODULE_DEVICE_TABLE(usb, bpa10x_table);

struct bpa10x_data {
55 56
	struct hci_dev    *hdev;
	struct usb_device *udev;
L
Linus Torvalds 已提交
57

58 59
	struct usb_anchor tx_anchor;
	struct usb_anchor rx_anchor;
L
Linus Torvalds 已提交
60

61
	struct sk_buff *rx_skb[2];
L
Linus Torvalds 已提交
62 63
};

64
#define HCI_VENDOR_HDR_SIZE 5
L
Linus Torvalds 已提交
65 66

struct hci_vendor_hdr {
67 68 69
	__u8    type;
	__le16  snum;
	__le16  dlen;
L
Linus Torvalds 已提交
70 71
} __attribute__ ((packed));

72
static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
L
Linus Torvalds 已提交
73
{
74 75 76 77 78 79 80 81 82
	struct bpa10x_data *data = hdev->driver_data;

	BT_DBG("%s queue %d buffer %p count %d", hdev->name,
							queue, buf, count);

	if (queue < 0 || queue > 1)
		return -EILSEQ;

	hdev->stat.byte_rx += count;
L
Linus Torvalds 已提交
83 84

	while (count) {
85 86 87
		struct sk_buff *skb = data->rx_skb[queue];
		struct { __u8 type; int expect; } *scb;
		int type, len = 0;
L
Linus Torvalds 已提交
88

89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
		if (!skb) {
			/* Start of the frame */

			type = *((__u8 *) buf);
			count--; buf++;

			switch (type) {
			case HCI_EVENT_PKT:
				if (count >= HCI_EVENT_HDR_SIZE) {
					struct hci_event_hdr *h = buf;
					len = HCI_EVENT_HDR_SIZE + h->plen;
				} else
					return -EILSEQ;
				break;

			case HCI_ACLDATA_PKT:
				if (count >= HCI_ACL_HDR_SIZE) {
					struct hci_acl_hdr *h = buf;
					len = HCI_ACL_HDR_SIZE +
							__le16_to_cpu(h->dlen);
				} else
					return -EILSEQ;
				break;

			case HCI_SCODATA_PKT:
				if (count >= HCI_SCO_HDR_SIZE) {
					struct hci_sco_hdr *h = buf;
					len = HCI_SCO_HDR_SIZE + h->dlen;
				} else
					return -EILSEQ;
				break;

			case HCI_VENDOR_PKT:
				if (count >= HCI_VENDOR_HDR_SIZE) {
					struct hci_vendor_hdr *h = buf;
					len = HCI_VENDOR_HDR_SIZE +
							__le16_to_cpu(h->dlen);
				} else
					return -EILSEQ;
				break;
L
Linus Torvalds 已提交
129 130 131
			}

			skb = bt_skb_alloc(len, GFP_ATOMIC);
132 133 134
			if (!skb) {
				BT_ERR("%s no memory for packet", hdev->name);
				return -ENOMEM;
L
Linus Torvalds 已提交
135 136
			}

137
			skb->dev = (void *) hdev;
L
Linus Torvalds 已提交
138

139
			data->rx_skb[queue] = skb;
L
Linus Torvalds 已提交
140

141 142 143 144 145
			scb = (void *) skb->cb;
			scb->type = type;
			scb->expect = len;
		} else {
			/* Continuation */
L
Linus Torvalds 已提交
146

147 148
			scb = (void *) skb->cb;
			len = scb->expect;
L
Linus Torvalds 已提交
149 150
		}

151
		len = min(len, count);
L
Linus Torvalds 已提交
152

153
		memcpy(skb_put(skb, len), buf, len);
L
Linus Torvalds 已提交
154

155
		scb->expect -= len;
L
Linus Torvalds 已提交
156

157 158
		if (scb->expect == 0) {
			/* Complete frame */
L
Linus Torvalds 已提交
159

160
			data->rx_skb[queue] = NULL;
L
Linus Torvalds 已提交
161

162
			bt_cb(skb)->pkt_type = scb->type;
L
Linus Torvalds 已提交
163 164
			hci_recv_frame(skb);
		}
165 166

		count -= len; buf += len;
L
Linus Torvalds 已提交
167 168 169 170 171
	}

	return 0;
}

172
static void bpa10x_tx_complete(struct urb *urb)
L
Linus Torvalds 已提交
173
{
174 175
	struct sk_buff *skb = urb->context;
	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
L
Linus Torvalds 已提交
176

177 178
	BT_DBG("%s urb %p status %d count %d", hdev->name,
					urb, urb->status, urb->actual_length);
L
Linus Torvalds 已提交
179

180 181 182 183 184
	if (!test_bit(HCI_RUNNING, &hdev->flags))
		goto done;

	if (!urb->status)
		hdev->stat.byte_tx += urb->transfer_buffer_length;
L
Linus Torvalds 已提交
185
	else
186
		hdev->stat.err_tx++;
L
Linus Torvalds 已提交
187

188 189
done:
	kfree(urb->setup_packet);
L
Linus Torvalds 已提交
190

191 192 193 194 195 196 197 198
	kfree_skb(skb);
}

static void bpa10x_rx_complete(struct urb *urb)
{
	struct hci_dev *hdev = urb->context;
	struct bpa10x_data *data = hdev->driver_data;
	int err;
L
Linus Torvalds 已提交
199

200 201
	BT_DBG("%s urb %p status %d count %d", hdev->name,
					urb, urb->status, urb->actual_length);
L
Linus Torvalds 已提交
202

203 204
	if (!test_bit(HCI_RUNNING, &hdev->flags))
		return;
L
Linus Torvalds 已提交
205

206 207 208 209 210 211 212
	if (urb->status == 0) {
		if (bpa10x_recv(hdev, usb_pipebulk(urb->pipe),
						urb->transfer_buffer,
						urb->actual_length) < 0) {
			BT_ERR("%s corrupted event packet", hdev->name);
			hdev->stat.err_rx++;
		}
L
Linus Torvalds 已提交
213 214
	}

215 216 217 218 219 220 221
	usb_anchor_urb(urb, &data->rx_anchor);

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err < 0) {
		BT_ERR("%s urb %p failed to resubmit (%d)",
						hdev->name, urb, -err);
		usb_unanchor_urb(urb);
L
Linus Torvalds 已提交
222 223 224
	}
}

225
static inline int bpa10x_submit_intr_urb(struct hci_dev *hdev)
L
Linus Torvalds 已提交
226
{
227 228 229 230 231
	struct bpa10x_data *data = hdev->driver_data;
	struct urb *urb;
	unsigned char *buf;
	unsigned int pipe;
	int err, size = 16;
L
Linus Torvalds 已提交
232

233
	BT_DBG("%s", hdev->name);
L
Linus Torvalds 已提交
234

235 236 237
	urb = usb_alloc_urb(0, GFP_KERNEL);
	if (!urb)
		return -ENOMEM;
L
Linus Torvalds 已提交
238

239 240 241 242 243
	buf = kmalloc(size, GFP_KERNEL);
	if (!buf) {
		usb_free_urb(urb);
		return -ENOMEM;
	}
L
Linus Torvalds 已提交
244

245
	pipe = usb_rcvintpipe(data->udev, 0x81);
L
Linus Torvalds 已提交
246

247 248
	usb_fill_int_urb(urb, data->udev, pipe, buf, size,
						bpa10x_rx_complete, hdev, 1);
L
Linus Torvalds 已提交
249

250
	urb->transfer_flags |= URB_FREE_BUFFER;
L
Linus Torvalds 已提交
251

252
	usb_anchor_urb(urb, &data->rx_anchor);
L
Linus Torvalds 已提交
253

254 255 256 257 258
	err = usb_submit_urb(urb, GFP_KERNEL);
	if (err < 0) {
		BT_ERR("%s urb %p submission failed (%d)",
						hdev->name, urb, -err);
		usb_unanchor_urb(urb);
L
Linus Torvalds 已提交
259 260
	}

261
	usb_free_urb(urb);
L
Linus Torvalds 已提交
262

263
	return err;
L
Linus Torvalds 已提交
264 265
}

266
static inline int bpa10x_submit_bulk_urb(struct hci_dev *hdev)
L
Linus Torvalds 已提交
267
{
268
	struct bpa10x_data *data = hdev->driver_data;
L
Linus Torvalds 已提交
269 270
	struct urb *urb;
	unsigned char *buf;
271 272
	unsigned int pipe;
	int err, size = 64;
L
Linus Torvalds 已提交
273

274
	BT_DBG("%s", hdev->name);
L
Linus Torvalds 已提交
275

276
	urb = usb_alloc_urb(0, GFP_KERNEL);
L
Linus Torvalds 已提交
277
	if (!urb)
278
		return -ENOMEM;
L
Linus Torvalds 已提交
279

280
	buf = kmalloc(size, GFP_KERNEL);
L
Linus Torvalds 已提交
281 282
	if (!buf) {
		usb_free_urb(urb);
283
		return -ENOMEM;
L
Linus Torvalds 已提交
284 285
	}

286
	pipe = usb_rcvbulkpipe(data->udev, 0x82);
L
Linus Torvalds 已提交
287

288 289
	usb_fill_bulk_urb(urb, data->udev, pipe,
					buf, size, bpa10x_rx_complete, hdev);
L
Linus Torvalds 已提交
290

291
	urb->transfer_flags |= URB_FREE_BUFFER;
L
Linus Torvalds 已提交
292

293
	usb_anchor_urb(urb, &data->rx_anchor);
L
Linus Torvalds 已提交
294

295 296 297 298 299
	err = usb_submit_urb(urb, GFP_KERNEL);
	if (err < 0) {
		BT_ERR("%s urb %p submission failed (%d)",
						hdev->name, urb, -err);
		usb_unanchor_urb(urb);
L
Linus Torvalds 已提交
300 301 302
	}

	usb_free_urb(urb);
303 304

	return err;
L
Linus Torvalds 已提交
305 306 307 308 309 310 311
}

static int bpa10x_open(struct hci_dev *hdev)
{
	struct bpa10x_data *data = hdev->driver_data;
	int err;

312
	BT_DBG("%s", hdev->name);
L
Linus Torvalds 已提交
313 314 315 316

	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
		return 0;

317 318 319
	err = bpa10x_submit_intr_urb(hdev);
	if (err < 0)
		goto error;
L
Linus Torvalds 已提交
320

321 322 323
	err = bpa10x_submit_bulk_urb(hdev);
	if (err < 0)
		goto error;
L
Linus Torvalds 已提交
324

325
	return 0;
L
Linus Torvalds 已提交
326

327 328
error:
	usb_kill_anchored_urbs(&data->rx_anchor);
L
Linus Torvalds 已提交
329

330
	clear_bit(HCI_RUNNING, &hdev->flags);
L
Linus Torvalds 已提交
331 332 333 334 335 336 337 338

	return err;
}

static int bpa10x_close(struct hci_dev *hdev)
{
	struct bpa10x_data *data = hdev->driver_data;

339
	BT_DBG("%s", hdev->name);
L
Linus Torvalds 已提交
340 341 342 343

	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
		return 0;

344
	usb_kill_anchored_urbs(&data->rx_anchor);
L
Linus Torvalds 已提交
345 346 347 348 349 350 351 352

	return 0;
}

static int bpa10x_flush(struct hci_dev *hdev)
{
	struct bpa10x_data *data = hdev->driver_data;

353
	BT_DBG("%s", hdev->name);
L
Linus Torvalds 已提交
354

355
	usb_kill_anchored_urbs(&data->tx_anchor);
L
Linus Torvalds 已提交
356 357 358 359 360 361 362

	return 0;
}

static int bpa10x_send_frame(struct sk_buff *skb)
{
	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
363 364 365 366 367
	struct bpa10x_data *data = hdev->driver_data;
	struct usb_ctrlrequest *dr;
	struct urb *urb;
	unsigned int pipe;
	int err;
L
Linus Torvalds 已提交
368

369
	BT_DBG("%s", hdev->name);
L
Linus Torvalds 已提交
370 371 372 373

	if (!test_bit(HCI_RUNNING, &hdev->flags))
		return -EBUSY;

374 375 376
	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!urb)
		return -ENOMEM;
L
Linus Torvalds 已提交
377 378

	/* Prepend skb with frame type */
379
	*skb_push(skb, 1) = bt_cb(skb)->pkt_type;
L
Linus Torvalds 已提交
380

381
	switch (bt_cb(skb)->pkt_type) {
L
Linus Torvalds 已提交
382
	case HCI_COMMAND_PKT:
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399
		dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
		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);

L
Linus Torvalds 已提交
400 401 402 403
		hdev->stat.cmd_tx++;
		break;

	case HCI_ACLDATA_PKT:
404 405 406 407 408
		pipe = usb_sndbulkpipe(data->udev, 0x02);

		usb_fill_bulk_urb(urb, data->udev, pipe,
				skb->data, skb->len, bpa10x_tx_complete, skb);

L
Linus Torvalds 已提交
409 410 411 412
		hdev->stat.acl_tx++;
		break;

	case HCI_SCODATA_PKT:
413 414 415 416 417
		pipe = usb_sndbulkpipe(data->udev, 0x02);

		usb_fill_bulk_urb(urb, data->udev, pipe,
				skb->data, skb->len, bpa10x_tx_complete, skb);

L
Linus Torvalds 已提交
418 419 420
		hdev->stat.sco_tx++;
		break;

421
	default:
422
		usb_free_urb(urb);
423 424 425 426
		return -EILSEQ;
	}

	usb_anchor_urb(urb, &data->tx_anchor);
L
Linus Torvalds 已提交
427

428 429 430 431 432 433
	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err < 0) {
		BT_ERR("%s urb %p submission failed", hdev->name, urb);
		kfree(urb->setup_packet);
		usb_unanchor_urb(urb);
	}
L
Linus Torvalds 已提交
434

435
	usb_free_urb(urb);
L
Linus Torvalds 已提交
436 437 438 439 440 441 442 443

	return 0;
}

static void bpa10x_destruct(struct hci_dev *hdev)
{
	struct bpa10x_data *data = hdev->driver_data;

444
	BT_DBG("%s", hdev->name);
L
Linus Torvalds 已提交
445

446 447
	kfree(data->rx_skb[0]);
	kfree(data->rx_skb[1]);
L
Linus Torvalds 已提交
448 449 450 451 452 453
	kfree(data);
}

static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct bpa10x_data *data;
454
	struct hci_dev *hdev;
L
Linus Torvalds 已提交
455 456 457 458
	int err;

	BT_DBG("intf %p id %p", intf, id);

459
	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
L
Linus Torvalds 已提交
460 461
		return -ENODEV;

462
	data = kzalloc(sizeof(*data), GFP_KERNEL);
463
	if (!data)
L
Linus Torvalds 已提交
464 465
		return -ENOMEM;

466
	data->udev = interface_to_usbdev(intf);
L
Linus Torvalds 已提交
467

468 469
	init_usb_anchor(&data->tx_anchor);
	init_usb_anchor(&data->rx_anchor);
L
Linus Torvalds 已提交
470 471 472 473 474 475 476 477 478

	hdev = hci_alloc_dev();
	if (!hdev) {
		kfree(data);
		return -ENOMEM;
	}

	hdev->type = HCI_USB;
	hdev->driver_data = data;
479 480 481

	data->hdev = hdev;

L
Linus Torvalds 已提交
482 483
	SET_HCIDEV_DEV(hdev, &intf->dev);

484 485 486 487 488
	hdev->open     = bpa10x_open;
	hdev->close    = bpa10x_close;
	hdev->flush    = bpa10x_flush;
	hdev->send     = bpa10x_send_frame;
	hdev->destruct = bpa10x_destruct;
L
Linus Torvalds 已提交
489 490 491 492 493 494

	hdev->owner = THIS_MODULE;

	err = hci_register_dev(hdev);
	if (err < 0) {
		hci_free_dev(hdev);
495
		kfree(data);
L
Linus Torvalds 已提交
496 497 498 499 500 501 502 503 504 505 506 507 508 509
		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);

	BT_DBG("intf %p", intf);

510
	if (!data)
L
Linus Torvalds 已提交
511 512 513 514
		return;

	usb_set_intfdata(intf, NULL);

515
	hci_unregister_dev(data->hdev);
L
Linus Torvalds 已提交
516

517
	hci_free_dev(data->hdev);
L
Linus Torvalds 已提交
518 519 520 521 522 523 524 525 526 527 528 529 530
}

static struct usb_driver bpa10x_driver = {
	.name		= "bpa10x",
	.probe		= bpa10x_probe,
	.disconnect	= bpa10x_disconnect,
	.id_table	= bpa10x_table,
};

static int __init bpa10x_init(void)
{
	BT_INFO("Digianswer Bluetooth USB driver ver %s", VERSION);

531
	return usb_register(&bpa10x_driver);
L
Linus Torvalds 已提交
532 533 534 535 536 537 538 539 540 541 542 543 544 545
}

static void __exit bpa10x_exit(void)
{
	usb_deregister(&bpa10x_driver);
}

module_init(bpa10x_init);
module_exit(bpa10x_exit);

MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("Digianswer Bluetooth USB driver ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");