bfusb.c 16.7 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4
/*
 *
 *  AVM BlueFRITZ! USB driver
 *
5
 *  Copyright (C) 2003-2006  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 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
 *
 *
 *  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/module.h>

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/skbuff.h>

#include <linux/device.h>
#include <linux/firmware.h>

#include <linux/usb.h>

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

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

46
#define VERSION "1.2"
L
Linus Torvalds 已提交
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

static struct usb_driver bfusb_driver;

static struct usb_device_id bfusb_table[] = {
	/* AVM BlueFRITZ! USB */
	{ USB_DEVICE(0x057c, 0x2200) },

	{ }	/* Terminating entry */
};

MODULE_DEVICE_TABLE(usb, bfusb_table);

#define BFUSB_MAX_BLOCK_SIZE	256

#define BFUSB_BLOCK_TIMEOUT	3000

#define BFUSB_TX_PROCESS	1
#define BFUSB_TX_WAKEUP		2

#define BFUSB_MAX_BULK_TX	2
#define BFUSB_MAX_BULK_RX	2

69
struct bfusb_data {
L
Linus Torvalds 已提交
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
	struct hci_dev		*hdev;

	unsigned long		state;

	struct usb_device	*udev;

	unsigned int		bulk_in_ep;
	unsigned int		bulk_out_ep;
	unsigned int		bulk_pkt_size;

	rwlock_t		lock;

	struct sk_buff_head	transmit_q;

	struct sk_buff		*reassembly;

	atomic_t		pending_tx;
	struct sk_buff_head	pending_q;
	struct sk_buff_head	completed_q;
};

91
struct bfusb_data_scb {
L
Linus Torvalds 已提交
92 93 94
	struct urb *urb;
};

95 96
static void bfusb_tx_complete(struct urb *urb);
static void bfusb_rx_complete(struct urb *urb);
L
Linus Torvalds 已提交
97

98
static struct urb *bfusb_get_completed(struct bfusb_data *data)
L
Linus Torvalds 已提交
99 100 101 102
{
	struct sk_buff *skb;
	struct urb *urb = NULL;

103
	BT_DBG("bfusb %p", data);
L
Linus Torvalds 已提交
104

105
	skb = skb_dequeue(&data->completed_q);
L
Linus Torvalds 已提交
106
	if (skb) {
107
		urb = ((struct bfusb_data_scb *) skb->cb)->urb;
L
Linus Torvalds 已提交
108 109 110 111 112 113
		kfree_skb(skb);
	}

	return urb;
}

114
static void bfusb_unlink_urbs(struct bfusb_data *data)
L
Linus Torvalds 已提交
115 116 117 118
{
	struct sk_buff *skb;
	struct urb *urb;

119
	BT_DBG("bfusb %p", data);
L
Linus Torvalds 已提交
120

121 122
	while ((skb = skb_dequeue(&data->pending_q))) {
		urb = ((struct bfusb_data_scb *) skb->cb)->urb;
L
Linus Torvalds 已提交
123
		usb_kill_urb(urb);
124
		skb_queue_tail(&data->completed_q, skb);
L
Linus Torvalds 已提交
125 126
	}

127
	while ((urb = bfusb_get_completed(data)))
L
Linus Torvalds 已提交
128 129 130
		usb_free_urb(urb);
}

131
static int bfusb_send_bulk(struct bfusb_data *data, struct sk_buff *skb)
L
Linus Torvalds 已提交
132
{
133 134
	struct bfusb_data_scb *scb = (void *) skb->cb;
	struct urb *urb = bfusb_get_completed(data);
L
Linus Torvalds 已提交
135 136
	int err, pipe;

137
	BT_DBG("bfusb %p skb %p len %d", data, skb, skb->len);
L
Linus Torvalds 已提交
138 139 140 141

	if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC)))
		return -ENOMEM;

142
	pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);
L
Linus Torvalds 已提交
143

144
	usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len,
L
Linus Torvalds 已提交
145 146 147 148
			bfusb_tx_complete, skb);

	scb->urb = urb;

