/*
 * 	connector.c
 *
 * 2004-2005 Copyright (c) Evgeniy Polyakov <johnpol@2ka.mipt.ru>
 * All rights reserved.
 *
 * 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/kernel.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/moduleparam.h>
#include <linux/connector.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>

#include <net/sock.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>");
MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector.");

static u32 cn_idx = CN_IDX_CONNECTOR;
static u32 cn_val = CN_VAL_CONNECTOR;

module_param(cn_idx, uint, 0);
module_param(cn_val, uint, 0);
MODULE_PARM_DESC(cn_idx, "Connector's main device idx.");
MODULE_PARM_DESC(cn_val, "Connector's main device val.");

static DEFINE_MUTEX(notify_lock);
static LIST_HEAD(notify_list);

static struct cn_dev cdev;

static int cn_already_initialized;

/*
 * msg->seq and msg->ack are used to determine message genealogy.
 * When someone sends message it puts there locally unique sequence
 * and random acknowledge numbers.  Sequence number may be copied into
 * nlmsghdr->nlmsg_seq too.
 *
 * Sequence number is incremented with each message to be sent.
 *
 * If we expect reply to our message then the sequence number in
 * received message MUST be the same as in original message, and
 * acknowledge number MUST be the same + 1.
 *
 * If we receive a message and its sequence number is not equal to the
 * one we are expecting then it is a new message.
 *
 * If we receive a message and its sequence number is the same as one
 * we are expecting but it's acknowledgement number is not equal to
 * the acknowledgement number in the original message + 1, then it is
 * a new message.
 *
 */
int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
{
	struct cn_callback_entry *__cbq;
	unsigned int size;
	struct sk_buff *skb;
	struct nlmsghdr *nlh;
	struct cn_msg *data;
	struct cn_dev *dev = &cdev;
	u32 group = 0;
	int found = 0;

	if (!__group) {
		spin_lock_bh(&dev->cbdev->queue_lock);
		list_for_each_entry(__cbq, &dev->cbdev->queue_list,
				    callback_entry) {
			if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
				found = 1;
				group = __cbq->group;
				break;
			}
		}
		spin_unlock_bh(&dev->cbdev->queue_lock);

		if (!found)
			return -ENODEV;
	} else {
		group = __group;
	}

	if (!netlink_has_listeners(dev->nls, group))
		return -ESRCH;

	size = NLMSG_SPACE(sizeof(*msg) + msg->len);

	skb = alloc_skb(size, gfp_mask);
	if (!skb)
		return -ENOMEM;

	nlh = NLMSG_PUT(skb, 0, msg->seq, NLMSG_DONE, size - sizeof(*nlh));

	data = NLMSG_DATA(nlh);

	memcpy(data, msg, sizeof(*data) + msg->len);

	NETLINK_CB(skb).dst_group = group;

	return netlink_broadcast(dev->nls, skb, 0, group, gfp_mask);

nlmsg_failure:
	kfree_skb(skb);
	return -EINVAL;
}
EXPORT_SYMBOL_GPL(cn_netlink_send);

/*
 * Callback helper - queues work and setup destructor for given data.
 */
static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), void *data)
{
	struct cn_callback_entry *__cbq, *__new_cbq;
	struct cn_dev *dev = &cdev;
	int err = -ENODEV;

	spin_lock_bh(&dev->cbdev->queue_lock);
	list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) {
		if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
			if (likely(!work_pending(&__cbq->work) &&
					__cbq->data.ddata == NULL)) {
				__cbq->data.callback_priv = msg;

				__cbq->data.ddata = data;
				__cbq->data.destruct_data = destruct_data;

				if (queue_cn_work(__cbq, &__cbq->work))
					err = 0;
				else
					err = -EINVAL;
			} else {
				struct cn_callback_data *d;

				err = -ENOMEM;
				__new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
				if (__new_cbq) {
					d = &__new_cbq->data;
					d->callback_priv = msg;
					d->callback = __cbq->data.callback;
					d->ddata = data;
					d->destruct_data = destruct_data;
					d->free = __new_cbq;

					__new_cbq->pdev = __cbq->pdev;

					INIT_WORK(&__new_cbq->work,
							&cn_queue_wrapper);

					if (queue_cn_work(__new_cbq,
						    &__new_cbq->work))
						err = 0;
					else {
						kfree(__new_cbq);
						err = -EINVAL;
					}
				}
			}
			break;
		}
	}
	spin_unlock_bh(&dev->cbdev->queue_lock);

	return err;
}

