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

#include "linux/config.h"
#include "linux/posix_types.h"
#include "linux/tty.h"
#include "linux/tty_flip.h"
#include "linux/types.h"
#include "linux/major.h"
#include "linux/kdev_t.h"
#include "linux/console.h"
#include "linux/string.h"
#include "linux/sched.h"
#include "linux/list.h"
#include "linux/init.h"
#include "linux/interrupt.h"
#include "linux/slab.h"
#include "linux/hardirq.h"
#include "asm/current.h"
#include "asm/irq.h"
#include "stdio_console.h"
#include "line.h"
#include "chan_kern.h"
#include "user_util.h"
#include "kern_util.h"
#include "irq_user.h"
#include "mconsole_kern.h"
#include "init.h"

#define MAX_TTYS (16)

/* ----------------------------------------------------------------------------- */

/* Referenced only by tty_driver below - presumably it's locked correctly
 * by the tty driver.
 */

static struct tty_driver *console_driver;

void stdio_announce(char *dev_name, int dev)
{
	printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev,
	       dev_name);
}

static struct chan_opts opts = {
	.announce 	= stdio_announce,
	.xterm_title	= "Virtual Console #%d",
	.raw		= 1,
	.tramp_stack 	= 0,
	.in_kernel 	= 1,
};

static int con_config(char *str);
static int con_get_config(char *dev, char *str, int size, char **error_out);
static int con_remove(char *str);

static struct line_driver driver = {
	.name 			= "UML console",
	.device_name 		= "tty",
	.devfs_name 		= "vc/",
	.major 			= TTY_MAJOR,
	.minor_start 		= 0,
	.type 		 	= TTY_DRIVER_TYPE_CONSOLE,
	.subtype 	 	= SYSTEM_TYPE_CONSOLE,
	.read_irq 		= CONSOLE_IRQ,
	.read_irq_name 		= "console",
	.write_irq 		= CONSOLE_WRITE_IRQ,
	.write_irq_name 	= "console-write",
	.symlink_from 		= "ttys",
	.symlink_to 		= "vc",
	.mc  = {
		.name  		= "con",
		.config 	= con_config,
		.get_config 	= con_get_config,
		.remove 	= con_remove,
	},
};

static struct lines console_lines = LINES_INIT(MAX_TTYS);

/* The array is initialized by line_init, which is an initcall.  The 
 * individual elements are protected by individual semaphores.
 */
struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
			      [ 1 ... MAX_TTYS - 1 ] = 
			      LINE_INIT(CONFIG_CON_CHAN, &driver) };

static int con_config(char *str)
{
	return(line_config(vts, sizeof(vts)/sizeof(vts[0]), str));
}

static int con_get_config(char *dev, char *str, int size, char **error_out)
{
	return(line_get_config(dev, vts, sizeof(vts)/sizeof(vts[0]), str, 
			       size, error_out));
}

static int con_remove(char *str)
{
	return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str));
}

static int con_open(struct tty_struct *tty, struct file *filp)
{
	return line_open(vts, tty, &opts);
}

static int con_init_done = 0;

static struct tty_operations console_ops = {
	.open 	 		= con_open,
	.close 	 		= line_close,
	.write 	 		= line_write,
	.put_char 		= line_put_char,
 	.write_room		= line_write_room,
	.chars_in_buffer 	= line_chars_in_buffer,
	.flush_buffer 		= line_flush_buffer,
	.flush_chars 		= line_flush_chars,
	.set_termios 		= line_set_termios,
	.ioctl 	 		= line_ioctl,
};

static void uml_console_write(struct console *console, const char *string,
			  unsigned len)
{
	struct line *line = &vts[console->index];
	unsigned long flags;

	spin_lock_irqsave(&line->lock, flags);
	console_write_chan(&line->chan_list, string, len);
	spin_unlock_irqrestore(&line->lock, flags);
}

static struct tty_driver *uml_console_device(struct console *c, int *index)
{
	*index = c->index;
	return console_driver;
}

static int uml_console_setup(struct console *co, char *options)
{
	struct line *line = &vts[co->index];

	return console_open_chan(line,co,&opts);
}

static struct console stdiocons = {
	.name		= "tty",
	.write		= uml_console_write,
	.device		= uml_console_device,
	.setup		= uml_console_setup,
	.flags		= CON_PRINTBUFFER,
	.index		= -1,
	.data           = &vts,
};

int stdio_init(void)
{
	char *new_title;

	console_driver = line_register_devfs(&console_lines, &driver,
					     &console_ops, vts,
					     ARRAY_SIZE(vts));
	if (NULL == console_driver)
		return -1;
	printk(KERN_INFO "Initialized stdio console driver\n");

	lines_init(vts, sizeof(vts)/sizeof(vts[0]));

	new_title = add_xterm_umid(opts.xterm_title);
	if(new_title != NULL)
		opts.xterm_title = new_title;

	con_init_done = 1;
	register_console(&stdiocons);
	return(0);
}
late_initcall(stdio_init);

static void console_exit(void)
{
	if (!con_init_done)
		return;
	close_lines(vts, sizeof(vts)/sizeof(vts[0]));
}
__uml_exitcall(console_exit);

static int console_chan_setup(char *str)
{
	return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1));
}
__setup("con", console_chan_setup);
__channel_help(console_chan_setup, "con");
