bfusb.c 16.6 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
 *
 *
 *  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>

41
#define VERSION "1.2"
L
Linus Torvalds 已提交
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

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

64
struct bfusb_data {
L
Linus Torvalds 已提交
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
	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;
};

86
struct bfusb_data_scb {
L
Linus Torvalds 已提交
87 88 89
	struct urb *urb;
};

90 91
static void bfusb_tx_complete(struct urb *urb);
static void bfusb_rx_complete(struct urb *urb);
L
Linus Torvalds 已提交
92

93
static struct urb *bfusb_get_completed(struct bfusb_data *data)
L
Linus Torvalds 已提交
94 95 96 97
{
	struct sk_buff *skb;
	struct urb *urb = NULL;

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

100
	skb = skb_dequeue(&data->completed_q);
L
Linus Torvalds 已提交
101
	if (skb) {
102
		urb = ((struct bfusb_data_scb *) skb->cb)->urb;
L
Linus Torvalds 已提交
103 104 105 106 107 108
		kfree_skb(skb);
	}

	return urb;
}

109
static void bfusb_unlink_urbs(struct bfusb_data *data)
L
Linus Torvalds 已提交
110 111 112 113
{
	struct sk_buff *skb;
	struct urb *urb;

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

116 117
	while ((skb = skb_dequeue(&data->pending_q))) {
		urb = ((struct bfusb_data_scb *) skb->cb)->urb;
L
Linus Torvalds 已提交
118
		usb_kill_urb(urb);
119
		skb_queue_tail(&data->completed_q, skb);
L
Linus Torvalds 已提交
120 121
	}

122
	while ((urb = bfusb_get_completed(data)))
L
Linus Torvalds 已提交
123 124 125
		usb_free_urb(urb);
}

126
static int bfusb_send_bulk(struct bfusb_data *data, struct sk_buff *skb)
L
Linus Torvalds 已提交
127
{
128 129
	struct bfusb_data_scb *scb = (void *) skb->cb;
	struct urb *urb = bfusb_get_completed(data);
L
Linus Torvalds 已提交
130 131
	int err, pipe;

132
	BT_DBG("bfusb %p skb %p len %d", data, skb, skb->len);
L
Linus Torvalds 已提交
133 134 135 136

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

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

139
	usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len,
L
Linus Torvalds 已提交
140 141 142 143
			bfusb_tx_complete, skb);

	scb->urb = urb;

144
	skb_queue_tail(&data->pending_q, skb);
L
Linus Torvalds 已提交
145 146 147 148

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

	return err;
}

158
static void bfusb_tx_wakeup(struct bfusb_data *data)
L
Linus Torvalds 已提交
159 160 161
{
	struct sk_buff *skb;

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

164 165
	if (test_and_set_bit(BFUSB_TX_PROCESS, &data->state)) {
		set_bit(BFUSB_TX_WAKEUP, &data->state);
L
Linus Torvalds 已提交
166 167 168 169
		return;
	}

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

172 173 174 175
		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 已提交
176 177 178 179
				break;
			}
		}

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

182
	clear_bit(BFUSB_TX_PROCESS, &data->state);
L
Linus Torvalds 已提交
183 184
}

185
static void bfusb_tx_complete(struct urb *urb)
L
Linus Torvalds 已提交
186 187
{
	struct sk_buff *skb = (struct sk_buff *) urb->context;
188
	struct bfusb_data *data = (struct bfusb_data *) skb->dev;
L
Linus Torvalds 已提交
189

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

192
	atomic_dec(&data->pending_tx);
L
Linus Torvalds 已提交
193

194
	if (!test_bit(HCI_RUNNING, &data->hdev->flags))
L
Linus Torvalds 已提交
195 196 197
		return;

	if (!urb->status)
198
		data->hdev->stat.byte_tx += skb->len;
L
Linus Torvalds 已提交
199
	else
200
		data->hdev->stat.err_tx++;
L
Linus Torvalds 已提交
201

202
	read_lock(&data->lock);
L
Linus Torvalds 已提交
203

204 205
	skb_unlink(skb, &data->pending_q);
	skb_queue_tail(&data->completed_q, skb);
L
Linus Torvalds 已提交
206

207
	bfusb_tx_wakeup(data);
L
Linus Torvalds 已提交
208

209
	read_unlock(&data->lock);
L
Linus Torvalds 已提交
210 211 212
}


