// SPDX-License-Identifier: GPL-2.0
/* 
 * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
 */

#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 "chan.h"
#include <irq_user.h>
#include "mconsole_kern.h"
#include <init.h>

#define MAX_TTYS (16)

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

/* Almost const, except that xterm_title may be changed in an initcall */
static struct chan_opts opts = {
	.announce 	= stdio_announce,
	.xterm_title	= "Virtual Console #%d",
	.raw		= 1,
};

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


/* Const, except for .mc.list */
static struct line_driver driver = {
	.name 			= "UML console",
	.device_name 		= "tty",
	.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",
	.mc  = {
		.list		= LIST_HEAD_INIT(driver.mc.list),
		.name  		= "con",
		.config 	= con_config,
		.get_config 	= con_get_config,
		.id		= line_id,
		.remove 	= con_remove,
	},
};

/* The array is initialized by line_init, at initcall time.  The
 * elements are locked individually as needed.
 */
static char *vt_conf[MAX_TTYS];
static char *def_conf;
static struct line vts[MAX_TTYS];

static int con_config(char *str, char **error_out)
{
	return line_config(vts, ARRAY_SIZE(vts), str, &opts, error_out);
}

static int con_get_config(char *dev, char *str, int size, char **error_out)
{
	return line_get_config(dev, vts, ARRAY_SIZE(vts), str, size, error_out);
}

static int con_remove(int n, char **error_out)
{
	return line_remove(vts, ARRAY_SIZE(vts), n, error_out);
}

/* Set in an initcall, checked in an exitcall */
static int con_init_done = 0;

static int con_install(struct tty_driver *driver, struct tty_struct *tty)
{
	return line_install(driver, tty, &vts[tty->index]);
}

static const struct tty_operations console_ops = {
	.open 	 		= line_open,
	.install		= con_install,
	.close 	 		= line_close,
	.write 	 		= line_write,
	.write_room		= line_write_room,
	.chars_in_buffer 	= line_chars_in_buffer,
	.flush_buffer 		= line_flush_buffer,
	.flush_chars 		= line_flush_chars,
	.throttle 		= line_throttle,
	.unthrottle 		= line_unthrottle,
	.hangup			= line_hangup,
};

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_out, string, len);
	spin_unlock_irqrestore(&line->lock, flags);
}

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

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

	return console_open_chan(line, co);
}

/* No locking for register_console call - relies on single-threaded initcalls */
static struct console stdiocons = {
	.name		= "tty",
	.write		= uml_console_write,
	.device		= uml_console_device,
	.setup		= uml_console_setup,
	.flags		= CON_PRINTBUFFER|CON_ANYTIME,
	.index		= -1,
};

static int stdio_init(void)
{
	char *new_title;
	int err;
	int i;

	err = register_lines(&driver, &console_ops, vts,
					ARRAY_SIZE(vts));
	if (err)
		return err;

	printk(KERN_INFO "Initialized stdio console driver\n");

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

	for (i = 0; i < MAX_TTYS; i++) {
		char *error;
		char *s = vt_conf[i];
		if (!s)
			s = def_conf;
		if (!s)
			s = i ? CONFIG_CON_CHAN : CONFIG_CON_ZERO_CHAN;
		if (setup_one_line(vts, i, s, &opts, &error))
			printk(KERN_ERR "setup_one_line failed for "
			       "device %d : %s\n", i, error);
	}

	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, ARRAY_SIZE(vts));
}
__uml_exitcall(console_exit);

static int console_chan_setup(char *str)
{
	if (!strncmp(str, "sole=", 5))	/* console= option specifies tty */
		return 0;

	line_setup(vt_conf, MAX_TTYS, &def_conf, str, "console");
	return 1;
}
__setup("con", console_chan_setup);
__channel_help(console_chan_setup, "con");
