/*
 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
 * Licensed under the GPL
 */

#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/string.h>
#include <linux/tty_flip.h>
#include <asm/irq.h>
#include "chan_kern.h"
#include "user_util.h"
#include "kern.h"
#include "irq_user.h"
#include "sigio.h"
#include "line.h"
#include "os.h"

#ifdef CONFIG_NOCONFIG_CHAN
static void *not_configged_init(char *str, int device,
				const struct chan_opts *opts)
{
	printk("Using a channel type which is configured out of "
	       "UML\n");
	return NULL;
}

static int not_configged_open(int input, int output, int primary, void *data,
			      char **dev_out)
{
	printk("Using a channel type which is configured out of "
	       "UML\n");
	return -ENODEV;
}

static void not_configged_close(int fd, void *data)
{
	printk("Using a channel type which is configured out of "
	       "UML\n");
}

static int not_configged_read(int fd, char *c_out, void *data)
{
	printk("Using a channel type which is configured out of "
	       "UML\n");
	return -EIO;
}

static int not_configged_write(int fd, const char *buf, int len, void *data)
{
	printk("Using a channel type which is configured out of "
	       "UML\n");
	return -EIO;
}

static int not_configged_console_write(int fd, const char *buf, int len)
{
	printk("Using a channel type which is configured out of "
	       "UML\n");
	return -EIO;
}

static int not_configged_window_size(int fd, void *data, unsigned short *rows,
				     unsigned short *cols)
{
	printk("Using a channel type which is configured out of "
	       "UML\n");
	return -ENODEV;
}

static void not_configged_free(void *data)
{
	printk("Using a channel type which is configured out of "
	       "UML\n");
}

static const struct chan_ops not_configged_ops = {
	.init		= not_configged_init,
	.open		= not_configged_open,
	.close		= not_configged_close,
	.read		= not_configged_read,
	.write		= not_configged_write,
	.console_write	= not_configged_console_write,
	.window_size	= not_configged_window_size,
	.free		= not_configged_free,
	.winch		= 0,
};
#endif /* CONFIG_NOCONFIG_CHAN */

void generic_close(int fd, void *unused)
{
	os_close_file(fd);
}

int generic_read(int fd, char *c_out, void *unused)
{
	int n;

	n = os_read_file(fd, c_out, sizeof(*c_out));

	if(n == -EAGAIN)
		return 0;
	else if(n == 0)
		return -EIO;
	return n;
}

/* XXX Trivial wrapper around os_write_file */

int generic_write(int fd, const char *buf, int n, void *unused)
{
	return os_write_file(fd, buf, n);
}

int generic_window_size(int fd, void *unused, unsigned short *rows_out,
			unsigned short *cols_out)
{
	int rows, cols;
	int ret;

	ret = os_window_size(fd, &rows, &cols);
	if(ret < 0)
		return ret;

	ret = ((*rows_out != rows) || (*cols_out != cols));

	*rows_out = rows;
	*cols_out = cols;

	return ret;
}

void generic_free(void *data)
{
	kfree(data);
}

static void tty_receive_char(struct tty_struct *tty, char ch)
{
	if(tty == NULL) return;

	if(I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
		if(ch == STOP_CHAR(tty)){
			stop_tty(tty);
			return;
		}
		else if(ch == START_CHAR(tty)){
			start_tty(tty);
			return;
		}
	}

	tty_insert_flip_char(tty, ch, TTY_NORMAL);
}

static int open_one_chan(struct chan *chan)
{
	int fd;

	if(chan->opened)
		return 0;

	if(chan->ops->open == NULL)
		fd = 0;
	else fd = (*chan->ops->open)(chan->input, chan->output, chan->primary,
				     chan->data, &chan->dev);
	if(fd < 0)
		return fd;
	chan->fd = fd;

	chan->opened = 1;
	return 0;
}

int open_chan(struct list_head *chans)
{
	struct list_head *ele;
	struct chan *chan;
	int ret, err = 0;

	list_for_each(ele, chans){
		chan = list_entry(ele, struct chan, list);
		ret = open_one_chan(chan);
		if(chan->primary)
			err = ret;
	}
	return err;
}