213
static int bfusb_rx_submit(struct bfusb_data *data, struct urb *urb)
L
Linus Torvalds 已提交
214
{
215
	struct bfusb_data_scb *scb;
L
Linus Torvalds 已提交
216 217 218
	struct sk_buff *skb;
	int err, pipe, size = HCI_MAX_FRAME_SIZE + 32;

219
	BT_DBG("bfusb %p urb %p", data, urb);
L
Linus Torvalds 已提交
220 221 222 223

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

224 225
	skb = bt_skb_alloc(size, GFP_ATOMIC);
	if (!skb) {
L
Linus Torvalds 已提交
226 227 228 229
		usb_free_urb(urb);
		return -ENOMEM;
	}

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

232
	scb = (struct bfusb_data_scb *) skb->cb;
L
Linus Torvalds 已提交
233 234
	scb->urb = urb;

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

237
	usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, size,
L
Linus Torvalds 已提交
238 239
			bfusb_rx_complete, skb);

240
	skb_queue_tail(&data->pending_q, skb);
L
Linus Torvalds 已提交
241 242 243 244

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

	return err;
}

254
static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned char *buf, int len)
L
Linus Torvalds 已提交
255
{
256
	BT_DBG("bfusb %p hdr 0x%02x data %p len %d", data, hdr, buf, len);
L
Linus Torvalds 已提交
257 258

	if (hdr & 0x10) {
259
		BT_ERR("%s error in block", data->hdev->name);
260
		kfree_skb(data->reassembly);
261
		data->reassembly = NULL;
L
Linus Torvalds 已提交
262 263 264 265 266 267 268 269
		return -EIO;
	}

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

270 271 272 273
		if (data->reassembly) {
			BT_ERR("%s unexpected start block", data->hdev->name);
			kfree_skb(data->reassembly);
			data->reassembly = NULL;
L
Linus Torvalds 已提交
274 275 276
		}

		if (len < 1) {
277
			BT_ERR("%s no packet type found", data->hdev->name);
L
Linus Torvalds 已提交
278 279 280
			return -EPROTO;
		}

281
		pkt_type = *buf++; len--;
L
Linus Torvalds 已提交
282 283 284 285

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

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

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

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

321
		skb->dev = (void *) data->hdev;
322
		bt_cb(skb)->pkt_type = pkt_type;
L
Linus Torvalds 已提交
323

324
		data->reassembly = skb;
L
Linus Torvalds 已提交
325
	} else {
326 327
		if (!data->reassembly) {
			BT_ERR("%s unexpected continuation block", data->hdev->name);
L
Linus Torvalds 已提交
328 329 330 331 332
			return -EIO;
		}
	}

	if (len > 0)
333
		memcpy(skb_put(data->reassembly, len), buf, len);
L
Linus Torvalds 已提交
334 335

	if (hdr & 0x08) {
336 337
		hci_recv_frame(data->reassembly);
		data->reassembly = NULL;
L
Linus Torvalds 已提交
338 339 340 341 342
	}

	return 0;
}

343
static void bfusb_rx_complete(struct urb *urb)
L
Linus Torvalds 已提交
344 345
{
	struct sk_buff *skb = (struct sk_buff *) urb->context;
346
	struct bfusb_data *data = (struct bfusb_data *) skb->dev;
L
Linus Torvalds 已提交
347 348 349 350
	unsigned char *buf = urb->transfer_buffer;
	int count = urb->actual_length;
	int err, hdr, len;

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

353
	read_lock(&data->lock);
L
Linus Torvalds 已提交
354

355
	if (!test_bit(HCI_RUNNING, &data->hdev->flags))
L
Linus Torvalds 已提交
356 357 358 359 360
		goto unlock;

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

361
	data->hdev->stat.byte_rx += count;
L
Linus Torvalds 已提交
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379

	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",
380
					data->hdev->name);
L
Linus Torvalds 已提交
381 382 383
		}

		if ((hdr & 0xe1) == 0xc1)
384
			bfusb_recv_block(data, hdr, buf, len);
L
Linus Torvalds 已提交
385 386 387 388 389

		count -= len;
		buf   += len;
	}

