bpa10x.c 10.9 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.9"
L
Linus Torvalds 已提交
44 45 46 47 48 49 50 51 52 53 54 55 56

static int ignore = 0;

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 {
57 58
	struct hci_dev    *hdev;
	struct usb_device *udev;
L
Linus Torvalds 已提交
59

60 61
	struct usb_anchor tx_anchor;
	struct usb_anchor rx_anchor;
L
Linus Torvalds 已提交
62

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

66
#define HCI_VENDOR_HDR_SIZE 5
L
Linus Torvalds 已提交
67 68

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

74
static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
L
Linus Torvalds 已提交
75
{
76 77 78 79 80 81 82 83 84
	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 已提交
85 86

	while (count) {
87 88 89
		struct sk_buff *skb = data->rx_skb[queue];
		struct { __u8 type; int expect; } *scb;
		int type, len = 0;
L
Linus Torvalds 已提交
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 129 130
		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 已提交
131 132 133
			}

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

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

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

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

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

153
		len = min(len, count);
L
Linus Torvalds 已提交
154

155
		memcpy(skb_put(skb, len), buf, len);
L
Linus Torvalds 已提交
156

157
		scb->expect -= len;
L
Linus Torvalds 已提交
158

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

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

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

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

	return 0;
}

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

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

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

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

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

193 194 195 196 197 198 199 200
	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 已提交
201

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

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

208 209 210 211 212 213 214
	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 已提交
215 216
	}

217 218 219 220 221 222 223
	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 已提交
224 225 226
	}
}

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

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

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

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

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

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

252
	urb->transfer_flags |= URB_FREE_BUFFER;
L
Linus Torvalds 已提交
253

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

256 257 258 259 260 261
	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);
		kfree(buf);
L
Linus Torvalds 已提交
262 263
	}

264
	usb_free_urb(urb);
L
Linus Torvalds 已提交
265

266
	return err;
L
Linus Torvalds 已提交
267 268
}

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

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

279
	urb = usb_alloc_urb(0, GFP_KERNEL);
L
Linus Torvalds 已提交
280
	if (!urb)
281
		return -ENOMEM;
L
Linus Torvalds 已提交
282

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

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

291 292
	usb_fill_bulk_urb(urb, data->udev, pipe,
					buf, size, bpa10x_rx_complete, hdev);
L
Linus Torvalds 已提交
293

294
	urb->transfer_flags |= URB_FREE_BUFFER;
L
Linus Torvalds 已提交
295

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

298 299 300 301 302
	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 已提交
303 304 305 306
		kfree(buf);
	}

	usb_free_urb(urb);
307 308

	return err;
L
Linus Torvalds 已提交
309 310 311 312 313 314 315
}

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

316
	BT_DBG("%s", hdev->name);
L
Linus Torvalds 已提交
317 318 319 320

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

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

325 326 327
	err = bpa10x_submit_bulk_urb(hdev);
	if (err < 0)
		goto error;
L
Linus Torvalds 已提交
328

329
	return 0;
L
Linus Torvalds 已提交
330

331 332
error:
	usb_kill_anchored_urbs(&data->rx_anchor);
L
Linus Torvalds 已提交
333

334
	clear_bit(HCI_RUNNING, &hdev->flags);
L
Linus Torvalds 已提交
335 336 337 338 339 340 341 342

	return err;
}

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

343
	BT_DBG("%s", hdev->name);
L
Linus Torvalds 已提交
344 345 346 347

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

348
	usb_kill_anchored_urbs(&data->rx_anchor);
L
Linus Torvalds 已提交
349 350 351 352 353 354 355 356

	return 0;
}

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

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

359
	usb_kill_anchored_urbs(&data->tx_anchor);
L
Linus Torvalds 已提交
360 361 362 363 364 365 366

	return 0;
}

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

373
	BT_DBG("%s", hdev->name);
L
Linus Torvalds 已提交
374 375 376 377

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

378 379 380
	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!urb)
		return -ENOMEM;
L
Linus Torvalds 已提交
381 382

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

385
	switch (bt_cb(skb)->pkt_type) {
L
Linus Torvalds 已提交
386
	case HCI_COMMAND_PKT:
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403
		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 已提交
404 405 406 407
		hdev->stat.cmd_tx++;
		break;

	case HCI_ACLDATA_PKT:
408 409 410 411 412
		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 已提交
413 414 415 416
		hdev->stat.acl_tx++;
		break;

	case HCI_SCODATA_PKT:
417 418 419 420 421
		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 已提交
422 423 424
		hdev->stat.sco_tx++;
		break;

425 426 427 428 429
	default:
		return -EILSEQ;
	}

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

431 432 433 434 435 436
	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 已提交
437

438
	usb_free_urb(urb);
L
Linus Torvalds 已提交
439 440 441 442 443 444 445 446

	return 0;
}

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

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

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

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

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

	if (ignore)
463 464
		return -ENODEV;

465
	if (intf->cur_altsetting->desc.bInterfaceNumber != 0)
L
Linus Torvalds 已提交
466 467
		return -ENODEV;

468
	data = kzalloc(sizeof(*data), GFP_KERNEL);
469
	if (!data)
L
Linus Torvalds 已提交
470 471
		return -ENOMEM;

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

474 475
	init_usb_anchor(&data->tx_anchor);
	init_usb_anchor(&data->rx_anchor);
L
Linus Torvalds 已提交
476 477 478 479 480 481 482 483 484

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

	hdev->type = HCI_USB;
	hdev->driver_data = data;
485 486 487

	data->hdev = hdev;

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

490 491 492 493 494
	hdev->open     = bpa10x_open;
	hdev->close    = bpa10x_close;
	hdev->flush    = bpa10x_flush;
	hdev->send     = bpa10x_send_frame;
	hdev->destruct = bpa10x_destruct;
L
Linus Torvalds 已提交
495 496 497 498 499 500

	hdev->owner = THIS_MODULE;

	err = hci_register_dev(hdev);
	if (err < 0) {
		hci_free_dev(hdev);
501
		kfree(data);
L
Linus Torvalds 已提交
502 503 504 505 506 507 508 509 510 511 512 513 514 515
		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);

516
	if (!data)
L
Linus Torvalds 已提交
517 518 519 520
		return;

	usb_set_intfdata(intf, NULL);

521
	hci_unregister_dev(data->hdev);
L
Linus Torvalds 已提交
522

523
	hci_free_dev(data->hdev);
L
Linus Torvalds 已提交
524 525 526 527 528 529 530 531 532 533 534 535 536
}

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);

537
	return usb_register(&bpa10x_driver);
L
Linus Torvalds 已提交
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554
}

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

module_init(bpa10x_init);
module_exit(bpa10x_exit);

module_param(ignore, bool, 0644);
MODULE_PARM_DESC(ignore, "Ignore devices from the matching table");

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