149
	skb_queue_tail(&data->pending_q, skb);
L
Linus Torvalds 已提交
150 151 152 153

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err) {
		BT_ERR("%s bulk tx submit failed urb %p err %d", 
154 155
					data->hdev->name, urb, err);
		skb_unlink(skb, &data->pending_q);
L
Linus Torvalds 已提交
156 157
		usb_free_urb(urb);
	} else
158
		atomic_inc(&data->pending_tx);
L
Linus Torvalds 已提交
159 160 161 162

	return err;
}

163
static void bfusb_tx_wakeup(struct bfusb_data *data)
L
Linus Torvalds 已提交
164 165 166
{
	struct sk_buff *skb;

167
	BT_DBG("bfusb %p", data);
L
Linus Torvalds 已提交
168

169 170
	if (test_and_set_bit(BFUSB_TX_PROCESS, &data->state)) {
		set_bit(BFUSB_TX_WAKEUP, &data->state);
L
Linus Torvalds 已提交
171 172 173 174
		return;
	}

	do {
175
		clear_bit(BFUSB_TX_WAKEUP, &data->state);
L
Linus Torvalds 已提交
176

177 178 179 180
		while ((atomic_read(&data->pending_tx) < BFUSB_MAX_BULK_TX) &&
				(skb = skb_dequeue(&data->transmit_q))) {
			if (bfusb_send_bulk(data, skb) < 0) {
				skb_queue_head(&data->transmit_q, skb);
L
Linus Torvalds 已提交
181 182 183 184
				break;
			}
		}

185
	} while (test_bit(BFUSB_TX_WAKEUP, &data->state));
L
Linus Torvalds 已提交
186

187
	clear_bit(BFUSB_TX_PROCESS, &data->state);
L
Linus Torvalds 已提交
188 189
}

190
static void bfusb_tx_complete(struct urb *urb)
L
Linus Torvalds 已提交
191 192
{
	struct sk_buff *skb = (struct sk_buff *) urb->context;
193
	struct bfusb_data *data = (struct bfusb_data *) skb->dev;
L
Linus Torvalds 已提交
194

195
	BT_DBG("bfusb %p urb %p skb %p len %d", data, urb, skb, skb->len);
L
Linus Torvalds 已提交
196

197
	atomic_dec(&data->pending_tx);
L
Linus Torvalds 已提交
198

199
	if (!test_bit(HCI_RUNNING, &data->hdev->flags))
L
Linus Torvalds 已提交
200 201 202
		return;

	if (!urb->status)
203
		data->hdev->stat.byte_tx += skb->len;
L
Linus Torvalds 已提交
204
	else
205
		data->hdev->stat.err_tx++;
L
Linus Torvalds 已提交
206

207
	read_lock(&data->lock);
L
Linus Torvalds 已提交
208

209 210
	skb_unlink(skb, &data->pending_q);
	skb_queue_tail(&data->completed_q, skb);
L
Linus Torvalds 已提交
211

212
	bfusb_tx_wakeup(data);
L
Linus Torvalds 已提交
213

214
	read_unlock(&data->lock);
L
Linus Torvalds 已提交
215 216 217
}


218
static int bfusb_rx_submit(struct bfusb_data *data, struct urb *urb)
L
Linus Torvalds 已提交
219
{
220
	struct bfusb_data_scb *scb;
L
Linus Torvalds 已提交
221 222 223 224 225 226 227 228
	struct sk_buff *skb;
	int err, pipe, size = HCI_MAX_FRAME_SIZE + 32;

	BT_DBG("bfusb %p urb %p", bfusb, urb);

	if (!urb && !(urb = usb_alloc_urb(0, GFP_ATOMIC)))
		return -ENOMEM;

229 230
	skb = bt_skb_alloc(size, GFP_ATOMIC);
	if (!skb) {
L
Linus Torvalds 已提交
231 232 233 234
		usb_free_urb(urb);
		return -ENOMEM;
	}

235
	skb->dev = (void *) data;
L
Linus Torvalds 已提交
236

237
	scb = (struct bfusb_data_scb *) skb->cb;
L
Linus Torvalds 已提交
238 239
	scb->urb = urb;

240
	pipe = usb_rcvbulkpipe(data->udev, data->bulk_in_ep);
L
Linus Torvalds 已提交
241

242
	usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, size,
L
Linus Torvalds 已提交
243 244
			bfusb_rx_complete, skb);