void chan_enable_winch(struct list_head *chans, struct tty_struct *tty)
{
	struct list_head *ele;
	struct chan *chan;

	list_for_each(ele, chans){
		chan = list_entry(ele, struct chan, list);
		if(chan->primary && chan->output && chan->ops->winch){
			register_winch(chan->fd, tty);
			return;
		}
	}
}

void enable_chan(struct line *line)
{
	struct list_head *ele;
	struct chan *chan;

	list_for_each(ele, &line->chan_list){
		chan = list_entry(ele, struct chan, list);
		if(open_one_chan(chan))
			continue;

		if(chan->enabled)
			continue;
		line_setup_irq(chan->fd, chan->input, chan->output, line,
			       chan);
		chan->enabled = 1;
	}
}

/* Items are added in IRQ context, when free_irq can't be called, and
 * removed in process context, when it can.
 * This handles interrupt sources which disappear, and which need to
 * be permanently disabled.  This is discovered in IRQ context, but
 * the freeing of the IRQ must be done later.
 */
static DEFINE_SPINLOCK(irqs_to_free_lock);
static LIST_HEAD(irqs_to_free);

void free_irqs(void)
{
	struct chan *chan;
	LIST_HEAD(list);
	struct list_head *ele;
	unsigned long flags;

	spin_lock_irqsave(&irqs_to_free_lock, flags);
	list_splice_init(&irqs_to_free, &list);
	spin_unlock_irqrestore(&irqs_to_free_lock, flags);

	list_for_each(ele, &list){
		chan = list_entry(ele, struct chan, free_list);

		if(chan->input)
			free_irq(chan->line->driver->read_irq, chan);
		if(chan->output)
			free_irq(chan->line->driver->write_irq, chan);
		chan->enabled = 0;
	}
}

static void close_one_chan(struct chan *chan, int delay_free_irq)
{
	unsigned long flags;

	if(!chan->opened)
		return;

	if(delay_free_irq){
		spin_lock_irqsave(&irqs_to_free_lock, flags);
		list_add(&chan->free_list, &irqs_to_free);
		spin_unlock_irqrestore(&irqs_to_free_lock, flags);
	}
	else {
		if(chan->input)
			free_irq(chan->line->driver->read_irq, chan);
		if(chan->output)
			free_irq(chan->line->driver->write_irq, chan);
		chan->enabled = 0;
	}
	if(chan->ops->close != NULL)
		(*chan->ops->close)(chan->fd, chan->data);

	chan->opened = 0;
	chan->fd = -1;
}

void close_chan(struct list_head *chans, int delay_free_irq)
{
	struct chan *chan;

	/* Close in reverse order as open in case more than one of them
	 * refers to the same device and they save and restore that device's
	 * state.  Then, the first one opened will have the original state,
	 * so it must be the last closed.
	 */
	list_for_each_entry_reverse(chan, chans, list) {
		close_one_chan(chan, delay_free_irq);
	}
}

void deactivate_chan(struct list_head *chans, int irq)
{
	struct list_head *ele;

	struct chan *chan;
	list_for_each(ele, chans) {
		chan = list_entry(ele, struct chan, list);

		if(chan->enabled && chan->input)
			deactivate_fd(chan->fd, irq);
	}
}

void reactivate_chan(struct list_head *chans, int irq)
{
	struct list_head *ele;
	struct chan *chan;

	list_for_each(ele, chans) {
		chan = list_entry(ele, struct chan, list);

		if(chan->enabled && chan->input)
			reactivate_fd(chan->fd, irq);
	}
}

int write_chan(struct list_head *chans, const char *buf, int len,
	       int write_irq)
{
	struct list_head *ele;
	struct chan *chan = NULL;
	int n, ret = 0;

	list_for_each(ele, chans) {
		chan = list_entry(ele, struct chan, list);
		if (!chan->output || (chan->ops->write == NULL))
			continue;
		n = chan->ops->write(chan->fd, buf, len, chan->data);
		if (chan->primary) {
			ret = n;
			if ((ret == -EAGAIN) || ((ret >= 0) && (ret < len)))
				reactivate_fd(chan->fd, write_irq);
		}
	}
	return ret;
}