/*
 * Main netlink receiving function.
 *
 * It checks skb, netlink header and msg sizes, and calls callback helper.
 */
static void cn_rx_skb(struct sk_buff *__skb)
{
	struct cn_msg *msg;
	struct nlmsghdr *nlh;
	int err;
	struct sk_buff *skb;

	skb = skb_get(__skb);

	if (skb->len >= NLMSG_SPACE(0)) {
		nlh = nlmsg_hdr(skb);

		if (nlh->nlmsg_len < sizeof(struct cn_msg) ||
		    skb->len < nlh->nlmsg_len ||
		    nlh->nlmsg_len > CONNECTOR_MAX_MSG_SIZE) {
			kfree_skb(skb);
			return;
		}

		msg = NLMSG_DATA(nlh);
		err = cn_call_callback(msg, (void (*)(void *))kfree_skb, skb);
		if (err < 0)
			kfree_skb(skb);
	}
}

/*
 * Notification routing.
 *
 * Gets id and checks if there are notification request for it's idx
 * and val.  If there are such requests notify the listeners with the
 * given notify event.
 *
 */
static void cn_notify(struct cb_id *id, u32 notify_event)
{
	struct cn_ctl_entry *ent;

	mutex_lock(&notify_lock);
	list_for_each_entry(ent, &notify_list, notify_entry) {
		int i;
		struct cn_notify_req *req;
		struct cn_ctl_msg *ctl = ent->msg;
		int idx_found, val_found;

		idx_found = val_found = 0;

		req = (struct cn_notify_req *)ctl->data;
		for (i = 0; i < ctl->idx_notify_num; ++i, ++req) {
			if (id->idx >= req->first &&
					id->idx < req->first + req->range) {
				idx_found = 1;
				break;
			}
		}

		for (i = 0; i < ctl->val_notify_num; ++i, ++req) {
			if (id->val >= req->first &&
					id->val < req->first + req->range) {
				val_found = 1;
				break;
			}
		}

		if (idx_found && val_found) {
			struct cn_msg m = { .ack = notify_event, };

			memcpy(&m.id, id, sizeof(m.id));
			cn_netlink_send(&m, ctl->group, GFP_KERNEL);
		}
	}
	mutex_unlock(&notify_lock);
}

/*
 * Callback add routing - adds callback with given ID and name.
 * If there is registered callback with the same ID it will not be added.
 *
 * May sleep.
 */
int cn_add_callback(struct cb_id *id, char *name, void (*callback)(void *))
{
	int err;
	struct cn_dev *dev = &cdev;

	if (!cn_already_initialized)
		return -EAGAIN;

	err = cn_queue_add_callback(dev->cbdev, name, id, callback);
	if (err)
		return err;

	cn_notify(id, 0);

	return 0;
}
EXPORT_SYMBOL_GPL(cn_add_callback);

/*
 * Callback remove routing - removes callback
 * with given ID.
 * If there is no registered callback with given
 * ID nothing happens.
 *
 * May sleep while waiting for reference counter to become zero.
 */
void cn_del_callback(struct cb_id *id)
{
	struct cn_dev *dev = &cdev;

	cn_queue_del_callback(dev->cbdev, id);
	cn_notify(id, 1);
}
EXPORT_SYMBOL_GPL(cn_del_callback);

/*
 * Checks two connector's control messages to be the same.
 * Returns 1 if they are the same or if the first one is corrupted.
 */
static int cn_ctl_msg_equals(struct cn_ctl_msg *m1, struct cn_ctl_msg *m2)
{
	int i;
	struct cn_notify_req *req1, *req2;

	if (m1->idx_notify_num != m2->idx_notify_num)
		return 0;

	if (m1->val_notify_num != m2->val_notify_num)
		return 0;

	if (m1->len != m2->len)
		return 0;

	if ((m1->idx_notify_num + m1->val_notify_num) * sizeof(*req1) !=
	    m1->len)
		return 1;

	req1 = (struct cn_notify_req *)m1->data;
	req2 = (struct cn_notify_req *)m2->data;

	for (i = 0; i < m1->idx_notify_num; ++i) {
		if (req1->first != req2->first || req1->range != req2->range)
			return 0;
		req1++;
		req2++;
	}

	for (i = 0; i < m1->val_notify_num; ++i) {
		if (req1->first != req2->first || req1->range != req2->range)
			return 0;
		req1++;
		req2++;
	}

	return 1;
}