245
	skb_queue_tail(&data->pending_q, skb);
L
Linus Torvalds 已提交
246 247 248 249

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err) {
		BT_ERR("%s bulk rx submit failed urb %p err %d",
250 251
					data->hdev->name, urb, err);
		skb_unlink(skb, &data->pending_q);
L
Linus Torvalds 已提交
252 253 254 255 256 257 258
		kfree_skb(skb);
		usb_free_urb(urb);
	}

	return err;
}

259
static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned char *buf, int len)
L
Linus Torvalds 已提交
260
{
261
	BT_DBG("bfusb %p hdr 0x%02x data %p len %d", data, hdr, buf, len);
L
Linus Torvalds 已提交
262 263

	if (hdr & 0x10) {
264 265 266 267
		BT_ERR("%s error in block", data->hdev->name);
		if (data->reassembly)
			kfree_skb(data->reassembly);
		data->reassembly = NULL;
L
Linus Torvalds 已提交
268 269 270 271 272 273 274 275
		return -EIO;
	}

	if (hdr & 0x04) {
		struct sk_buff *skb;
		unsigned char pkt_type;
		int pkt_len = 0;

276 277 278 279
		if (data->reassembly) {
			BT_ERR("%s unexpected start block", data->hdev->name);
			kfree_skb(data->reassembly);
			data->reassembly = NULL;
L
Linus Torvalds 已提交
280 281 282
		}

		if (len < 1) {
283
			BT_ERR("%s no packet type found", data->hdev->name);
L
Linus Torvalds 已提交
284 285 286
			return -EPROTO;
		}

287
		pkt_type = *buf++; len--;
L
Linus Torvalds 已提交
288 289 290 291

		switch (pkt_type) {
		case HCI_EVENT_PKT:
			if (len >= HCI_EVENT_HDR_SIZE) {
292
				struct hci_event_hdr *hdr = (struct hci_event_hdr *) buf;
L
Linus Torvalds 已提交
293 294
				pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;
			} else {
295
				BT_ERR("%s event block is too short", data->hdev->name);
L
Linus Torvalds 已提交
296 297 298 299 300 301
				return -EILSEQ;
			}
			break;

		case HCI_ACLDATA_PKT:
			if (len >= HCI_ACL_HDR_SIZE) {
302
				struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) buf;
L
Linus Torvalds 已提交
303 304
				pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen);
			} else {
305
				BT_ERR("%s data block is too short", data->hdev->name);
L
Linus Torvalds 已提交
306 307 308 309 310 311
				return -EILSEQ;
			}
			break;

		case HCI_SCODATA_PKT:
			if (len >= HCI_SCO_HDR_SIZE) {
312
				struct hci_sco_hdr *hdr = (struct hci_sco_hdr *) buf;
L
Linus Torvalds 已提交
313 314
				pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen;
			} else {
315
				BT_ERR("%s audio block is too short", data->hdev->name);
L
Linus Torvalds 已提交
316 317 318 319 320 321 322
				return -EILSEQ;
			}
			break;
		}

		skb = bt_skb_alloc(pkt_len, GFP_ATOMIC);
		if (!skb) {
323
			BT_ERR("%s no memory for the packet", data->hdev->name);
L
Linus Torvalds 已提交
324 325 326
			return -ENOMEM;
		}

327
		skb->dev = (void *) data->hdev;
328
		bt_cb(skb)->pkt_type = pkt_type;
L
Linus Torvalds 已提交
329

330
		data->reassembly = skb;