390
	skb_unlink(skb, &data->pending_q);
L
Linus Torvalds 已提交
391 392
	kfree_skb(skb);

393
	bfusb_rx_submit(data, urb);
L
Linus Torvalds 已提交
394

395
	read_unlock(&data->lock);
L
Linus Torvalds 已提交
396 397 398 399

	return;

resubmit:
400
	urb->dev = data->udev;
L
Linus Torvalds 已提交
401 402 403 404

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

unlock:
409
	read_unlock(&data->lock);
L
Linus Torvalds 已提交
410 411 412 413
}

static int bfusb_open(struct hci_dev *hdev)
{
414
	struct bfusb_data *data = hdev->driver_data;
L
Linus Torvalds 已提交
415 416 417
	unsigned long flags;
	int i, err;

418
	BT_DBG("hdev %p bfusb %p", hdev, data);
L
Linus Torvalds 已提交
419 420 421 422

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

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

425
	err = bfusb_rx_submit(data, NULL);
L
Linus Torvalds 已提交
426 427
	if (!err) {
		for (i = 1; i < BFUSB_MAX_BULK_RX; i++)
428
			bfusb_rx_submit(data, NULL);
L
Linus Torvalds 已提交
429 430 431 432
	} else {
		clear_bit(HCI_RUNNING, &hdev->flags);
	}

433
	write_unlock_irqrestore(&data->lock, flags);
L
Linus Torvalds 已提交
434 435 436 437 438 439

	return err;
}

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

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

444
	skb_queue_purge(&data->transmit_q);
L
Linus Torvalds 已提交
445 446 447 448 449 450

	return 0;
}

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

454
	BT_DBG("hdev %p bfusb %p", hdev, data);
L
Linus Torvalds 已提交
455 456 457 458

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

459 460
	write_lock_irqsave(&data->lock, flags);
	write_unlock_irqrestore(&data->lock, flags);
L
Linus Torvalds 已提交
461

462
	bfusb_unlink_urbs(data);
L
Linus Torvalds 已提交
463 464 465 466 467 468 469 470
	bfusb_flush(hdev);

	return 0;
}

static int bfusb_send_frame(struct sk_buff *skb)
{
	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
471
	struct bfusb_data *data;
L
Linus Torvalds 已提交
472 473 474 475
	struct sk_buff *nskb;
	unsigned char buf[3];
	int sent = 0, size, count;

476
	BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
L
Linus Torvalds 已提交
477 478 479 480 481 482 483 484 485

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

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

486
	data = hdev->driver_data;
L
Linus Torvalds 已提交
487

488
	switch (bt_cb(skb)->pkt_type) {
L
Linus Torvalds 已提交
489 490 491 492 493 494 495 496 497 498 499 500
	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 */
501
	memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
L
Linus Torvalds 已提交
502 503 504 505

	count = skb->len;

	/* Max HCI frame size seems to be 1511 + 1 */
506 507
	nskb = bt_skb_alloc(count + 32, GFP_ATOMIC);
	if (!nskb) {
L
Linus Torvalds 已提交
508 509 510 511
		BT_ERR("Can't allocate memory for new packet");
		return -ENOMEM;
	}

512
	nskb->dev = (void *) data;
L
Linus Torvalds 已提交
513 514 515 516 517 518 519 520 521

	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);
522
		skb_copy_from_linear_data_offset(skb, sent, skb_put(nskb, size), size);
L
Linus Torvalds 已提交
523 524 525 526 527 528

		sent  += size;
		count -= size;
	}

	/* Don't send frame with multiple size of bulk max packet */
529
	if ((nskb->len % data->bulk_pkt_size) == 0) {
L
Linus Torvalds 已提交
530 531 532 533 534
		buf[0] = 0xdd;
		buf[1] = 0x00;
		memcpy(skb_put(nskb, 2), buf, 2);
	}

535
	read_lock(&data->lock);
L
Linus Torvalds 已提交
536

537 538
	skb_queue_tail(&data->transmit_q, nskb);
	bfusb_tx_wakeup(data);
L
Linus Torvalds 已提交
539

540
	read_unlock(&data->lock);
L
Linus Torvalds 已提交
541 542 543 544 545 546 547 548

	kfree_skb(skb);

	return 0;
}

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

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

