/*
 *
 *  Digianswer Bluetooth USB driver
 *
 *  Copyright (C) 2004-2005  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  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/config.h>
#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/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

#define VERSION "0.8"

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

#define BPA10X_CMD_EP		0x00
#define BPA10X_EVT_EP		0x81
#define BPA10X_TX_EP		0x02
#define BPA10X_RX_EP		0x82

#define BPA10X_CMD_BUF_SIZE	252
#define BPA10X_EVT_BUF_SIZE	16
#define BPA10X_TX_BUF_SIZE	384
#define BPA10X_RX_BUF_SIZE	384

struct bpa10x_data {
	struct hci_dev		*hdev;
	struct usb_device	*udev;

	rwlock_t		lock;

	struct sk_buff_head	cmd_queue;
	struct urb		*cmd_urb;
	struct urb		*evt_urb;
	struct sk_buff		*evt_skb;
	unsigned int		evt_len;

	struct sk_buff_head	tx_queue;
	struct urb		*tx_urb;
	struct urb		*rx_urb;
};

#define HCI_VENDOR_HDR_SIZE	5

struct hci_vendor_hdr {
	__u8	type;
	__u16	snum;
	__u16	dlen;
} __attribute__ ((packed));

static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int count)
{
	struct hci_acl_hdr *ah;
	struct hci_sco_hdr *sh;
	struct hci_vendor_hdr *vh;
	struct sk_buff *skb;
	int len;

	while (count) {
		switch (*buf++) {
		case HCI_ACLDATA_PKT:
			ah = (struct hci_acl_hdr *) buf;
			len = HCI_ACL_HDR_SIZE + __le16_to_cpu(ah->dlen);
			skb = bt_skb_alloc(len, GFP_ATOMIC);
			if (skb) {
				memcpy(skb_put(skb, len), buf, len);
				skb->dev = (void *) data->hdev;
				skb->pkt_type = HCI_ACLDATA_PKT;
				hci_recv_frame(skb);
			}
			break;

		case HCI_SCODATA_PKT:
			sh = (struct hci_sco_hdr *) buf;
			len = HCI_SCO_HDR_SIZE + sh->dlen;
			skb = bt_skb_alloc(len, GFP_ATOMIC);
			if (skb) {
				memcpy(skb_put(skb, len), buf, len);
				skb->dev = (void *) data->hdev;
				skb->pkt_type = HCI_SCODATA_PKT;
				hci_recv_frame(skb);
			}
			break;

		case HCI_VENDOR_PKT:
			vh = (struct hci_vendor_hdr *) buf;
			len = HCI_VENDOR_HDR_SIZE + __le16_to_cpu(vh->dlen);
			skb = bt_skb_alloc(len, GFP_ATOMIC);
			if (skb) {
				memcpy(skb_put(skb, len), buf, len);
				skb->dev = (void *) data->hdev;
				skb->pkt_type = HCI_VENDOR_PKT;
				hci_recv_frame(skb);
			}
			break;

		default:
			len = count - 1;
			break;
		}

		buf   += len;
		count -= (len + 1);
	}
}

static int bpa10x_recv_event(struct bpa10x_data *data, unsigned char *buf, int size)
{
	BT_DBG("data %p buf %p size %d", data, buf, size);

	if (data->evt_skb) {
		struct sk_buff *skb = data->evt_skb;

		memcpy(skb_put(skb, size), buf, size);

		if (skb->len == data->evt_len) {
			data->evt_skb = NULL;
			data->evt_len = 0;
			hci_recv_frame(skb);
		}
	} else {
		struct sk_buff *skb;
		struct hci_event_hdr *hdr;
		unsigned char pkt_type;
		int pkt_len = 0;

		if (size < HCI_EVENT_HDR_SIZE + 1) {
			BT_ERR("%s event packet block with size %d is too short",
							data->hdev->name, size);
			return -EILSEQ;
		}

		pkt_type = *buf++;
		size--;

		if (pkt_type != HCI_EVENT_PKT) {
			BT_ERR("%s unexpected event packet start byte 0x%02x",
							data->hdev->name, pkt_type);
			return -EPROTO;
		}

		hdr = (struct hci_event_hdr *) buf;
		pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;

		skb = bt_skb_alloc(pkt_len, GFP_ATOMIC);
		if (!skb) {
			BT_ERR("%s no memory for new event packet",
							data->hdev->name);
			return -ENOMEM;
		}

		skb->dev = (void *) data->hdev;
		skb->pkt_type = pkt_type;

		memcpy(skb_put(skb, size), buf, size);

		if (pkt_len == size) {
			hci_recv_frame(skb);
		} else {
			data->evt_skb = skb;
			data->evt_len = pkt_len;
		}
	}

	return 0;
}

static void bpa10x_wakeup(struct bpa10x_data *data)
{
	struct urb *urb;
	struct sk_buff *skb;
	int err;

	BT_DBG("data %p", data);

	urb = data->cmd_urb;
	if (urb->status == -EINPROGRESS)
		skb = NULL;
	else
		skb = skb_dequeue(&data->cmd_queue);

	if (skb) {
		struct usb_ctrlrequest *cr;

		if (skb->len > BPA10X_CMD_BUF_SIZE) {
			BT_ERR("%s command packet with size %d is too big",
							data->hdev->name, skb->len);
			kfree_skb(skb);
			return;
		}

		cr = (struct usb_ctrlrequest *) urb->setup_packet;
		cr->wLength = __cpu_to_le16(skb->len);

		memcpy(urb->transfer_buffer, skb->data, skb->len);
		urb->transfer_buffer_length = skb->len;

		err = usb_submit_urb(urb, GFP_ATOMIC);
		if (err < 0 && err != -ENODEV) {
			BT_ERR("%s submit failed for command urb %p with error %d",
							data->hdev->name, urb, err);
			skb_queue_head(&data->cmd_queue, skb);
		} else
			kfree_skb(skb);
	}

	urb = data->tx_urb;
	if (urb->status == -EINPROGRESS)
		skb = NULL;
	else
		skb = skb_dequeue(&data->tx_queue);

	if (skb) {
		memcpy(urb->transfer_buffer, skb->data, skb->len);
		urb->transfer_buffer_length = skb->len;

		err = usb_submit_urb(urb, GFP_ATOMIC);
		if (err < 0 && err != -ENODEV) {
			BT_ERR("%s submit failed for command urb %p with error %d",
							data->hdev->name, urb, err);
			skb_queue_head(&data->tx_queue, skb);
		} else
			kfree_skb(skb);
	}
}

static void bpa10x_complete(struct urb *urb, struct pt_regs *regs)
{
	struct bpa10x_data *data = urb->context;
	unsigned char *buf = urb->transfer_buffer;
	int err, count = urb->actual_length;

	BT_DBG("data %p urb %p buf %p count %d", data, urb, buf, count);

	read_lock(&data->lock);

	if (!test_bit(HCI_RUNNING, &data->hdev->flags))
		goto unlock;

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

	if (usb_pipein(urb->pipe)) {
		data->hdev->stat.byte_rx += count;

		if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT)
			bpa10x_recv_event(data, buf, count);

		if (usb_pipetype(urb->pipe) == PIPE_BULK)
			bpa10x_recv_bulk(data, buf, count);
	} else {
		data->hdev->stat.byte_tx += count;

		bpa10x_wakeup(data);
	}

resubmit:
	if (usb_pipein(urb->pipe)) {
		err = usb_submit_urb(urb, GFP_ATOMIC);
		if (err < 0 && err != -ENODEV) {
			BT_ERR("%s urb %p type %d resubmit status %d",
				data->hdev->name, urb, usb_pipetype(urb->pipe), err);
		}
	}

unlock:
	read_unlock(&data->lock);
}

static inline struct urb *bpa10x_alloc_urb(struct usb_device *udev, unsigned int pipe, size_t size, int flags, void *data)
{
	struct urb *urb;
	struct usb_ctrlrequest *cr;
	unsigned char *buf;

	BT_DBG("udev %p data %p", udev, data);

	urb = usb_alloc_urb(0, flags);
	if (!urb)
		return NULL;

	buf = kmalloc(size, flags);
	if (!buf) {
		usb_free_urb(urb);
		return NULL;
	}

	switch (usb_pipetype(pipe)) {
	case PIPE_CONTROL:
		cr = kmalloc(sizeof(*cr), flags);
		if (!cr) {
			kfree(buf);
			usb_free_urb(urb);
			return NULL;
		}

		cr->bRequestType = USB_TYPE_VENDOR;
		cr->bRequest     = 0;
		cr->wIndex       = 0;
		cr->wValue       = 0;
		cr->wLength      = __cpu_to_le16(0);

		usb_fill_control_urb(urb, udev, pipe, (void *) cr, buf, 0, bpa10x_complete, data);
		break;

	case PIPE_INTERRUPT:
		usb_fill_int_urb(urb, udev, pipe, buf, size, bpa10x_complete, data, 1);
		break;

	case PIPE_BULK:
		usb_fill_bulk_urb(urb, udev, pipe, buf, size, bpa10x_complete, data);
		break;

	default:
		kfree(buf);
		usb_free_urb(urb);
		return NULL;
	}

	return urb;
}

static inline void bpa10x_free_urb(struct urb *urb)
{
	BT_DBG("urb %p", urb);

	if (!urb)
		return;

	if (urb->setup_packet)
		kfree(urb->setup_packet);

	if (urb->transfer_buffer)
		kfree(urb->transfer_buffer);

	usb_free_urb(urb);
}

static int bpa10x_open(struct hci_dev *hdev)
{
	struct bpa10x_data *data = hdev->driver_data;
	struct usb_device *udev = data->udev;
	unsigned long flags;
	int err;

	BT_DBG("hdev %p data %p", hdev, data);

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

	data->cmd_urb = bpa10x_alloc_urb(udev, usb_sndctrlpipe(udev, BPA10X_CMD_EP),
					BPA10X_CMD_BUF_SIZE, GFP_KERNEL, data);
	if (!data->cmd_urb) {
		err = -ENOMEM;
		goto done;
	}

	data->evt_urb = bpa10x_alloc_urb(udev, usb_rcvintpipe(udev, BPA10X_EVT_EP),
					BPA10X_EVT_BUF_SIZE, GFP_KERNEL, data);
	if (!data->evt_urb) {
		bpa10x_free_urb(data->cmd_urb);
		err = -ENOMEM;
		goto done;
	}

	data->rx_urb = bpa10x_alloc_urb(udev, usb_rcvbulkpipe(udev, BPA10X_RX_EP),
					BPA10X_RX_BUF_SIZE, GFP_KERNEL, data);
	if (!data->rx_urb) {
		bpa10x_free_urb(data->evt_urb);
		bpa10x_free_urb(data->cmd_urb);
		err = -ENOMEM;
		goto done;
	}

	data->tx_urb = bpa10x_alloc_urb(udev, usb_sndbulkpipe(udev, BPA10X_TX_EP),
					BPA10X_TX_BUF_SIZE, GFP_KERNEL, data);
	if (!data->rx_urb) {
		bpa10x_free_urb(data->rx_urb);
		bpa10x_free_urb(data->evt_urb);
		bpa10x_free_urb(data->cmd_urb);
		err = -ENOMEM;
		goto done;
	}

	write_lock_irqsave(&data->lock, flags);

	err = usb_submit_urb(data->evt_urb, GFP_ATOMIC);
	if (err < 0) {
		BT_ERR("%s submit failed for event urb %p with error %d",
					data->hdev->name, data->evt_urb, err);
	} else {
		err = usb_submit_urb(data->rx_urb, GFP_ATOMIC);
		if (err < 0) {
			BT_ERR("%s submit failed for rx urb %p with error %d",
					data->hdev->name, data->evt_urb, err);
			usb_kill_urb(data->evt_urb);
		}
	}

	write_unlock_irqrestore(&data->lock, flags);

done:
	if (err < 0)
		clear_bit(HCI_RUNNING, &hdev->flags);

	return err;
}

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

	BT_DBG("hdev %p data %p", hdev, data);

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

	write_lock_irqsave(&data->lock, flags);

	skb_queue_purge(&data->cmd_queue);
	usb_kill_urb(data->cmd_urb);
	usb_kill_urb(data->evt_urb);
	usb_kill_urb(data->rx_urb);
	usb_kill_urb(data->tx_urb);

	write_unlock_irqrestore(&data->lock, flags);

	bpa10x_free_urb(data->cmd_urb);
	bpa10x_free_urb(data->evt_urb);
	bpa10x_free_urb(data->rx_urb);
	bpa10x_free_urb(data->tx_urb);

	return 0;
}

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

	BT_DBG("hdev %p data %p", hdev, data);

	skb_queue_purge(&data->cmd_queue);

	return 0;
}

static int bpa10x_send_frame(struct sk_buff *skb)
{
	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
	struct bpa10x_data *data;

	BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len);

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

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

	data = hdev->driver_data;

	/* Prepend skb with frame type */
	memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);

	switch (skb->pkt_type) {
	case HCI_COMMAND_PKT:
		hdev->stat.cmd_tx++;
		skb_queue_tail(&data->cmd_queue, skb);
		break;

	case HCI_ACLDATA_PKT:
		hdev->stat.acl_tx++;
		skb_queue_tail(&data->tx_queue, skb);
		break;

	case HCI_SCODATA_PKT:
		hdev->stat.sco_tx++;
		skb_queue_tail(&data->tx_queue, skb);
		break;
	};

	read_lock(&data->lock);

	bpa10x_wakeup(data);

	read_unlock(&data->lock);

	return 0;
}

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

	BT_DBG("hdev %p data %p", hdev, data);

	kfree(data);
}

