brintos

brintos / linux-shallow public Read only

0
0
Text · 14.9 KiB · cab9393 Raw
726 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 *4 *  AVM BlueFRITZ! USB driver5 *6 *  Copyright (C) 2003-2006  Marcel Holtmann <marcel@holtmann.org>7 */8 9#include <linux/module.h>10 11#include <linux/kernel.h>12#include <linux/init.h>13#include <linux/slab.h>14#include <linux/types.h>15#include <linux/errno.h>16#include <linux/skbuff.h>17 18#include <linux/device.h>19#include <linux/firmware.h>20 21#include <linux/usb.h>22 23#include <net/bluetooth/bluetooth.h>24#include <net/bluetooth/hci_core.h>25 26#define VERSION "1.2"27 28static struct usb_driver bfusb_driver;29 30static const struct usb_device_id bfusb_table[] = {31	/* AVM BlueFRITZ! USB */32	{ USB_DEVICE(0x057c, 0x2200) },33 34	{ }	/* Terminating entry */35};36 37MODULE_DEVICE_TABLE(usb, bfusb_table);38 39#define BFUSB_MAX_BLOCK_SIZE	25640 41#define BFUSB_BLOCK_TIMEOUT	300042 43#define BFUSB_TX_PROCESS	144#define BFUSB_TX_WAKEUP		245 46#define BFUSB_MAX_BULK_TX	247#define BFUSB_MAX_BULK_RX	248 49struct bfusb_data {50	struct hci_dev		*hdev;51 52	unsigned long		state;53 54	struct usb_device	*udev;55 56	unsigned int		bulk_in_ep;57	unsigned int		bulk_out_ep;58	unsigned int		bulk_pkt_size;59 60	rwlock_t		lock;61 62	struct sk_buff_head	transmit_q;63 64	struct sk_buff		*reassembly;65 66	atomic_t		pending_tx;67	struct sk_buff_head	pending_q;68	struct sk_buff_head	completed_q;69};70 71struct bfusb_data_scb {72	struct urb *urb;73};74 75static void bfusb_tx_complete(struct urb *urb);76static void bfusb_rx_complete(struct urb *urb);77 78static struct urb *bfusb_get_completed(struct bfusb_data *data)79{80	struct sk_buff *skb;81	struct urb *urb = NULL;82 83	BT_DBG("bfusb %p", data);84 85	skb = skb_dequeue(&data->completed_q);86	if (skb) {87		urb = ((struct bfusb_data_scb *) skb->cb)->urb;88		kfree_skb(skb);89	}90 91	return urb;92}93 94static void bfusb_unlink_urbs(struct bfusb_data *data)95{96	struct sk_buff *skb;97	struct urb *urb;98 99	BT_DBG("bfusb %p", data);100 101	while ((skb = skb_dequeue(&data->pending_q))) {102		urb = ((struct bfusb_data_scb *) skb->cb)->urb;103		usb_kill_urb(urb);104		skb_queue_tail(&data->completed_q, skb);105	}106 107	while ((urb = bfusb_get_completed(data)))108		usb_free_urb(urb);109}110 111static int bfusb_send_bulk(struct bfusb_data *data, struct sk_buff *skb)112{113	struct bfusb_data_scb *scb = (void *) skb->cb;114	struct urb *urb = bfusb_get_completed(data);115	int err, pipe;116 117	BT_DBG("bfusb %p skb %p len %d", data, skb, skb->len);118 119	if (!urb) {120		urb = usb_alloc_urb(0, GFP_ATOMIC);121		if (!urb)122			return -ENOMEM;123	}124 125	pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);126 127	usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, skb->len,128			bfusb_tx_complete, skb);129 130	scb->urb = urb;131 132	skb_queue_tail(&data->pending_q, skb);133 134	err = usb_submit_urb(urb, GFP_ATOMIC);135	if (err) {136		bt_dev_err(data->hdev, "bulk tx submit failed urb %p err %d",137			   urb, err);138		skb_unlink(skb, &data->pending_q);139		usb_free_urb(urb);140	} else141		atomic_inc(&data->pending_tx);142 143	return err;144}145 146static void bfusb_tx_wakeup(struct bfusb_data *data)147{148	struct sk_buff *skb;149 150	BT_DBG("bfusb %p", data);151 152	if (test_and_set_bit(BFUSB_TX_PROCESS, &data->state)) {153		set_bit(BFUSB_TX_WAKEUP, &data->state);154		return;155	}156 157	do {158		clear_bit(BFUSB_TX_WAKEUP, &data->state);159 160		while ((atomic_read(&data->pending_tx) < BFUSB_MAX_BULK_TX) &&161				(skb = skb_dequeue(&data->transmit_q))) {162			if (bfusb_send_bulk(data, skb) < 0) {163				skb_queue_head(&data->transmit_q, skb);164				break;165			}166		}167 168	} while (test_bit(BFUSB_TX_WAKEUP, &data->state));169 170	clear_bit(BFUSB_TX_PROCESS, &data->state);171}172 173static void bfusb_tx_complete(struct urb *urb)174{175	struct sk_buff *skb = (struct sk_buff *) urb->context;176	struct bfusb_data *data = (struct bfusb_data *) skb->dev;177 178	BT_DBG("bfusb %p urb %p skb %p len %d", data, urb, skb, skb->len);179 180	atomic_dec(&data->pending_tx);181 182	if (!test_bit(HCI_RUNNING, &data->hdev->flags))183		return;184 185	if (!urb->status)186		data->hdev->stat.byte_tx += skb->len;187	else188		data->hdev->stat.err_tx++;189 190	read_lock(&data->lock);191 192	skb_unlink(skb, &data->pending_q);193	skb_queue_tail(&data->completed_q, skb);194 195	bfusb_tx_wakeup(data);196 197	read_unlock(&data->lock);198}199 200 201static int bfusb_rx_submit(struct bfusb_data *data, struct urb *urb)202{203	struct bfusb_data_scb *scb;204	struct sk_buff *skb;205	int err, pipe, size = HCI_MAX_FRAME_SIZE + 32;206 207	BT_DBG("bfusb %p urb %p", data, urb);208 209	if (!urb) {210		urb = usb_alloc_urb(0, GFP_ATOMIC);211		if (!urb)212			return -ENOMEM;213	}214 215	skb = bt_skb_alloc(size, GFP_ATOMIC);216	if (!skb) {217		usb_free_urb(urb);218		return -ENOMEM;219	}220 221	skb->dev = (void *) data;222 223	scb = (struct bfusb_data_scb *) skb->cb;224	scb->urb = urb;225 226	pipe = usb_rcvbulkpipe(data->udev, data->bulk_in_ep);227 228	usb_fill_bulk_urb(urb, data->udev, pipe, skb->data, size,229			bfusb_rx_complete, skb);230 231	skb_queue_tail(&data->pending_q, skb);232 233	err = usb_submit_urb(urb, GFP_ATOMIC);234	if (err) {235		bt_dev_err(data->hdev, "bulk rx submit failed urb %p err %d",236			   urb, err);237		skb_unlink(skb, &data->pending_q);238		kfree_skb(skb);239		usb_free_urb(urb);240	}241 242	return err;243}244 245static inline int bfusb_recv_block(struct bfusb_data *data, int hdr, unsigned char *buf, int len)246{247	BT_DBG("bfusb %p hdr 0x%02x data %p len %d", data, hdr, buf, len);248 249	if (hdr & 0x10) {250		bt_dev_err(data->hdev, "error in block");251		kfree_skb(data->reassembly);252		data->reassembly = NULL;253		return -EIO;254	}255 256	if (hdr & 0x04) {257		struct sk_buff *skb;258		unsigned char pkt_type;259		int pkt_len = 0;260 261		if (data->reassembly) {262			bt_dev_err(data->hdev, "unexpected start block");263			kfree_skb(data->reassembly);264			data->reassembly = NULL;265		}266 267		if (len < 1) {268			bt_dev_err(data->hdev, "no packet type found");269			return -EPROTO;270		}271 272		pkt_type = *buf++; len--;273 274		switch (pkt_type) {275		case HCI_EVENT_PKT:276			if (len >= HCI_EVENT_HDR_SIZE) {277				struct hci_event_hdr *hdr = (struct hci_event_hdr *) buf;278				pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;279			} else {280				bt_dev_err(data->hdev, "event block is too short");281				return -EILSEQ;282			}283			break;284 285		case HCI_ACLDATA_PKT:286			if (len >= HCI_ACL_HDR_SIZE) {287				struct hci_acl_hdr *hdr = (struct hci_acl_hdr *) buf;288				pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen);289			} else {290				bt_dev_err(data->hdev, "data block is too short");291				return -EILSEQ;292			}293			break;294 295		case HCI_SCODATA_PKT:296			if (len >= HCI_SCO_HDR_SIZE) {297				struct hci_sco_hdr *hdr = (struct hci_sco_hdr *) buf;298				pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen;299			} else {300				bt_dev_err(data->hdev, "audio block is too short");301				return -EILSEQ;302			}303			break;304		}305 306		skb = bt_skb_alloc(pkt_len, GFP_ATOMIC);307		if (!skb) {308			bt_dev_err(data->hdev, "no memory for the packet");309			return -ENOMEM;310		}311 312		hci_skb_pkt_type(skb) = pkt_type;313 314		data->reassembly = skb;315	} else {316		if (!data->reassembly) {317			bt_dev_err(data->hdev, "unexpected continuation block");318			return -EIO;319		}320	}321 322	if (len > 0)323		skb_put_data(data->reassembly, buf, len);324 325	if (hdr & 0x08) {326		hci_recv_frame(data->hdev, data->reassembly);327		data->reassembly = NULL;328	}329 330	return 0;331}332 333static void bfusb_rx_complete(struct urb *urb)334{335	struct sk_buff *skb = (struct sk_buff *) urb->context;336	struct bfusb_data *data = (struct bfusb_data *) skb->dev;337	unsigned char *buf = urb->transfer_buffer;338	int count = urb->actual_length;339	int err, hdr, len;340 341	BT_DBG("bfusb %p urb %p skb %p len %d", data, urb, skb, skb->len);342 343	read_lock(&data->lock);344 345	if (!test_bit(HCI_RUNNING, &data->hdev->flags))346		goto unlock;347 348	if (urb->status || !count)349		goto resubmit;350 351	data->hdev->stat.byte_rx += count;352 353	skb_put(skb, count);354 355	while (count) {356		hdr = buf[0] | (buf[1] << 8);357 358		if (hdr & 0x4000) {359			len = 0;360			count -= 2;361			buf   += 2;362		} else {363			len = (buf[2] == 0) ? 256 : buf[2];364			count -= 3;365			buf   += 3;366		}367 368		if (count < len) {369			bt_dev_err(data->hdev, "block extends over URB buffer ranges");370		}371 372		if ((hdr & 0xe1) == 0xc1)373			bfusb_recv_block(data, hdr, buf, len);374 375		count -= len;376		buf   += len;377	}378 379	skb_unlink(skb, &data->pending_q);380	kfree_skb(skb);381 382	bfusb_rx_submit(data, urb);383 384	read_unlock(&data->lock);385 386	return;387 388resubmit:389	urb->dev = data->udev;390 391	err = usb_submit_urb(urb, GFP_ATOMIC);392	if (err) {393		bt_dev_err(data->hdev, "bulk resubmit failed urb %p err %d",394			   urb, err);395	}396 397unlock:398	read_unlock(&data->lock);399}400 401static int bfusb_open(struct hci_dev *hdev)402{403	struct bfusb_data *data = hci_get_drvdata(hdev);404	unsigned long flags;405	int i, err;406 407	BT_DBG("hdev %p bfusb %p", hdev, data);408 409	write_lock_irqsave(&data->lock, flags);410 411	err = bfusb_rx_submit(data, NULL);412	if (!err) {413		for (i = 1; i < BFUSB_MAX_BULK_RX; i++)414			bfusb_rx_submit(data, NULL);415	}416 417	write_unlock_irqrestore(&data->lock, flags);418 419	return err;420}421 422static int bfusb_flush(struct hci_dev *hdev)423{424	struct bfusb_data *data = hci_get_drvdata(hdev);425 426	BT_DBG("hdev %p bfusb %p", hdev, data);427 428	skb_queue_purge(&data->transmit_q);429 430	return 0;431}432 433static int bfusb_close(struct hci_dev *hdev)434{435	struct bfusb_data *data = hci_get_drvdata(hdev);436	unsigned long flags;437 438	BT_DBG("hdev %p bfusb %p", hdev, data);439 440	write_lock_irqsave(&data->lock, flags);441	write_unlock_irqrestore(&data->lock, flags);442 443	bfusb_unlink_urbs(data);444	bfusb_flush(hdev);445 446	return 0;447}448 449static int bfusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)450{451	struct bfusb_data *data = hci_get_drvdata(hdev);452	struct sk_buff *nskb;453	unsigned char buf[3];454	int sent = 0, size, count;455 456	BT_DBG("hdev %p skb %p type %d len %d", hdev, skb,457	       hci_skb_pkt_type(skb), skb->len);458 459	switch (hci_skb_pkt_type(skb)) {460	case HCI_COMMAND_PKT:461		hdev->stat.cmd_tx++;462		break;463	case HCI_ACLDATA_PKT:464		hdev->stat.acl_tx++;465		break;466	case HCI_SCODATA_PKT:467		hdev->stat.sco_tx++;468		break;469	}470 471	/* Prepend skb with frame type */472	memcpy(skb_push(skb, 1), &hci_skb_pkt_type(skb), 1);473 474	count = skb->len;475 476	/* Max HCI frame size seems to be 1511 + 1 */477	nskb = bt_skb_alloc(count + 32, GFP_KERNEL);478	if (!nskb) {479		bt_dev_err(hdev, "Can't allocate memory for new packet");480		return -ENOMEM;481	}482 483	nskb->dev = (void *) data;484 485	while (count) {486		size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE);487 488		buf[0] = 0xc1 | ((sent == 0) ? 0x04 : 0) | ((count == size) ? 0x08 : 0);489		buf[1] = 0x00;490		buf[2] = (size == BFUSB_MAX_BLOCK_SIZE) ? 0 : size;491 492		skb_put_data(nskb, buf, 3);493		skb_copy_from_linear_data_offset(skb, sent, skb_put(nskb, size), size);494 495		sent  += size;496		count -= size;497	}498 499	/* Don't send frame with multiple size of bulk max packet */500	if ((nskb->len % data->bulk_pkt_size) == 0) {501		buf[0] = 0xdd;502		buf[1] = 0x00;503		skb_put_data(nskb, buf, 2);504	}505 506	read_lock(&data->lock);507 508	skb_queue_tail(&data->transmit_q, nskb);509	bfusb_tx_wakeup(data);510 511	read_unlock(&data->lock);512 513	kfree_skb(skb);514 515	return 0;516}517 518static int bfusb_load_firmware(struct bfusb_data *data,519			       const unsigned char *firmware, int count)520{521	unsigned char *buf;522	int err, pipe, len, size, sent = 0;523 524	BT_DBG("bfusb %p udev %p", data, data->udev);525 526	BT_INFO("BlueFRITZ! USB loading firmware");527 528	buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_KERNEL);529	if (!buf) {530		BT_ERR("Can't allocate memory chunk for firmware");531		return -ENOMEM;532	}533 534	pipe = usb_sndctrlpipe(data->udev, 0);535 536	if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,537				0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {538		BT_ERR("Can't change to loading configuration");539		kfree(buf);540		return -EBUSY;541	}542 543	data->udev->toggle[0] = data->udev->toggle[1] = 0;544 545	pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);546 547	while (count) {548		size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3);549 550		memcpy(buf, firmware + sent, size);551 552		err = usb_bulk_msg(data->udev, pipe, buf, size,553					&len, BFUSB_BLOCK_TIMEOUT);554 555		if (err || (len != size)) {556			BT_ERR("Error in firmware loading");557			goto error;558		}559 560		sent  += size;561		count -= size;562	}563 564	err = usb_bulk_msg(data->udev, pipe, NULL, 0,565					&len, BFUSB_BLOCK_TIMEOUT);566	if (err < 0) {567		BT_ERR("Error in null packet request");568		goto error;569	}570 571	pipe = usb_sndctrlpipe(data->udev, 0);572 573	err = usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,574				0, 2, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);575	if (err < 0) {576		BT_ERR("Can't change to running configuration");577		goto error;578	}579 580	data->udev->toggle[0] = data->udev->toggle[1] = 0;581 582	BT_INFO("BlueFRITZ! USB device ready");583 584	kfree(buf);585	return 0;586 587error:588	kfree(buf);589 590	pipe = usb_sndctrlpipe(data->udev, 0);591 592	usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,593				0, 0, 0, NULL, 0, USB_CTRL_SET_TIMEOUT);594 595	return err;596}597 598static int bfusb_probe(struct usb_interface *intf, const struct usb_device_id *id)599{600	const struct firmware *firmware;601	struct usb_device *udev = interface_to_usbdev(intf);602	struct usb_host_endpoint *bulk_out_ep;603	struct usb_host_endpoint *bulk_in_ep;604	struct hci_dev *hdev;605	struct bfusb_data *data;606 607	BT_DBG("intf %p id %p", intf, id);608 609	/* Check number of endpoints */610	if (intf->cur_altsetting->desc.bNumEndpoints < 2)611		return -EIO;612 613	bulk_out_ep = &intf->cur_altsetting->endpoint[0];614	bulk_in_ep  = &intf->cur_altsetting->endpoint[1];615 616	if (!bulk_out_ep || !bulk_in_ep) {617		BT_ERR("Bulk endpoints not found");618		goto done;619	}620 621	/* Initialize control structure and load firmware */622	data = devm_kzalloc(&intf->dev, sizeof(struct bfusb_data), GFP_KERNEL);623	if (!data)624		return -ENOMEM;625 626	data->udev = udev;627	data->bulk_in_ep    = bulk_in_ep->desc.bEndpointAddress;628	data->bulk_out_ep   = bulk_out_ep->desc.bEndpointAddress;629	data->bulk_pkt_size = le16_to_cpu(bulk_out_ep->desc.wMaxPacketSize);630 631	if (!data->bulk_pkt_size)632		goto done;633 634	rwlock_init(&data->lock);635 636	data->reassembly = NULL;637 638	skb_queue_head_init(&data->transmit_q);639	skb_queue_head_init(&data->pending_q);640	skb_queue_head_init(&data->completed_q);641 642	if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) {643		BT_ERR("Firmware request failed");644		goto done;645	}646 647	BT_DBG("firmware data %p size %zu", firmware->data, firmware->size);648 649	if (bfusb_load_firmware(data, firmware->data, firmware->size) < 0) {650		BT_ERR("Firmware loading failed");651		goto release;652	}653 654	release_firmware(firmware);655 656	/* Initialize and register HCI device */657	hdev = hci_alloc_dev();658	if (!hdev) {659		BT_ERR("Can't allocate HCI device");660		goto done;661	}662 663	data->hdev = hdev;664 665	hdev->bus = HCI_USB;666	hci_set_drvdata(hdev, data);667	SET_HCIDEV_DEV(hdev, &intf->dev);668 669	hdev->open  = bfusb_open;670	hdev->close = bfusb_close;671	hdev->flush = bfusb_flush;672	hdev->send  = bfusb_send_frame;673 674	set_bit(HCI_QUIRK_BROKEN_LOCAL_COMMANDS, &hdev->quirks);675 676	if (hci_register_dev(hdev) < 0) {677		BT_ERR("Can't register HCI device");678		hci_free_dev(hdev);679		goto done;680	}681 682	usb_set_intfdata(intf, data);683 684	return 0;685 686release:687	release_firmware(firmware);688 689done:690	return -EIO;691}692 693static void bfusb_disconnect(struct usb_interface *intf)694{695	struct bfusb_data *data = usb_get_intfdata(intf);696	struct hci_dev *hdev = data->hdev;697 698	BT_DBG("intf %p", intf);699 700	if (!hdev)701		return;702 703	usb_set_intfdata(intf, NULL);704 705	bfusb_close(hdev);706 707	hci_unregister_dev(hdev);708	hci_free_dev(hdev);709}710 711static struct usb_driver bfusb_driver = {712	.name		= "bfusb",713	.probe		= bfusb_probe,714	.disconnect	= bfusb_disconnect,715	.id_table	= bfusb_table,716	.disable_hub_initiated_lpm = 1,717};718 719module_usb_driver(bfusb_driver);720 721MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");722MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);723MODULE_VERSION(VERSION);724MODULE_LICENSE("GPL");725MODULE_FIRMWARE("bfubase.frm");726