aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/drivers/stdio_console.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/drivers/stdio_console.c')
-rw-r--r--arch/um/drivers/stdio_console.c51
1 files changed, 28 insertions, 23 deletions
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 7a4897e27f42..7ff0b0fc37e7 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -30,8 +30,6 @@
30 30
31#define MAX_TTYS (16) 31#define MAX_TTYS (16)
32 32
33/* ----------------------------------------------------------------------------- */
34
35/* Referenced only by tty_driver below - presumably it's locked correctly 33/* Referenced only by tty_driver below - presumably it's locked correctly
36 * by the tty driver. 34 * by the tty driver.
37 */ 35 */
@@ -44,6 +42,7 @@ void stdio_announce(char *dev_name, int dev)
44 dev_name); 42 dev_name);
45} 43}
46 44
45/* Almost const, except that xterm_title may be changed in an initcall */
47static struct chan_opts opts = { 46static struct chan_opts opts = {
48 .announce = stdio_announce, 47 .announce = stdio_announce,
49 .xterm_title = "Virtual Console #%d", 48 .xterm_title = "Virtual Console #%d",
@@ -52,10 +51,12 @@ static struct chan_opts opts = {
52 .in_kernel = 1, 51 .in_kernel = 1,
53}; 52};
54 53
55static int con_config(char *str); 54static int con_config(char *str, char **error_out);
56static int con_get_config(char *dev, char *str, int size, char **error_out); 55static int con_get_config(char *dev, char *str, int size, char **error_out);
57static int con_remove(int n); 56static int con_remove(int n, char **con_remove);
57
58 58
59/* Const, except for .mc.list */
59static struct line_driver driver = { 60static struct line_driver driver = {
60 .name = "UML console", 61 .name = "UML console",
61 .device_name = "tty", 62 .device_name = "tty",
@@ -67,9 +68,8 @@ static struct line_driver driver = {
67 .read_irq_name = "console", 68 .read_irq_name = "console",
68 .write_irq = CONSOLE_WRITE_IRQ, 69 .write_irq = CONSOLE_WRITE_IRQ,
69 .write_irq_name = "console-write", 70 .write_irq_name = "console-write",
70 .symlink_from = "ttys",
71 .symlink_to = "vc",
72 .mc = { 71 .mc = {
72 .list = LIST_HEAD_INIT(driver.mc.list),
73 .name = "con", 73 .name = "con",
74 .config = con_config, 74 .config = con_config,
75 .get_config = con_get_config, 75 .get_config = con_get_config,
@@ -78,18 +78,16 @@ static struct line_driver driver = {
78 }, 78 },
79}; 79};
80 80
81static struct lines console_lines = LINES_INIT(MAX_TTYS); 81/* The array is initialized by line_init, at initcall time. The
82 82 * elements are locked individually as needed.
83/* The array is initialized by line_init, which is an initcall. The
84 * individual elements are protected by individual semaphores.
85 */ 83 */
86struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver), 84static struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
87 [ 1 ... MAX_TTYS - 1 ] = 85 [ 1 ... MAX_TTYS - 1 ] =
88 LINE_INIT(CONFIG_CON_CHAN, &driver) }; 86 LINE_INIT(CONFIG_CON_CHAN, &driver) };
89 87
90static int con_config(char *str) 88static int con_config(char *str, char **error_out)
91{ 89{
92 return line_config(vts, ARRAY_SIZE(vts), str, &opts); 90 return line_config(vts, ARRAY_SIZE(vts), str, &opts, error_out);
93} 91}
94 92
95static int con_get_config(char *dev, char *str, int size, char **error_out) 93static int con_get_config(char *dev, char *str, int size, char **error_out)
@@ -97,9 +95,9 @@ static int con_get_config(char *dev, char *str, int size, char **error_out)
97 return line_get_config(dev, vts, ARRAY_SIZE(vts), str, size, error_out); 95 return line_get_config(dev, vts, ARRAY_SIZE(vts), str, size, error_out);
98} 96}
99 97
100static int con_remove(int n) 98static int con_remove(int n, char **error_out)
101{ 99{
102 return line_remove(vts, ARRAY_SIZE(vts), n); 100 return line_remove(vts, ARRAY_SIZE(vts), n, error_out);
103} 101}
104 102
105static int con_open(struct tty_struct *tty, struct file *filp) 103static int con_open(struct tty_struct *tty, struct file *filp)
@@ -146,9 +144,10 @@ static int uml_console_setup(struct console *co, char *options)
146{ 144{
147 struct line *line = &vts[co->index]; 145 struct line *line = &vts[co->index];
148 146
149 return console_open_chan(line, co, &opts); 147 return console_open_chan(line, co);
150} 148}
151 149
150/* No locking for register_console call - relies on single-threaded initcalls */
152static struct console stdiocons = { 151static struct console stdiocons = {
153 .name = "tty", 152 .name = "tty",
154 .write = uml_console_write, 153 .write = uml_console_write,
@@ -156,16 +155,14 @@ static struct console stdiocons = {
156 .setup = uml_console_setup, 155 .setup = uml_console_setup,
157 .flags = CON_PRINTBUFFER, 156 .flags = CON_PRINTBUFFER,
158 .index = -1, 157 .index = -1,
159 .data = &vts,
160}; 158};
161 159
162int stdio_init(void) 160int stdio_init(void)
163{ 161{
164 char *new_title; 162 char *new_title;
165 163
166 console_driver = line_register_devfs(&console_lines, &driver, 164 console_driver = register_lines(&driver, &console_ops, vts,
167 &console_ops, vts, 165 ARRAY_SIZE(vts));
168 ARRAY_SIZE(vts));
169 if (console_driver == NULL) 166 if (console_driver == NULL)
170 return -1; 167 return -1;
171 printk(KERN_INFO "Initialized stdio console driver\n"); 168 printk(KERN_INFO "Initialized stdio console driver\n");
@@ -192,7 +189,15 @@ __uml_exitcall(console_exit);
192 189
193static int console_chan_setup(char *str) 190static int console_chan_setup(char *str)
194{ 191{
195 return line_setup(vts, ARRAY_SIZE(vts), str); 192 char *error;
193 int ret;
194
195 ret = line_setup(vts, ARRAY_SIZE(vts), str, &error);
196 if(ret < 0)
197 printk(KERN_ERR "Failed to set up console with "
198 "configuration string \"%s\" : %s\n", str, error);
199
200 return 1;
196} 201}
197__setup("con", console_chan_setup); 202__setup("con", console_chan_setup);
198__channel_help(console_chan_setup, "con"); 203__channel_help(console_chan_setup, "con");