Blame view

arch/um/drivers/stdio_console.c 4.93 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
  /* 
   * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
   * Licensed under the GPL
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  #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"
510c72a3c   Al Viro   um: take chan_*.h...
22
  #include "chan.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
23
24
25
  #include "irq_user.h"
  #include "mconsole_kern.h"
  #include "init.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
  
  #define MAX_TTYS (16)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28
29
30
31
32
  /* Referenced only by tty_driver below - presumably it's locked correctly
   * by the tty driver.
   */
  
  static struct tty_driver *console_driver;
074a0db8e   WANG Cong   uml: make several...
33
  static void stdio_announce(char *dev_name, int dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
35
36
37
38
  {
  	printk(KERN_INFO "Virtual console %d assigned device '%s'
  ", dev,
  	       dev_name);
  }
a52f362f8   Jeff Dike   [PATCH] uml: most...
39
  /* Almost const, except that xterm_title may be changed in an initcall */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
42
43
  static struct chan_opts opts = {
  	.announce 	= stdio_announce,
  	.xterm_title	= "Virtual Console #%d",
  	.raw		= 1,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
  };
f28169d20   Jeff Dike   [PATCH] uml: retu...
45
  static int con_config(char *str, char **error_out);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  static int con_get_config(char *dev, char *str, int size, char **error_out);
f28169d20   Jeff Dike   [PATCH] uml: retu...
47
  static int con_remove(int n, char **con_remove);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48

d5c9ffc6c   Jeff Dike   [PATCH] uml: cons...
49
50
  
  /* Const, except for .mc.list */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
52
53
  static struct line_driver driver = {
  	.name 			= "UML console",
  	.device_name 		= "tty",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
55
56
57
58
59
60
61
  	.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   Linus Torvalds   Linux-2.6.12-rc2
62
  	.mc  = {
c0961c180   Jeff Dike   [PATCH] uml: init...
63
  		.list		= LIST_HEAD_INIT(driver.mc.list),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
65
66
  		.name  		= "con",
  		.config 	= con_config,
  		.get_config 	= con_get_config,
d50084a29   Jeff Dike   [PATCH] uml: Form...
67
  		.id		= line_id,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
69
70
  		.remove 	= con_remove,
  	},
  };
d5c9ffc6c   Jeff Dike   [PATCH] uml: cons...
71
72
  /* The array is initialized by line_init, at initcall time.  The
   * elements are locked individually as needed.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
   */
d79a58093   Jeff Dike   [PATCH] uml: cons...
74
75
76
  static struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
  				     [ 1 ... MAX_TTYS - 1 ] =
  				     LINE_INIT(CONFIG_CON_CHAN, &driver) };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77

f28169d20   Jeff Dike   [PATCH] uml: retu...
78
  static int con_config(char *str, char **error_out)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
  {
f28169d20   Jeff Dike   [PATCH] uml: retu...
80
  	return line_config(vts, ARRAY_SIZE(vts), str, &opts, error_out);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
82
83
84
  }
  
  static int con_get_config(char *dev, char *str, int size, char **error_out)
  {
0834cc77a   Jeff Dike   [PATCH] uml: use ...
85
  	return line_get_config(dev, vts, ARRAY_SIZE(vts), str, size, error_out);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
  }
f28169d20   Jeff Dike   [PATCH] uml: retu...
87
  static int con_remove(int n, char **error_out)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
  {
f28169d20   Jeff Dike   [PATCH] uml: retu...
89
  	return line_remove(vts, ARRAY_SIZE(vts), n, error_out);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90
91
92
93
  }
  
  static int con_open(struct tty_struct *tty, struct file *filp)
  {
d14ad81f8   Jeff Dike   uml: handle error...
94
95
96
97
98
99
100
  	int err = line_open(vts, tty);
  	if (err)
  		printk(KERN_ERR "Failed to open console %d, err = %d
  ",
  		       tty->index, err);
  
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
  }
730760e90   Jeff Dike   [PATCH] uml: lock...
102
  /* Set in an initcall, checked in an exitcall */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
103
  static int con_init_done = 0;
5e7672ec3   Jeff Dike   [PATCH] uml: cons...
104
  static const struct tty_operations console_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