L
Linus Torvalds 已提交
331
	} else {
332 333
		if (!data->reassembly) {
			BT_ERR("%s unexpected continuation block", data->hdev->name);
L
Linus Torvalds 已提交
334 335 336 337 338
			return -EIO;
		}
	}

	if (len > 0)
339
		memcpy(skb_put(data->reassembly, len), buf, len);
L
Linus Torvalds 已提交
340 341

	if (hdr & 0x08) {
342 343
		hci_recv_frame(data->reassembly);
		data->reassembly = NULL;
L
Linus Torvalds 已提交
344 345 346 347 348
	}

	return 0;
}

349
static void bfusb_rx_complete(struct urb *urb)
L
Linus Torvalds 已提交
350 351
{
	struct sk_buff *skb = (struct sk_buff *) urb->context;
352
	struct bfusb_data *data = (struct bfusb_data *) skb->dev;
L
Linus Torvalds 已提交
353 354 355 356 357 358
	unsigned char *buf = urb->transfer_buffer;
	int count = urb->actual_length;
	int err, hdr, len;

	BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);

359
	read_lock(&data->lock);
L
Linus Torvalds 已提交
360

361
	if (!test_bit(HCI_RUNNING, &data->hdev->flags))
L
Linus Torvalds 已提交
362 363 364 365 366
		goto unlock;

	if (urb->status || !count)
		goto resubmit;

367
	data->hdev->stat.byte_rx += count;
L
Linus Torvalds 已提交
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385

	skb_put(skb, count);

	while (count) {
		hdr = buf[0] | (buf[1] << 8);

		if (hdr & 0x4000) {
			len = 0;
			count -= 2;
			buf   += 2;
		} else {
			len = (buf[2] == 0) ? 256 : buf[2];
			count -= 3;
			buf   += 3;
		}

		if (count < len) {
			BT_ERR("%s block extends over URB buffer ranges",
386
					data->hdev->name);
L
Linus Torvalds 已提交
387 388 389
		}

		if ((hdr & 0xe1) == 0xc1)
390
			bfusb_recv_block(data, hdr, buf, len);
L
Linus Torvalds 已提交
391 392 393 394 395

		count -= len;
		buf   += len;
	}

396
	skb_unlink(skb, &data->pending_q);
L
Linus Torvalds 已提交
397 398
	kfree_skb(skb);

399
	bfusb_rx_submit(data, urb);
L
Linus Torvalds 已提交
400

401
	read_unlock(&data->lock);
L
Linus Torvalds 已提交
402 403 404 405

	return;

resubmit:
406
	urb->dev = data->udev;
L
Linus Torvalds 已提交
407 408 409 410

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err) {
		BT_ERR("%s bulk resubmit failed urb %p err %d",
411
					data->hdev->name, urb, err);
L
Linus Torvalds 已提交
412 413 414
	}

unlock:
415
	read_unlock(&data->lock);
L
Linus Torvalds 已提交
416 417 418 419
}

static int bfusb_open(struct hci_dev *hdev)
{
420
	struct bfusb_data *data = hdev->driver_data;
L
Linus Torvalds 已提交
421 422 423
	unsigned long flags;
	int i, err;

424
	BT_DBG("hdev %p bfusb %p", hdev, data);
L
Linus Torvalds 已提交
425 426 427 428

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

429
	write_lock_irqsave(&data->lock, flags);
L
Linus Torvalds 已提交
430

431
	err = bfusb_rx_submit(data, NULL);
L
Linus Torvalds 已提交
432 433
	if (!err) {
		for (i = 1; i < BFUSB_MAX_BULK_RX; i++)
434
			bfusb_rx_submit(data, NULL);
L
Linus Torvalds 已提交
435 436 437 438
	} else {
		clear_bit(HCI_RUNNING, &hdev->flags);
	}

439
	write_unlock_irqrestore(&data->lock, flags);
L
Linus Torvalds 已提交
440 441 442 443 444 445

	return err;
}

