Blame view
arch/um/drivers/stdio_console.c
4.95 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 |
/* * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) * Licensed under the GPL */ |
1da177e4c Linux-2.6.12-rc2 |
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#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" |
1da177e4c Linux-2.6.12-rc2 |
24 25 26 |
#include "irq_user.h" #include "mconsole_kern.h" #include "init.h" |
1da177e4c Linux-2.6.12-rc2 |
27 28 |
#define MAX_TTYS (16) |
1da177e4c Linux-2.6.12-rc2 |
29 30 31 32 33 |
/* Referenced only by tty_driver below - presumably it's locked correctly * by the tty driver. */ static struct tty_driver *console_driver; |
074a0db8e uml: make several... |
34 |
static void stdio_announce(char *dev_name, int dev) |
1da177e4c Linux-2.6.12-rc2 |
35 36 37 38 39 |
{ printk(KERN_INFO "Virtual console %d assigned device '%s' ", dev, dev_name); } |
a52f362f8 [PATCH] uml: most... |
40 |
/* Almost const, except that xterm_title may be changed in an initcall */ |
1da177e4c Linux-2.6.12-rc2 |
41 42 43 44 |
static struct chan_opts opts = { .announce = stdio_announce, .xterm_title = "Virtual Console #%d", .raw = 1, |
1da177e4c Linux-2.6.12-rc2 |
45 |
}; |
f28169d20 [PATCH] uml: retu... |
46 |
static int con_config(char *str, char **error_out); |
1da177e4c Linux-2.6.12-rc2 |
47 |
static int con_get_config(char *dev, char *str, int size, char **error_out); |
f28169d20 [PATCH] uml: retu... |
48 |
static int con_remove(int n, char **con_remove); |
1da177e4c Linux-2.6.12-rc2 |
49 |
|
d5c9ffc6c [PATCH] uml: cons... |
50 51 |
/* Const, except for .mc.list */ |
1da177e4c Linux-2.6.12-rc2 |
52 53 54 |
static struct line_driver driver = { .name = "UML console", .device_name = "tty", |
1da177e4c Linux-2.6.12-rc2 |
55 56 57 58 59 60 61 62 |
.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", |
1da177e4c Linux-2.6.12-rc2 |
63 |
.mc = { |
c0961c180 [PATCH] uml: init... |
64 |
.list = LIST_HEAD_INIT(driver.mc.list), |
1da177e4c Linux-2.6.12-rc2 |
65 66 67 |
.name = "con", .config = con_config, .get_config = con_get_config, |
d50084a29 [PATCH] uml: Form... |
68 |
.id = line_id, |
1da177e4c Linux-2.6.12-rc2 |
69 70 71 |
.remove = con_remove, }, }; |
d5c9ffc6c [PATCH] uml: cons... |
72 73 |
/* The array is initialized by line_init, at initcall time. The * elements are locked individually as needed. |
1da177e4c Linux-2.6.12-rc2 |
74 |
*/ |
d79a58093 [PATCH] uml: cons... |
75 76 77 |
static struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver), [ 1 ... MAX_TTYS - 1 ] = LINE_INIT(CONFIG_CON_CHAN, &driver) }; |
1da177e4c Linux-2.6.12-rc2 |
78 |
|
f28169d20 [PATCH] uml: retu... |
79 |
static int con_config(char *str, char **error_out) |
1da177e4c Linux-2.6.12-rc2 |
80 |
{ |
f28169d20 [PATCH] uml: retu... |
81 |
return line_config(vts, ARRAY_SIZE(vts), str, &opts, error_out); |
1da177e4c Linux-2.6.12-rc2 |
82 83 84 85 |
} static int con_get_config(char *dev, char *str, int size, char **error_out) { |
0834cc77a [PATCH] uml: use ... |
86 |
return line_get_config(dev, vts, ARRAY_SIZE(vts), str, size, error_out); |
1da177e4c Linux-2.6.12-rc2 |
87 |
} |
f28169d20 [PATCH] uml: retu... |
88 |
static int con_remove(int n, char **error_out) |
1da177e4c Linux-2.6.12-rc2 |
89 |
{ |
f28169d20 [PATCH] uml: retu... |
90 |
return line_remove(vts, ARRAY_SIZE(vts), n, error_out); |
1da177e4c Linux-2.6.12-rc2 |
91 92 93 94 |
} static int con_open(struct tty_struct *tty, struct file *filp) { |
d14ad81f8 uml: handle error... |
95 96 97 98 99 100 101 |
int err = line_open(vts, tty); if (err) printk(KERN_ERR "Failed to open console %d, err = %d ", tty->index, err); return err; |
1da177e4c Linux-2.6.12-rc2 |
102 |
} |
730760e90 [PATCH] uml: lock... |
103 |
/* Set in an initcall, checked in an exitcall */ |
1da177e4c Linux-2.6.12-rc2 |
104 |
static int con_init_done = 0; |
5e7672ec3 [PATCH] uml: cons... |
105 |
static const struct tty_operations console_ops = { |
1da177e4c Linux-2.6.12-rc2 |
106 107 108 |
.open = con_open, .close = line_close, .write = line_write, |
b97b77cca [PATCH] uml: redo... |
109 |
.put_char = line_put_char, |
d50084a29 [PATCH] uml: Form... |
110 |
.write_room = line_write_room, |
1da177e4c Linux-2.6.12-rc2 |
111 |
.chars_in_buffer = line_chars_in_buffer, |
b97b77cca [PATCH] uml: redo... |
112 113 |
.flush_buffer = line_flush_buffer, .flush_chars = line_flush_chars, |
1da177e4c Linux-2.6.12-rc2 |
114 115 |
.set_termios = line_set_termios, .ioctl = line_ioctl, |
e4dcee809 [PATCH] uml: Add ... |
116 117 |
.throttle = line_throttle, .unthrottle = line_unthrottle, |
1da177e4c Linux-2.6.12-rc2 |
118 119 120 |
}; static void uml_console_write(struct console *console, const char *string, |
d50084a29 [PATCH] uml: Form... |
121 |
unsigned len) |
1da177e4c Linux-2.6.12-rc2 |
122 123 |
{ struct line *line = &vts[console->index]; |
b97b77cca [PATCH] uml: redo... |
124 |
unsigned long flags; |
1da177e4c Linux-2.6.12-rc2 |
125 |
|
b97b77cca [PATCH] uml: redo... |
126 |
spin_lock_irqsave(&line->lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
127 |
console_write_chan(&line->chan_list, string, len); |
b97b77cca [PATCH] uml: redo... |
128 |
spin_unlock_irqrestore(&line->lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
129 130 131 132 133 134 135 136 137 138 139 |
} 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]; |
a52f362f8 [PATCH] uml: most... |
140 |
return console_open_chan(line, co); |
1da177e4c Linux-2.6.12-rc2 |
141 |
} |
d5c9ffc6c [PATCH] uml: cons... |
142 |
/* No locking for register_console call - relies on single-threaded initcalls */ |
1da177e4c Linux-2.6.12-rc2 |
143 144 145 146 147 |
static struct console stdiocons = { .name = "tty", .write = uml_console_write, .device = uml_console_device, .setup = uml_console_setup, |
b53378856 [PATCH] um: mark ... |
148 |
.flags = CON_PRINTBUFFER|CON_ANYTIME, |
1da177e4c Linux-2.6.12-rc2 |
149 |
.index = -1, |
1da177e4c Linux-2.6.12-rc2 |
150 |
}; |
074a0db8e uml: make several... |
151 |
static int stdio_init(void) |
1da177e4c Linux-2.6.12-rc2 |
152 153 |
{ char *new_title; |
d5c9ffc6c [PATCH] uml: cons... |
154 155 |
console_driver = register_lines(&driver, &console_ops, vts, ARRAY_SIZE(vts)); |
d50084a29 [PATCH] uml: Form... |
156 |
if (console_driver == NULL) |
1da177e4c Linux-2.6.12-rc2 |
157 158 159 |
return -1; printk(KERN_INFO "Initialized stdio console driver "); |
1da177e4c Linux-2.6.12-rc2 |
160 161 162 |
new_title = add_xterm_umid(opts.xterm_title); if(new_title != NULL) opts.xterm_title = new_title; |
57ac895a7 uml: fix umid in ... |
163 |
lines_init(vts, ARRAY_SIZE(vts), &opts); |
1da177e4c Linux-2.6.12-rc2 |
164 165 |
con_init_done = 1; register_console(&stdiocons); |
d50084a29 [PATCH] uml: Form... |
166 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
167 168 169 170 171 172 173 |
} late_initcall(stdio_init); static void console_exit(void) { if (!con_init_done) return; |
0834cc77a [PATCH] uml: use ... |
174 |
close_lines(vts, ARRAY_SIZE(vts)); |
1da177e4c Linux-2.6.12-rc2 |
175 176 177 178 179 |
} __uml_exitcall(console_exit); static int console_chan_setup(char *str) { |
f28169d20 [PATCH] uml: retu... |
180 181 182 183 184 185 186 187 188 189 |
char *error; int ret; ret = line_setup(vts, ARRAY_SIZE(vts), str, &error); if(ret < 0) printk(KERN_ERR "Failed to set up console with " "configuration string \"%s\" : %s ", str, error); return 1; |
1da177e4c Linux-2.6.12-rc2 |
190 191 192 |
} __setup("con", console_chan_setup); __channel_help(console_chan_setup, "con"); |