553
	kfree(data);
L
Linus Torvalds 已提交
554 555 556 557 558 559 560
}

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

561 562
static int bfusb_load_firmware(struct bfusb_data *data,
			       const unsigned char *firmware, int count)
L
Linus Torvalds 已提交
563 564 565 566
{
	unsigned char *buf;
	int err, pipe, len, size, sent = 0;

567
	BT_DBG("bfusb %p udev %p", data, data->udev);
L
Linus Torvalds 已提交
568 569 570

	BT_INFO("BlueFRITZ! USB loading firmware");

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

573
	if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
L
Linus Torvalds 已提交
574 575 576 577 578
				0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {
		BT_ERR("Can't change to loading configuration");
		return -EBUSY;
	}

579
	data->udev->toggle[0] = data->udev->toggle[1] = 0;
L
Linus Torvalds 已提交
580 581 582 583 584 585 586

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

587
	pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);
L
Linus Torvalds 已提交
588 589 590 591 592 593

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

		memcpy(buf, firmware + sent, size);

594
		err = usb_bulk_msg(data->udev, pipe, buf, size,
L
Linus Torvalds 已提交
595 596 597 598 599 600 601 602 603 604 605
					&len, BFUSB_BLOCK_TIMEOUT);

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

		sent  += size;
		count -= size;
	}

606 607 608
	err = usb_bulk_msg(data->udev, pipe, NULL, 0,
					&len, BFUSB_BLOCK_TIMEOUT);
	if (err < 0) {
L
Linus Torvalds 已提交
609 610 611 612
		BT_ERR("Error in null packet request");
		goto error;
	}

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

615 616 617
	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 已提交
618 619 620 621
		BT_ERR("Can't change to running configuration");
		goto error;
	}

622
	data->udev->toggle[0] = data->udev->toggle[1] = 0;
L
Linus Torvalds 已提交
623 624 625 626 627 628 629 630 631

	BT_INFO("BlueFRITZ! USB device ready");

	kfree(buf);
	return 0;

error:
	kfree(buf);

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

634
	usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
L
Linus Torvalds 已提交
635 636 637 638 639 640 641 642 643 644 645 646
				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;
647
	struct bfusb_data *data;
L
Linus Torvalds 已提交
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663

	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 */
664 665
	data = kzalloc(sizeof(struct bfusb_data), GFP_KERNEL);
	if (!data) {
L
Linus Torvalds 已提交
666 667 668 669
		BT_ERR("Can't allocate memory for control structure");
		goto done;
	}

670 671 672 673
	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 已提交
674

675
	rwlock_init(&data->lock);
L
Linus Torvalds 已提交
676

677
	data->reassembly = NULL;
L
Linus Torvalds 已提交
678

679 680 681
	skb_queue_head_init(&data->transmit_q);
	skb_queue_head_init(&data->pending_q);
	skb_queue_head_init(&data->completed_q);
L
Linus Torvalds 已提交
682 683 684 685 686 687

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

688
	BT_DBG("firmware data %p size %zu", firmware->data, firmware->size);
L
Linus Torvalds 已提交
689

690
	if (bfusb_load_firmware(data, firmware->data, firmware->size) < 0) {
L
Linus Torvalds 已提交
691 692 693 694 695 696 697 698 699 700 701 702 703
		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;
	}

704
	data->hdev = hdev;
L
Linus Torvalds 已提交
705 706

	hdev->type = HCI_USB;
707
	hdev->driver_data = data;
L
Linus Torvalds 已提交
708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724
	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;
	}

725
	usb_set_intfdata(intf, data);
L
Linus Torvalds 已提交
726 727 728 729 730 731 732

	return 0;

release:
	release_firmware(firmware);

error:
733
	kfree(data);
L
Linus Torvalds 已提交
734 735 736 737 738 739 740

done:
	return -EIO;
}

static void bfusb_disconnect(struct usb_interface *intf)
{
741 742
	struct bfusb_data *data = usb_get_intfdata(intf);
	struct hci_dev *hdev = data->hdev;
L
Linus Torvalds 已提交
743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771

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

772 773
	err = usb_register(&bfusb_driver);
	if (err < 0)
L
Linus Torvalds 已提交
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790
		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");
791
MODULE_FIRMWARE("bfubase.frm");