/*
 * drivers/media/video/v4l2-int-device.c
 *
 * V4L2 internal ioctl interface.
 *
 * Copyright (C) 2007 Nokia Corporation.
 *
 * Contact: Sakari Ailus <sakari.ailus@nokia.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/sort.h>
#include <linux/string.h>

#include <media/v4l2-int-device.h>

static DEFINE_MUTEX(mutex);
static LIST_HEAD(int_list);

void v4l2_int_device_try_attach_all(void)
{
	struct v4l2_int_device *m, *s;

	list_for_each_entry(m, &int_list, head) {
		if (m->type != v4l2_int_type_master)
			continue;

		list_for_each_entry(s, &int_list, head) {
			if (s->type != v4l2_int_type_slave)
				continue;

			/* Slave is connected? */
			if (s->u.slave->master)
				continue;

			/* Slave wants to attach to master? */
			if (s->u.slave->attach_to[0] != 0
			    && strncmp(m->name, s->u.slave->attach_to,
				       V4L2NAMESIZE))
				continue;

			if (!try_module_get(m->module))
				continue;

			s->u.slave->master = m;
			if (m->u.master->attach(s)) {
				s->u.slave->master = NULL;
				module_put(m->module);
				continue;
			}
		}
	}
}
EXPORT_SYMBOL_GPL(v4l2_int_device_try_attach_all);

static int ioctl_sort_cmp(const void *a, const void *b)
{
	const struct v4l2_int_ioctl_desc *d1 = a, *d2 = b;

	if (d1->num > d2->num)
		return 1;

	if (d1->num < d2->num)
		return -1;

	return 0;
}

int v4l2_int_device_register(struct v4l2_int_device *d)
{
	if (d->type == v4l2_int_type_slave)
		sort(d->u.slave->ioctls, d->u.slave->num_ioctls,
		     sizeof(struct v4l2_int_ioctl_desc),
		     &ioctl_sort_cmp, NULL);
	mutex_lock(&mutex);
	list_add(&d->head, &int_list);
	v4l2_int_device_try_attach_all();
	mutex_unlock(&mutex);

	return 0;
}
EXPORT_SYMBOL_GPL(v4l2_int_device_register);

void v4l2_int_device_unregister(struct v4l2_int_device *d)
{
	mutex_lock(&mutex);
	list_del(&d->head);
	if (d->type == v4l2_int_type_slave
	    && d->u.slave->master != NULL) {
		d->u.slave->master->u.master->detach(d);
		module_put(d->u.slave->master->module);
		d->u.slave->master = NULL;
	}
	mutex_unlock(&mutex);
}
EXPORT_SYMBOL_GPL(v4l2_int_device_unregister);

/* Adapted from search_extable in extable.c. */
static v4l2_int_ioctl_func *find_ioctl(struct v4l2_int_slave *slave, int cmd,
				       v4l2_int_ioctl_func *no_such_ioctl)
{
	const struct v4l2_int_ioctl_desc *first = slave->ioctls;
	const struct v4l2_int_ioctl_desc *last =
		first + slave->num_ioctls - 1;

	while (first <= last) {
		const struct v4l2_int_ioctl_desc *mid;

		mid = (last - first) / 2 + first;

		if (mid->num < cmd)
			first = mid + 1;
		else if (mid->num > cmd)
			last = mid - 1;
		else
			return mid->func;
	}

	return no_such_ioctl;
}

static int no_such_ioctl_0(struct v4l2_int_device *d)
{
	return -ENOIOCTLCMD;
}

int v4l2_int_ioctl_0(struct v4l2_int_device *d, int cmd)
{
	return ((v4l2_int_ioctl_func_0 *)
		find_ioctl(d->u.slave, cmd,
			   (v4l2_int_ioctl_func *)no_such_ioctl_0))(d);
}
EXPORT_SYMBOL_GPL(v4l2_int_ioctl_0);

static int no_such_ioctl_1(struct v4l2_int_device *d, void *arg)
{
	return -ENOIOCTLCMD;
}

int v4l2_int_ioctl_1(struct v4l2_int_device *d, int cmd, void *arg)
{
	return ((v4l2_int_ioctl_func_1 *)
		find_ioctl(d->u.slave, cmd,
			   (v4l2_int_ioctl_func *)no_such_ioctl_1))(d, arg);
}
EXPORT_SYMBOL_GPL(v4l2_int_ioctl_1);

MODULE_LICENSE("GPL");