int console_write_chan(struct list_head *chans, const char *buf, int len)
{
	struct list_head *ele;
	struct chan *chan;
	int n, ret = 0;

	list_for_each(ele, chans){
		chan = list_entry(ele, struct chan, list);
		if(!chan->output || (chan->ops->console_write == NULL))
			continue;
		n = chan->ops->console_write(chan->fd, buf, len);
		if(chan->primary) ret = n;
	}
	return ret;
}

int console_open_chan(struct line *line, struct console *co)
{
	int err;

	err = open_chan(&line->chan_list);
	if(err)
		return err;

	printk("Console initialized on /dev/%s%d\n", co->name, co->index);
	return 0;
}

int chan_window_size(struct list_head *chans, unsigned short *rows_out,
		      unsigned short *cols_out)
{
	struct list_head *ele;
	struct chan *chan;

	list_for_each(ele, chans){
		chan = list_entry(ele, struct chan, list);
		if(chan->primary){
			if(chan->ops->window_size == NULL)
				return 0;
			return chan->ops->window_size(chan->fd, chan->data,
						      rows_out, cols_out);
		}
	}
	return 0;
}

static void free_one_chan(struct chan *chan, int delay_free_irq)
{
	list_del(&chan->list);

	close_one_chan(chan, delay_free_irq);

	if(chan->ops->free != NULL)
		(*chan->ops->free)(chan->data);

	if(chan->primary && chan->output) ignore_sigio_fd(chan->fd);
	kfree(chan);
}

static void free_chan(struct list_head *chans, int delay_free_irq)
{
	struct list_head *ele, *next;
	struct chan *chan;

	list_for_each_safe(ele, next, chans){
		chan = list_entry(ele, struct chan, list);
		free_one_chan(chan, delay_free_irq);
	}
}

static int one_chan_config_string(struct chan *chan, char *str, int size,
				  char **error_out)
{
	int n = 0;

	if(chan == NULL){
		CONFIG_CHUNK(str, size, n, "none", 1);
		return n;
	}

	CONFIG_CHUNK(str, size, n, chan->ops->type, 0);

	if(chan->dev == NULL){
		CONFIG_CHUNK(str, size, n, "", 1);
		return n;
	}

	CONFIG_CHUNK(str, size, n, ":", 0);
	CONFIG_CHUNK(str, size, n, chan->dev, 0);

	return n;
}

static int chan_pair_config_string(struct chan *in, struct chan *out,
				   char *str, int size, char **error_out)
{
	int n;

	n = one_chan_config_string(in, str, size, error_out);
	str += n;
	size -= n;

	if(in == out){
		CONFIG_CHUNK(str, size, n, "", 1);
		return n;
	}

	CONFIG_CHUNK(str, size, n, ",", 1);
	n = one_chan_config_string(out, str, size, error_out);
	str += n;
	size -= n;
	CONFIG_CHUNK(str, size, n, "", 1);

	return n;
}

int chan_config_string(struct list_head *chans, char *str, int size,
		       char **error_out)
{
	struct list_head *ele;
	struct chan *chan, *in = NULL, *out = NULL;

	list_for_each(ele, chans){
		chan = list_entry(ele, struct chan, list);
		if(!chan->primary)
			continue;
		if(chan->input)
			in = chan;
		if(chan->output)
			out = chan;
	}

	return chan_pair_config_string(in, out, str, size, error_out);
}

struct chan_type {
	char *key;
	const struct chan_ops *ops;
};

static const struct chan_type chan_table[] = {
	{ "fd", &fd_ops },

#ifdef CONFIG_NULL_CHAN
	{ "null", &null_ops },
#else
	{ "null", &not_configged_ops },
#endif

#ifdef CONFIG_PORT_CHAN
	{ "port", &port_ops },
#else
	{ "port", &not_configged_ops },
#endif

#ifdef CONFIG_PTY_CHAN
	{ "pty", &pty_ops },
	{ "pts", &pts_ops },
#else
	{ "pty", &not_configged_ops },
	{ "pts", &not_configged_ops },
#endif

#ifdef CONFIG_TTY_CHAN
	{ "tty", &tty_ops },
#else
	{ "tty", &not_configged_ops },
#endif

#ifdef CONFIG_XTERM_CHAN
	{ "xterm", &xterm_ops },
#else
	{ "xterm", &not_configged_ops },
#endif
};

