root/arch/um/drivers/stdio_console.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. stdio_announce
  2. con_config
  3. con_get_config
  4. con_remove
  5. con_install
  6. uml_console_write
  7. uml_console_device
  8. uml_console_setup
  9. stdio_init
  10. console_exit
  11. console_chan_setup

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* 
   3  * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
   4  */
   5 
   6 #include <linux/posix_types.h>
   7 #include <linux/tty.h>
   8 #include <linux/tty_flip.h>
   9 #include <linux/types.h>
  10 #include <linux/major.h>
  11 #include <linux/kdev_t.h>
  12 #include <linux/console.h>
  13 #include <linux/string.h>
  14 #include <linux/sched.h>
  15 #include <linux/list.h>
  16 #include <linux/init.h>
  17 #include <linux/interrupt.h>
  18 #include <linux/slab.h>
  19 #include <linux/hardirq.h>
  20 #include <asm/current.h>
  21 #include <asm/irq.h>
  22 #include "stdio_console.h"
  23 #include "chan.h"
  24 #include <irq_user.h>
  25 #include "mconsole_kern.h"
  26 #include <init.h>
  27 
  28 #define MAX_TTYS (16)
  29 
  30 static void stdio_announce(char *dev_name, int dev)
  31 {
  32         printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev,
  33                dev_name);
  34 }
  35 
  36 /* Almost const, except that xterm_title may be changed in an initcall */
  37 static struct chan_opts opts = {
  38         .announce       = stdio_announce,
  39         .xterm_title    = "Virtual Console #%d",
  40         .raw            = 1,
  41 };
  42 
  43 static int con_config(char *str, char **error_out);
  44 static int con_get_config(char *dev, char *str, int size, char **error_out);
  45 static int con_remove(int n, char **con_remove);
  46 
  47 
  48 /* Const, except for .mc.list */
  49 static struct line_driver driver = {
  50         .name                   = "UML console",
  51         .device_name            = "tty",
  52         .major                  = TTY_MAJOR,
  53         .minor_start            = 0,
  54         .type                   = TTY_DRIVER_TYPE_CONSOLE,
  55         .subtype                = SYSTEM_TYPE_CONSOLE,
  56         .read_irq               = CONSOLE_IRQ,
  57         .read_irq_name          = "console",
  58         .write_irq              = CONSOLE_WRITE_IRQ,
  59         .write_irq_name         = "console-write",
  60         .mc  = {
  61                 .list           = LIST_HEAD_INIT(driver.mc.list),
  62                 .name           = "con",
  63                 .config         = con_config,
  64                 .get_config     = con_get_config,
  65                 .id             = line_id,
  66                 .remove         = con_remove,
  67         },
  68 };
  69 
  70 /* The array is initialized by line_init, at initcall time.  The
  71  * elements are locked individually as needed.
  72  */
  73 static char *vt_conf[MAX_TTYS];
  74 static char *def_conf;
  75 static struct line vts[MAX_TTYS];
  76 
  77 static int con_config(char *str, char **error_out)
  78 {
  79         return line_config(vts, ARRAY_SIZE(vts), str, &opts, error_out);
  80 }
  81 
  82 static int con_get_config(char *dev, char *str, int size, char **error_out)
  83 {
  84         return line_get_config(dev, vts, ARRAY_SIZE(vts), str, size, error_out);
  85 }
  86 
  87 static int con_remove(int n, char **error_out)
  88 {
  89         return line_remove(vts, ARRAY_SIZE(vts), n, error_out);
  90 }
  91 
  92 /* Set in an initcall, checked in an exitcall */
  93 static int con_init_done = 0;
  94 
  95 static int con_install(struct tty_driver *driver, struct tty_struct *tty)
  96 {
  97         return line_install(driver, tty, &vts[tty->index]);
  98 }
  99 
 100 static const struct tty_operations console_ops = {
 101         .open                   = line_open,
 102         .install                = con_install,
 103         .close                  = line_close,
 104         .write                  = line_write,
 105         .put_char               = line_put_char,
 106         .write_room             = line_write_room,
 107         .chars_in_buffer        = line_chars_in_buffer,
 108         .flush_buffer           = line_flush_buffer,
 109         .flush_chars            = line_flush_chars,
 110         .set_termios            = line_set_termios,
 111         .throttle               = line_throttle,
 112         .unthrottle             = line_unthrottle,
 113         .hangup                 = line_hangup,
 114 };
 115 
 116 static void uml_console_write(struct console *console, const char *string,
 117                               unsigned len)
 118 {
 119         struct line *line = &vts[console->index];
 120         unsigned long flags;
 121 
 122         spin_lock_irqsave(&line->lock, flags);
 123         console_write_chan(line->chan_out, string, len);
 124         spin_unlock_irqrestore(&line->lock, flags);
 125 }
 126 
 127 static struct tty_driver *uml_console_device(struct console *c, int *index)
 128 {
 129         *index = c->index;
 130         return driver.driver;
 131 }
 132 
 133 static int uml_console_setup(struct console *co, char *options)
 134 {
 135         struct line *line = &vts[co->index];
 136 
 137         return console_open_chan(line, co);
 138 }
 139 
 140 /* No locking for register_console call - relies on single-threaded initcalls */
 141 static struct console stdiocons = {
 142         .name           = "tty",
 143         .write          = uml_console_write,
 144         .device         = uml_console_device,
 145         .setup          = uml_console_setup,
 146         .flags          = CON_PRINTBUFFER|CON_ANYTIME,
 147         .index          = -1,
 148 };
 149 
 150 static int stdio_init(void)
 151 {
 152         char *new_title;
 153         int err;
 154         int i;
 155 
 156         err = register_lines(&driver, &console_ops, vts,
 157                                         ARRAY_SIZE(vts));
 158         if (err)
 159                 return err;
 160 
 161         printk(KERN_INFO "Initialized stdio console driver\n");
 162 
 163         new_title = add_xterm_umid(opts.xterm_title);
 164         if(new_title != NULL)
 165                 opts.xterm_title = new_title;
 166 
 167         for (i = 0; i < MAX_TTYS; i++) {
 168                 char *error;
 169                 char *s = vt_conf[i];
 170                 if (!s)
 171                         s = def_conf;
 172                 if (!s)
 173                         s = i ? CONFIG_CON_CHAN : CONFIG_CON_ZERO_CHAN;
 174                 if (setup_one_line(vts, i, s, &opts, &error))
 175                         printk(KERN_ERR "setup_one_line failed for "
 176                                "device %d : %s\n", i, error);
 177         }
 178 
 179         con_init_done = 1;
 180         register_console(&stdiocons);
 181         return 0;
 182 }
 183 late_initcall(stdio_init);
 184 
 185 static void console_exit(void)
 186 {
 187         if (!con_init_done)
 188                 return;
 189         close_lines(vts, ARRAY_SIZE(vts));
 190 }
 191 __uml_exitcall(console_exit);
 192 
 193 static int console_chan_setup(char *str)
 194 {
 195         if (!strncmp(str, "sole=", 5))  /* console= option specifies tty */
 196                 return 0;
 197 
 198         line_setup(vt_conf, MAX_TTYS, &def_conf, str, "console");
 199         return 1;
 200 }
 201 __setup("con", console_chan_setup);
 202 __channel_help(console_chan_setup, "con");

/* [<][>][^][v][top][bottom][index][help] */