static int bfusb_flush(struct hci_dev *hdev)
{
446
	struct bfusb_data *data = hdev->driver_data;
L
Linus Torvalds 已提交
447

448
	BT_DBG("hdev %p bfusb %p", hdev, data);
L
Linus Torvalds 已提交
449

450
	skb_queue_purge(&data->transmit_q);
L
Linus Torvalds 已提交
451 452 453 454 455 456

	return 0;
}

static int bfusb_close(struct hci_dev *hdev)
{
457
	struct bfusb_data *data = hdev->driver_data;
L
Linus Torvalds 已提交
458 459
	unsigned long flags;

460
	BT_DBG("hdev %p bfusb %p", hdev, data);
L
Linus Torvalds 已提交
461 462 463 464

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

465 466
	write_lock_irqsave(&data->lock, flags);
	write_unlock_irqrestore(&data->lock, flags);
L
Linus Torvalds 已提交
467

468
	bfusb_unlink_urbs(data);
L
Linus Torvalds 已提交
469 470 471 472 473 474 475 476
	bfusb_flush(hdev);

	return 0;
}

static int bfusb_send_frame(struct sk_buff *skb)
{
	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
477
	struct bfusb_data *data;
L
Linus Torvalds 已提交
478 479 480 481
	struct sk_buff *nskb;
	unsigned char buf[3];
	int sent = 0, size, count;

482
	BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
L
Linus Torvalds 已提交
483 484 485 486 487 488 489 490 491

	if (!hdev) {
		BT_ERR("Frame for unknown HCI device (hdev=NULL)");
		return -ENODEV;
	}

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

492
	data = hdev->driver_data;
L
Linus Torvalds 已提交
493

494
	switch (bt_cb(skb)->pkt_type) {
L
Linus Torvalds 已提交
495 496 497 498 499 500 501 502 503 504 505 506
	case HCI_COMMAND_PKT:
		hdev->stat.cmd_tx++;
		break;
	case HCI_ACLDATA_PKT:
		hdev->stat.acl_tx++;
		break;
	case HCI_SCODATA_PKT:
		hdev->stat.sco_tx++;
		break;
	};

	/* Prepend skb with frame type */
507
	memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
L
Linus Torvalds 已提交
508 509 510 511

	count = skb->len;

	/* Max HCI frame size seems to be 1511 + 1 */
512 513
	nskb = bt_skb_alloc(count + 32, GFP_ATOMIC);
	if (!nskb) {
L
Linus Torvalds 已提交
514 515 516 517
		BT_ERR("Can't allocate memory for new packet");
		return -ENOMEM;
	}

518
	nskb->dev = (void *) data;
L
Linus Torvalds 已提交
519 520 521 522 523 524 525 526 527

	while (count) {
		size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE);

		buf[0] = 0xc1 | ((sent == 0) ? 0x04 : 0) | ((count == size) ? 0x08 : 0);
		buf[1] = 0x00;
		buf[2] = (size == BFUSB_MAX_BLOCK_SIZE) ? 0 : size;

		memcpy(skb_put(nskb, 3), buf, 3);
528
		skb_copy_from_linear_data_offset(skb, sent, skb_put(nskb, size), size);
L
Linus Torvalds 已提交
529 530 531 532 533 534

		sent  += size;
		count -= size;
	}

	/* Don't send frame with multiple size of bulk max packet */
535
	if ((nskb->len % data->bulk_pkt_size) == 0) {
L
Linus Torvalds 已提交
536 537 538 539 540
		buf[0] = 0xdd;
		buf[1] = 0x00;
		memcpy(skb_put(nskb, 2), buf, 2);
	}

541
	read_lock(&data->lock);
L
Linus Torvalds 已提交
542

543 544
	skb_queue_tail(&data->transmit_q, nskb);
	bfusb_tx_wakeup(data);
L
Linus Torvalds 已提交
545

546
	read_unlock(&data->lock);
L
Linus Torvalds 已提交
547 548 549 550 551 552 553 554

	kfree_skb(skb);

	return 0;
}