static struct chan *parse_chan(struct line *line, char *str, int device,
			       const struct chan_opts *opts, char **error_out)
{
	const struct chan_type *entry;
	const struct chan_ops *ops;
	struct chan *chan;
	void *data;
	int i;

	ops = NULL;
	data = NULL;
	for(i = 0; i < ARRAY_SIZE(chan_table); i++){
		entry = &chan_table[i];
		if(!strncmp(str, entry->key, strlen(entry->key))){
			ops = entry->ops;
			str += strlen(entry->key);
			break;
		}
	}
	if(ops == NULL){
		*error_out = "No match for configured backends";
		return NULL;
	}

	data = (*ops->init)(str, device, opts);
	if(data == NULL){
		*error_out = "Configuration failed";
		return NULL;
	}

	chan = kmalloc(sizeof(*chan), GFP_ATOMIC);
	if(chan == NULL){
		*error_out = "Memory allocation failed";
		return NULL;
	}
	*chan = ((struct chan) { .list	 	= LIST_HEAD_INIT(chan->list),
				 .free_list 	=
				 	LIST_HEAD_INIT(chan->free_list),
				 .line		= line,
				 .primary	= 1,
				 .input		= 0,
				 .output 	= 0,
				 .opened  	= 0,
				 .enabled  	= 0,
				 .fd 		= -1,
				 .ops 		= ops,
				 .data 		= data });
	return chan;
}

int parse_chan_pair(char *str, struct line *line, int device,
		    const struct chan_opts *opts, char **error_out)
{
	struct list_head *chans = &line->chan_list;
	struct chan *new, *chan;
	char *in, *out;

	if(!list_empty(chans)){
		chan = list_entry(chans->next, struct chan, list);
		free_chan(chans, 0);
		INIT_LIST_HEAD(chans);
	}

	out = strchr(str, ',');
	if(out != NULL){
		in = str;
		*out = '\0';
		out++;
		new = parse_chan(line, in, device, opts, error_out);
		if(new == NULL)
			return -1;

		new->input = 1;
		list_add(&new->list, chans);

		new = parse_chan(line, out, device, opts, error_out);
		if(new == NULL)
			return -1;

		list_add(&new->list, chans);
		new->output = 1;
	}
	else {
		new = parse_chan(line, str, device, opts, error_out);
		if(new == NULL)
			return -1;

		list_add(&new->list, chans);
		new->input = 1;
		new->output = 1;
	}
	return 0;
}

int chan_out_fd(struct list_head *chans)
{
	struct list_head *ele;
	struct chan *chan;

	list_for_each(ele, chans){
		chan = list_entry(ele, struct chan, list);
		if(chan->primary && chan->output)
			return chan->fd;
	}
	return -1;
}

void chan_interrupt(struct list_head *chans, struct delayed_work *task,
		    struct tty_struct *tty, int irq)
{
	struct list_head *ele, *next;
	struct chan *chan;
	int err;
	char c;

	list_for_each_safe(ele, next, chans){
		chan = list_entry(ele, struct chan, list);
		if(!chan->input || (chan->ops->read == NULL)) continue;
		do {
			if (tty && !tty_buffer_request_room(tty, 1)) {
				schedule_delayed_work(task, 1);
				goto out;
			}
			err = chan->ops->read(chan->fd, &c, chan->data);
			if(err > 0)
				tty_receive_char(tty, c);
		} while(err > 0);

		if(err == 0) reactivate_fd(chan->fd, irq);
		if(err == -EIO){
			if(chan->primary){
				if(tty != NULL)
					tty_hangup(tty);
				close_chan(chans, 1);
				return;
			}
			else close_one_chan(chan, 1);
		}
	}
 out:
	if(tty) tty_flip_buffer_push(tty);
}