/*
 * Main connector device's callback.
 *
 * Used for notification of a request's processing.
 */
static void cn_callback(void *data)
{
	struct cn_msg *msg = data;
	struct cn_ctl_msg *ctl;
	struct cn_ctl_entry *ent;
	u32 size;

	if (msg->len < sizeof(*ctl))
		return;

	ctl = (struct cn_ctl_msg *)msg->data;

	size = (sizeof(*ctl) + ((ctl->idx_notify_num +
				 ctl->val_notify_num) *
				sizeof(struct cn_notify_req)));

	if (msg->len != size)
		return;

	if (ctl->len + sizeof(*ctl) != msg->len)
		return;

	/*
	 * Remove notification.
	 */
	if (ctl->group == 0) {
		struct cn_ctl_entry *n;

		mutex_lock(&notify_lock);
		list_for_each_entry_safe(ent, n, &notify_list, notify_entry) {
			if (cn_ctl_msg_equals(ent->msg, ctl)) {
				list_del(&ent->notify_entry);
				kfree(ent);
			}
		}
		mutex_unlock(&notify_lock);

		return;
	}

	size += sizeof(*ent);

	ent = kzalloc(size, GFP_KERNEL);
	if (!ent)
		return;

	ent->msg = (struct cn_ctl_msg *)(ent + 1);

	memcpy(ent->msg, ctl, size - sizeof(*ent));

	mutex_lock(&notify_lock);
	list_add(&ent->notify_entry, &notify_list);
	mutex_unlock(&notify_lock);
}

static int cn_proc_show(struct seq_file *m, void *v)
{
	struct cn_queue_dev *dev = cdev.cbdev;
	struct cn_callback_entry *cbq;

	seq_printf(m, "Name            ID\n");

	spin_lock_bh(&dev->queue_lock);

	list_for_each_entry(cbq, &dev->queue_list, callback_entry) {
		seq_printf(m, "%-15s %u:%u\n",
			   cbq->id.name,
			   cbq->id.id.idx,
			   cbq->id.id.val);
	}

	spin_unlock_bh(&dev->queue_lock);

	return 0;
}

static int cn_proc_open(struct inode *inode, struct file *file)
{
	return single_open(file, cn_proc_show, NULL);
}

static const struct file_operations cn_file_ops = {
	.owner   = THIS_MODULE,
	.open    = cn_proc_open,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.release = single_release
};

static int __devinit cn_init(void)
{
	struct cn_dev *dev = &cdev;
	int err;

	dev->input = cn_rx_skb;
	dev->id.idx = cn_idx;
	dev->id.val = cn_val;

	dev->nls = netlink_kernel_create(&init_net, NETLINK_CONNECTOR,
					 CN_NETLINK_USERS + 0xf,
					 dev->input, NULL, THIS_MODULE);
	if (!dev->nls)
		return -EIO;

	dev->cbdev = cn_queue_alloc_dev("cqueue", dev->nls);
	if (!dev->cbdev) {
		netlink_kernel_release(dev->nls);
		return -EINVAL;
	}

	cn_already_initialized = 1;

	err = cn_add_callback(&dev->id, "connector", &cn_callback);
	if (err) {
		cn_already_initialized = 0;
		cn_queue_free_dev(dev->cbdev);
		netlink_kernel_release(dev->nls);
		return -EINVAL;
	}

	proc_net_fops_create(&init_net, "connector", S_IRUGO, &cn_file_ops);

	return 0;
}

static void __devexit cn_fini(void)
{
	struct cn_dev *dev = &cdev;

	cn_already_initialized = 0;

	proc_net_remove(&init_net, "connector");

	cn_del_callback(&dev->id);
	cn_queue_free_dev(dev->cbdev);
	netlink_kernel_release(dev->nls);
}

subsys_initcall(cn_init);
module_exit(cn_fini);