static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct hci_dev *hdev;
	struct bpa10x_data *data;
	int err;

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

	if (ignore)
		return -ENODEV;

	data = kmalloc(sizeof(*data), GFP_KERNEL);
	if (!data) {
		BT_ERR("Can't allocate data structure");
		return -ENOMEM;
	}

	memset(data, 0, sizeof(*data));

	data->udev = udev;

	rwlock_init(&data->lock);

	skb_queue_head_init(&data->cmd_queue);
	skb_queue_head_init(&data->tx_queue);

	hdev = hci_alloc_dev();
	if (!hdev) {
		BT_ERR("Can't allocate HCI device");
		kfree(data);
		return -ENOMEM;
	}

	data->hdev = hdev;

	hdev->type = HCI_USB;
	hdev->driver_data = data;
	SET_HCIDEV_DEV(hdev, &intf->dev);

	hdev->open	= bpa10x_open;
	hdev->close	= bpa10x_close;
	hdev->flush	= bpa10x_flush;
	hdev->send	= bpa10x_send_frame;
	hdev->destruct	= bpa10x_destruct;

	hdev->owner = THIS_MODULE;

	err = hci_register_dev(hdev);
	if (err < 0) {
		BT_ERR("Can't register HCI device");
		kfree(data);
		hci_free_dev(hdev);
		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);
	struct hci_dev *hdev = data->hdev;

	BT_DBG("intf %p", intf);

	if (!hdev)
		return;

	usb_set_intfdata(intf, NULL);

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

	hci_free_dev(hdev);
}

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

static int __init bpa10x_init(void)
{
	int err;

	BT_INFO("Digianswer Bluetooth USB driver ver %s", VERSION);

	err = usb_register(&bpa10x_driver);
	if (err < 0)
		BT_ERR("Failed to register USB driver");

	return err;
}

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