/*
 *
 *  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;
				bt_cb(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;
				bt_cb(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;
				bt_cb(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;
		bt_cb(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, unsigned int __nocast 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;

	kfree(urb->setup_packet);
	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, bt_cb(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), &bt_cb(skb)->pkt_type, 1);

	switch (bt_cb(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");