static void bfusb_destruct(struct hci_dev *hdev)
{
555
	struct bfusb_data *data = hdev->driver_data;
L
Linus Torvalds 已提交
556

557
	BT_DBG("hdev %p bfusb %p", hdev, data);
L
Linus Torvalds 已提交
558

559
	kfree(data);
L
Linus Torvalds 已提交
560 561 562 563 564 565 566
}

static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
{
	return -ENOIOCTLCMD;
}

567 568
static int bfusb_load_firmware(struct bfusb_data *data,
			       const unsigned char *firmware, int count)
L
Linus Torvalds 已提交
569 570 571 572
{
	unsigned char *buf;
	int err, pipe, len, size, sent = 0;

573
	BT_DBG("bfusb %p udev %p", data, data->udev);
L
Linus Torvalds 已提交
574 575 576

	BT_INFO("BlueFRITZ! USB loading firmware");

577
	pipe = usb_sndctrlpipe(data->udev, 0);
L
Linus Torvalds 已提交
578

579
	if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
L
Linus Torvalds 已提交
580 581 582 583 584
				0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {
		BT_ERR("Can't change to loading configuration");
		return -EBUSY;
	}

585
	data->udev->toggle[0] = data->udev->toggle[1] = 0;
L
Linus Torvalds 已提交
586 587 588 589 590 591 592

	buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
	if (!buf) {
		BT_ERR("Can't allocate memory chunk for firmware");
		return -ENOMEM;
	}

593
	pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);
L
Linus Torvalds 已提交
594 595 596 597 598 599

	while (count) {
		size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3);

		memcpy(buf, firmware + sent, size);

600
		err = usb_bulk_msg(data->udev, pipe, buf, size,
L
Linus Torvalds 已提交
601 602 603 604 605 606 607 608 609 610 611
					&len, BFUSB_BLOCK_TIMEOUT);

		if (err || (len != size)) {
			BT_ERR("Error in firmware loading");
			goto error;
		}

		sent  += size;
		count -= size;
	}

612 613 614
	err = usb_bulk_msg(data->udev, pipe, NULL, 0,
					&len, BFUSB_BLOCK_TIMEOUT);
	if (err < 0) {
L
Linus Torvalds 已提交
615 616 617 618
		BT_ERR("Error in null packet request");
		goto error;
	}

619
	pipe = usb_sndctrlpipe(data->udev, 0);
L
Linus Torvalds 已提交
620

621 622 623
	err = usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
				0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);
	if (err < 0) {
L
Linus Torvalds 已提交
624 625 626 627
		BT_ERR("Can't change to running configuration");
		goto error;
	}

628
	data->udev->toggle[0] = data->udev->toggle[1] = 0;
L
Linus Torvalds 已提交
629 630 631 632 633 634 635 636 637

	BT_INFO("BlueFRITZ! USB device ready");

	kfree(buf);
	return 0;

error:
	kfree(buf);

638
	pipe = usb_sndctrlpipe(data->udev, 0);
L
Linus Torvalds 已提交
639

640
	usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
L
Linus Torvalds 已提交
641 642 643 644 645 646 647 648 649 650 651 652
				0, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);

	return err;
}

static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	const struct firmware *firmware;
	struct usb_device *udev = interface_to_usbdev(intf);
	struct usb_host_endpoint *bulk_out_ep;
	struct usb_host_endpoint *bulk_in_ep;
	struct hci_dev *hdev;
653
	struct bfusb_data *data;
L
Linus Torvalds 已提交
654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669

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

	/* Check number of endpoints */
	if (intf->cur_altsetting->desc.bNumEndpoints < 2)
		return -EIO;

	bulk_out_ep = &intf->cur_altsetting->endpoint[0];
	bulk_in_ep  = &intf->cur_altsetting->endpoint[1];

	if (!bulk_out_ep || !bulk_in_ep) {
		BT_ERR("Bulk endpoints not found");
		goto done;
	}

	/* Initialize control structure and load firmware */