105
106
107
  	.open 	 		= con_open,
  	.close 	 		= line_close,
  	.write 	 		= line_write,
b97b77cca   Paolo 'Blaisorblade' Giarrusso   [PATCH] uml: redo...
108
  	.put_char 		= line_put_char,
d50084a29   Jeff Dike   [PATCH] uml: Form...
109
  	.write_room		= line_write_room,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
  	.chars_in_buffer 	= line_chars_in_buffer,
b97b77cca   Paolo 'Blaisorblade' Giarrusso   [PATCH] uml: redo...
111
112
  	.flush_buffer 		= line_flush_buffer,
  	.flush_chars 		= line_flush_chars,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
  	.set_termios 		= line_set_termios,
  	.ioctl 	 		= line_ioctl,
e4dcee809   Jeff Dike   [PATCH] uml: Add ...
115
116
  	.throttle 		= line_throttle,
  	.unthrottle 		= line_unthrottle,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
118
119
  };
  
  static void uml_console_write(struct console *console, const char *string,
d50084a29   Jeff Dike   [PATCH] uml: Form...
120
  			      unsigned len)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
122
  {
  	struct line *line = &vts[console->index];
b97b77cca   Paolo 'Blaisorblade' Giarrusso   [PATCH] uml: redo...
123
  	unsigned long flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124

b97b77cca   Paolo 'Blaisorblade' Giarrusso   [PATCH] uml: redo...
125
  	spin_lock_irqsave(&line->lock, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126
  	console_write_chan(&line->chan_list, string, len);
b97b77cca   Paolo 'Blaisorblade' Giarrusso   [PATCH] uml: redo...
127
  	spin_unlock_irqrestore(&line->lock, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
130
131
132
133
134
135
136
137
138
  }
  
  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   Jeff Dike   [PATCH] uml: most...
139
  	return console_open_chan(line, co);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
140
  }
d5c9ffc6c   Jeff Dike   [PATCH] uml: cons...
141
  /* No locking for register_console call - relies on single-threaded initcalls */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
143
144
145
146
  static struct console stdiocons = {
  	.name		= "tty",
  	.write		= uml_console_write,
  	.device		= uml_console_device,
  	.setup		= uml_console_setup,
b53378856   Paolo 'Blaisorblade' Giarrusso   [PATCH] um: mark ...
147
  	.flags		= CON_PRINTBUFFER|CON_ANYTIME,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
  	.index		= -1,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
  };
074a0db8e   WANG Cong   uml: make several...
150
  static int stdio_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
  {
  	char *new_title;
d5c9ffc6c   Jeff Dike   [PATCH] uml: cons...
153
154
  	console_driver = register_lines(&driver, &console_ops, vts,
  					ARRAY_SIZE(vts));
d50084a29   Jeff Dike   [PATCH] uml: Form...
155
  	if (console_driver == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
157
158
  		return -1;
  	printk(KERN_INFO "Initialized stdio console driver
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
160
161
  	new_title = add_xterm_umid(opts.xterm_title);
  	if(new_title != NULL)
  		opts.xterm_title = new_title;
57ac895a7   Davide Brini   uml: fix umid in ...
162
  	lines_init(vts, ARRAY_SIZE(vts), &opts);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163
164
  	con_init_done = 1;
  	register_console(&stdiocons);
d50084a29   Jeff Dike   [PATCH] uml: Form...
165
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166
167
168
169
170
171
172
  }
  late_initcall(stdio_init);
  
  static void console_exit(void)
  {
  	if (!con_init_done)
  		return;
0834cc77a   Jeff Dike   [PATCH] uml: use ...
173
  	close_lines(vts, ARRAY_SIZE(vts));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
175
176
177
178
  }
  __uml_exitcall(console_exit);
  
  static int console_chan_setup(char *str)
  {
f28169d20   Jeff Dike   [PATCH] uml: retu...
179
180
181
182
183
184
185
186
187
188
  	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   Linus Torvalds   Linux-2.6.12-rc2
189
190
191
  }
  __setup("con", console_chan_setup);
  __channel_help(console_chan_setup, "con");