670 671
	data = kzalloc(sizeof(struct bfusb_data), GFP_KERNEL);
	if (!data) {
L
Linus Torvalds 已提交
672 673 674 675
		BT_ERR("Can't allocate memory for control structure");
		goto done;
	}

676 677 678 679
	data->udev = udev;
	data->bulk_in_ep    = bulk_in_ep->desc.bEndpointAddress;
	data->bulk_out_ep   = bulk_out_ep->desc.bEndpointAddress;
	data->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize);
L
Linus Torvalds 已提交
680

681
	rwlock_init(&data->lock);
L
Linus Torvalds 已提交
682

683
	data->reassembly = NULL;
L
Linus Torvalds 已提交
684

685 686 687
	skb_queue_head_init(&data->transmit_q);
	skb_queue_head_init(&data->pending_q);
	skb_queue_head_init(&data->completed_q);
L
Linus Torvalds 已提交
688 689 690 691 692 693 694 695

	if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) {
		BT_ERR("Firmware request failed");
		goto error;
	}

	BT_DBG("firmware data %p size %d", firmware->data, firmware->size);

696
	if (bfusb_load_firmware(data, firmware->data, firmware->size) < 0) {
L
Linus Torvalds 已提交
697 698 699 700 701 702 703 704 705 706 707 708 709
		BT_ERR("Firmware loading failed");
		goto release;
	}

	release_firmware(firmware);

	/* Initialize and register HCI device */
	hdev = hci_alloc_dev();
	if (!hdev) {
		BT_ERR("Can't allocate HCI device");
		goto error;
	}

710
	data->hdev = hdev;
L
Linus Torvalds 已提交
711 712

	hdev->type = HCI_USB;
713
	hdev->driver_data = data;
L
Linus Torvalds 已提交
714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730
	SET_HCIDEV_DEV(hdev, &intf->dev);

	hdev->open     = bfusb_open;
	hdev->close    = bfusb_close;
	hdev->flush    = bfusb_flush;
	hdev->send     = bfusb_send_frame;
	hdev->destruct = bfusb_destruct;
	hdev->ioctl    = bfusb_ioctl;

	hdev->owner = THIS_MODULE;

	if (hci_register_dev(hdev) < 0) {
		BT_ERR("Can't register HCI device");
		hci_free_dev(hdev);
		goto error;
	}

731
	usb_set_intfdata(intf, data);
L
Linus Torvalds 已提交
732 733 734 735 736 737 738

	return 0;

release:
	release_firmware(firmware);

error:
739
	kfree(data);
L
Linus Torvalds 已提交
740 741 742 743 744 745 746

done:
	return -EIO;
}

static void bfusb_disconnect(struct usb_interface *intf)
{
747 748
	struct bfusb_data *data = usb_get_intfdata(intf);
	struct hci_dev *hdev = data->hdev;
L
Linus Torvalds 已提交
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

	BT_DBG("intf %p", intf);

	if (!hdev)
		return;

	usb_set_intfdata(intf, NULL);

	bfusb_close(hdev);

	if (hci_unregister_dev(hdev) < 0)
		BT_ERR("Can't unregister HCI device %s", hdev->name);

	hci_free_dev(hdev);
}

static struct usb_driver bfusb_driver = {
	.name		= "bfusb",
	.probe		= bfusb_probe,
	.disconnect	= bfusb_disconnect,
	.id_table	= bfusb_table,
};

static int __init bfusb_init(void)
{
	int err;

	BT_INFO("BlueFRITZ! USB driver ver %s", VERSION);

778 779
	err = usb_register(&bfusb_driver);
	if (err < 0)
L
Linus Torvalds 已提交
780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796
		BT_ERR("Failed to register BlueFRITZ! USB driver");

	return err;
}

static void __exit bfusb_exit(void)
{
	usb_deregister(&bfusb_driver);
}

module_init(bfusb_init);
module_exit(bfusb_exit);

MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);
MODULE_VERSION(VERSION);
MODULE_LICENSE("GPL");
797
MODULE_FIRMWARE("bfubase.frm");