aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/vt
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2010-11-04 15:50:47 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-11-05 11:16:52 -0400
commit60d4ae8d436b8be6a8aedb63440203d5395e9f53 (patch)
tree2e0798d278100518634b999dc6705e9f02027d9f /drivers/tty/vt
parent96fd7ce58ffb5c7bf376796b5525ba3ea1c9d69f (diff)
TTY: create drivers/tty/vt and move the vt code there
The vt and other related code is moved into the drivers/tty/vt directory. Acked-by: Arnd Bergmann <arnd@arndb.de> Cc: Jiri Slaby <jslaby@suse.cz> Cc: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/tty/vt')
-rw-r--r--drivers/tty/vt/Makefile34
-rw-r--r--drivers/tty/vt/consolemap.c745
-rw-r--r--drivers/tty/vt/cp437.uni291
-rw-r--r--drivers/tty/vt/defkeymap.c_shipped262
-rw-r--r--drivers/tty/vt/defkeymap.map357
-rw-r--r--drivers/tty/vt/keyboard.c1454
-rw-r--r--drivers/tty/vt/selection.c348
-rw-r--r--drivers/tty/vt/vc_screen.c644
-rw-r--r--drivers/tty/vt/vt.c4209
-rw-r--r--drivers/tty/vt/vt_ioctl.c1788
10 files changed, 10132 insertions, 0 deletions
diff --git a/drivers/tty/vt/Makefile b/drivers/tty/vt/Makefile
new file mode 100644
index 000000000000..14a51c9960df
--- /dev/null
+++ b/drivers/tty/vt/Makefile
@@ -0,0 +1,34 @@
1#
2# This file contains the font map for the default (hardware) font
3#
4FONTMAPFILE = cp437.uni
5
6obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o \
7 selection.o keyboard.o
8obj-$(CONFIG_CONSOLE_TRANSLATIONS) += consolemap.o consolemap_deftbl.o
9obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o
10
11# Files generated that shall be removed upon make clean
12clean-files := consolemap_deftbl.c defkeymap.c
13
14quiet_cmd_conmk = CONMK $@
15 cmd_conmk = scripts/conmakehash $< > $@
16
17$(obj)/consolemap_deftbl.c: $(src)/$(FONTMAPFILE)
18 $(call cmd,conmk)
19
20$(obj)/defkeymap.o: $(obj)/defkeymap.c
21
22# Uncomment if you're changing the keymap and have an appropriate
23# loadkeys version for the map. By default, we'll use the shipped
24# versions.
25# GENERATE_KEYMAP := 1
26
27ifdef GENERATE_KEYMAP
28
29$(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map
30 loadkeys --mktable $< > $@.tmp
31 sed -e 's/^static *//' $@.tmp > $@
32 rm $@.tmp
33
34endif
diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c
new file mode 100644
index 000000000000..45d3e80156d4
--- /dev/null
+++ b/drivers/tty/vt/consolemap.c
@@ -0,0 +1,745 @@
1/*
2 * consolemap.c
3 *
4 * Mapping from internal code (such as Latin-1 or Unicode or IBM PC code)
5 * to font positions.
6 *
7 * aeb, 950210
8 *
9 * Support for multiple unimaps by Jakub Jelinek <jj@ultra.linux.cz>, July 1998
10 *
11 * Fix bug in inverse translation. Stanislav Voronyi <stas@cnti.uanet.kharkov.ua>, Dec 1998
12 */
13
14#include <linux/module.h>
15#include <linux/kd.h>
16#include <linux/errno.h>
17#include <linux/mm.h>
18#include <linux/slab.h>
19#include <linux/init.h>
20#include <linux/tty.h>
21#include <asm/uaccess.h>
22#include <linux/consolemap.h>
23#include <linux/vt_kern.h>
24
25static unsigned short translations[][256] = {
26 /* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
27 {
28 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
29 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
30 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
31 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
32 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
33 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
34 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
35 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
36 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
37 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
38 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
39 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
40 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
41 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
42 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
43 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
44 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
45 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
46 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
47 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
48 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
49 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
50 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
51 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
52 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
53 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
54 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
55 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
56 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
57 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
58 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
59 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
60 },
61 /* VT100 graphics mapped to Unicode */
62 {
63 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
64 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
65 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
66 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
67 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
68 0x0028, 0x0029, 0x002a, 0x2192, 0x2190, 0x2191, 0x2193, 0x002f,
69 0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
70 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
71 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
72 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
73 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
74 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0,
75 0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
76 0x2591, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
77 0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
78 0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f,
79 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
80 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
81 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
82 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
83 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
84 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
85 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
86 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
87 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
88 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
89 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
90 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
91 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
92 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
93 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
94 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
95 },
96 /* IBM Codepage 437 mapped to Unicode */
97 {
98 0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
99 0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c,
100 0x25b6, 0x25c0, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x25ac, 0x21a8,
101 0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc,
102 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
103 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
104 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
105 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
106 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
107 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
108 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
109 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
110 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
111 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
112 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
113 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302,
114 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
115 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
116 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
117 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
118 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
119 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
120 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
121 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
122 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
123 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
124 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
125 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
126 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
127 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
128 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
129 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
130 },
131 /* User mapping -- default to codes for direct font mapping */
132 {
133 0xf000, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007,
134 0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f,
135 0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017,
136 0xf018, 0xf019, 0xf01a, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
137 0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
138 0xf028, 0xf029, 0xf02a, 0xf02b, 0xf02c, 0xf02d, 0xf02e, 0xf02f,
139 0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
140 0xf038, 0xf039, 0xf03a, 0xf03b, 0xf03c, 0xf03d, 0xf03e, 0xf03f,
141 0xf040, 0xf041, 0xf042, 0xf043, 0xf044, 0xf045, 0xf046, 0xf047,
142 0xf048, 0xf049, 0xf04a, 0xf04b, 0xf04c, 0xf04d, 0xf04e, 0xf04f,
143 0xf050, 0xf051, 0xf052, 0xf053, 0xf054, 0xf055, 0xf056, 0xf057,
144 0xf058, 0xf059, 0xf05a, 0xf05b, 0xf05c, 0xf05d, 0xf05e, 0xf05f,
145 0xf060, 0xf061, 0xf062, 0xf063, 0xf064, 0xf065, 0xf066, 0xf067,
146 0xf068, 0xf069, 0xf06a, 0xf06b, 0xf06c, 0xf06d, 0xf06e, 0xf06f,
147 0xf070, 0xf071, 0xf072, 0xf073, 0xf074, 0xf075, 0xf076, 0xf077,
148 0xf078, 0xf079, 0xf07a, 0xf07b, 0xf07c, 0xf07d, 0xf07e, 0xf07f,
149 0xf080, 0xf081, 0xf082, 0xf083, 0xf084, 0xf085, 0xf086, 0xf087,
150 0xf088, 0xf089, 0xf08a, 0xf08b, 0xf08c, 0xf08d, 0xf08e, 0xf08f,
151 0xf090, 0xf091, 0xf092, 0xf093, 0xf094, 0xf095, 0xf096, 0xf097,
152 0xf098, 0xf099, 0xf09a, 0xf09b, 0xf09c, 0xf09d, 0xf09e, 0xf09f,
153 0xf0a0, 0xf0a1, 0xf0a2, 0xf0a3, 0xf0a4, 0xf0a5, 0xf0a6, 0xf0a7,
154 0xf0a8, 0xf0a9, 0xf0aa, 0xf0ab, 0xf0ac, 0xf0ad, 0xf0ae, 0xf0af,
155 0xf0b0, 0xf0b1, 0xf0b2, 0xf0b3, 0xf0b4, 0xf0b5, 0xf0b6, 0xf0b7,
156 0xf0b8, 0xf0b9, 0xf0ba, 0xf0bb, 0xf0bc, 0xf0bd, 0xf0be, 0xf0bf,
157 0xf0c0, 0xf0c1, 0xf0c2, 0xf0c3, 0xf0c4, 0xf0c5, 0xf0c6, 0xf0c7,
158 0xf0c8, 0xf0c9, 0xf0ca, 0xf0cb, 0xf0cc, 0xf0cd, 0xf0ce, 0xf0cf,
159 0xf0d0, 0xf0d1, 0xf0d2, 0xf0d3, 0xf0d4, 0xf0d5, 0xf0d6, 0xf0d7,
160 0xf0d8, 0xf0d9, 0xf0da, 0xf0db, 0xf0dc, 0xf0dd, 0xf0de, 0xf0df,
161 0xf0e0, 0xf0e1, 0xf0e2, 0xf0e3, 0xf0e4, 0xf0e5, 0xf0e6, 0xf0e7,
162 0xf0e8, 0xf0e9, 0xf0ea, 0xf0eb, 0xf0ec, 0xf0ed, 0xf0ee, 0xf0ef,
163 0xf0f0, 0xf0f1, 0xf0f2, 0xf0f3, 0xf0f4, 0xf0f5, 0xf0f6, 0xf0f7,
164 0xf0f8, 0xf0f9, 0xf0fa, 0xf0fb, 0xf0fc, 0xf0fd, 0xf0fe, 0xf0ff
165 }
166};
167
168/* The standard kernel character-to-font mappings are not invertible
169 -- this is just a best effort. */
170
171#define MAX_GLYPH 512 /* Max possible glyph value */
172
173static int inv_translate[MAX_NR_CONSOLES];
174
175struct uni_pagedir {
176 u16 **uni_pgdir[32];
177 unsigned long refcount;
178 unsigned long sum;
179 unsigned char *inverse_translations[4];
180 u16 *inverse_trans_unicode;
181 int readonly;
182};
183
184static struct uni_pagedir *dflt;
185
186static void set_inverse_transl(struct vc_data *conp, struct uni_pagedir *p, int i)
187{
188 int j, glyph;
189 unsigned short *t = translations[i];
190 unsigned char *q;
191
192 if (!p) return;
193 q = p->inverse_translations[i];
194
195 if (!q) {
196 q = p->inverse_translations[i] = (unsigned char *)
197 kmalloc(MAX_GLYPH, GFP_KERNEL);
198 if (!q) return;
199 }
200 memset(q, 0, MAX_GLYPH);
201
202 for (j = 0; j < E_TABSZ; j++) {
203 glyph = conv_uni_to_pc(conp, t[j]);
204 if (glyph >= 0 && glyph < MAX_GLYPH && q[glyph] < 32) {
205 /* prefer '-' above SHY etc. */
206 q[glyph] = j;
207 }
208 }
209}
210
211static void set_inverse_trans_unicode(struct vc_data *conp,
212 struct uni_pagedir *p)
213{
214 int i, j, k, glyph;
215 u16 **p1, *p2;
216 u16 *q;
217
218 if (!p) return;
219 q = p->inverse_trans_unicode;
220 if (!q) {
221 q = p->inverse_trans_unicode =
222 kmalloc(MAX_GLYPH * sizeof(u16), GFP_KERNEL);
223 if (!q)
224 return;
225 }
226 memset(q, 0, MAX_GLYPH * sizeof(u16));
227
228 for (i = 0; i < 32; i++) {
229 p1 = p->uni_pgdir[i];
230 if (!p1)
231 continue;
232 for (j = 0; j < 32; j++) {
233 p2 = p1[j];
234 if (!p2)
235 continue;
236 for (k = 0; k < 64; k++) {
237 glyph = p2[k];
238 if (glyph >= 0 && glyph < MAX_GLYPH
239 && q[glyph] < 32)
240 q[glyph] = (i << 11) + (j << 6) + k;
241 }
242 }
243 }
244}
245
246unsigned short *set_translate(int m, struct vc_data *vc)
247{
248 inv_translate[vc->vc_num] = m;
249 return translations[m];
250}
251
252/*
253 * Inverse translation is impossible for several reasons:
254 * 1. The font<->character maps are not 1-1.
255 * 2. The text may have been written while a different translation map
256 * was active.
257 * Still, it is now possible to a certain extent to cut and paste non-ASCII.
258 */
259u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode)
260{
261 struct uni_pagedir *p;
262 int m;
263 if (glyph < 0 || glyph >= MAX_GLYPH)
264 return 0;
265 else if (!(p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc))
266 return glyph;
267 else if (use_unicode) {
268 if (!p->inverse_trans_unicode)
269 return glyph;
270 else
271 return p->inverse_trans_unicode[glyph];
272 } else {
273 m = inv_translate[conp->vc_num];
274 if (!p->inverse_translations[m])
275 return glyph;
276 else
277 return p->inverse_translations[m][glyph];
278 }
279}
280EXPORT_SYMBOL_GPL(inverse_translate);
281
282static void update_user_maps(void)
283{
284 int i;
285 struct uni_pagedir *p, *q = NULL;
286
287 for (i = 0; i < MAX_NR_CONSOLES; i++) {
288 if (!vc_cons_allocated(i))
289 continue;
290 p = (struct uni_pagedir *)*vc_cons[i].d->vc_uni_pagedir_loc;
291 if (p && p != q) {
292 set_inverse_transl(vc_cons[i].d, p, USER_MAP);
293 set_inverse_trans_unicode(vc_cons[i].d, p);
294 q = p;
295 }
296 }
297}
298
299/*
300 * Load customizable translation table
301 * arg points to a 256 byte translation table.
302 *
303 * The "old" variants are for translation directly to font (using the
304 * 0xf000-0xf0ff "transparent" Unicodes) whereas the "new" variants set
305 * Unicodes explicitly.
306 */
307int con_set_trans_old(unsigned char __user * arg)
308{
309 int i;
310 unsigned short *p = translations[USER_MAP];
311
312 if (!access_ok(VERIFY_READ, arg, E_TABSZ))
313 return -EFAULT;
314
315 for (i=0; i<E_TABSZ ; i++) {
316 unsigned char uc;
317 __get_user(uc, arg+i);
318 p[i] = UNI_DIRECT_BASE | uc;
319 }
320
321 update_user_maps();
322 return 0;
323}
324
325int con_get_trans_old(unsigned char __user * arg)
326{
327 int i, ch;
328 unsigned short *p = translations[USER_MAP];
329
330 if (!access_ok(VERIFY_WRITE, arg, E_TABSZ))
331 return -EFAULT;
332
333 for (i=0; i<E_TABSZ ; i++)
334 {
335 ch = conv_uni_to_pc(vc_cons[fg_console].d, p[i]);
336 __put_user((ch & ~0xff) ? 0 : ch, arg+i);
337 }
338 return 0;
339}
340
341int con_set_trans_new(ushort __user * arg)
342{
343 int i;
344 unsigned short *p = translations[USER_MAP];
345
346 if (!access_ok(VERIFY_READ, arg, E_TABSZ*sizeof(unsigned short)))
347 return -EFAULT;
348
349 for (i=0; i<E_TABSZ ; i++) {
350 unsigned short us;
351 __get_user(us, arg+i);
352 p[i] = us;
353 }
354
355 update_user_maps();
356 return 0;
357}
358
359int con_get_trans_new(ushort __user * arg)
360{
361 int i;
362 unsigned short *p = translations[USER_MAP];
363
364 if (!access_ok(VERIFY_WRITE, arg, E_TABSZ*sizeof(unsigned short)))
365 return -EFAULT;
366
367 for (i=0; i<E_TABSZ ; i++)
368 __put_user(p[i], arg+i);
369
370 return 0;
371}
372
373/*
374 * Unicode -> current font conversion
375 *
376 * A font has at most 512 chars, usually 256.
377 * But one font position may represent several Unicode chars.
378 * A hashtable is somewhat of a pain to deal with, so use a
379 * "paged table" instead. Simulation has shown the memory cost of
380 * this 3-level paged table scheme to be comparable to a hash table.
381 */
382
383extern u8 dfont_unicount[]; /* Defined in console_defmap.c */
384extern u16 dfont_unitable[];
385
386static void con_release_unimap(struct uni_pagedir *p)
387{
388 u16 **p1;
389 int i, j;
390
391 if (p == dflt) dflt = NULL;
392 for (i = 0; i < 32; i++) {
393 if ((p1 = p->uni_pgdir[i]) != NULL) {
394 for (j = 0; j < 32; j++)
395 kfree(p1[j]);
396 kfree(p1);
397 }
398 p->uni_pgdir[i] = NULL;
399 }
400 for (i = 0; i < 4; i++) {
401 kfree(p->inverse_translations[i]);
402 p->inverse_translations[i] = NULL;
403 }
404 if (p->inverse_trans_unicode) {
405 kfree(p->inverse_trans_unicode);
406 p->inverse_trans_unicode = NULL;
407 }
408}
409
410void con_free_unimap(struct vc_data *vc)
411{
412 struct uni_pagedir *p;
413
414 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
415 if (!p)
416 return;
417 *vc->vc_uni_pagedir_loc = 0;
418 if (--p->refcount)
419 return;
420 con_release_unimap(p);
421 kfree(p);
422}
423
424static int con_unify_unimap(struct vc_data *conp, struct uni_pagedir *p)
425{
426 int i, j, k;
427 struct uni_pagedir *q;
428
429 for (i = 0; i < MAX_NR_CONSOLES; i++) {
430 if (!vc_cons_allocated(i))
431 continue;
432 q = (struct uni_pagedir *)*vc_cons[i].d->vc_uni_pagedir_loc;
433 if (!q || q == p || q->sum != p->sum)
434 continue;
435 for (j = 0; j < 32; j++) {
436 u16 **p1, **q1;
437 p1 = p->uni_pgdir[j]; q1 = q->uni_pgdir[j];
438 if (!p1 && !q1)
439 continue;
440 if (!p1 || !q1)
441 break;
442 for (k = 0; k < 32; k++) {
443 if (!p1[k] && !q1[k])
444 continue;
445 if (!p1[k] || !q1[k])
446 break;
447 if (memcmp(p1[k], q1[k], 64*sizeof(u16)))
448 break;
449 }
450 if (k < 32)
451 break;
452 }
453 if (j == 32) {
454 q->refcount++;
455 *conp->vc_uni_pagedir_loc = (unsigned long)q;
456 con_release_unimap(p);
457 kfree(p);
458 return 1;
459 }
460 }
461 return 0;
462}
463
464static int
465con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos)
466{
467 int i, n;
468 u16 **p1, *p2;
469
470 if (!(p1 = p->uni_pgdir[n = unicode >> 11])) {
471 p1 = p->uni_pgdir[n] = kmalloc(32*sizeof(u16 *), GFP_KERNEL);
472 if (!p1) return -ENOMEM;
473 for (i = 0; i < 32; i++)
474 p1[i] = NULL;
475 }
476
477 if (!(p2 = p1[n = (unicode >> 6) & 0x1f])) {
478 p2 = p1[n] = kmalloc(64*sizeof(u16), GFP_KERNEL);
479 if (!p2) return -ENOMEM;
480 memset(p2, 0xff, 64*sizeof(u16)); /* No glyphs for the characters (yet) */
481 }
482
483 p2[unicode & 0x3f] = fontpos;
484
485 p->sum += (fontpos << 20) + unicode;
486
487 return 0;
488}
489
490/* ui is a leftover from using a hashtable, but might be used again */
491int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
492{
493 struct uni_pagedir *p, *q;
494
495 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
496 if (p && p->readonly) return -EIO;
497 if (!p || --p->refcount) {
498 q = kzalloc(sizeof(*p), GFP_KERNEL);
499 if (!q) {
500 if (p) p->refcount++;
501 return -ENOMEM;
502 }
503 q->refcount=1;
504 *vc->vc_uni_pagedir_loc = (unsigned long)q;
505 } else {
506 if (p == dflt) dflt = NULL;
507 p->refcount++;
508 p->sum = 0;
509 con_release_unimap(p);
510 }
511 return 0;
512}
513
514int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
515{
516 int err = 0, err1, i;
517 struct uni_pagedir *p, *q;
518
519 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
520 if (p->readonly) return -EIO;
521
522 if (!ct) return 0;
523
524 if (p->refcount > 1) {
525 int j, k;
526 u16 **p1, *p2, l;
527
528 err1 = con_clear_unimap(vc, NULL);
529 if (err1) return err1;
530
531 q = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
532 for (i = 0, l = 0; i < 32; i++)
533 if ((p1 = p->uni_pgdir[i]))
534 for (j = 0; j < 32; j++)
535 if ((p2 = p1[j]))
536 for (k = 0; k < 64; k++, l++)
537 if (p2[k] != 0xffff) {
538 err1 = con_insert_unipair(q, l, p2[k]);
539 if (err1) {
540 p->refcount++;
541 *vc->vc_uni_pagedir_loc = (unsigned long)p;
542 con_release_unimap(q);
543 kfree(q);
544 return err1;
545 }
546 }
547 p = q;
548 } else if (p == dflt)
549 dflt = NULL;
550
551 while (ct--) {
552 unsigned short unicode, fontpos;
553 __get_user(unicode, &list->unicode);
554 __get_user(fontpos, &list->fontpos);
555 if ((err1 = con_insert_unipair(p, unicode,fontpos)) != 0)
556 err = err1;
557 list++;
558 }
559
560 if (con_unify_unimap(vc, p))
561 return err;
562
563 for (i = 0; i <= 3; i++)
564 set_inverse_transl(vc, p, i); /* Update all inverse translations */
565 set_inverse_trans_unicode(vc, p);
566
567 return err;
568}
569
570/* Loads the unimap for the hardware font, as defined in uni_hash.tbl.
571 The representation used was the most compact I could come up
572 with. This routine is executed at sys_setup time, and when the
573 PIO_FONTRESET ioctl is called. */
574
575int con_set_default_unimap(struct vc_data *vc)
576{
577 int i, j, err = 0, err1;
578 u16 *q;
579 struct uni_pagedir *p;
580
581 if (dflt) {
582 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
583 if (p == dflt)
584 return 0;
585 dflt->refcount++;
586 *vc->vc_uni_pagedir_loc = (unsigned long)dflt;
587 if (p && --p->refcount) {
588 con_release_unimap(p);
589 kfree(p);
590 }
591 return 0;
592 }
593
594 /* The default font is always 256 characters */
595
596 err = con_clear_unimap(vc, NULL);
597 if (err) return err;
598
599 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
600 q = dfont_unitable;
601
602 for (i = 0; i < 256; i++)
603 for (j = dfont_unicount[i]; j; j--) {
604 err1 = con_insert_unipair(p, *(q++), i);
605 if (err1)
606 err = err1;
607 }
608
609 if (con_unify_unimap(vc, p)) {
610 dflt = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
611 return err;
612 }
613
614 for (i = 0; i <= 3; i++)
615 set_inverse_transl(vc, p, i); /* Update all inverse translations */
616 set_inverse_trans_unicode(vc, p);
617 dflt = p;
618 return err;
619}
620EXPORT_SYMBOL(con_set_default_unimap);
621
622int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc)
623{
624 struct uni_pagedir *q;
625
626 if (!*src_vc->vc_uni_pagedir_loc)
627 return -EINVAL;
628 if (*dst_vc->vc_uni_pagedir_loc == *src_vc->vc_uni_pagedir_loc)
629 return 0;
630 con_free_unimap(dst_vc);
631 q = (struct uni_pagedir *)*src_vc->vc_uni_pagedir_loc;
632 q->refcount++;
633 *dst_vc->vc_uni_pagedir_loc = (long)q;
634 return 0;
635}
636
637int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct unipair __user *list)
638{
639 int i, j, k, ect;
640 u16 **p1, *p2;
641 struct uni_pagedir *p;
642
643 ect = 0;
644 if (*vc->vc_uni_pagedir_loc) {
645 p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
646 for (i = 0; i < 32; i++)
647 if ((p1 = p->uni_pgdir[i]))
648 for (j = 0; j < 32; j++)
649 if ((p2 = *(p1++)))
650 for (k = 0; k < 64; k++) {
651 if (*p2 < MAX_GLYPH && ect++ < ct) {
652 __put_user((u_short)((i<<11)+(j<<6)+k),
653 &list->unicode);
654 __put_user((u_short) *p2,
655 &list->fontpos);
656 list++;
657 }
658 p2++;
659 }
660 }
661 __put_user(ect, uct);
662 return ((ect <= ct) ? 0 : -ENOMEM);
663}
664
665void con_protect_unimap(struct vc_data *vc, int rdonly)
666{
667 struct uni_pagedir *p = (struct uni_pagedir *)*vc->vc_uni_pagedir_loc;
668
669 if (p)
670 p->readonly = rdonly;
671}
672
673/*
674 * Always use USER_MAP. These functions are used by the keyboard,
675 * which shouldn't be affected by G0/G1 switching, etc.
676 * If the user map still contains default values, i.e. the
677 * direct-to-font mapping, then assume user is using Latin1.
678 */
679/* may be called during an interrupt */
680u32 conv_8bit_to_uni(unsigned char c)
681{
682 unsigned short uni = translations[USER_MAP][c];
683 return uni == (0xf000 | c) ? c : uni;
684}
685
686int conv_uni_to_8bit(u32 uni)
687{
688 int c;
689 for (c = 0; c < 0x100; c++)
690 if (translations[USER_MAP][c] == uni ||
691 (translations[USER_MAP][c] == (c | 0xf000) && uni == c))
692 return c;
693 return -1;
694}
695
696int
697conv_uni_to_pc(struct vc_data *conp, long ucs)
698{
699 int h;
700 u16 **p1, *p2;
701 struct uni_pagedir *p;
702
703 /* Only 16-bit codes supported at this time */
704 if (ucs > 0xffff)
705 return -4; /* Not found */
706 else if (ucs < 0x20)
707 return -1; /* Not a printable character */
708 else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f))
709 return -2; /* Zero-width space */
710 /*
711 * UNI_DIRECT_BASE indicates the start of the region in the User Zone
712 * which always has a 1:1 mapping to the currently loaded font. The
713 * UNI_DIRECT_MASK indicates the bit span of the region.
714 */
715 else if ((ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE)
716 return ucs & UNI_DIRECT_MASK;
717
718 if (!*conp->vc_uni_pagedir_loc)
719 return -3;
720
721 p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc;
722 if ((p1 = p->uni_pgdir[ucs >> 11]) &&
723 (p2 = p1[(ucs >> 6) & 0x1f]) &&
724 (h = p2[ucs & 0x3f]) < MAX_GLYPH)
725 return h;
726
727 return -4; /* not found */
728}
729
730/*
731 * This is called at sys_setup time, after memory and the console are
732 * initialized. It must be possible to call kmalloc(..., GFP_KERNEL)
733 * from this function, hence the call from sys_setup.
734 */
735void __init
736console_map_init(void)
737{
738 int i;
739
740 for (i = 0; i < MAX_NR_CONSOLES; i++)
741 if (vc_cons_allocated(i) && !*vc_cons[i].d->vc_uni_pagedir_loc)
742 con_set_default_unimap(vc_cons[i].d);
743}
744
745EXPORT_SYMBOL(con_copy_unimap);
diff --git a/drivers/tty/vt/cp437.uni b/drivers/tty/vt/cp437.uni
new file mode 100644
index 000000000000..bc6163484f62
--- /dev/null
+++ b/drivers/tty/vt/cp437.uni
@@ -0,0 +1,291 @@
1#
2# Unicode table for IBM Codepage 437. Note that there are many more
3# substitutions that could be conceived (for example, thick-line
4# graphs probably should be replaced with double-line ones, accented
5# Latin characters should replaced with their nonaccented versions,
6# and some upper case Greek characters could be replaced by Latin), however,
7# I have limited myself to the Unicodes used by the kernel ISO 8859-1,
8# DEC VT, and IBM CP 437 tables.
9#
10# --------------------------------
11#
12# Basic IBM dingbats, some of which will never have a purpose clear
13# to mankind
14#
150x00 U+0000
160x01 U+263a
170x02 U+263b
180x03 U+2665
190x04 U+2666 U+25c6
200x05 U+2663
210x06 U+2660
220x07 U+2022
230x08 U+25d8
240x09 U+25cb
250x0a U+25d9
260x0b U+2642
270x0c U+2640
280x0d U+266a
290x0e U+266b
300x0f U+263c U+00a4
310x10 U+25b6 U+25ba
320x11 U+25c0 U+25c4
330x12 U+2195
340x13 U+203c
350x14 U+00b6
360x15 U+00a7
370x16 U+25ac
380x17 U+21a8
390x18 U+2191
400x19 U+2193
410x1a U+2192
420x1b U+2190
430x1c U+221f
440x1d U+2194
450x1e U+25b2
460x1f U+25bc
47#
48# The ASCII range is identity-mapped, but some of the characters also
49# have to act as substitutes, especially the upper-case characters.
50#
510x20 U+0020
520x21 U+0021
530x22 U+0022 U+00a8
540x23 U+0023
550x24 U+0024
560x25 U+0025
570x26 U+0026
580x27 U+0027 U+00b4
590x28 U+0028
600x29 U+0029
610x2a U+002a
620x2b U+002b
630x2c U+002c U+00b8
640x2d U+002d U+00ad
650x2e U+002e
660x2f U+002f
670x30 U+0030
680x31 U+0031
690x32 U+0032
700x33 U+0033
710x34 U+0034
720x35 U+0035
730x36 U+0036
740x37 U+0037
750x38 U+0038
760x39 U+0039
770x3a U+003a
780x3b U+003b
790x3c U+003c
800x3d U+003d
810x3e U+003e
820x3f U+003f
830x40 U+0040
840x41 U+0041 U+00c0 U+00c1 U+00c2 U+00c3
850x42 U+0042
860x43 U+0043 U+00a9
870x44 U+0044 U+00d0
880x45 U+0045 U+00c8 U+00ca U+00cb
890x46 U+0046
900x47 U+0047
910x48 U+0048
920x49 U+0049 U+00cc U+00cd U+00ce U+00cf
930x4a U+004a
940x4b U+004b U+212a
950x4c U+004c
960x4d U+004d
970x4e U+004e
980x4f U+004f U+00d2 U+00d3 U+00d4 U+00d5
990x50 U+0050
1000x51 U+0051
1010x52 U+0052 U+00ae
1020x53 U+0053
1030x54 U+0054
1040x55 U+0055 U+00d9 U+00da U+00db
1050x56 U+0056
1060x57 U+0057
1070x58 U+0058
1080x59 U+0059 U+00dd
1090x5a U+005a
1100x5b U+005b
1110x5c U+005c
1120x5d U+005d
1130x5e U+005e
1140x5f U+005f U+23bd U+f804
1150x60 U+0060
1160x61 U+0061 U+00e3
1170x62 U+0062
1180x63 U+0063
1190x64 U+0064
1200x65 U+0065
1210x66 U+0066
1220x67 U+0067
1230x68 U+0068
1240x69 U+0069
1250x6a U+006a
1260x6b U+006b
1270x6c U+006c
1280x6d U+006d
1290x6e U+006e
1300x6f U+006f U+00f5
1310x70 U+0070
1320x71 U+0071
1330x72 U+0072
1340x73 U+0073
1350x74 U+0074
1360x75 U+0075
1370x76 U+0076
1380x77 U+0077
1390x78 U+0078 U+00d7
1400x79 U+0079 U+00fd
1410x7a U+007a
1420x7b U+007b
1430x7c U+007c U+00a6
1440x7d U+007d
1450x7e U+007e
146#
147# Okay, what on Earth is this one supposed to be used for?
148#
1490x7f U+2302
150#
151# Non-English characters, mostly lower case letters...
152#
1530x80 U+00c7
1540x81 U+00fc
1550x82 U+00e9
1560x83 U+00e2
1570x84 U+00e4
1580x85 U+00e0
1590x86 U+00e5
1600x87 U+00e7
1610x88 U+00ea
1620x89 U+00eb
1630x8a U+00e8
1640x8b U+00ef
1650x8c U+00ee
1660x8d U+00ec
1670x8e U+00c4
1680x8f U+00c5 U+212b
1690x90 U+00c9
1700x91 U+00e6
1710x92 U+00c6
1720x93 U+00f4
1730x94 U+00f6
1740x95 U+00f2
1750x96 U+00fb
1760x97 U+00f9
1770x98 U+00ff
1780x99 U+00d6
1790x9a U+00dc
1800x9b U+00a2
1810x9c U+00a3
1820x9d U+00a5
1830x9e U+20a7
1840x9f U+0192
1850xa0 U+00e1
1860xa1 U+00ed
1870xa2 U+00f3
1880xa3 U+00fa
1890xa4 U+00f1
1900xa5 U+00d1
1910xa6 U+00aa
1920xa7 U+00ba
1930xa8 U+00bf
1940xa9 U+2310
1950xaa U+00ac
1960xab U+00bd
1970xac U+00bc
1980xad U+00a1
1990xae U+00ab
2000xaf U+00bb
201#
202# Block graphics
203#
2040xb0 U+2591
2050xb1 U+2592
2060xb2 U+2593
2070xb3 U+2502
2080xb4 U+2524
2090xb5 U+2561
2100xb6 U+2562
2110xb7 U+2556
2120xb8 U+2555
2130xb9 U+2563
2140xba U+2551
2150xbb U+2557
2160xbc U+255d
2170xbd U+255c
2180xbe U+255b
2190xbf U+2510
2200xc0 U+2514
2210xc1 U+2534
2220xc2 U+252c
2230xc3 U+251c
2240xc4 U+2500
2250xc5 U+253c
2260xc6 U+255e
2270xc7 U+255f
2280xc8 U+255a
2290xc9 U+2554
2300xca U+2569
2310xcb U+2566
2320xcc U+2560
2330xcd U+2550
2340xce U+256c
2350xcf U+2567
2360xd0 U+2568
2370xd1 U+2564
2380xd2 U+2565
2390xd3 U+2559
2400xd4 U+2558
2410xd5 U+2552
2420xd6 U+2553
2430xd7 U+256b
2440xd8 U+256a
2450xd9 U+2518
2460xda U+250c
2470xdb U+2588
2480xdc U+2584
2490xdd U+258c
2500xde U+2590
2510xdf U+2580
252#
253# Greek letters and mathematical symbols
254#
2550xe0 U+03b1
2560xe1 U+03b2 U+00df
2570xe2 U+0393
2580xe3 U+03c0
2590xe4 U+03a3
2600xe5 U+03c3
2610xe6 U+00b5 U+03bc
2620xe7 U+03c4
2630xe8 U+03a6 U+00d8
2640xe9 U+0398
2650xea U+03a9 U+2126
2660xeb U+03b4 U+00f0
2670xec U+221e
2680xed U+03c6 U+00f8
2690xee U+03b5 U+2208
2700xef U+2229
2710xf0 U+2261
2720xf1 U+00b1
2730xf2 U+2265
2740xf3 U+2264
2750xf4 U+2320
2760xf5 U+2321
2770xf6 U+00f7
2780xf7 U+2248
2790xf8 U+00b0
2800xf9 U+2219
2810xfa U+00b7
2820xfb U+221a
2830xfc U+207f
2840xfd U+00b2
285#
286# Square bullet, non-spacing blank
287# Mapping U+fffd to the square bullet means it is the substitution
288# character
289#
2900xfe U+25a0 U+fffd
2910xff U+00a0
diff --git a/drivers/tty/vt/defkeymap.c_shipped b/drivers/tty/vt/defkeymap.c_shipped
new file mode 100644
index 000000000000..d2208dfe3f67
--- /dev/null
+++ b/drivers/tty/vt/defkeymap.c_shipped
@@ -0,0 +1,262 @@
1/* Do not edit this file! It was automatically generated by */
2/* loadkeys --mktable defkeymap.map > defkeymap.c */
3
4#include <linux/types.h>
5#include <linux/keyboard.h>
6#include <linux/kd.h>
7
8u_short plain_map[NR_KEYS] = {
9 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
10 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009,
11 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
12 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
13 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
14 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
15 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c,
16 0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
17 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307,
18 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
19 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a,
20 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
21 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
22 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
23 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
24 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
25};
26
27u_short shift_map[NR_KEYS] = {
28 0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
29 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009,
30 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
31 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53,
32 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
33 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
34 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c,
35 0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e,
36 0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307,
37 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
38 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a,
39 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
40 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
41 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
42 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
43 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
44};
45
46u_short altgr_map[NR_KEYS] = {
47 0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
48 0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200,
49 0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
50 0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73,
51 0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200,
52 0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76,
53 0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
54 0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510,
55 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911,
56 0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b,
57 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516,
58 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
59 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
60 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
61 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
62 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
63};
64
65u_short ctrl_map[NR_KEYS] = {
66 0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
67 0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200,
68 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
69 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013,
70 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
71 0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016,
72 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c,
73 0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
74 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307,
75 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
76 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a,
77 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
78 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
79 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
80 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
81 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
82};
83
84u_short shift_ctrl_map[NR_KEYS] = {
85 0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
86 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200,
87 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
88 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013,
89 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
90 0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
91 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
92 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
93 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307,
94 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
95 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200,
96 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
97 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
98 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
99 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
100 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
101};
102
103u_short alt_map[NR_KEYS] = {
104 0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
105 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809,
106 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
107 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873,
108 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b,
109 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876,
110 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c,
111 0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
112 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907,
113 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901,
114 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a,
115 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
116 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
117 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
118 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
119 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
120};
121
122u_short ctrl_alt_map[NR_KEYS] = {
123 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
124 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
125 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
126 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813,
127 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
128 0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816,
129 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
130 0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
131 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307,
132 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
133 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a,
134 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
135 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
136 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
137 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
138 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
139};
140
141ushort *key_maps[MAX_NR_KEYMAPS] = {
142 plain_map, shift_map, altgr_map, NULL,
143 ctrl_map, shift_ctrl_map, NULL, NULL,
144 alt_map, NULL, NULL, NULL,
145 ctrl_alt_map, NULL
146};
147
148unsigned int keymap_count = 7;
149
150/*
151 * Philosophy: most people do not define more strings, but they who do
152 * often want quite a lot of string space. So, we statically allocate
153 * the default and allocate dynamically in chunks of 512 bytes.
154 */
155
156char func_buf[] = {
157 '\033', '[', '[', 'A', 0,
158 '\033', '[', '[', 'B', 0,
159 '\033', '[', '[', 'C', 0,
160 '\033', '[', '[', 'D', 0,
161 '\033', '[', '[', 'E', 0,
162 '\033', '[', '1', '7', '~', 0,
163 '\033', '[', '1', '8', '~', 0,
164 '\033', '[', '1', '9', '~', 0,
165 '\033', '[', '2', '0', '~', 0,
166 '\033', '[', '2', '1', '~', 0,
167 '\033', '[', '2', '3', '~', 0,
168 '\033', '[', '2', '4', '~', 0,
169 '\033', '[', '2', '5', '~', 0,
170 '\033', '[', '2', '6', '~', 0,
171 '\033', '[', '2', '8', '~', 0,
172 '\033', '[', '2', '9', '~', 0,
173 '\033', '[', '3', '1', '~', 0,
174 '\033', '[', '3', '2', '~', 0,
175 '\033', '[', '3', '3', '~', 0,
176 '\033', '[', '3', '4', '~', 0,
177 '\033', '[', '1', '~', 0,
178 '\033', '[', '2', '~', 0,
179 '\033', '[', '3', '~', 0,
180 '\033', '[', '4', '~', 0,
181 '\033', '[', '5', '~', 0,
182 '\033', '[', '6', '~', 0,
183 '\033', '[', 'M', 0,
184 '\033', '[', 'P', 0,
185};
186
187char *funcbufptr = func_buf;
188int funcbufsize = sizeof(func_buf);
189int funcbufleft = 0; /* space left */
190
191char *func_table[MAX_NR_FUNC] = {
192 func_buf + 0,
193 func_buf + 5,
194 func_buf + 10,
195 func_buf + 15,
196 func_buf + 20,
197 func_buf + 25,
198 func_buf + 31,
199 func_buf + 37,
200 func_buf + 43,
201 func_buf + 49,
202 func_buf + 55,
203 func_buf + 61,
204 func_buf + 67,
205 func_buf + 73,
206 func_buf + 79,
207 func_buf + 85,
208 func_buf + 91,
209 func_buf + 97,
210 func_buf + 103,
211 func_buf + 109,
212 func_buf + 115,
213 func_buf + 120,
214 func_buf + 125,
215 func_buf + 130,
216 func_buf + 135,
217 func_buf + 140,
218 func_buf + 145,
219 NULL,
220 NULL,
221 func_buf + 149,
222 NULL,
223};
224
225struct kbdiacruc accent_table[MAX_DIACR] = {
226 {'`', 'A', 0300}, {'`', 'a', 0340},
227 {'\'', 'A', 0301}, {'\'', 'a', 0341},
228 {'^', 'A', 0302}, {'^', 'a', 0342},
229 {'~', 'A', 0303}, {'~', 'a', 0343},
230 {'"', 'A', 0304}, {'"', 'a', 0344},
231 {'O', 'A', 0305}, {'o', 'a', 0345},
232 {'0', 'A', 0305}, {'0', 'a', 0345},
233 {'A', 'A', 0305}, {'a', 'a', 0345},
234 {'A', 'E', 0306}, {'a', 'e', 0346},
235 {',', 'C', 0307}, {',', 'c', 0347},
236 {'`', 'E', 0310}, {'`', 'e', 0350},
237 {'\'', 'E', 0311}, {'\'', 'e', 0351},
238 {'^', 'E', 0312}, {'^', 'e', 0352},
239 {'"', 'E', 0313}, {'"', 'e', 0353},
240 {'`', 'I', 0314}, {'`', 'i', 0354},
241 {'\'', 'I', 0315}, {'\'', 'i', 0355},
242 {'^', 'I', 0316}, {'^', 'i', 0356},
243 {'"', 'I', 0317}, {'"', 'i', 0357},
244 {'-', 'D', 0320}, {'-', 'd', 0360},
245 {'~', 'N', 0321}, {'~', 'n', 0361},
246 {'`', 'O', 0322}, {'`', 'o', 0362},
247 {'\'', 'O', 0323}, {'\'', 'o', 0363},
248 {'^', 'O', 0324}, {'^', 'o', 0364},
249 {'~', 'O', 0325}, {'~', 'o', 0365},
250 {'"', 'O', 0326}, {'"', 'o', 0366},
251 {'/', 'O', 0330}, {'/', 'o', 0370},
252 {'`', 'U', 0331}, {'`', 'u', 0371},
253 {'\'', 'U', 0332}, {'\'', 'u', 0372},
254 {'^', 'U', 0333}, {'^', 'u', 0373},
255 {'"', 'U', 0334}, {'"', 'u', 0374},
256 {'\'', 'Y', 0335}, {'\'', 'y', 0375},
257 {'T', 'H', 0336}, {'t', 'h', 0376},
258 {'s', 's', 0337}, {'"', 'y', 0377},
259 {'s', 'z', 0337}, {'i', 'j', 0377},
260};
261
262unsigned int accent_table_size = 68;
diff --git a/drivers/tty/vt/defkeymap.map b/drivers/tty/vt/defkeymap.map
new file mode 100644
index 000000000000..50b30cace261
--- /dev/null
+++ b/drivers/tty/vt/defkeymap.map
@@ -0,0 +1,357 @@
1# Default kernel keymap. This uses 7 modifier combinations.
2keymaps 0-2,4-5,8,12
3# Change the above line into
4# keymaps 0-2,4-6,8,12
5# in case you want the entries
6# altgr control keycode 83 = Boot
7# altgr control keycode 111 = Boot
8# below.
9#
10# In fact AltGr is used very little, and one more keymap can
11# be saved by mapping AltGr to Alt (and adapting a few entries):
12# keycode 100 = Alt
13#
14keycode 1 = Escape Escape
15 alt keycode 1 = Meta_Escape
16keycode 2 = one exclam
17 alt keycode 2 = Meta_one
18keycode 3 = two at at
19 control keycode 3 = nul
20 shift control keycode 3 = nul
21 alt keycode 3 = Meta_two
22keycode 4 = three numbersign
23 control keycode 4 = Escape
24 alt keycode 4 = Meta_three
25keycode 5 = four dollar dollar
26 control keycode 5 = Control_backslash
27 alt keycode 5 = Meta_four
28keycode 6 = five percent
29 control keycode 6 = Control_bracketright
30 alt keycode 6 = Meta_five
31keycode 7 = six asciicircum
32 control keycode 7 = Control_asciicircum
33 alt keycode 7 = Meta_six
34keycode 8 = seven ampersand braceleft
35 control keycode 8 = Control_underscore
36 alt keycode 8 = Meta_seven
37keycode 9 = eight asterisk bracketleft
38 control keycode 9 = Delete
39 alt keycode 9 = Meta_eight
40keycode 10 = nine parenleft bracketright
41 alt keycode 10 = Meta_nine
42keycode 11 = zero parenright braceright
43 alt keycode 11 = Meta_zero
44keycode 12 = minus underscore backslash
45 control keycode 12 = Control_underscore
46 shift control keycode 12 = Control_underscore
47 alt keycode 12 = Meta_minus
48keycode 13 = equal plus
49 alt keycode 13 = Meta_equal
50keycode 14 = Delete Delete
51 control keycode 14 = BackSpace
52 alt keycode 14 = Meta_Delete
53keycode 15 = Tab Tab
54 alt keycode 15 = Meta_Tab
55keycode 16 = q
56keycode 17 = w
57keycode 18 = e
58 altgr keycode 18 = Hex_E
59keycode 19 = r
60keycode 20 = t
61keycode 21 = y
62keycode 22 = u
63keycode 23 = i
64keycode 24 = o
65keycode 25 = p
66keycode 26 = bracketleft braceleft
67 control keycode 26 = Escape
68 alt keycode 26 = Meta_bracketleft
69keycode 27 = bracketright braceright asciitilde
70 control keycode 27 = Control_bracketright
71 alt keycode 27 = Meta_bracketright
72keycode 28 = Return
73 alt keycode 28 = Meta_Control_m
74keycode 29 = Control
75keycode 30 = a
76 altgr keycode 30 = Hex_A
77keycode 31 = s
78keycode 32 = d
79 altgr keycode 32 = Hex_D
80keycode 33 = f
81 altgr keycode 33 = Hex_F
82keycode 34 = g
83keycode 35 = h
84keycode 36 = j
85keycode 37 = k
86keycode 38 = l
87keycode 39 = semicolon colon
88 alt keycode 39 = Meta_semicolon
89keycode 40 = apostrophe quotedbl
90 control keycode 40 = Control_g
91 alt keycode 40 = Meta_apostrophe
92keycode 41 = grave asciitilde
93 control keycode 41 = nul
94 alt keycode 41 = Meta_grave
95keycode 42 = Shift
96keycode 43 = backslash bar
97 control keycode 43 = Control_backslash
98 alt keycode 43 = Meta_backslash
99keycode 44 = z
100keycode 45 = x
101keycode 46 = c
102 altgr keycode 46 = Hex_C
103keycode 47 = v
104keycode 48 = b
105 altgr keycode 48 = Hex_B
106keycode 49 = n
107keycode 50 = m
108keycode 51 = comma less
109 alt keycode 51 = Meta_comma
110keycode 52 = period greater
111 control keycode 52 = Compose
112 alt keycode 52 = Meta_period
113keycode 53 = slash question
114 control keycode 53 = Delete
115 alt keycode 53 = Meta_slash
116keycode 54 = Shift
117keycode 55 = KP_Multiply
118keycode 56 = Alt
119keycode 57 = space space
120 control keycode 57 = nul
121 alt keycode 57 = Meta_space
122keycode 58 = Caps_Lock
123keycode 59 = F1 F11 Console_13
124 control keycode 59 = F1
125 alt keycode 59 = Console_1
126 control alt keycode 59 = Console_1
127keycode 60 = F2 F12 Console_14
128 control keycode 60 = F2
129 alt keycode 60 = Console_2
130 control alt keycode 60 = Console_2
131keycode 61 = F3 F13 Console_15
132 control keycode 61 = F3
133 alt keycode 61 = Console_3
134 control alt keycode 61 = Console_3
135keycode 62 = F4 F14 Console_16
136 control keycode 62 = F4
137 alt keycode 62 = Console_4
138 control alt keycode 62 = Console_4
139keycode 63 = F5 F15 Console_17
140 control keycode 63 = F5
141 alt keycode 63 = Console_5
142 control alt keycode 63 = Console_5
143keycode 64 = F6 F16 Console_18
144 control keycode 64 = F6
145 alt keycode 64 = Console_6
146 control alt keycode 64 = Console_6
147keycode 65 = F7 F17 Console_19
148 control keycode 65 = F7
149 alt keycode 65 = Console_7
150 control alt keycode 65 = Console_7
151keycode 66 = F8 F18 Console_20
152 control keycode 66 = F8
153 alt keycode 66 = Console_8
154 control alt keycode 66 = Console_8
155keycode 67 = F9 F19 Console_21
156 control keycode 67 = F9
157 alt keycode 67 = Console_9
158 control alt keycode 67 = Console_9
159keycode 68 = F10 F20 Console_22
160 control keycode 68 = F10
161 alt keycode 68 = Console_10
162 control alt keycode 68 = Console_10
163keycode 69 = Num_Lock
164 shift keycode 69 = Bare_Num_Lock
165keycode 70 = Scroll_Lock Show_Memory Show_Registers
166 control keycode 70 = Show_State
167 alt keycode 70 = Scroll_Lock
168keycode 71 = KP_7
169 alt keycode 71 = Ascii_7
170 altgr keycode 71 = Hex_7
171keycode 72 = KP_8
172 alt keycode 72 = Ascii_8
173 altgr keycode 72 = Hex_8
174keycode 73 = KP_9
175 alt keycode 73 = Ascii_9
176 altgr keycode 73 = Hex_9
177keycode 74 = KP_Subtract
178keycode 75 = KP_4
179 alt keycode 75 = Ascii_4
180 altgr keycode 75 = Hex_4
181keycode 76 = KP_5
182 alt keycode 76 = Ascii_5
183 altgr keycode 76 = Hex_5
184keycode 77 = KP_6
185 alt keycode 77 = Ascii_6
186 altgr keycode 77 = Hex_6
187keycode 78 = KP_Add
188keycode 79 = KP_1
189 alt keycode 79 = Ascii_1
190 altgr keycode 79 = Hex_1
191keycode 80 = KP_2
192 alt keycode 80 = Ascii_2
193 altgr keycode 80 = Hex_2
194keycode 81 = KP_3
195 alt keycode 81 = Ascii_3
196 altgr keycode 81 = Hex_3
197keycode 82 = KP_0
198 alt keycode 82 = Ascii_0
199 altgr keycode 82 = Hex_0
200keycode 83 = KP_Period
201# altgr control keycode 83 = Boot
202 control alt keycode 83 = Boot
203keycode 84 = Last_Console
204keycode 85 =
205keycode 86 = less greater bar
206 alt keycode 86 = Meta_less
207keycode 87 = F11 F11 Console_23
208 control keycode 87 = F11
209 alt keycode 87 = Console_11
210 control alt keycode 87 = Console_11
211keycode 88 = F12 F12 Console_24
212 control keycode 88 = F12
213 alt keycode 88 = Console_12
214 control alt keycode 88 = Console_12
215keycode 89 =
216keycode 90 =
217keycode 91 =
218keycode 92 =
219keycode 93 =
220keycode 94 =
221keycode 95 =
222keycode 96 = KP_Enter
223keycode 97 = Control
224keycode 98 = KP_Divide
225keycode 99 = Control_backslash
226 control keycode 99 = Control_backslash
227 alt keycode 99 = Control_backslash
228keycode 100 = AltGr
229keycode 101 = Break
230keycode 102 = Find
231keycode 103 = Up
232keycode 104 = Prior
233 shift keycode 104 = Scroll_Backward
234keycode 105 = Left
235 alt keycode 105 = Decr_Console
236keycode 106 = Right
237 alt keycode 106 = Incr_Console
238keycode 107 = Select
239keycode 108 = Down
240keycode 109 = Next
241 shift keycode 109 = Scroll_Forward
242keycode 110 = Insert
243keycode 111 = Remove
244# altgr control keycode 111 = Boot
245 control alt keycode 111 = Boot
246keycode 112 = Macro
247keycode 113 = F13
248keycode 114 = F14
249keycode 115 = Help
250keycode 116 = Do
251keycode 117 = F17
252keycode 118 = KP_MinPlus
253keycode 119 = Pause
254keycode 120 =
255keycode 121 =
256keycode 122 =
257keycode 123 =
258keycode 124 =
259keycode 125 =
260keycode 126 =
261keycode 127 =
262string F1 = "\033[[A"
263string F2 = "\033[[B"
264string F3 = "\033[[C"
265string F4 = "\033[[D"
266string F5 = "\033[[E"
267string F6 = "\033[17~"
268string F7 = "\033[18~"
269string F8 = "\033[19~"
270string F9 = "\033[20~"
271string F10 = "\033[21~"
272string F11 = "\033[23~"
273string F12 = "\033[24~"
274string F13 = "\033[25~"
275string F14 = "\033[26~"
276string F15 = "\033[28~"
277string F16 = "\033[29~"
278string F17 = "\033[31~"
279string F18 = "\033[32~"
280string F19 = "\033[33~"
281string F20 = "\033[34~"
282string Find = "\033[1~"
283string Insert = "\033[2~"
284string Remove = "\033[3~"
285string Select = "\033[4~"
286string Prior = "\033[5~"
287string Next = "\033[6~"
288string Macro = "\033[M"
289string Pause = "\033[P"
290compose '`' 'A' to 'À'
291compose '`' 'a' to 'à'
292compose '\'' 'A' to 'Á'
293compose '\'' 'a' to 'á'
294compose '^' 'A' to 'Â'
295compose '^' 'a' to 'â'
296compose '~' 'A' to 'Ã'
297compose '~' 'a' to 'ã'
298compose '"' 'A' to 'Ä'
299compose '"' 'a' to 'ä'
300compose 'O' 'A' to 'Å'
301compose 'o' 'a' to 'å'
302compose '0' 'A' to 'Å'
303compose '0' 'a' to 'å'
304compose 'A' 'A' to 'Å'
305compose 'a' 'a' to 'å'
306compose 'A' 'E' to 'Æ'
307compose 'a' 'e' to 'æ'
308compose ',' 'C' to 'Ç'
309compose ',' 'c' to 'ç'
310compose '`' 'E' to 'È'
311compose '`' 'e' to 'è'
312compose '\'' 'E' to 'É'
313compose '\'' 'e' to 'é'
314compose '^' 'E' to 'Ê'
315compose '^' 'e' to 'ê'
316compose '"' 'E' to 'Ë'
317compose '"' 'e' to 'ë'
318compose '`' 'I' to 'Ì'
319compose '`' 'i' to 'ì'
320compose '\'' 'I' to 'Í'
321compose '\'' 'i' to 'í'
322compose '^' 'I' to 'Î'
323compose '^' 'i' to 'î'
324compose '"' 'I' to 'Ï'
325compose '"' 'i' to 'ï'
326compose '-' 'D' to 'Ð'
327compose '-' 'd' to 'ð'
328compose '~' 'N' to 'Ñ'
329compose '~' 'n' to 'ñ'
330compose '`' 'O' to 'Ò'
331compose '`' 'o' to 'ò'
332compose '\'' 'O' to 'Ó'
333compose '\'' 'o' to 'ó'
334compose '^' 'O' to 'Ô'
335compose '^' 'o' to 'ô'
336compose '~' 'O' to 'Õ'
337compose '~' 'o' to 'õ'
338compose '"' 'O' to 'Ö'
339compose '"' 'o' to 'ö'
340compose '/' 'O' to 'Ø'
341compose '/' 'o' to 'ø'
342compose '`' 'U' to 'Ù'
343compose '`' 'u' to 'ù'
344compose '\'' 'U' to 'Ú'
345compose '\'' 'u' to 'ú'
346compose '^' 'U' to 'Û'
347compose '^' 'u' to 'û'
348compose '"' 'U' to 'Ü'
349compose '"' 'u' to 'ü'
350compose '\'' 'Y' to 'Ý'
351compose '\'' 'y' to 'ý'
352compose 'T' 'H' to 'Þ'
353compose 't' 'h' to 'þ'
354compose 's' 's' to 'ß'
355compose '"' 'y' to 'ÿ'
356compose 's' 'z' to 'ß'
357compose 'i' 'j' to 'ÿ'
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
new file mode 100644
index 000000000000..e95d7876ca6b
--- /dev/null
+++ b/drivers/tty/vt/keyboard.c
@@ -0,0 +1,1454 @@
1/*
2 * linux/drivers/char/keyboard.c
3 *
4 * Written for linux by Johan Myreen as a translation from
5 * the assembly version by Linus (with diacriticals added)
6 *
7 * Some additional features added by Christoph Niemann (ChN), March 1993
8 *
9 * Loadable keymaps by Risto Kankkunen, May 1993
10 *
11 * Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
12 * Added decr/incr_console, dynamic keymaps, Unicode support,
13 * dynamic function/string keys, led setting, Sept 1994
14 * `Sticky' modifier keys, 951006.
15 *
16 * 11-11-96: SAK should now work in the raw mode (Martin Mares)
17 *
18 * Modified to provide 'generic' keyboard support by Hamish Macdonald
19 * Merge with the m68k keyboard driver and split-off of the PC low-level
20 * parts by Geert Uytterhoeven, May 1997
21 *
22 * 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
23 * 30-07-98: Dead keys redone, aeb@cwi.nl.
24 * 21-08-02: Converted to input API, major cleanup. (Vojtech Pavlik)
25 */
26
27#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28
29#include <linux/consolemap.h>
30#include <linux/module.h>
31#include <linux/sched.h>
32#include <linux/tty.h>
33#include <linux/tty_flip.h>
34#include <linux/mm.h>
35#include <linux/string.h>
36#include <linux/init.h>
37#include <linux/slab.h>
38#include <linux/irq.h>
39
40#include <linux/kbd_kern.h>
41#include <linux/kbd_diacr.h>
42#include <linux/vt_kern.h>
43#include <linux/input.h>
44#include <linux/reboot.h>
45#include <linux/notifier.h>
46#include <linux/jiffies.h>
47
48extern void ctrl_alt_del(void);
49
50/*
51 * Exported functions/variables
52 */
53
54#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
55
56/*
57 * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
58 * This seems a good reason to start with NumLock off. On HIL keyboards
59 * of PARISC machines however there is no NumLock key and everyone expects the keypad
60 * to be used for numbers.
61 */
62
63#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
64#define KBD_DEFLEDS (1 << VC_NUMLOCK)
65#else
66#define KBD_DEFLEDS 0
67#endif
68
69#define KBD_DEFLOCK 0
70
71void compute_shiftstate(void);
72
73/*
74 * Handler Tables.
75 */
76
77#define K_HANDLERS\
78 k_self, k_fn, k_spec, k_pad,\
79 k_dead, k_cons, k_cur, k_shift,\
80 k_meta, k_ascii, k_lock, k_lowercase,\
81 k_slock, k_dead2, k_brl, k_ignore
82
83typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
84 char up_flag);
85static k_handler_fn K_HANDLERS;
86static k_handler_fn *k_handler[16] = { K_HANDLERS };
87
88#define FN_HANDLERS\
89 fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\
90 fn_show_state, fn_send_intr, fn_lastcons, fn_caps_toggle,\
91 fn_num, fn_hold, fn_scroll_forw, fn_scroll_back,\
92 fn_boot_it, fn_caps_on, fn_compose, fn_SAK,\
93 fn_dec_console, fn_inc_console, fn_spawn_con, fn_bare_num
94
95typedef void (fn_handler_fn)(struct vc_data *vc);
96static fn_handler_fn FN_HANDLERS;
97static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
98
99/*
100 * Variables exported for vt_ioctl.c
101 */
102
103/* maximum values each key_handler can handle */
104const int max_vals[] = {
105 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
106 NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
107 255, NR_LOCK - 1, 255, NR_BRL - 1
108};
109
110const int NR_TYPES = ARRAY_SIZE(max_vals);
111
112struct kbd_struct kbd_table[MAX_NR_CONSOLES];
113EXPORT_SYMBOL_GPL(kbd_table);
114static struct kbd_struct *kbd = kbd_table;
115
116struct vt_spawn_console vt_spawn_con = {
117 .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock),
118 .pid = NULL,
119 .sig = 0,
120};
121
122/*
123 * Variables exported for vt.c
124 */
125
126int shift_state = 0;
127
128/*
129 * Internal Data.
130 */
131
132static struct input_handler kbd_handler;
133static DEFINE_SPINLOCK(kbd_event_lock);
134static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
135static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
136static bool dead_key_next;
137static int npadch = -1; /* -1 or number assembled on pad */
138static unsigned int diacr;
139static char rep; /* flag telling character repeat */
140
141static unsigned char ledstate = 0xff; /* undefined */
142static unsigned char ledioctl;
143
144static struct ledptr {
145 unsigned int *addr;
146 unsigned int mask;
147 unsigned char valid:1;
148} ledptrs[3];
149
150/*
151 * Notifier list for console keyboard events
152 */
153static ATOMIC_NOTIFIER_HEAD(keyboard_notifier_list);
154
155int register_keyboard_notifier(struct notifier_block *nb)
156{
157 return atomic_notifier_chain_register(&keyboard_notifier_list, nb);
158}
159EXPORT_SYMBOL_GPL(register_keyboard_notifier);
160
161int unregister_keyboard_notifier(struct notifier_block *nb)
162{
163 return atomic_notifier_chain_unregister(&keyboard_notifier_list, nb);
164}
165EXPORT_SYMBOL_GPL(unregister_keyboard_notifier);
166
167/*
168 * Translation of scancodes to keycodes. We set them on only the first
169 * keyboard in the list that accepts the scancode and keycode.
170 * Explanation for not choosing the first attached keyboard anymore:
171 * USB keyboards for example have two event devices: one for all "normal"
172 * keys and one for extra function keys (like "volume up", "make coffee",
173 * etc.). So this means that scancodes for the extra function keys won't
174 * be valid for the first event device, but will be for the second.
175 */
176
177struct getset_keycode_data {
178 struct input_keymap_entry ke;
179 int error;
180};
181
182static int getkeycode_helper(struct input_handle *handle, void *data)
183{
184 struct getset_keycode_data *d = data;
185
186 d->error = input_get_keycode(handle->dev, &d->ke);
187
188 return d->error == 0; /* stop as soon as we successfully get one */
189}
190
191int getkeycode(unsigned int scancode)
192{
193 struct getset_keycode_data d = {
194 .ke = {
195 .flags = 0,
196 .len = sizeof(scancode),
197 .keycode = 0,
198 },
199 .error = -ENODEV,
200 };
201
202 memcpy(d.ke.scancode, &scancode, sizeof(scancode));
203
204 input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper);
205
206 return d.error ?: d.ke.keycode;
207}
208
209static int setkeycode_helper(struct input_handle *handle, void *data)
210{
211 struct getset_keycode_data *d = data;
212
213 d->error = input_set_keycode(handle->dev, &d->ke);
214
215 return d->error == 0; /* stop as soon as we successfully set one */
216}
217
218int setkeycode(unsigned int scancode, unsigned int keycode)
219{
220 struct getset_keycode_data d = {
221 .ke = {
222 .flags = 0,
223 .len = sizeof(scancode),
224 .keycode = keycode,
225 },
226 .error = -ENODEV,
227 };
228
229 memcpy(d.ke.scancode, &scancode, sizeof(scancode));
230
231 input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper);
232
233 return d.error;
234}
235
236/*
237 * Making beeps and bells. Note that we prefer beeps to bells, but when
238 * shutting the sound off we do both.
239 */
240
241static int kd_sound_helper(struct input_handle *handle, void *data)
242{
243 unsigned int *hz = data;
244 struct input_dev *dev = handle->dev;
245
246 if (test_bit(EV_SND, dev->evbit)) {
247 if (test_bit(SND_TONE, dev->sndbit)) {
248 input_inject_event(handle, EV_SND, SND_TONE, *hz);
249 if (*hz)
250 return 0;
251 }
252 if (test_bit(SND_BELL, dev->sndbit))
253 input_inject_event(handle, EV_SND, SND_BELL, *hz ? 1 : 0);
254 }
255
256 return 0;
257}
258
259static void kd_nosound(unsigned long ignored)
260{
261 static unsigned int zero;
262
263 input_handler_for_each_handle(&kbd_handler, &zero, kd_sound_helper);
264}
265
266static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0);
267
268void kd_mksound(unsigned int hz, unsigned int ticks)
269{
270 del_timer_sync(&kd_mksound_timer);
271
272 input_handler_for_each_handle(&kbd_handler, &hz, kd_sound_helper);
273
274 if (hz && ticks)
275 mod_timer(&kd_mksound_timer, jiffies + ticks);
276}
277EXPORT_SYMBOL(kd_mksound);
278
279/*
280 * Setting the keyboard rate.
281 */
282
283static int kbd_rate_helper(struct input_handle *handle, void *data)
284{
285 struct input_dev *dev = handle->dev;
286 struct kbd_repeat *rep = data;
287
288 if (test_bit(EV_REP, dev->evbit)) {
289
290 if (rep[0].delay > 0)
291 input_inject_event(handle,
292 EV_REP, REP_DELAY, rep[0].delay);
293 if (rep[0].period > 0)
294 input_inject_event(handle,
295 EV_REP, REP_PERIOD, rep[0].period);
296
297 rep[1].delay = dev->rep[REP_DELAY];
298 rep[1].period = dev->rep[REP_PERIOD];
299 }
300
301 return 0;
302}
303
304int kbd_rate(struct kbd_repeat *rep)
305{
306 struct kbd_repeat data[2] = { *rep };
307
308 input_handler_for_each_handle(&kbd_handler, data, kbd_rate_helper);
309 *rep = data[1]; /* Copy currently used settings */
310
311 return 0;
312}
313
314/*
315 * Helper Functions.
316 */
317static void put_queue(struct vc_data *vc, int ch)
318{
319 struct tty_struct *tty = vc->port.tty;
320
321 if (tty) {
322 tty_insert_flip_char(tty, ch, 0);
323 con_schedule_flip(tty);
324 }
325}
326
327static void puts_queue(struct vc_data *vc, char *cp)
328{
329 struct tty_struct *tty = vc->port.tty;
330
331 if (!tty)
332 return;
333
334 while (*cp) {
335 tty_insert_flip_char(tty, *cp, 0);
336 cp++;
337 }
338 con_schedule_flip(tty);
339}
340
341static void applkey(struct vc_data *vc, int key, char mode)
342{
343 static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
344
345 buf[1] = (mode ? 'O' : '[');
346 buf[2] = key;
347 puts_queue(vc, buf);
348}
349
350/*
351 * Many other routines do put_queue, but I think either
352 * they produce ASCII, or they produce some user-assigned
353 * string, and in both cases we might assume that it is
354 * in utf-8 already.
355 */
356static void to_utf8(struct vc_data *vc, uint c)
357{
358 if (c < 0x80)
359 /* 0******* */
360 put_queue(vc, c);
361 else if (c < 0x800) {
362 /* 110***** 10****** */
363 put_queue(vc, 0xc0 | (c >> 6));
364 put_queue(vc, 0x80 | (c & 0x3f));
365 } else if (c < 0x10000) {
366 if (c >= 0xD800 && c < 0xE000)
367 return;
368 if (c == 0xFFFF)
369 return;
370 /* 1110**** 10****** 10****** */
371 put_queue(vc, 0xe0 | (c >> 12));
372 put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
373 put_queue(vc, 0x80 | (c & 0x3f));
374 } else if (c < 0x110000) {
375 /* 11110*** 10****** 10****** 10****** */
376 put_queue(vc, 0xf0 | (c >> 18));
377 put_queue(vc, 0x80 | ((c >> 12) & 0x3f));
378 put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
379 put_queue(vc, 0x80 | (c & 0x3f));
380 }
381}
382
383/*
384 * Called after returning from RAW mode or when changing consoles - recompute
385 * shift_down[] and shift_state from key_down[] maybe called when keymap is
386 * undefined, so that shiftkey release is seen
387 */
388void compute_shiftstate(void)
389{
390 unsigned int i, j, k, sym, val;
391
392 shift_state = 0;
393 memset(shift_down, 0, sizeof(shift_down));
394
395 for (i = 0; i < ARRAY_SIZE(key_down); i++) {
396
397 if (!key_down[i])
398 continue;
399
400 k = i * BITS_PER_LONG;
401
402 for (j = 0; j < BITS_PER_LONG; j++, k++) {
403
404 if (!test_bit(k, key_down))
405 continue;
406
407 sym = U(key_maps[0][k]);
408 if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
409 continue;
410
411 val = KVAL(sym);
412 if (val == KVAL(K_CAPSSHIFT))
413 val = KVAL(K_SHIFT);
414
415 shift_down[val]++;
416 shift_state |= (1 << val);
417 }
418 }
419}
420
421/*
422 * We have a combining character DIACR here, followed by the character CH.
423 * If the combination occurs in the table, return the corresponding value.
424 * Otherwise, if CH is a space or equals DIACR, return DIACR.
425 * Otherwise, conclude that DIACR was not combining after all,
426 * queue it and return CH.
427 */
428static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch)
429{
430 unsigned int d = diacr;
431 unsigned int i;
432
433 diacr = 0;
434
435 if ((d & ~0xff) == BRL_UC_ROW) {
436 if ((ch & ~0xff) == BRL_UC_ROW)
437 return d | ch;
438 } else {
439 for (i = 0; i < accent_table_size; i++)
440 if (accent_table[i].diacr == d && accent_table[i].base == ch)
441 return accent_table[i].result;
442 }
443
444 if (ch == ' ' || ch == (BRL_UC_ROW|0) || ch == d)
445 return d;
446
447 if (kbd->kbdmode == VC_UNICODE)
448 to_utf8(vc, d);
449 else {
450 int c = conv_uni_to_8bit(d);
451 if (c != -1)
452 put_queue(vc, c);
453 }
454
455 return ch;
456}
457
458/*
459 * Special function handlers
460 */
461static void fn_enter(struct vc_data *vc)
462{
463 if (diacr) {
464 if (kbd->kbdmode == VC_UNICODE)
465 to_utf8(vc, diacr);
466 else {
467 int c = conv_uni_to_8bit(diacr);
468 if (c != -1)
469 put_queue(vc, c);
470 }
471 diacr = 0;
472 }
473
474 put_queue(vc, 13);
475 if (vc_kbd_mode(kbd, VC_CRLF))
476 put_queue(vc, 10);
477}
478
479static void fn_caps_toggle(struct vc_data *vc)
480{
481 if (rep)
482 return;
483
484 chg_vc_kbd_led(kbd, VC_CAPSLOCK);
485}
486
487static void fn_caps_on(struct vc_data *vc)
488{
489 if (rep)
490 return;
491
492 set_vc_kbd_led(kbd, VC_CAPSLOCK);
493}
494
495static void fn_show_ptregs(struct vc_data *vc)
496{
497 struct pt_regs *regs = get_irq_regs();
498
499 if (regs)
500 show_regs(regs);
501}
502
503static void fn_hold(struct vc_data *vc)
504{
505 struct tty_struct *tty = vc->port.tty;
506
507 if (rep || !tty)
508 return;
509
510 /*
511 * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty);
512 * these routines are also activated by ^S/^Q.
513 * (And SCROLLOCK can also be set by the ioctl KDSKBLED.)
514 */
515 if (tty->stopped)
516 start_tty(tty);
517 else
518 stop_tty(tty);
519}
520
521static void fn_num(struct vc_data *vc)
522{
523 if (vc_kbd_mode(kbd, VC_APPLIC))
524 applkey(vc, 'P', 1);
525 else
526 fn_bare_num(vc);
527}
528
529/*
530 * Bind this to Shift-NumLock if you work in application keypad mode
531 * but want to be able to change the NumLock flag.
532 * Bind this to NumLock if you prefer that the NumLock key always
533 * changes the NumLock flag.
534 */
535static void fn_bare_num(struct vc_data *vc)
536{
537 if (!rep)
538 chg_vc_kbd_led(kbd, VC_NUMLOCK);
539}
540
541static void fn_lastcons(struct vc_data *vc)
542{
543 /* switch to the last used console, ChN */
544 set_console(last_console);
545}
546
547static void fn_dec_console(struct vc_data *vc)
548{
549 int i, cur = fg_console;
550
551 /* Currently switching? Queue this next switch relative to that. */
552 if (want_console != -1)
553 cur = want_console;
554
555 for (i = cur - 1; i != cur; i--) {
556 if (i == -1)
557 i = MAX_NR_CONSOLES - 1;
558 if (vc_cons_allocated(i))
559 break;
560 }
561 set_console(i);
562}
563
564static void fn_inc_console(struct vc_data *vc)
565{
566 int i, cur = fg_console;
567
568 /* Currently switching? Queue this next switch relative to that. */
569 if (want_console != -1)
570 cur = want_console;
571
572 for (i = cur+1; i != cur; i++) {
573 if (i == MAX_NR_CONSOLES)
574 i = 0;
575 if (vc_cons_allocated(i))
576 break;
577 }
578 set_console(i);
579}
580
581static void fn_send_intr(struct vc_data *vc)
582{
583 struct tty_struct *tty = vc->port.tty;
584
585 if (!tty)
586 return;
587 tty_insert_flip_char(tty, 0, TTY_BREAK);
588 con_schedule_flip(tty);
589}
590
591static void fn_scroll_forw(struct vc_data *vc)
592{
593 scrollfront(vc, 0);
594}
595
596static void fn_scroll_back(struct vc_data *vc)
597{
598 scrollback(vc, 0);
599}
600
601static void fn_show_mem(struct vc_data *vc)
602{
603 show_mem();
604}
605
606static void fn_show_state(struct vc_data *vc)
607{
608 show_state();
609}
610
611static void fn_boot_it(struct vc_data *vc)
612{
613 ctrl_alt_del();
614}
615
616static void fn_compose(struct vc_data *vc)
617{
618 dead_key_next = true;
619}
620
621static void fn_spawn_con(struct vc_data *vc)
622{
623 spin_lock(&vt_spawn_con.lock);
624 if (vt_spawn_con.pid)
625 if (kill_pid(vt_spawn_con.pid, vt_spawn_con.sig, 1)) {
626 put_pid(vt_spawn_con.pid);
627 vt_spawn_con.pid = NULL;
628 }
629 spin_unlock(&vt_spawn_con.lock);
630}
631
632static void fn_SAK(struct vc_data *vc)
633{
634 struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
635 schedule_work(SAK_work);
636}
637
638static void fn_null(struct vc_data *vc)
639{
640 compute_shiftstate();
641}
642
643/*
644 * Special key handlers
645 */
646static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag)
647{
648}
649
650static void k_spec(struct vc_data *vc, unsigned char value, char up_flag)
651{
652 if (up_flag)
653 return;
654 if (value >= ARRAY_SIZE(fn_handler))
655 return;
656 if ((kbd->kbdmode == VC_RAW ||
657 kbd->kbdmode == VC_MEDIUMRAW) &&
658 value != KVAL(K_SAK))
659 return; /* SAK is allowed even in raw mode */
660 fn_handler[value](vc);
661}
662
663static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag)
664{
665 pr_err("k_lowercase was called - impossible\n");
666}
667
668static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag)
669{
670 if (up_flag)
671 return; /* no action, if this is a key release */
672
673 if (diacr)
674 value = handle_diacr(vc, value);
675
676 if (dead_key_next) {
677 dead_key_next = false;
678 diacr = value;
679 return;
680 }
681 if (kbd->kbdmode == VC_UNICODE)
682 to_utf8(vc, value);
683 else {
684 int c = conv_uni_to_8bit(value);
685 if (c != -1)
686 put_queue(vc, c);
687 }
688}
689
690/*
691 * Handle dead key. Note that we now may have several
692 * dead keys modifying the same character. Very useful
693 * for Vietnamese.
694 */
695static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag)
696{
697 if (up_flag)
698 return;
699
700 diacr = (diacr ? handle_diacr(vc, value) : value);
701}
702
703static void k_self(struct vc_data *vc, unsigned char value, char up_flag)
704{
705 k_unicode(vc, conv_8bit_to_uni(value), up_flag);
706}
707
708static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag)
709{
710 k_deadunicode(vc, value, up_flag);
711}
712
713/*
714 * Obsolete - for backwards compatibility only
715 */
716static void k_dead(struct vc_data *vc, unsigned char value, char up_flag)
717{
718 static const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' };
719
720 k_deadunicode(vc, ret_diacr[value], up_flag);
721}
722
723static void k_cons(struct vc_data *vc, unsigned char value, char up_flag)
724{
725 if (up_flag)
726 return;
727
728 set_console(value);
729}
730
731static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
732{
733 if (up_flag)
734 return;
735
736 if ((unsigned)value < ARRAY_SIZE(func_table)) {
737 if (func_table[value])
738 puts_queue(vc, func_table[value]);
739 } else
740 pr_err("k_fn called with value=%d\n", value);
741}
742
743static void k_cur(struct vc_data *vc, unsigned char value, char up_flag)
744{
745 static const char cur_chars[] = "BDCA";
746
747 if (up_flag)
748 return;
749
750 applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE));
751}
752
753static void k_pad(struct vc_data *vc, unsigned char value, char up_flag)
754{
755 static const char pad_chars[] = "0123456789+-*/\015,.?()#";
756 static const char app_map[] = "pqrstuvwxylSRQMnnmPQS";
757
758 if (up_flag)
759 return; /* no action, if this is a key release */
760
761 /* kludge... shift forces cursor/number keys */
762 if (vc_kbd_mode(kbd, VC_APPLIC) && !shift_down[KG_SHIFT]) {
763 applkey(vc, app_map[value], 1);
764 return;
765 }
766
767 if (!vc_kbd_led(kbd, VC_NUMLOCK)) {
768
769 switch (value) {
770 case KVAL(K_PCOMMA):
771 case KVAL(K_PDOT):
772 k_fn(vc, KVAL(K_REMOVE), 0);
773 return;
774 case KVAL(K_P0):
775 k_fn(vc, KVAL(K_INSERT), 0);
776 return;
777 case KVAL(K_P1):
778 k_fn(vc, KVAL(K_SELECT), 0);
779 return;
780 case KVAL(K_P2):
781 k_cur(vc, KVAL(K_DOWN), 0);
782 return;
783 case KVAL(K_P3):
784 k_fn(vc, KVAL(K_PGDN), 0);
785 return;
786 case KVAL(K_P4):
787 k_cur(vc, KVAL(K_LEFT), 0);
788 return;
789 case KVAL(K_P6):
790 k_cur(vc, KVAL(K_RIGHT), 0);
791 return;
792 case KVAL(K_P7):
793 k_fn(vc, KVAL(K_FIND), 0);
794 return;
795 case KVAL(K_P8):
796 k_cur(vc, KVAL(K_UP), 0);
797 return;
798 case KVAL(K_P9):
799 k_fn(vc, KVAL(K_PGUP), 0);
800 return;
801 case KVAL(K_P5):
802 applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC));
803 return;
804 }
805 }
806
807 put_queue(vc, pad_chars[value]);
808 if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
809 put_queue(vc, 10);
810}
811
812static void k_shift(struct vc_data *vc, unsigned char value, char up_flag)
813{
814 int old_state = shift_state;
815
816 if (rep)
817 return;
818 /*
819 * Mimic typewriter:
820 * a CapsShift key acts like Shift but undoes CapsLock
821 */
822 if (value == KVAL(K_CAPSSHIFT)) {
823 value = KVAL(K_SHIFT);
824 if (!up_flag)
825 clr_vc_kbd_led(kbd, VC_CAPSLOCK);
826 }
827
828 if (up_flag) {
829 /*
830 * handle the case that two shift or control
831 * keys are depressed simultaneously
832 */
833 if (shift_down[value])
834 shift_down[value]--;
835 } else
836 shift_down[value]++;
837
838 if (shift_down[value])
839 shift_state |= (1 << value);
840 else
841 shift_state &= ~(1 << value);
842
843 /* kludge */
844 if (up_flag && shift_state != old_state && npadch != -1) {
845 if (kbd->kbdmode == VC_UNICODE)
846 to_utf8(vc, npadch);
847 else
848 put_queue(vc, npadch & 0xff);
849 npadch = -1;
850 }
851}
852
853static void k_meta(struct vc_data *vc, unsigned char value, char up_flag)
854{
855 if (up_flag)
856 return;
857
858 if (vc_kbd_mode(kbd, VC_META)) {
859 put_queue(vc, '\033');
860 put_queue(vc, value);
861 } else
862 put_queue(vc, value | 0x80);
863}
864
865static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag)
866{
867 int base;
868
869 if (up_flag)
870 return;
871
872 if (value < 10) {
873 /* decimal input of code, while Alt depressed */
874 base = 10;
875 } else {
876 /* hexadecimal input of code, while AltGr depressed */
877 value -= 10;
878 base = 16;
879 }
880
881 if (npadch == -1)
882 npadch = value;
883 else
884 npadch = npadch * base + value;
885}
886
887static void k_lock(struct vc_data *vc, unsigned char value, char up_flag)
888{
889 if (up_flag || rep)
890 return;
891
892 chg_vc_kbd_lock(kbd, value);
893}
894
895static void k_slock(struct vc_data *vc, unsigned char value, char up_flag)
896{
897 k_shift(vc, value, up_flag);
898 if (up_flag || rep)
899 return;
900
901 chg_vc_kbd_slock(kbd, value);
902 /* try to make Alt, oops, AltGr and such work */
903 if (!key_maps[kbd->lockstate ^ kbd->slockstate]) {
904 kbd->slockstate = 0;
905 chg_vc_kbd_slock(kbd, value);
906 }
907}
908
909/* by default, 300ms interval for combination release */
910static unsigned brl_timeout = 300;
911MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for commit on first key release)");
912module_param(brl_timeout, uint, 0644);
913
914static unsigned brl_nbchords = 1;
915MODULE_PARM_DESC(brl_nbchords, "Number of chords that produce a braille pattern (0 for dead chords)");
916module_param(brl_nbchords, uint, 0644);
917
918static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag)
919{
920 static unsigned long chords;
921 static unsigned committed;
922
923 if (!brl_nbchords)
924 k_deadunicode(vc, BRL_UC_ROW | pattern, up_flag);
925 else {
926 committed |= pattern;
927 chords++;
928 if (chords == brl_nbchords) {
929 k_unicode(vc, BRL_UC_ROW | committed, up_flag);
930 chords = 0;
931 committed = 0;
932 }
933 }
934}
935
936static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
937{
938 static unsigned pressed, committing;
939 static unsigned long releasestart;
940
941 if (kbd->kbdmode != VC_UNICODE) {
942 if (!up_flag)
943 pr_warning("keyboard mode must be unicode for braille patterns\n");
944 return;
945 }
946
947 if (!value) {
948 k_unicode(vc, BRL_UC_ROW, up_flag);
949 return;
950 }
951
952 if (value > 8)
953 return;
954
955 if (!up_flag) {
956 pressed |= 1 << (value - 1);
957 if (!brl_timeout)
958 committing = pressed;
959 } else if (brl_timeout) {
960 if (!committing ||
961 time_after(jiffies,
962 releasestart + msecs_to_jiffies(brl_timeout))) {
963 committing = pressed;
964 releasestart = jiffies;
965 }
966 pressed &= ~(1 << (value - 1));
967 if (!pressed && committing) {
968 k_brlcommit(vc, committing, 0);
969 committing = 0;
970 }
971 } else {
972 if (committing) {
973 k_brlcommit(vc, committing, 0);
974 committing = 0;
975 }
976 pressed &= ~(1 << (value - 1));
977 }
978}
979
980/*
981 * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
982 * or (ii) whatever pattern of lights people want to show using KDSETLED,
983 * or (iii) specified bits of specified words in kernel memory.
984 */
985unsigned char getledstate(void)
986{
987 return ledstate;
988}
989
990void setledstate(struct kbd_struct *kbd, unsigned int led)
991{
992 if (!(led & ~7)) {
993 ledioctl = led;
994 kbd->ledmode = LED_SHOW_IOCTL;
995 } else
996 kbd->ledmode = LED_SHOW_FLAGS;
997
998 set_leds();
999}
1000
1001static inline unsigned char getleds(void)
1002{
1003 struct kbd_struct *kbd = kbd_table + fg_console;
1004 unsigned char leds;
1005 int i;
1006
1007 if (kbd->ledmode == LED_SHOW_IOCTL)
1008 return ledioctl;
1009
1010 leds = kbd->ledflagstate;
1011
1012 if (kbd->ledmode == LED_SHOW_MEM) {
1013 for (i = 0; i < 3; i++)
1014 if (ledptrs[i].valid) {
1015 if (*ledptrs[i].addr & ledptrs[i].mask)
1016 leds |= (1 << i);
1017 else
1018 leds &= ~(1 << i);
1019 }
1020 }
1021 return leds;
1022}
1023
1024static int kbd_update_leds_helper(struct input_handle *handle, void *data)
1025{
1026 unsigned char leds = *(unsigned char *)data;
1027
1028 if (test_bit(EV_LED, handle->dev->evbit)) {
1029 input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
1030 input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
1031 input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
1032 input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
1033 }
1034
1035 return 0;
1036}
1037
1038/*
1039 * This is the tasklet that updates LED state on all keyboards
1040 * attached to the box. The reason we use tasklet is that we
1041 * need to handle the scenario when keyboard handler is not
1042 * registered yet but we already getting updates form VT to
1043 * update led state.
1044 */
1045static void kbd_bh(unsigned long dummy)
1046{
1047 unsigned char leds = getleds();
1048
1049 if (leds != ledstate) {
1050 input_handler_for_each_handle(&kbd_handler, &leds,
1051 kbd_update_leds_helper);
1052 ledstate = leds;
1053 }
1054}
1055
1056DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
1057
1058#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
1059 defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
1060 defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
1061 (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC)) ||\
1062 defined(CONFIG_AVR32)
1063
1064#define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
1065 ((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
1066
1067static const unsigned short x86_keycodes[256] =
1068 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1069 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1070 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
1071 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
1072 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
1073 80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92,
1074 284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339,
1075 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349,
1076 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355,
1077 103,104,105,275,287,279,258,106,274,107,294,364,358,363,362,361,
1078 291,108,381,281,290,272,292,305,280, 99,112,257,306,359,113,114,
1079 264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116,
1080 377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307,
1081 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
1082 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 };
1083
1084#ifdef CONFIG_SPARC
1085static int sparc_l1_a_state;
1086extern void sun_do_break(void);
1087#endif
1088
1089static int emulate_raw(struct vc_data *vc, unsigned int keycode,
1090 unsigned char up_flag)
1091{
1092 int code;
1093
1094 switch (keycode) {
1095
1096 case KEY_PAUSE:
1097 put_queue(vc, 0xe1);
1098 put_queue(vc, 0x1d | up_flag);
1099 put_queue(vc, 0x45 | up_flag);
1100 break;
1101
1102 case KEY_HANGEUL:
1103 if (!up_flag)
1104 put_queue(vc, 0xf2);
1105 break;
1106
1107 case KEY_HANJA:
1108 if (!up_flag)
1109 put_queue(vc, 0xf1);
1110 break;
1111
1112 case KEY_SYSRQ:
1113 /*
1114 * Real AT keyboards (that's what we're trying
1115 * to emulate here emit 0xe0 0x2a 0xe0 0x37 when
1116 * pressing PrtSc/SysRq alone, but simply 0x54
1117 * when pressing Alt+PrtSc/SysRq.
1118 */
1119 if (test_bit(KEY_LEFTALT, key_down) ||
1120 test_bit(KEY_RIGHTALT, key_down)) {
1121 put_queue(vc, 0x54 | up_flag);
1122 } else {
1123 put_queue(vc, 0xe0);
1124 put_queue(vc, 0x2a | up_flag);
1125 put_queue(vc, 0xe0);
1126 put_queue(vc, 0x37 | up_flag);
1127 }
1128 break;
1129
1130 default:
1131 if (keycode > 255)
1132 return -1;
1133
1134 code = x86_keycodes[keycode];
1135 if (!code)
1136 return -1;
1137
1138 if (code & 0x100)
1139 put_queue(vc, 0xe0);
1140 put_queue(vc, (code & 0x7f) | up_flag);
1141
1142 break;
1143 }
1144
1145 return 0;
1146}
1147
1148#else
1149
1150#define HW_RAW(dev) 0
1151
1152static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
1153{
1154 if (keycode > 127)
1155 return -1;
1156
1157 put_queue(vc, keycode | up_flag);
1158 return 0;
1159}
1160#endif
1161
1162static void kbd_rawcode(unsigned char data)
1163{
1164 struct vc_data *vc = vc_cons[fg_console].d;
1165
1166 kbd = kbd_table + vc->vc_num;
1167 if (kbd->kbdmode == VC_RAW)
1168 put_queue(vc, data);
1169}
1170
1171static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
1172{
1173 struct vc_data *vc = vc_cons[fg_console].d;
1174 unsigned short keysym, *key_map;
1175 unsigned char type;
1176 bool raw_mode;
1177 struct tty_struct *tty;
1178 int shift_final;
1179 struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down };
1180 int rc;
1181
1182 tty = vc->port.tty;
1183
1184 if (tty && (!tty->driver_data)) {
1185 /* No driver data? Strange. Okay we fix it then. */
1186 tty->driver_data = vc;
1187 }
1188
1189 kbd = kbd_table + vc->vc_num;
1190
1191#ifdef CONFIG_SPARC
1192 if (keycode == KEY_STOP)
1193 sparc_l1_a_state = down;
1194#endif
1195
1196 rep = (down == 2);
1197
1198 raw_mode = (kbd->kbdmode == VC_RAW);
1199 if (raw_mode && !hw_raw)
1200 if (emulate_raw(vc, keycode, !down << 7))
1201 if (keycode < BTN_MISC && printk_ratelimit())
1202 pr_warning("can't emulate rawmode for keycode %d\n",
1203 keycode);
1204
1205#ifdef CONFIG_SPARC
1206 if (keycode == KEY_A && sparc_l1_a_state) {
1207 sparc_l1_a_state = false;
1208 sun_do_break();
1209 }
1210#endif
1211
1212 if (kbd->kbdmode == VC_MEDIUMRAW) {
1213 /*
1214 * This is extended medium raw mode, with keys above 127
1215 * encoded as 0, high 7 bits, low 7 bits, with the 0 bearing
1216 * the 'up' flag if needed. 0 is reserved, so this shouldn't
1217 * interfere with anything else. The two bytes after 0 will
1218 * always have the up flag set not to interfere with older
1219 * applications. This allows for 16384 different keycodes,
1220 * which should be enough.
1221 */
1222 if (keycode < 128) {
1223 put_queue(vc, keycode | (!down << 7));
1224 } else {
1225 put_queue(vc, !down << 7);
1226 put_queue(vc, (keycode >> 7) | 0x80);
1227 put_queue(vc, keycode | 0x80);
1228 }
1229 raw_mode = true;
1230 }
1231
1232 if (down)
1233 set_bit(keycode, key_down);
1234 else
1235 clear_bit(keycode, key_down);
1236
1237 if (rep &&
1238 (!vc_kbd_mode(kbd, VC_REPEAT) ||
1239 (tty && !L_ECHO(tty) && tty_chars_in_buffer(tty)))) {
1240 /*
1241 * Don't repeat a key if the input buffers are not empty and the
1242 * characters get aren't echoed locally. This makes key repeat
1243 * usable with slow applications and under heavy loads.
1244 */
1245 return;
1246 }
1247
1248 param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
1249 param.ledstate = kbd->ledflagstate;
1250 key_map = key_maps[shift_final];
1251
1252 rc = atomic_notifier_call_chain(&keyboard_notifier_list,
1253 KBD_KEYCODE, &param);
1254 if (rc == NOTIFY_STOP || !key_map) {
1255 atomic_notifier_call_chain(&keyboard_notifier_list,
1256 KBD_UNBOUND_KEYCODE, &param);
1257 compute_shiftstate();
1258 kbd->slockstate = 0;
1259 return;
1260 }
1261
1262 if (keycode < NR_KEYS)
1263 keysym = key_map[keycode];
1264 else if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
1265 keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1));
1266 else
1267 return;
1268
1269 type = KTYP(keysym);
1270
1271 if (type < 0xf0) {
1272 param.value = keysym;
1273 rc = atomic_notifier_call_chain(&keyboard_notifier_list,
1274 KBD_UNICODE, &param);
1275 if (rc != NOTIFY_STOP)
1276 if (down && !raw_mode)
1277 to_utf8(vc, keysym);
1278 return;
1279 }
1280
1281 type -= 0xf0;
1282
1283 if (type == KT_LETTER) {
1284 type = KT_LATIN;
1285 if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
1286 key_map = key_maps[shift_final ^ (1 << KG_SHIFT)];
1287 if (key_map)
1288 keysym = key_map[keycode];
1289 }
1290 }
1291
1292 param.value = keysym;
1293 rc = atomic_notifier_call_chain(&keyboard_notifier_list,
1294 KBD_KEYSYM, &param);
1295 if (rc == NOTIFY_STOP)
1296 return;
1297
1298 if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
1299 return;
1300
1301 (*k_handler[type])(vc, keysym & 0xff, !down);
1302
1303 param.ledstate = kbd->ledflagstate;
1304 atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, &param);
1305
1306 if (type != KT_SLOCK)
1307 kbd->slockstate = 0;
1308}
1309
1310static void kbd_event(struct input_handle *handle, unsigned int event_type,
1311 unsigned int event_code, int value)
1312{
1313 /* We are called with interrupts disabled, just take the lock */
1314 spin_lock(&kbd_event_lock);
1315
1316 if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
1317 kbd_rawcode(value);
1318 if (event_type == EV_KEY)
1319 kbd_keycode(event_code, value, HW_RAW(handle->dev));
1320
1321 spin_unlock(&kbd_event_lock);
1322
1323 tasklet_schedule(&keyboard_tasklet);
1324 do_poke_blanked_console = 1;
1325 schedule_console_callback();
1326}
1327
1328static bool kbd_match(struct input_handler *handler, struct input_dev *dev)
1329{
1330 int i;
1331
1332 if (test_bit(EV_SND, dev->evbit))
1333 return true;
1334
1335 if (test_bit(EV_KEY, dev->evbit)) {
1336 for (i = KEY_RESERVED; i < BTN_MISC; i++)
1337 if (test_bit(i, dev->keybit))
1338 return true;
1339 for (i = KEY_BRL_DOT1; i <= KEY_BRL_DOT10; i++)
1340 if (test_bit(i, dev->keybit))
1341 return true;
1342 }
1343
1344 return false;
1345}
1346
1347/*
1348 * When a keyboard (or other input device) is found, the kbd_connect
1349 * function is called. The function then looks at the device, and if it
1350 * likes it, it can open it and get events from it. In this (kbd_connect)
1351 * function, we should decide which VT to bind that keyboard to initially.
1352 */
1353static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
1354 const struct input_device_id *id)
1355{
1356 struct input_handle *handle;
1357 int error;
1358
1359 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
1360 if (!handle)
1361 return -ENOMEM;
1362
1363 handle->dev = dev;
1364 handle->handler = handler;
1365 handle->name = "kbd";
1366
1367 error = input_register_handle(handle);
1368 if (error)
1369 goto err_free_handle;
1370
1371 error = input_open_device(handle);
1372 if (error)
1373 goto err_unregister_handle;
1374
1375 return 0;
1376
1377 err_unregister_handle:
1378 input_unregister_handle(handle);
1379 err_free_handle:
1380 kfree(handle);
1381 return error;
1382}
1383
1384static void kbd_disconnect(struct input_handle *handle)
1385{
1386 input_close_device(handle);
1387 input_unregister_handle(handle);
1388 kfree(handle);
1389}
1390
1391/*
1392 * Start keyboard handler on the new keyboard by refreshing LED state to
1393 * match the rest of the system.
1394 */
1395static void kbd_start(struct input_handle *handle)
1396{
1397 tasklet_disable(&keyboard_tasklet);
1398
1399 if (ledstate != 0xff)
1400 kbd_update_leds_helper(handle, &ledstate);
1401
1402 tasklet_enable(&keyboard_tasklet);
1403}
1404
1405static const struct input_device_id kbd_ids[] = {
1406 {
1407 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
1408 .evbit = { BIT_MASK(EV_KEY) },
1409 },
1410
1411 {
1412 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
1413 .evbit = { BIT_MASK(EV_SND) },
1414 },
1415
1416 { }, /* Terminating entry */
1417};
1418
1419MODULE_DEVICE_TABLE(input, kbd_ids);
1420
1421static struct input_handler kbd_handler = {
1422 .event = kbd_event,
1423 .match = kbd_match,
1424 .connect = kbd_connect,
1425 .disconnect = kbd_disconnect,
1426 .start = kbd_start,
1427 .name = "kbd",
1428 .id_table = kbd_ids,
1429};
1430
1431int __init kbd_init(void)
1432{
1433 int i;
1434 int error;
1435
1436 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1437 kbd_table[i].ledflagstate = KBD_DEFLEDS;
1438 kbd_table[i].default_ledflagstate = KBD_DEFLEDS;
1439 kbd_table[i].ledmode = LED_SHOW_FLAGS;
1440 kbd_table[i].lockstate = KBD_DEFLOCK;
1441 kbd_table[i].slockstate = 0;
1442 kbd_table[i].modeflags = KBD_DEFMODE;
1443 kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
1444 }
1445
1446 error = input_register_handler(&kbd_handler);
1447 if (error)
1448 return error;
1449
1450 tasklet_enable(&keyboard_tasklet);
1451 tasklet_schedule(&keyboard_tasklet);
1452
1453 return 0;
1454}
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c
new file mode 100644
index 000000000000..ebae344ce910
--- /dev/null
+++ b/drivers/tty/vt/selection.c
@@ -0,0 +1,348 @@
1/*
2 * linux/drivers/char/selection.c
3 *
4 * This module exports the functions:
5 *
6 * 'int set_selection(struct tiocl_selection __user *, struct tty_struct *)'
7 * 'void clear_selection(void)'
8 * 'int paste_selection(struct tty_struct *)'
9 * 'int sel_loadlut(char __user *)'
10 *
11 * Now that /dev/vcs exists, most of this can disappear again.
12 */
13
14#include <linux/module.h>
15#include <linux/tty.h>
16#include <linux/sched.h>
17#include <linux/mm.h>
18#include <linux/slab.h>
19#include <linux/types.h>
20
21#include <asm/uaccess.h>
22
23#include <linux/kbd_kern.h>
24#include <linux/vt_kern.h>
25#include <linux/consolemap.h>
26#include <linux/selection.h>
27#include <linux/tiocl.h>
28#include <linux/console.h>
29#include <linux/smp_lock.h>
30
31/* Don't take this from <ctype.h>: 011-015 on the screen aren't spaces */
32#define isspace(c) ((c) == ' ')
33
34extern void poke_blanked_console(void);
35
36/* Variables for selection control. */
37/* Use a dynamic buffer, instead of static (Dec 1994) */
38struct vc_data *sel_cons; /* must not be deallocated */
39static int use_unicode;
40static volatile int sel_start = -1; /* cleared by clear_selection */
41static int sel_end;
42static int sel_buffer_lth;
43static char *sel_buffer;
44
45/* clear_selection, highlight and highlight_pointer can be called
46 from interrupt (via scrollback/front) */
47
48/* set reverse video on characters s-e of console with selection. */
49static inline void highlight(const int s, const int e)
50{
51 invert_screen(sel_cons, s, e-s+2, 1);
52}
53
54/* use complementary color to show the pointer */
55static inline void highlight_pointer(const int where)
56{
57 complement_pos(sel_cons, where);
58}
59
60static u16
61sel_pos(int n)
62{
63 return inverse_translate(sel_cons, screen_glyph(sel_cons, n),
64 use_unicode);
65}
66
67/* remove the current selection highlight, if any,
68 from the console holding the selection. */
69void
70clear_selection(void) {
71 highlight_pointer(-1); /* hide the pointer */
72 if (sel_start != -1) {
73 highlight(sel_start, sel_end);
74 sel_start = -1;
75 }
76}
77
78/*
79 * User settable table: what characters are to be considered alphabetic?
80 * 256 bits
81 */
82static u32 inwordLut[8]={
83 0x00000000, /* control chars */
84 0x03FF0000, /* digits */
85 0x87FFFFFE, /* uppercase and '_' */
86 0x07FFFFFE, /* lowercase */
87 0x00000000,
88 0x00000000,
89 0xFF7FFFFF, /* latin-1 accented letters, not multiplication sign */
90 0xFF7FFFFF /* latin-1 accented letters, not division sign */
91};
92
93static inline int inword(const u16 c) {
94 return c > 0xff || (( inwordLut[c>>5] >> (c & 0x1F) ) & 1);
95}
96
97/* set inwordLut contents. Invoked by ioctl(). */
98int sel_loadlut(char __user *p)
99{
100 return copy_from_user(inwordLut, (u32 __user *)(p+4), 32) ? -EFAULT : 0;
101}
102
103/* does screen address p correspond to character at LH/RH edge of screen? */
104static inline int atedge(const int p, int size_row)
105{
106 return (!(p % size_row) || !((p + 2) % size_row));
107}
108
109/* constrain v such that v <= u */
110static inline unsigned short limit(const unsigned short v, const unsigned short u)
111{
112 return (v > u) ? u : v;
113}
114
115/* stores the char in UTF8 and returns the number of bytes used (1-3) */
116static int store_utf8(u16 c, char *p)
117{
118 if (c < 0x80) {
119 /* 0******* */
120 p[0] = c;
121 return 1;
122 } else if (c < 0x800) {
123 /* 110***** 10****** */
124 p[0] = 0xc0 | (c >> 6);
125 p[1] = 0x80 | (c & 0x3f);
126 return 2;
127 } else {
128 /* 1110**** 10****** 10****** */
129 p[0] = 0xe0 | (c >> 12);
130 p[1] = 0x80 | ((c >> 6) & 0x3f);
131 p[2] = 0x80 | (c & 0x3f);
132 return 3;
133 }
134}
135
136/* set the current selection. Invoked by ioctl() or by kernel code. */
137int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty)
138{
139 struct vc_data *vc = vc_cons[fg_console].d;
140 int sel_mode, new_sel_start, new_sel_end, spc;
141 char *bp, *obp;
142 int i, ps, pe, multiplier;
143 u16 c;
144 struct kbd_struct *kbd = kbd_table + fg_console;
145
146 poke_blanked_console();
147
148 { unsigned short xs, ys, xe, ye;
149
150 if (!access_ok(VERIFY_READ, sel, sizeof(*sel)))
151 return -EFAULT;
152 __get_user(xs, &sel->xs);
153 __get_user(ys, &sel->ys);
154 __get_user(xe, &sel->xe);
155 __get_user(ye, &sel->ye);
156 __get_user(sel_mode, &sel->sel_mode);
157 xs--; ys--; xe--; ye--;
158 xs = limit(xs, vc->vc_cols - 1);
159 ys = limit(ys, vc->vc_rows - 1);
160 xe = limit(xe, vc->vc_cols - 1);
161 ye = limit(ye, vc->vc_rows - 1);
162 ps = ys * vc->vc_size_row + (xs << 1);
163 pe = ye * vc->vc_size_row + (xe << 1);
164
165 if (sel_mode == TIOCL_SELCLEAR) {
166 /* useful for screendump without selection highlights */
167 clear_selection();
168 return 0;
169 }
170
171 if (mouse_reporting() && (sel_mode & TIOCL_SELMOUSEREPORT)) {
172 mouse_report(tty, sel_mode & TIOCL_SELBUTTONMASK, xs, ys);
173 return 0;
174 }
175 }
176
177 if (ps > pe) /* make sel_start <= sel_end */
178 {
179 int tmp = ps;
180 ps = pe;
181 pe = tmp;
182 }
183
184 if (sel_cons != vc_cons[fg_console].d) {
185 clear_selection();
186 sel_cons = vc_cons[fg_console].d;
187 }
188 use_unicode = kbd && kbd->kbdmode == VC_UNICODE;
189
190 switch (sel_mode)
191 {
192 case TIOCL_SELCHAR: /* character-by-character selection */
193 new_sel_start = ps;
194 new_sel_end = pe;
195 break;
196 case TIOCL_SELWORD: /* word-by-word selection */
197 spc = isspace(sel_pos(ps));
198 for (new_sel_start = ps; ; ps -= 2)
199 {
200 if ((spc && !isspace(sel_pos(ps))) ||
201 (!spc && !inword(sel_pos(ps))))
202 break;
203 new_sel_start = ps;
204 if (!(ps % vc->vc_size_row))
205 break;
206 }
207 spc = isspace(sel_pos(pe));
208 for (new_sel_end = pe; ; pe += 2)
209 {
210 if ((spc && !isspace(sel_pos(pe))) ||
211 (!spc && !inword(sel_pos(pe))))
212 break;
213 new_sel_end = pe;
214 if (!((pe + 2) % vc->vc_size_row))
215 break;
216 }
217 break;
218 case TIOCL_SELLINE: /* line-by-line selection */
219 new_sel_start = ps - ps % vc->vc_size_row;
220 new_sel_end = pe + vc->vc_size_row
221 - pe % vc->vc_size_row - 2;
222 break;
223 case TIOCL_SELPOINTER:
224 highlight_pointer(pe);
225 return 0;
226 default:
227 return -EINVAL;
228 }
229
230 /* remove the pointer */
231 highlight_pointer(-1);
232
233 /* select to end of line if on trailing space */
234 if (new_sel_end > new_sel_start &&
235 !atedge(new_sel_end, vc->vc_size_row) &&
236 isspace(sel_pos(new_sel_end))) {
237 for (pe = new_sel_end + 2; ; pe += 2)
238 if (!isspace(sel_pos(pe)) ||
239 atedge(pe, vc->vc_size_row))
240 break;
241 if (isspace(sel_pos(pe)))
242 new_sel_end = pe;
243 }
244 if (sel_start == -1) /* no current selection */
245 highlight(new_sel_start, new_sel_end);
246 else if (new_sel_start == sel_start)
247 {
248 if (new_sel_end == sel_end) /* no action required */
249 return 0;
250 else if (new_sel_end > sel_end) /* extend to right */
251 highlight(sel_end + 2, new_sel_end);
252 else /* contract from right */
253 highlight(new_sel_end + 2, sel_end);
254 }
255 else if (new_sel_end == sel_end)
256 {
257 if (new_sel_start < sel_start) /* extend to left */
258 highlight(new_sel_start, sel_start - 2);
259 else /* contract from left */
260 highlight(sel_start, new_sel_start - 2);
261 }
262 else /* some other case; start selection from scratch */
263 {
264 clear_selection();
265 highlight(new_sel_start, new_sel_end);
266 }
267 sel_start = new_sel_start;
268 sel_end = new_sel_end;
269
270 /* Allocate a new buffer before freeing the old one ... */
271 multiplier = use_unicode ? 3 : 1; /* chars can take up to 3 bytes */
272 bp = kmalloc(((sel_end-sel_start)/2+1)*multiplier, GFP_KERNEL);
273 if (!bp) {
274 printk(KERN_WARNING "selection: kmalloc() failed\n");
275 clear_selection();
276 return -ENOMEM;
277 }
278 kfree(sel_buffer);
279 sel_buffer = bp;
280
281 obp = bp;
282 for (i = sel_start; i <= sel_end; i += 2) {
283 c = sel_pos(i);
284 if (use_unicode)
285 bp += store_utf8(c, bp);
286 else
287 *bp++ = c;
288 if (!isspace(c))
289 obp = bp;
290 if (! ((i + 2) % vc->vc_size_row)) {
291 /* strip trailing blanks from line and add newline,
292 unless non-space at end of line. */
293 if (obp != bp) {
294 bp = obp;
295 *bp++ = '\r';
296 }
297 obp = bp;
298 }
299 }
300 sel_buffer_lth = bp - sel_buffer;
301 return 0;
302}
303
304/* Insert the contents of the selection buffer into the
305 * queue of the tty associated with the current console.
306 * Invoked by ioctl().
307 */
308int paste_selection(struct tty_struct *tty)
309{
310 struct vc_data *vc = tty->driver_data;
311 int pasted = 0;
312 unsigned int count;
313 struct tty_ldisc *ld;
314 DECLARE_WAITQUEUE(wait, current);
315
316 /* always called with BTM from vt_ioctl */
317 WARN_ON(!tty_locked());
318
319 acquire_console_sem();
320 poke_blanked_console();
321 release_console_sem();
322
323 ld = tty_ldisc_ref(tty);
324 if (!ld) {
325 tty_unlock();
326 ld = tty_ldisc_ref_wait(tty);
327 tty_lock();
328 }
329
330 add_wait_queue(&vc->paste_wait, &wait);
331 while (sel_buffer && sel_buffer_lth > pasted) {
332 set_current_state(TASK_INTERRUPTIBLE);
333 if (test_bit(TTY_THROTTLED, &tty->flags)) {
334 schedule();
335 continue;
336 }
337 count = sel_buffer_lth - pasted;
338 count = min(count, tty->receive_room);
339 tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
340 NULL, count);
341 pasted += count;
342 }
343 remove_wait_queue(&vc->paste_wait, &wait);
344 __set_current_state(TASK_RUNNING);
345
346 tty_ldisc_deref(ld);
347 return 0;
348}
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c
new file mode 100644
index 000000000000..273ab44cc91d
--- /dev/null
+++ b/drivers/tty/vt/vc_screen.c
@@ -0,0 +1,644 @@
1/*
2 * linux/drivers/char/vc_screen.c
3 *
4 * Provide access to virtual console memory.
5 * /dev/vcs0: the screen as it is being viewed right now (possibly scrolled)
6 * /dev/vcsN: the screen of /dev/ttyN (1 <= N <= 63)
7 * [minor: N]
8 *
9 * /dev/vcsaN: idem, but including attributes, and prefixed with
10 * the 4 bytes lines,columns,x,y (as screendump used to give).
11 * Attribute/character pair is in native endianity.
12 * [minor: N+128]
13 *
14 * This replaces screendump and part of selection, so that the system
15 * administrator can control access using file system permissions.
16 *
17 * aeb@cwi.nl - efter Friedas begravelse - 950211
18 *
19 * machek@k332.feld.cvut.cz - modified not to send characters to wrong console
20 * - fixed some fatal off-by-one bugs (0-- no longer == -1 -> looping and looping and looping...)
21 * - making it shorter - scr_readw are macros which expand in PRETTY long code
22 */
23
24#include <linux/kernel.h>
25#include <linux/major.h>
26#include <linux/errno.h>
27#include <linux/tty.h>
28#include <linux/interrupt.h>
29#include <linux/mm.h>
30#include <linux/init.h>
31#include <linux/mutex.h>
32#include <linux/vt_kern.h>
33#include <linux/selection.h>
34#include <linux/kbd_kern.h>
35#include <linux/console.h>
36#include <linux/device.h>
37#include <linux/smp_lock.h>
38#include <linux/sched.h>
39#include <linux/fs.h>
40#include <linux/poll.h>
41#include <linux/signal.h>
42#include <linux/slab.h>
43#include <linux/notifier.h>
44
45#include <asm/uaccess.h>
46#include <asm/byteorder.h>
47#include <asm/unaligned.h>
48
49#undef attr
50#undef org
51#undef addr
52#define HEADER_SIZE 4
53
54struct vcs_poll_data {
55 struct notifier_block notifier;
56 unsigned int cons_num;
57 bool seen_last_update;
58 wait_queue_head_t waitq;
59 struct fasync_struct *fasync;
60};
61
62static int
63vcs_notifier(struct notifier_block *nb, unsigned long code, void *_param)
64{
65 struct vt_notifier_param *param = _param;
66 struct vc_data *vc = param->vc;
67 struct vcs_poll_data *poll =
68 container_of(nb, struct vcs_poll_data, notifier);
69 int currcons = poll->cons_num;
70
71 if (code != VT_UPDATE)
72 return NOTIFY_DONE;
73
74 if (currcons == 0)
75 currcons = fg_console;
76 else
77 currcons--;
78 if (currcons != vc->vc_num)
79 return NOTIFY_DONE;
80
81 poll->seen_last_update = false;
82 wake_up_interruptible(&poll->waitq);
83 kill_fasync(&poll->fasync, SIGIO, POLL_IN);
84 return NOTIFY_OK;
85}
86
87static void
88vcs_poll_data_free(struct vcs_poll_data *poll)
89{
90 unregister_vt_notifier(&poll->notifier);
91 kfree(poll);
92}
93
94static struct vcs_poll_data *
95vcs_poll_data_get(struct file *file)
96{
97 struct vcs_poll_data *poll = file->private_data;
98
99 if (poll)
100 return poll;
101
102 poll = kzalloc(sizeof(*poll), GFP_KERNEL);
103 if (!poll)
104 return NULL;
105 poll->cons_num = iminor(file->f_path.dentry->d_inode) & 127;
106 init_waitqueue_head(&poll->waitq);
107 poll->notifier.notifier_call = vcs_notifier;
108 if (register_vt_notifier(&poll->notifier) != 0) {
109 kfree(poll);
110 return NULL;
111 }
112
113 /*
114 * This code may be called either through ->poll() or ->fasync().
115 * If we have two threads using the same file descriptor, they could
116 * both enter this function, both notice that the structure hasn't
117 * been allocated yet and go ahead allocating it in parallel, but
118 * only one of them must survive and be shared otherwise we'd leak
119 * memory with a dangling notifier callback.
120 */
121 spin_lock(&file->f_lock);
122 if (!file->private_data) {
123 file->private_data = poll;
124 } else {
125 /* someone else raced ahead of us */
126 vcs_poll_data_free(poll);
127 poll = file->private_data;
128 }
129 spin_unlock(&file->f_lock);
130
131 return poll;
132}
133
134static int
135vcs_size(struct inode *inode)
136{
137 int size;
138 int minor = iminor(inode);
139 int currcons = minor & 127;
140 struct vc_data *vc;
141
142 if (currcons == 0)
143 currcons = fg_console;
144 else
145 currcons--;
146 if (!vc_cons_allocated(currcons))
147 return -ENXIO;
148 vc = vc_cons[currcons].d;
149
150 size = vc->vc_rows * vc->vc_cols;
151
152 if (minor & 128)
153 size = 2*size + HEADER_SIZE;
154 return size;
155}
156
157static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
158{
159 int size;
160
161 mutex_lock(&con_buf_mtx);
162 size = vcs_size(file->f_path.dentry->d_inode);
163 switch (orig) {
164 default:
165 mutex_unlock(&con_buf_mtx);
166 return -EINVAL;
167 case 2:
168 offset += size;
169 break;
170 case 1:
171 offset += file->f_pos;
172 case 0:
173 break;
174 }
175 if (offset < 0 || offset > size) {
176 mutex_unlock(&con_buf_mtx);
177 return -EINVAL;
178 }
179 file->f_pos = offset;
180 mutex_unlock(&con_buf_mtx);
181 return file->f_pos;
182}
183
184
185static ssize_t
186vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
187{
188 struct inode *inode = file->f_path.dentry->d_inode;
189 unsigned int currcons = iminor(inode);
190 struct vc_data *vc;
191 struct vcs_poll_data *poll;
192 long pos;
193 long viewed, attr, read;
194 int col, maxcol;
195 unsigned short *org = NULL;
196 ssize_t ret;
197
198 mutex_lock(&con_buf_mtx);
199
200 pos = *ppos;
201
202 /* Select the proper current console and verify
203 * sanity of the situation under the console lock.
204 */
205 acquire_console_sem();
206
207 attr = (currcons & 128);
208 currcons = (currcons & 127);
209 if (currcons == 0) {
210 currcons = fg_console;
211 viewed = 1;
212 } else {
213 currcons--;
214 viewed = 0;
215 }
216 ret = -ENXIO;
217 if (!vc_cons_allocated(currcons))
218 goto unlock_out;
219 vc = vc_cons[currcons].d;
220
221 ret = -EINVAL;
222 if (pos < 0)
223 goto unlock_out;
224 poll = file->private_data;
225 if (count && poll)
226 poll->seen_last_update = true;
227 read = 0;
228 ret = 0;
229 while (count) {
230 char *con_buf0, *con_buf_start;
231 long this_round, size;
232 ssize_t orig_count;
233 long p = pos;
234
235 /* Check whether we are above size each round,
236 * as copy_to_user at the end of this loop
237 * could sleep.
238 */
239 size = vcs_size(inode);
240 if (pos >= size)
241 break;
242 if (count > size - pos)
243 count = size - pos;
244
245 this_round = count;
246 if (this_round > CON_BUF_SIZE)
247 this_round = CON_BUF_SIZE;
248
249 /* Perform the whole read into the local con_buf.
250 * Then we can drop the console spinlock and safely
251 * attempt to move it to userspace.
252 */
253
254 con_buf_start = con_buf0 = con_buf;
255 orig_count = this_round;
256 maxcol = vc->vc_cols;
257 if (!attr) {
258 org = screen_pos(vc, p, viewed);
259 col = p % maxcol;
260 p += maxcol - col;
261 while (this_round-- > 0) {
262 *con_buf0++ = (vcs_scr_readw(vc, org++) & 0xff);
263 if (++col == maxcol) {
264 org = screen_pos(vc, p, viewed);
265 col = 0;
266 p += maxcol;
267 }
268 }
269 } else {
270 if (p < HEADER_SIZE) {
271 size_t tmp_count;
272
273 con_buf0[0] = (char)vc->vc_rows;
274 con_buf0[1] = (char)vc->vc_cols;
275 getconsxy(vc, con_buf0 + 2);
276
277 con_buf_start += p;
278 this_round += p;
279 if (this_round > CON_BUF_SIZE) {
280 this_round = CON_BUF_SIZE;
281 orig_count = this_round - p;
282 }
283
284 tmp_count = HEADER_SIZE;
285 if (tmp_count > this_round)
286 tmp_count = this_round;
287
288 /* Advance state pointers and move on. */
289 this_round -= tmp_count;
290 p = HEADER_SIZE;
291 con_buf0 = con_buf + HEADER_SIZE;
292 /* If this_round >= 0, then p is even... */
293 } else if (p & 1) {
294 /* Skip first byte for output if start address is odd
295 * Update region sizes up/down depending on free
296 * space in buffer.
297 */
298 con_buf_start++;
299 if (this_round < CON_BUF_SIZE)
300 this_round++;
301 else
302 orig_count--;
303 }
304 if (this_round > 0) {
305 unsigned short *tmp_buf = (unsigned short *)con_buf0;
306
307 p -= HEADER_SIZE;
308 p /= 2;
309 col = p % maxcol;
310
311 org = screen_pos(vc, p, viewed);
312 p += maxcol - col;
313
314 /* Buffer has even length, so we can always copy
315 * character + attribute. We do not copy last byte
316 * to userspace if this_round is odd.
317 */
318 this_round = (this_round + 1) >> 1;
319
320 while (this_round) {
321 *tmp_buf++ = vcs_scr_readw(vc, org++);
322 this_round --;
323 if (++col == maxcol) {
324 org = screen_pos(vc, p, viewed);
325 col = 0;
326 p += maxcol;
327 }
328 }
329 }
330 }
331
332 /* Finally, release the console semaphore while we push
333 * all the data to userspace from our temporary buffer.
334 *
335 * AKPM: Even though it's a semaphore, we should drop it because
336 * the pagefault handling code may want to call printk().
337 */
338
339 release_console_sem();
340 ret = copy_to_user(buf, con_buf_start, orig_count);
341 acquire_console_sem();
342
343 if (ret) {
344 read += (orig_count - ret);
345 ret = -EFAULT;
346 break;
347 }
348 buf += orig_count;
349 pos += orig_count;
350 read += orig_count;
351 count -= orig_count;
352 }
353 *ppos += read;
354 if (read)
355 ret = read;
356unlock_out:
357 release_console_sem();
358 mutex_unlock(&con_buf_mtx);
359 return ret;
360}
361
362static ssize_t
363vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
364{
365 struct inode *inode = file->f_path.dentry->d_inode;
366 unsigned int currcons = iminor(inode);
367 struct vc_data *vc;
368 long pos;
369 long viewed, attr, size, written;
370 char *con_buf0;
371 int col, maxcol;
372 u16 *org0 = NULL, *org = NULL;
373 size_t ret;
374
375 mutex_lock(&con_buf_mtx);
376
377 pos = *ppos;
378
379 /* Select the proper current console and verify
380 * sanity of the situation under the console lock.
381 */
382 acquire_console_sem();
383
384 attr = (currcons & 128);
385 currcons = (currcons & 127);
386
387 if (currcons == 0) {
388 currcons = fg_console;
389 viewed = 1;
390 } else {
391 currcons--;
392 viewed = 0;
393 }
394 ret = -ENXIO;
395 if (!vc_cons_allocated(currcons))
396 goto unlock_out;
397 vc = vc_cons[currcons].d;
398
399 size = vcs_size(inode);
400 ret = -EINVAL;
401 if (pos < 0 || pos > size)
402 goto unlock_out;
403 if (count > size - pos)
404 count = size - pos;
405 written = 0;
406 while (count) {
407 long this_round = count;
408 size_t orig_count;
409 long p;
410
411 if (this_round > CON_BUF_SIZE)
412 this_round = CON_BUF_SIZE;
413
414 /* Temporarily drop the console lock so that we can read
415 * in the write data from userspace safely.
416 */
417 release_console_sem();
418 ret = copy_from_user(con_buf, buf, this_round);
419 acquire_console_sem();
420
421 if (ret) {
422 this_round -= ret;
423 if (!this_round) {
424 /* Abort loop if no data were copied. Otherwise
425 * fail with -EFAULT.
426 */
427 if (written)
428 break;
429 ret = -EFAULT;
430 goto unlock_out;
431 }
432 }
433
434 /* The vcs_size might have changed while we slept to grab
435 * the user buffer, so recheck.
436 * Return data written up to now on failure.
437 */
438 size = vcs_size(inode);
439 if (pos >= size)
440 break;
441 if (this_round > size - pos)
442 this_round = size - pos;
443
444 /* OK, now actually push the write to the console
445 * under the lock using the local kernel buffer.
446 */
447
448 con_buf0 = con_buf;
449 orig_count = this_round;
450 maxcol = vc->vc_cols;
451 p = pos;
452 if (!attr) {
453 org0 = org = screen_pos(vc, p, viewed);
454 col = p % maxcol;
455 p += maxcol - col;
456
457 while (this_round > 0) {
458 unsigned char c = *con_buf0++;
459
460 this_round--;
461 vcs_scr_writew(vc,
462 (vcs_scr_readw(vc, org) & 0xff00) | c, org);
463 org++;
464 if (++col == maxcol) {
465 org = screen_pos(vc, p, viewed);
466 col = 0;
467 p += maxcol;
468 }
469 }
470 } else {
471 if (p < HEADER_SIZE) {
472 char header[HEADER_SIZE];
473
474 getconsxy(vc, header + 2);
475 while (p < HEADER_SIZE && this_round > 0) {
476 this_round--;
477 header[p++] = *con_buf0++;
478 }
479 if (!viewed)
480 putconsxy(vc, header + 2);
481 }
482 p -= HEADER_SIZE;
483 col = (p/2) % maxcol;
484 if (this_round > 0) {
485 org0 = org = screen_pos(vc, p/2, viewed);
486 if ((p & 1) && this_round > 0) {
487 char c;
488
489 this_round--;
490 c = *con_buf0++;
491#ifdef __BIG_ENDIAN
492 vcs_scr_writew(vc, c |
493 (vcs_scr_readw(vc, org) & 0xff00), org);
494#else
495 vcs_scr_writew(vc, (c << 8) |
496 (vcs_scr_readw(vc, org) & 0xff), org);
497#endif
498 org++;
499 p++;
500 if (++col == maxcol) {
501 org = screen_pos(vc, p/2, viewed);
502 col = 0;
503 }
504 }
505 p /= 2;
506 p += maxcol - col;
507 }
508 while (this_round > 1) {
509 unsigned short w;
510
511 w = get_unaligned(((unsigned short *)con_buf0));
512 vcs_scr_writew(vc, w, org++);
513 con_buf0 += 2;
514 this_round -= 2;
515 if (++col == maxcol) {
516 org = screen_pos(vc, p, viewed);
517 col = 0;
518 p += maxcol;
519 }
520 }
521 if (this_round > 0) {
522 unsigned char c;
523
524 c = *con_buf0++;
525#ifdef __BIG_ENDIAN
526 vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff) | (c << 8), org);
527#else
528 vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff00) | c, org);
529#endif
530 }
531 }
532 count -= orig_count;
533 written += orig_count;
534 buf += orig_count;
535 pos += orig_count;
536 if (org0)
537 update_region(vc, (unsigned long)(org0), org - org0);
538 }
539 *ppos += written;
540 ret = written;
541 if (written)
542 vcs_scr_updated(vc);
543
544unlock_out:
545 release_console_sem();
546
547 mutex_unlock(&con_buf_mtx);
548
549 return ret;
550}
551
552static unsigned int
553vcs_poll(struct file *file, poll_table *wait)
554{
555 struct vcs_poll_data *poll = vcs_poll_data_get(file);
556 int ret = 0;
557
558 if (poll) {
559 poll_wait(file, &poll->waitq, wait);
560 if (!poll->seen_last_update)
561 ret = POLLIN | POLLRDNORM;
562 }
563 return ret;
564}
565
566static int
567vcs_fasync(int fd, struct file *file, int on)
568{
569 struct vcs_poll_data *poll = file->private_data;
570
571 if (!poll) {
572 /* don't allocate anything if all we want is disable fasync */
573 if (!on)
574 return 0;
575 poll = vcs_poll_data_get(file);
576 if (!poll)
577 return -ENOMEM;
578 }
579
580 return fasync_helper(fd, file, on, &poll->fasync);
581}
582
583static int
584vcs_open(struct inode *inode, struct file *filp)
585{
586 unsigned int currcons = iminor(inode) & 127;
587 int ret = 0;
588
589 tty_lock();
590 if(currcons && !vc_cons_allocated(currcons-1))
591 ret = -ENXIO;
592 tty_unlock();
593 return ret;
594}
595
596static int vcs_release(struct inode *inode, struct file *file)
597{
598 struct vcs_poll_data *poll = file->private_data;
599
600 if (poll)
601 vcs_poll_data_free(poll);
602 return 0;
603}
604
605static const struct file_operations vcs_fops = {
606 .llseek = vcs_lseek,
607 .read = vcs_read,
608 .write = vcs_write,
609 .poll = vcs_poll,
610 .fasync = vcs_fasync,
611 .open = vcs_open,
612 .release = vcs_release,
613};
614
615static struct class *vc_class;
616
617void vcs_make_sysfs(int index)
618{
619 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 1), NULL,
620 "vcs%u", index + 1);
621 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 129), NULL,
622 "vcsa%u", index + 1);
623}
624
625void vcs_remove_sysfs(int index)
626{
627 device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 1));
628 device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 129));
629}
630
631int __init vcs_init(void)
632{
633 unsigned int i;
634
635 if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops))
636 panic("unable to get major %d for vcs device", VCS_MAJOR);
637 vc_class = class_create(THIS_MODULE, "vc");
638
639 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
640 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
641 for (i = 0; i < MIN_NR_CONSOLES; i++)
642 vcs_make_sysfs(i);
643 return 0;
644}
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
new file mode 100644
index 000000000000..a8ec48ed14d9
--- /dev/null
+++ b/drivers/tty/vt/vt.c
@@ -0,0 +1,4209 @@
1/*
2 * linux/drivers/char/vt.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
6
7/*
8 * Hopefully this will be a rather complete VT102 implementation.
9 *
10 * Beeping thanks to John T Kohl.
11 *
12 * Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics
13 * Chars, and VT100 enhancements by Peter MacDonald.
14 *
15 * Copy and paste function by Andrew Haylett,
16 * some enhancements by Alessandro Rubini.
17 *
18 * Code to check for different video-cards mostly by Galen Hunt,
19 * <g-hunt@ee.utah.edu>
20 *
21 * Rudimentary ISO 10646/Unicode/UTF-8 character set support by
22 * Markus Kuhn, <mskuhn@immd4.informatik.uni-erlangen.de>.
23 *
24 * Dynamic allocation of consoles, aeb@cwi.nl, May 1994
25 * Resizing of consoles, aeb, 940926
26 *
27 * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
28 * <poe@daimi.aau.dk>
29 *
30 * User-defined bell sound, new setterm control sequences and printk
31 * redirection by Martin Mares <mj@k332.feld.cvut.cz> 19-Nov-95
32 *
33 * APM screenblank bug fixed Takashi Manabe <manabe@roy.dsl.tutics.tut.jp>
34 *
35 * Merge with the abstract console driver by Geert Uytterhoeven
36 * <geert@linux-m68k.org>, Jan 1997.
37 *
38 * Original m68k console driver modifications by
39 *
40 * - Arno Griffioen <arno@usn.nl>
41 * - David Carter <carter@cs.bris.ac.uk>
42 *
43 * The abstract console driver provides a generic interface for a text
44 * console. It supports VGA text mode, frame buffer based graphical consoles
45 * and special graphics processors that are only accessible through some
46 * registers (e.g. a TMS340x0 GSP).
47 *
48 * The interface to the hardware is specified using a special structure
49 * (struct consw) which contains function pointers to console operations
50 * (see <linux/console.h> for more information).
51 *
52 * Support for changeable cursor shape
53 * by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>, August 1997
54 *
55 * Ported to i386 and con_scrolldelta fixed
56 * by Emmanuel Marty <core@ggi-project.org>, April 1998
57 *
58 * Resurrected character buffers in videoram plus lots of other trickery
59 * by Martin Mares <mj@atrey.karlin.mff.cuni.cz>, July 1998
60 *
61 * Removed old-style timers, introduced console_timer, made timer
62 * deletion SMP-safe. 17Jun00, Andrew Morton
63 *
64 * Removed console_lock, enabled interrupts across all console operations
65 * 13 March 2001, Andrew Morton
66 *
67 * Fixed UTF-8 mode so alternate charset modes always work according
68 * to control sequences interpreted in do_con_trol function
69 * preserving backward VT100 semigraphics compatibility,
70 * malformed UTF sequences represented as sequences of replacement glyphs,
71 * original codes or '?' as a last resort if replacement glyph is undefined
72 * by Adam Tla/lka <atlka@pg.gda.pl>, Aug 2006
73 */
74
75#include <linux/module.h>
76#include <linux/types.h>
77#include <linux/sched.h>
78#include <linux/tty.h>
79#include <linux/tty_flip.h>
80#include <linux/kernel.h>
81#include <linux/string.h>
82#include <linux/errno.h>
83#include <linux/kd.h>
84#include <linux/slab.h>
85#include <linux/major.h>
86#include <linux/mm.h>
87#include <linux/console.h>
88#include <linux/init.h>
89#include <linux/mutex.h>
90#include <linux/vt_kern.h>
91#include <linux/selection.h>
92#include <linux/smp_lock.h>
93#include <linux/tiocl.h>
94#include <linux/kbd_kern.h>
95#include <linux/consolemap.h>
96#include <linux/timer.h>
97#include <linux/interrupt.h>
98#include <linux/workqueue.h>
99#include <linux/pm.h>
100#include <linux/font.h>
101#include <linux/bitops.h>
102#include <linux/notifier.h>
103#include <linux/device.h>
104#include <linux/io.h>
105#include <asm/system.h>
106#include <linux/uaccess.h>
107#include <linux/kdb.h>
108#include <linux/ctype.h>
109
110#define MAX_NR_CON_DRIVER 16
111
112#define CON_DRIVER_FLAG_MODULE 1
113#define CON_DRIVER_FLAG_INIT 2
114#define CON_DRIVER_FLAG_ATTR 4
115
116struct con_driver {
117 const struct consw *con;
118 const char *desc;
119 struct device *dev;
120 int node;
121 int first;
122 int last;
123 int flag;
124};
125
126static struct con_driver registered_con_driver[MAX_NR_CON_DRIVER];
127const struct consw *conswitchp;
128
129/* A bitmap for codes <32. A bit of 1 indicates that the code
130 * corresponding to that bit number invokes some special action
131 * (such as cursor movement) and should not be displayed as a
132 * glyph unless the disp_ctrl mode is explicitly enabled.
133 */
134#define CTRL_ACTION 0x0d00ff81
135#define CTRL_ALWAYS 0x0800f501 /* Cannot be overridden by disp_ctrl */
136
137/*
138 * Here is the default bell parameters: 750HZ, 1/8th of a second
139 */
140#define DEFAULT_BELL_PITCH 750
141#define DEFAULT_BELL_DURATION (HZ/8)
142
143struct vc vc_cons [MAX_NR_CONSOLES];
144
145#ifndef VT_SINGLE_DRIVER
146static const struct consw *con_driver_map[MAX_NR_CONSOLES];
147#endif
148
149static int con_open(struct tty_struct *, struct file *);
150static void vc_init(struct vc_data *vc, unsigned int rows,
151 unsigned int cols, int do_clear);
152static void gotoxy(struct vc_data *vc, int new_x, int new_y);
153static void save_cur(struct vc_data *vc);
154static void reset_terminal(struct vc_data *vc, int do_clear);
155static void con_flush_chars(struct tty_struct *tty);
156static int set_vesa_blanking(char __user *p);
157static void set_cursor(struct vc_data *vc);
158static void hide_cursor(struct vc_data *vc);
159static void console_callback(struct work_struct *ignored);
160static void blank_screen_t(unsigned long dummy);
161static void set_palette(struct vc_data *vc);
162
163static int printable; /* Is console ready for printing? */
164int default_utf8 = true;
165module_param(default_utf8, int, S_IRUGO | S_IWUSR);
166int global_cursor_default = -1;
167module_param(global_cursor_default, int, S_IRUGO | S_IWUSR);
168
169static int cur_default = CUR_DEFAULT;
170module_param(cur_default, int, S_IRUGO | S_IWUSR);
171
172/*
173 * ignore_poke: don't unblank the screen when things are typed. This is
174 * mainly for the privacy of braille terminal users.
175 */
176static int ignore_poke;
177
178int do_poke_blanked_console;
179int console_blanked;
180
181static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
182static int vesa_off_interval;
183static int blankinterval = 10*60;
184core_param(consoleblank, blankinterval, int, 0444);
185
186static DECLARE_WORK(console_work, console_callback);
187
188/*
189 * fg_console is the current virtual console,
190 * last_console is the last used one,
191 * want_console is the console we want to switch to,
192 * saved_* variants are for save/restore around kernel debugger enter/leave
193 */
194int fg_console;
195int last_console;
196int want_console = -1;
197static int saved_fg_console;
198static int saved_last_console;
199static int saved_want_console;
200static int saved_vc_mode;
201static int saved_console_blanked;
202
203/*
204 * For each existing display, we have a pointer to console currently visible
205 * on that display, allowing consoles other than fg_console to be refreshed
206 * appropriately. Unless the low-level driver supplies its own display_fg
207 * variable, we use this one for the "master display".
208 */
209static struct vc_data *master_display_fg;
210
211/*
212 * Unfortunately, we need to delay tty echo when we're currently writing to the
213 * console since the code is (and always was) not re-entrant, so we schedule
214 * all flip requests to process context with schedule-task() and run it from
215 * console_callback().
216 */
217
218/*
219 * For the same reason, we defer scrollback to the console callback.
220 */
221static int scrollback_delta;
222
223/*
224 * Hook so that the power management routines can (un)blank
225 * the console on our behalf.
226 */
227int (*console_blank_hook)(int);
228
229static DEFINE_TIMER(console_timer, blank_screen_t, 0, 0);
230static int blank_state;
231static int blank_timer_expired;
232enum {
233 blank_off = 0,
234 blank_normal_wait,
235 blank_vesa_wait,
236};
237
238/*
239 * Notifier list for console events.
240 */
241static ATOMIC_NOTIFIER_HEAD(vt_notifier_list);
242
243int register_vt_notifier(struct notifier_block *nb)
244{
245 return atomic_notifier_chain_register(&vt_notifier_list, nb);
246}
247EXPORT_SYMBOL_GPL(register_vt_notifier);
248
249int unregister_vt_notifier(struct notifier_block *nb)
250{
251 return atomic_notifier_chain_unregister(&vt_notifier_list, nb);
252}
253EXPORT_SYMBOL_GPL(unregister_vt_notifier);
254
255static void notify_write(struct vc_data *vc, unsigned int unicode)
256{
257 struct vt_notifier_param param = { .vc = vc, unicode = unicode };
258 atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, &param);
259}
260
261static void notify_update(struct vc_data *vc)
262{
263 struct vt_notifier_param param = { .vc = vc };
264 atomic_notifier_call_chain(&vt_notifier_list, VT_UPDATE, &param);
265}
266/*
267 * Low-Level Functions
268 */
269
270#define IS_FG(vc) ((vc)->vc_num == fg_console)
271
272#ifdef VT_BUF_VRAM_ONLY
273#define DO_UPDATE(vc) 0
274#else
275#define DO_UPDATE(vc) (CON_IS_VISIBLE(vc) && !console_blanked)
276#endif
277
278static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed)
279{
280 unsigned short *p;
281
282 if (!viewed)
283 p = (unsigned short *)(vc->vc_origin + offset);
284 else if (!vc->vc_sw->con_screen_pos)
285 p = (unsigned short *)(vc->vc_visible_origin + offset);
286 else
287 p = vc->vc_sw->con_screen_pos(vc, offset);
288 return p;
289}
290
291/* Called from the keyboard irq path.. */
292static inline void scrolldelta(int lines)
293{
294 /* FIXME */
295 /* scrolldelta needs some kind of consistency lock, but the BKL was
296 and still is not protecting versus the scheduled back end */
297 scrollback_delta += lines;
298 schedule_console_callback();
299}
300
301void schedule_console_callback(void)
302{
303 schedule_work(&console_work);
304}
305
306static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
307{
308 unsigned short *d, *s;
309
310 if (t+nr >= b)
311 nr = b - t - 1;
312 if (b > vc->vc_rows || t >= b || nr < 1)
313 return;
314 if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_UP, nr))
315 return;
316 d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
317 s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr));
318 scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row);
319 scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_video_erase_char,
320 vc->vc_size_row * nr);
321}
322
323static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
324{
325 unsigned short *s;
326 unsigned int step;
327
328 if (t+nr >= b)
329 nr = b - t - 1;
330 if (b > vc->vc_rows || t >= b || nr < 1)
331 return;
332 if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_DOWN, nr))
333 return;
334 s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
335 step = vc->vc_cols * nr;
336 scr_memmovew(s + step, s, (b - t - nr) * vc->vc_size_row);
337 scr_memsetw(s, vc->vc_video_erase_char, 2 * step);
338}
339
340static void do_update_region(struct vc_data *vc, unsigned long start, int count)
341{
342#ifndef VT_BUF_VRAM_ONLY
343 unsigned int xx, yy, offset;
344 u16 *p;
345
346 p = (u16 *) start;
347 if (!vc->vc_sw->con_getxy) {
348 offset = (start - vc->vc_origin) / 2;
349 xx = offset % vc->vc_cols;
350 yy = offset / vc->vc_cols;
351 } else {
352 int nxx, nyy;
353 start = vc->vc_sw->con_getxy(vc, start, &nxx, &nyy);
354 xx = nxx; yy = nyy;
355 }
356 for(;;) {
357 u16 attrib = scr_readw(p) & 0xff00;
358 int startx = xx;
359 u16 *q = p;
360 while (xx < vc->vc_cols && count) {
361 if (attrib != (scr_readw(p) & 0xff00)) {
362 if (p > q)
363 vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
364 startx = xx;
365 q = p;
366 attrib = scr_readw(p) & 0xff00;
367 }
368 p++;
369 xx++;
370 count--;
371 }
372 if (p > q)
373 vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
374 if (!count)
375 break;
376 xx = 0;
377 yy++;
378 if (vc->vc_sw->con_getxy) {
379 p = (u16 *)start;
380 start = vc->vc_sw->con_getxy(vc, start, NULL, NULL);
381 }
382 }
383#endif
384}
385
386void update_region(struct vc_data *vc, unsigned long start, int count)
387{
388 WARN_CONSOLE_UNLOCKED();
389
390 if (DO_UPDATE(vc)) {
391 hide_cursor(vc);
392 do_update_region(vc, start, count);
393 set_cursor(vc);
394 }
395}
396
397/* Structure of attributes is hardware-dependent */
398
399static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
400 u8 _underline, u8 _reverse, u8 _italic)
401{
402 if (vc->vc_sw->con_build_attr)
403 return vc->vc_sw->con_build_attr(vc, _color, _intensity,
404 _blink, _underline, _reverse, _italic);
405
406#ifndef VT_BUF_VRAM_ONLY
407/*
408 * ++roman: I completely changed the attribute format for monochrome
409 * mode (!can_do_color). The formerly used MDA (monochrome display
410 * adapter) format didn't allow the combination of certain effects.
411 * Now the attribute is just a bit vector:
412 * Bit 0..1: intensity (0..2)
413 * Bit 2 : underline
414 * Bit 3 : reverse
415 * Bit 7 : blink
416 */
417 {
418 u8 a = _color;
419 if (!vc->vc_can_do_color)
420 return _intensity |
421 (_italic ? 2 : 0) |
422 (_underline ? 4 : 0) |
423 (_reverse ? 8 : 0) |
424 (_blink ? 0x80 : 0);
425 if (_italic)
426 a = (a & 0xF0) | vc->vc_itcolor;
427 else if (_underline)
428 a = (a & 0xf0) | vc->vc_ulcolor;
429 else if (_intensity == 0)
430 a = (a & 0xf0) | vc->vc_ulcolor;
431 if (_reverse)
432 a = ((a) & 0x88) | ((((a) >> 4) | ((a) << 4)) & 0x77);
433 if (_blink)
434 a ^= 0x80;
435 if (_intensity == 2)
436 a ^= 0x08;
437 if (vc->vc_hi_font_mask == 0x100)
438 a <<= 1;
439 return a;
440 }
441#else
442 return 0;
443#endif
444}
445
446static void update_attr(struct vc_data *vc)
447{
448 vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity,
449 vc->vc_blink, vc->vc_underline,
450 vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
451 vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' ';
452}
453
454/* Note: inverting the screen twice should revert to the original state */
455void invert_screen(struct vc_data *vc, int offset, int count, int viewed)
456{
457 unsigned short *p;
458
459 WARN_CONSOLE_UNLOCKED();
460
461 count /= 2;
462 p = screenpos(vc, offset, viewed);
463 if (vc->vc_sw->con_invert_region)
464 vc->vc_sw->con_invert_region(vc, p, count);
465#ifndef VT_BUF_VRAM_ONLY
466 else {
467 u16 *q = p;
468 int cnt = count;
469 u16 a;
470
471 if (!vc->vc_can_do_color) {
472 while (cnt--) {
473 a = scr_readw(q);
474 a ^= 0x0800;
475 scr_writew(a, q);
476 q++;
477 }
478 } else if (vc->vc_hi_font_mask == 0x100) {
479 while (cnt--) {
480 a = scr_readw(q);
481 a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4);
482 scr_writew(a, q);
483 q++;
484 }
485 } else {
486 while (cnt--) {
487 a = scr_readw(q);
488 a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
489 scr_writew(a, q);
490 q++;
491 }
492 }
493 }
494#endif
495 if (DO_UPDATE(vc))
496 do_update_region(vc, (unsigned long) p, count);
497}
498
499/* used by selection: complement pointer position */
500void complement_pos(struct vc_data *vc, int offset)
501{
502 static int old_offset = -1;
503 static unsigned short old;
504 static unsigned short oldx, oldy;
505
506 WARN_CONSOLE_UNLOCKED();
507
508 if (old_offset != -1 && old_offset >= 0 &&
509 old_offset < vc->vc_screenbuf_size) {
510 scr_writew(old, screenpos(vc, old_offset, 1));
511 if (DO_UPDATE(vc))
512 vc->vc_sw->con_putc(vc, old, oldy, oldx);
513 }
514
515 old_offset = offset;
516
517 if (offset != -1 && offset >= 0 &&
518 offset < vc->vc_screenbuf_size) {
519 unsigned short new;
520 unsigned short *p;
521 p = screenpos(vc, offset, 1);
522 old = scr_readw(p);
523 new = old ^ vc->vc_complement_mask;
524 scr_writew(new, p);
525 if (DO_UPDATE(vc)) {
526 oldx = (offset >> 1) % vc->vc_cols;
527 oldy = (offset >> 1) / vc->vc_cols;
528 vc->vc_sw->con_putc(vc, new, oldy, oldx);
529 }
530 }
531
532}
533
534static void insert_char(struct vc_data *vc, unsigned int nr)
535{
536 unsigned short *p, *q = (unsigned short *)vc->vc_pos;
537
538 p = q + vc->vc_cols - nr - vc->vc_x;
539 while (--p >= q)
540 scr_writew(scr_readw(p), p + nr);
541 scr_memsetw(q, vc->vc_video_erase_char, nr * 2);
542 vc->vc_need_wrap = 0;
543 if (DO_UPDATE(vc)) {
544 unsigned short oldattr = vc->vc_attr;
545 vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x, vc->vc_y, vc->vc_x + nr, 1,
546 vc->vc_cols - vc->vc_x - nr);
547 vc->vc_attr = vc->vc_video_erase_char >> 8;
548 while (nr--)
549 vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y, vc->vc_x + nr);
550 vc->vc_attr = oldattr;
551 }
552}
553
554static void delete_char(struct vc_data *vc, unsigned int nr)
555{
556 unsigned int i = vc->vc_x;
557 unsigned short *p = (unsigned short *)vc->vc_pos;
558
559 while (++i <= vc->vc_cols - nr) {
560 scr_writew(scr_readw(p+nr), p);
561 p++;
562 }
563 scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
564 vc->vc_need_wrap = 0;
565 if (DO_UPDATE(vc)) {
566 unsigned short oldattr = vc->vc_attr;
567 vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x + nr, vc->vc_y, vc->vc_x, 1,
568 vc->vc_cols - vc->vc_x - nr);
569 vc->vc_attr = vc->vc_video_erase_char >> 8;
570 while (nr--)
571 vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y,
572 vc->vc_cols - 1 - nr);
573 vc->vc_attr = oldattr;
574 }
575}
576
577static int softcursor_original;
578
579static void add_softcursor(struct vc_data *vc)
580{
581 int i = scr_readw((u16 *) vc->vc_pos);
582 u32 type = vc->vc_cursor_type;
583
584 if (! (type & 0x10)) return;
585 if (softcursor_original != -1) return;
586 softcursor_original = i;
587 i |= ((type >> 8) & 0xff00 );
588 i ^= ((type) & 0xff00 );
589 if ((type & 0x20) && ((softcursor_original & 0x7000) == (i & 0x7000))) i ^= 0x7000;
590 if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700;
591 scr_writew(i, (u16 *) vc->vc_pos);
592 if (DO_UPDATE(vc))
593 vc->vc_sw->con_putc(vc, i, vc->vc_y, vc->vc_x);
594}
595
596static void hide_softcursor(struct vc_data *vc)
597{
598 if (softcursor_original != -1) {
599 scr_writew(softcursor_original, (u16 *)vc->vc_pos);
600 if (DO_UPDATE(vc))
601 vc->vc_sw->con_putc(vc, softcursor_original,
602 vc->vc_y, vc->vc_x);
603 softcursor_original = -1;
604 }
605}
606
607static void hide_cursor(struct vc_data *vc)
608{
609 if (vc == sel_cons)
610 clear_selection();
611 vc->vc_sw->con_cursor(vc, CM_ERASE);
612 hide_softcursor(vc);
613}
614
615static void set_cursor(struct vc_data *vc)
616{
617 if (!IS_FG(vc) || console_blanked ||
618 vc->vc_mode == KD_GRAPHICS)
619 return;
620 if (vc->vc_deccm) {
621 if (vc == sel_cons)
622 clear_selection();
623 add_softcursor(vc);
624 if ((vc->vc_cursor_type & 0x0f) != 1)
625 vc->vc_sw->con_cursor(vc, CM_DRAW);
626 } else
627 hide_cursor(vc);
628}
629
630static void set_origin(struct vc_data *vc)
631{
632 WARN_CONSOLE_UNLOCKED();
633
634 if (!CON_IS_VISIBLE(vc) ||
635 !vc->vc_sw->con_set_origin ||
636 !vc->vc_sw->con_set_origin(vc))
637 vc->vc_origin = (unsigned long)vc->vc_screenbuf;
638 vc->vc_visible_origin = vc->vc_origin;
639 vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size;
640 vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->vc_y + 2 * vc->vc_x;
641}
642
643static inline void save_screen(struct vc_data *vc)
644{
645 WARN_CONSOLE_UNLOCKED();
646
647 if (vc->vc_sw->con_save_screen)
648 vc->vc_sw->con_save_screen(vc);
649}
650
651/*
652 * Redrawing of screen
653 */
654
655static void clear_buffer_attributes(struct vc_data *vc)
656{
657 unsigned short *p = (unsigned short *)vc->vc_origin;
658 int count = vc->vc_screenbuf_size / 2;
659 int mask = vc->vc_hi_font_mask | 0xff;
660
661 for (; count > 0; count--, p++) {
662 scr_writew((scr_readw(p)&mask) | (vc->vc_video_erase_char & ~mask), p);
663 }
664}
665
666void redraw_screen(struct vc_data *vc, int is_switch)
667{
668 int redraw = 0;
669
670 WARN_CONSOLE_UNLOCKED();
671
672 if (!vc) {
673 /* strange ... */
674 /* printk("redraw_screen: tty %d not allocated ??\n", new_console+1); */
675 return;
676 }
677
678 if (is_switch) {
679 struct vc_data *old_vc = vc_cons[fg_console].d;
680 if (old_vc == vc)
681 return;
682 if (!CON_IS_VISIBLE(vc))
683 redraw = 1;
684 *vc->vc_display_fg = vc;
685 fg_console = vc->vc_num;
686 hide_cursor(old_vc);
687 if (!CON_IS_VISIBLE(old_vc)) {
688 save_screen(old_vc);
689 set_origin(old_vc);
690 }
691 } else {
692 hide_cursor(vc);
693 redraw = 1;
694 }
695
696 if (redraw) {
697 int update;
698 int old_was_color = vc->vc_can_do_color;
699
700 set_origin(vc);
701 update = vc->vc_sw->con_switch(vc);
702 set_palette(vc);
703 /*
704 * If console changed from mono<->color, the best we can do
705 * is to clear the buffer attributes. As it currently stands,
706 * rebuilding new attributes from the old buffer is not doable
707 * without overly complex code.
708 */
709 if (old_was_color != vc->vc_can_do_color) {
710 update_attr(vc);
711 clear_buffer_attributes(vc);
712 }
713
714 /* Forcibly update if we're panicing */
715 if ((update && vc->vc_mode != KD_GRAPHICS) ||
716 vt_force_oops_output(vc))
717 do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
718 }
719 set_cursor(vc);
720 if (is_switch) {
721 set_leds();
722 compute_shiftstate();
723 notify_update(vc);
724 }
725}
726
727/*
728 * Allocation, freeing and resizing of VTs.
729 */
730
731int vc_cons_allocated(unsigned int i)
732{
733 return (i < MAX_NR_CONSOLES && vc_cons[i].d);
734}
735
736static void visual_init(struct vc_data *vc, int num, int init)
737{
738 /* ++Geert: vc->vc_sw->con_init determines console size */
739 if (vc->vc_sw)
740 module_put(vc->vc_sw->owner);
741 vc->vc_sw = conswitchp;
742#ifndef VT_SINGLE_DRIVER
743 if (con_driver_map[num])
744 vc->vc_sw = con_driver_map[num];
745#endif
746 __module_get(vc->vc_sw->owner);
747 vc->vc_num = num;
748 vc->vc_display_fg = &master_display_fg;
749 vc->vc_uni_pagedir_loc = &vc->vc_uni_pagedir;
750 vc->vc_uni_pagedir = 0;
751 vc->vc_hi_font_mask = 0;
752 vc->vc_complement_mask = 0;
753 vc->vc_can_do_color = 0;
754 vc->vc_panic_force_write = false;
755 vc->vc_sw->con_init(vc, init);
756 if (!vc->vc_complement_mask)
757 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
758 vc->vc_s_complement_mask = vc->vc_complement_mask;
759 vc->vc_size_row = vc->vc_cols << 1;
760 vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;
761}
762
763int vc_allocate(unsigned int currcons) /* return 0 on success */
764{
765 WARN_CONSOLE_UNLOCKED();
766
767 if (currcons >= MAX_NR_CONSOLES)
768 return -ENXIO;
769 if (!vc_cons[currcons].d) {
770 struct vc_data *vc;
771 struct vt_notifier_param param;
772
773 /* prevent users from taking too much memory */
774 if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE))
775 return -EPERM;
776
777 /* due to the granularity of kmalloc, we waste some memory here */
778 /* the alloc is done in two steps, to optimize the common situation
779 of a 25x80 console (structsize=216, screenbuf_size=4000) */
780 /* although the numbers above are not valid since long ago, the
781 point is still up-to-date and the comment still has its value
782 even if only as a historical artifact. --mj, July 1998 */
783 param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL);
784 if (!vc)
785 return -ENOMEM;
786 vc_cons[currcons].d = vc;
787 tty_port_init(&vc->port);
788 INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
789 visual_init(vc, currcons, 1);
790 if (!*vc->vc_uni_pagedir_loc)
791 con_set_default_unimap(vc);
792 vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
793 if (!vc->vc_screenbuf) {
794 kfree(vc);
795 vc_cons[currcons].d = NULL;
796 return -ENOMEM;
797 }
798
799 /* If no drivers have overridden us and the user didn't pass a
800 boot option, default to displaying the cursor */
801 if (global_cursor_default == -1)
802 global_cursor_default = 1;
803
804 vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
805 vcs_make_sysfs(currcons);
806 atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
807 }
808 return 0;
809}
810
811static inline int resize_screen(struct vc_data *vc, int width, int height,
812 int user)
813{
814 /* Resizes the resolution of the display adapater */
815 int err = 0;
816
817 if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_resize)
818 err = vc->vc_sw->con_resize(vc, width, height, user);
819
820 return err;
821}
822
823/*
824 * Change # of rows and columns (0 means unchanged/the size of fg_console)
825 * [this is to be used together with some user program
826 * like resize that changes the hardware videomode]
827 */
828#define VC_RESIZE_MAXCOL (32767)
829#define VC_RESIZE_MAXROW (32767)
830
831/**
832 * vc_do_resize - resizing method for the tty
833 * @tty: tty being resized
834 * @real_tty: real tty (different to tty if a pty/tty pair)
835 * @vc: virtual console private data
836 * @cols: columns
837 * @lines: lines
838 *
839 * Resize a virtual console, clipping according to the actual constraints.
840 * If the caller passes a tty structure then update the termios winsize
841 * information and perform any necessary signal handling.
842 *
843 * Caller must hold the console semaphore. Takes the termios mutex and
844 * ctrl_lock of the tty IFF a tty is passed.
845 */
846
847static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
848 unsigned int cols, unsigned int lines)
849{
850 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
851 unsigned long end;
852 unsigned int old_cols, old_rows, old_row_size, old_screen_size;
853 unsigned int new_cols, new_rows, new_row_size, new_screen_size;
854 unsigned int user;
855 unsigned short *newscreen;
856
857 WARN_CONSOLE_UNLOCKED();
858
859 if (!vc)
860 return -ENXIO;
861
862 user = vc->vc_resize_user;
863 vc->vc_resize_user = 0;
864
865 if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW)
866 return -EINVAL;
867
868 new_cols = (cols ? cols : vc->vc_cols);
869 new_rows = (lines ? lines : vc->vc_rows);
870 new_row_size = new_cols << 1;
871 new_screen_size = new_row_size * new_rows;
872
873 if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
874 return 0;
875
876 newscreen = kmalloc(new_screen_size, GFP_USER);
877 if (!newscreen)
878 return -ENOMEM;
879
880 old_rows = vc->vc_rows;
881 old_cols = vc->vc_cols;
882 old_row_size = vc->vc_size_row;
883 old_screen_size = vc->vc_screenbuf_size;
884
885 err = resize_screen(vc, new_cols, new_rows, user);
886 if (err) {
887 kfree(newscreen);
888 return err;
889 }
890
891 vc->vc_rows = new_rows;
892 vc->vc_cols = new_cols;
893 vc->vc_size_row = new_row_size;
894 vc->vc_screenbuf_size = new_screen_size;
895
896 rlth = min(old_row_size, new_row_size);
897 rrem = new_row_size - rlth;
898 old_origin = vc->vc_origin;
899 new_origin = (long) newscreen;
900 new_scr_end = new_origin + new_screen_size;
901
902 if (vc->vc_y > new_rows) {
903 if (old_rows - vc->vc_y < new_rows) {
904 /*
905 * Cursor near the bottom, copy contents from the
906 * bottom of buffer
907 */
908 old_origin += (old_rows - new_rows) * old_row_size;
909 } else {
910 /*
911 * Cursor is in no man's land, copy 1/2 screenful
912 * from the top and bottom of cursor position
913 */
914 old_origin += (vc->vc_y - new_rows/2) * old_row_size;
915 }
916 }
917
918 end = old_origin + old_row_size * min(old_rows, new_rows);
919
920 update_attr(vc);
921
922 while (old_origin < end) {
923 scr_memcpyw((unsigned short *) new_origin,
924 (unsigned short *) old_origin, rlth);
925 if (rrem)
926 scr_memsetw((void *)(new_origin + rlth),
927 vc->vc_video_erase_char, rrem);
928 old_origin += old_row_size;
929 new_origin += new_row_size;
930 }
931 if (new_scr_end > new_origin)
932 scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
933 new_scr_end - new_origin);
934 kfree(vc->vc_screenbuf);
935 vc->vc_screenbuf = newscreen;
936 vc->vc_screenbuf_size = new_screen_size;
937 set_origin(vc);
938
939 /* do part of a reset_terminal() */
940 vc->vc_top = 0;
941 vc->vc_bottom = vc->vc_rows;
942 gotoxy(vc, vc->vc_x, vc->vc_y);
943 save_cur(vc);
944
945 if (tty) {
946 /* Rewrite the requested winsize data with the actual
947 resulting sizes */
948 struct winsize ws;
949 memset(&ws, 0, sizeof(ws));
950 ws.ws_row = vc->vc_rows;
951 ws.ws_col = vc->vc_cols;
952 ws.ws_ypixel = vc->vc_scan_lines;
953 tty_do_resize(tty, &ws);
954 }
955
956 if (CON_IS_VISIBLE(vc))
957 update_screen(vc);
958 vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num);
959 return err;
960}
961
962/**
963 * vc_resize - resize a VT
964 * @vc: virtual console
965 * @cols: columns
966 * @rows: rows
967 *
968 * Resize a virtual console as seen from the console end of things. We
969 * use the common vc_do_resize methods to update the structures. The
970 * caller must hold the console sem to protect console internals and
971 * vc->port.tty
972 */
973
974int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows)
975{
976 return vc_do_resize(vc->port.tty, vc, cols, rows);
977}
978
979/**
980 * vt_resize - resize a VT
981 * @tty: tty to resize
982 * @ws: winsize attributes
983 *
984 * Resize a virtual terminal. This is called by the tty layer as we
985 * register our own handler for resizing. The mutual helper does all
986 * the actual work.
987 *
988 * Takes the console sem and the called methods then take the tty
989 * termios_mutex and the tty ctrl_lock in that order.
990 */
991static int vt_resize(struct tty_struct *tty, struct winsize *ws)
992{
993 struct vc_data *vc = tty->driver_data;
994 int ret;
995
996 acquire_console_sem();
997 ret = vc_do_resize(tty, vc, ws->ws_col, ws->ws_row);
998 release_console_sem();
999 return ret;
1000}
1001
1002void vc_deallocate(unsigned int currcons)
1003{
1004 WARN_CONSOLE_UNLOCKED();
1005
1006 if (vc_cons_allocated(currcons)) {
1007 struct vc_data *vc = vc_cons[currcons].d;
1008 struct vt_notifier_param param = { .vc = vc };
1009
1010 atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
1011 vcs_remove_sysfs(currcons);
1012 vc->vc_sw->con_deinit(vc);
1013 put_pid(vc->vt_pid);
1014 module_put(vc->vc_sw->owner);
1015 kfree(vc->vc_screenbuf);
1016 if (currcons >= MIN_NR_CONSOLES)
1017 kfree(vc);
1018 vc_cons[currcons].d = NULL;
1019 }
1020}
1021
1022/*
1023 * VT102 emulator
1024 */
1025
1026#define set_kbd(vc, x) set_vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
1027#define clr_kbd(vc, x) clr_vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
1028#define is_kbd(vc, x) vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
1029
1030#define decarm VC_REPEAT
1031#define decckm VC_CKMODE
1032#define kbdapplic VC_APPLIC
1033#define lnm VC_CRLF
1034
1035/*
1036 * this is what the terminal answers to a ESC-Z or csi0c query.
1037 */
1038#define VT100ID "\033[?1;2c"
1039#define VT102ID "\033[?6c"
1040
1041unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
1042 8,12,10,14, 9,13,11,15 };
1043
1044/* the default colour table, for VGA+ colour systems */
1045int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,
1046 0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
1047int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
1048 0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
1049int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
1050 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
1051
1052module_param_array(default_red, int, NULL, S_IRUGO | S_IWUSR);
1053module_param_array(default_grn, int, NULL, S_IRUGO | S_IWUSR);
1054module_param_array(default_blu, int, NULL, S_IRUGO | S_IWUSR);
1055
1056/*
1057 * gotoxy() must verify all boundaries, because the arguments
1058 * might also be negative. If the given position is out of
1059 * bounds, the cursor is placed at the nearest margin.
1060 */
1061static void gotoxy(struct vc_data *vc, int new_x, int new_y)
1062{
1063 int min_y, max_y;
1064
1065 if (new_x < 0)
1066 vc->vc_x = 0;
1067 else {
1068 if (new_x >= vc->vc_cols)
1069 vc->vc_x = vc->vc_cols - 1;
1070 else
1071 vc->vc_x = new_x;
1072 }
1073
1074 if (vc->vc_decom) {
1075 min_y = vc->vc_top;
1076 max_y = vc->vc_bottom;
1077 } else {
1078 min_y = 0;
1079 max_y = vc->vc_rows;
1080 }
1081 if (new_y < min_y)
1082 vc->vc_y = min_y;
1083 else if (new_y >= max_y)
1084 vc->vc_y = max_y - 1;
1085 else
1086 vc->vc_y = new_y;
1087 vc->vc_pos = vc->vc_origin + vc->vc_y * vc->vc_size_row + (vc->vc_x<<1);
1088 vc->vc_need_wrap = 0;
1089}
1090
1091/* for absolute user moves, when decom is set */
1092static void gotoxay(struct vc_data *vc, int new_x, int new_y)
1093{
1094 gotoxy(vc, new_x, vc->vc_decom ? (vc->vc_top + new_y) : new_y);
1095}
1096
1097void scrollback(struct vc_data *vc, int lines)
1098{
1099 if (!lines)
1100 lines = vc->vc_rows / 2;
1101 scrolldelta(-lines);
1102}
1103
1104void scrollfront(struct vc_data *vc, int lines)
1105{
1106 if (!lines)
1107 lines = vc->vc_rows / 2;
1108 scrolldelta(lines);
1109}
1110
1111static void lf(struct vc_data *vc)
1112{
1113 /* don't scroll if above bottom of scrolling region, or
1114 * if below scrolling region
1115 */
1116 if (vc->vc_y + 1 == vc->vc_bottom)
1117 scrup(vc, vc->vc_top, vc->vc_bottom, 1);
1118 else if (vc->vc_y < vc->vc_rows - 1) {
1119 vc->vc_y++;
1120 vc->vc_pos += vc->vc_size_row;
1121 }
1122 vc->vc_need_wrap = 0;
1123 notify_write(vc, '\n');
1124}
1125
1126static void ri(struct vc_data *vc)
1127{
1128 /* don't scroll if below top of scrolling region, or
1129 * if above scrolling region
1130 */
1131 if (vc->vc_y == vc->vc_top)
1132 scrdown(vc, vc->vc_top, vc->vc_bottom, 1);
1133 else if (vc->vc_y > 0) {
1134 vc->vc_y--;
1135 vc->vc_pos -= vc->vc_size_row;
1136 }
1137 vc->vc_need_wrap = 0;
1138}
1139
1140static inline void cr(struct vc_data *vc)
1141{
1142 vc->vc_pos -= vc->vc_x << 1;
1143 vc->vc_need_wrap = vc->vc_x = 0;
1144 notify_write(vc, '\r');
1145}
1146
1147static inline void bs(struct vc_data *vc)
1148{
1149 if (vc->vc_x) {
1150 vc->vc_pos -= 2;
1151 vc->vc_x--;
1152 vc->vc_need_wrap = 0;
1153 notify_write(vc, '\b');
1154 }
1155}
1156
1157static inline void del(struct vc_data *vc)
1158{
1159 /* ignored */
1160}
1161
1162static void csi_J(struct vc_data *vc, int vpar)
1163{
1164 unsigned int count;
1165 unsigned short * start;
1166
1167 switch (vpar) {
1168 case 0: /* erase from cursor to end of display */
1169 count = (vc->vc_scr_end - vc->vc_pos) >> 1;
1170 start = (unsigned short *)vc->vc_pos;
1171 if (DO_UPDATE(vc)) {
1172 /* do in two stages */
1173 vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
1174 vc->vc_cols - vc->vc_x);
1175 vc->vc_sw->con_clear(vc, vc->vc_y + 1, 0,
1176 vc->vc_rows - vc->vc_y - 1,
1177 vc->vc_cols);
1178 }
1179 break;
1180 case 1: /* erase from start to cursor */
1181 count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1;
1182 start = (unsigned short *)vc->vc_origin;
1183 if (DO_UPDATE(vc)) {
1184 /* do in two stages */
1185 vc->vc_sw->con_clear(vc, 0, 0, vc->vc_y,
1186 vc->vc_cols);
1187 vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
1188 vc->vc_x + 1);
1189 }
1190 break;
1191 case 2: /* erase whole display */
1192 count = vc->vc_cols * vc->vc_rows;
1193 start = (unsigned short *)vc->vc_origin;
1194 if (DO_UPDATE(vc))
1195 vc->vc_sw->con_clear(vc, 0, 0,
1196 vc->vc_rows,
1197 vc->vc_cols);
1198 break;
1199 default:
1200 return;
1201 }
1202 scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
1203 vc->vc_need_wrap = 0;
1204}
1205
1206static void csi_K(struct vc_data *vc, int vpar)
1207{
1208 unsigned int count;
1209 unsigned short * start;
1210
1211 switch (vpar) {
1212 case 0: /* erase from cursor to end of line */
1213 count = vc->vc_cols - vc->vc_x;
1214 start = (unsigned short *)vc->vc_pos;
1215 if (DO_UPDATE(vc))
1216 vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
1217 vc->vc_cols - vc->vc_x);
1218 break;
1219 case 1: /* erase from start of line to cursor */
1220 start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
1221 count = vc->vc_x + 1;
1222 if (DO_UPDATE(vc))
1223 vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
1224 vc->vc_x + 1);
1225 break;
1226 case 2: /* erase whole line */
1227 start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
1228 count = vc->vc_cols;
1229 if (DO_UPDATE(vc))
1230 vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
1231 vc->vc_cols);
1232 break;
1233 default:
1234 return;
1235 }
1236 scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
1237 vc->vc_need_wrap = 0;
1238}
1239
1240static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */
1241{ /* not vt100? */
1242 int count;
1243
1244 if (!vpar)
1245 vpar++;
1246 count = (vpar > vc->vc_cols - vc->vc_x) ? (vc->vc_cols - vc->vc_x) : vpar;
1247
1248 scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count);
1249 if (DO_UPDATE(vc))
1250 vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, count);
1251 vc->vc_need_wrap = 0;
1252}
1253
1254static void default_attr(struct vc_data *vc)
1255{
1256 vc->vc_intensity = 1;
1257 vc->vc_italic = 0;
1258 vc->vc_underline = 0;
1259 vc->vc_reverse = 0;
1260 vc->vc_blink = 0;
1261 vc->vc_color = vc->vc_def_color;
1262}
1263
1264/* console_sem is held */
1265static void csi_m(struct vc_data *vc)
1266{
1267 int i;
1268
1269 for (i = 0; i <= vc->vc_npar; i++)
1270 switch (vc->vc_par[i]) {
1271 case 0: /* all attributes off */
1272 default_attr(vc);
1273 break;
1274 case 1:
1275 vc->vc_intensity = 2;
1276 break;
1277 case 2:
1278 vc->vc_intensity = 0;
1279 break;
1280 case 3:
1281 vc->vc_italic = 1;
1282 break;
1283 case 4:
1284 vc->vc_underline = 1;
1285 break;
1286 case 5:
1287 vc->vc_blink = 1;
1288 break;
1289 case 7:
1290 vc->vc_reverse = 1;
1291 break;
1292 case 10: /* ANSI X3.64-1979 (SCO-ish?)
1293 * Select primary font, don't display
1294 * control chars if defined, don't set
1295 * bit 8 on output.
1296 */
1297 vc->vc_translate = set_translate(vc->vc_charset == 0
1298 ? vc->vc_G0_charset
1299 : vc->vc_G1_charset, vc);
1300 vc->vc_disp_ctrl = 0;
1301 vc->vc_toggle_meta = 0;
1302 break;
1303 case 11: /* ANSI X3.64-1979 (SCO-ish?)
1304 * Select first alternate font, lets
1305 * chars < 32 be displayed as ROM chars.
1306 */
1307 vc->vc_translate = set_translate(IBMPC_MAP, vc);
1308 vc->vc_disp_ctrl = 1;
1309 vc->vc_toggle_meta = 0;
1310 break;
1311 case 12: /* ANSI X3.64-1979 (SCO-ish?)
1312 * Select second alternate font, toggle
1313 * high bit before displaying as ROM char.
1314 */
1315 vc->vc_translate = set_translate(IBMPC_MAP, vc);
1316 vc->vc_disp_ctrl = 1;
1317 vc->vc_toggle_meta = 1;
1318 break;
1319 case 21:
1320 case 22:
1321 vc->vc_intensity = 1;
1322 break;
1323 case 23:
1324 vc->vc_italic = 0;
1325 break;
1326 case 24:
1327 vc->vc_underline = 0;
1328 break;
1329 case 25:
1330 vc->vc_blink = 0;
1331 break;
1332 case 27:
1333 vc->vc_reverse = 0;
1334 break;
1335 case 38: /* ANSI X3.64-1979 (SCO-ish?)
1336 * Enables underscore, white foreground
1337 * with white underscore (Linux - use
1338 * default foreground).
1339 */
1340 vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
1341 vc->vc_underline = 1;
1342 break;
1343 case 39: /* ANSI X3.64-1979 (SCO-ish?)
1344 * Disable underline option.
1345 * Reset colour to default? It did this
1346 * before...
1347 */
1348 vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
1349 vc->vc_underline = 0;
1350 break;
1351 case 49:
1352 vc->vc_color = (vc->vc_def_color & 0xf0) | (vc->vc_color & 0x0f);
1353 break;
1354 default:
1355 if (vc->vc_par[i] >= 30 && vc->vc_par[i] <= 37)
1356 vc->vc_color = color_table[vc->vc_par[i] - 30]
1357 | (vc->vc_color & 0xf0);
1358 else if (vc->vc_par[i] >= 40 && vc->vc_par[i] <= 47)
1359 vc->vc_color = (color_table[vc->vc_par[i] - 40] << 4)
1360 | (vc->vc_color & 0x0f);
1361 break;
1362 }
1363 update_attr(vc);
1364}
1365
1366static void respond_string(const char *p, struct tty_struct *tty)
1367{
1368 while (*p) {
1369 tty_insert_flip_char(tty, *p, 0);
1370 p++;
1371 }
1372 con_schedule_flip(tty);
1373}
1374
1375static void cursor_report(struct vc_data *vc, struct tty_struct *tty)
1376{
1377 char buf[40];
1378
1379 sprintf(buf, "\033[%d;%dR", vc->vc_y + (vc->vc_decom ? vc->vc_top + 1 : 1), vc->vc_x + 1);
1380 respond_string(buf, tty);
1381}
1382
1383static inline void status_report(struct tty_struct *tty)
1384{
1385 respond_string("\033[0n", tty); /* Terminal ok */
1386}
1387
1388static inline void respond_ID(struct tty_struct * tty)
1389{
1390 respond_string(VT102ID, tty);
1391}
1392
1393void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry)
1394{
1395 char buf[8];
1396
1397 sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
1398 (char)('!' + mry));
1399 respond_string(buf, tty);
1400}
1401
1402/* invoked via ioctl(TIOCLINUX) and through set_selection */
1403int mouse_reporting(void)
1404{
1405 return vc_cons[fg_console].d->vc_report_mouse;
1406}
1407
1408/* console_sem is held */
1409static void set_mode(struct vc_data *vc, int on_off)
1410{
1411 int i;
1412
1413 for (i = 0; i <= vc->vc_npar; i++)
1414 if (vc->vc_ques) {
1415 switch(vc->vc_par[i]) { /* DEC private modes set/reset */
1416 case 1: /* Cursor keys send ^[Ox/^[[x */
1417 if (on_off)
1418 set_kbd(vc, decckm);
1419 else
1420 clr_kbd(vc, decckm);
1421 break;
1422 case 3: /* 80/132 mode switch unimplemented */
1423 vc->vc_deccolm = on_off;
1424#if 0
1425 vc_resize(deccolm ? 132 : 80, vc->vc_rows);
1426 /* this alone does not suffice; some user mode
1427 utility has to change the hardware regs */
1428#endif
1429 break;
1430 case 5: /* Inverted screen on/off */
1431 if (vc->vc_decscnm != on_off) {
1432 vc->vc_decscnm = on_off;
1433 invert_screen(vc, 0, vc->vc_screenbuf_size, 0);
1434 update_attr(vc);
1435 }
1436 break;
1437 case 6: /* Origin relative/absolute */
1438 vc->vc_decom = on_off;
1439 gotoxay(vc, 0, 0);
1440 break;
1441 case 7: /* Autowrap on/off */
1442 vc->vc_decawm = on_off;
1443 break;
1444 case 8: /* Autorepeat on/off */
1445 if (on_off)
1446 set_kbd(vc, decarm);
1447 else
1448 clr_kbd(vc, decarm);
1449 break;
1450 case 9:
1451 vc->vc_report_mouse = on_off ? 1 : 0;
1452 break;
1453 case 25: /* Cursor on/off */
1454 vc->vc_deccm = on_off;
1455 break;
1456 case 1000:
1457 vc->vc_report_mouse = on_off ? 2 : 0;
1458 break;
1459 }
1460 } else {
1461 switch(vc->vc_par[i]) { /* ANSI modes set/reset */
1462 case 3: /* Monitor (display ctrls) */
1463 vc->vc_disp_ctrl = on_off;
1464 break;
1465 case 4: /* Insert Mode on/off */
1466 vc->vc_decim = on_off;
1467 break;
1468 case 20: /* Lf, Enter == CrLf/Lf */
1469 if (on_off)
1470 set_kbd(vc, lnm);
1471 else
1472 clr_kbd(vc, lnm);
1473 break;
1474 }
1475 }
1476}
1477
1478/* console_sem is held */
1479static void setterm_command(struct vc_data *vc)
1480{
1481 switch(vc->vc_par[0]) {
1482 case 1: /* set color for underline mode */
1483 if (vc->vc_can_do_color &&
1484 vc->vc_par[1] < 16) {
1485 vc->vc_ulcolor = color_table[vc->vc_par[1]];
1486 if (vc->vc_underline)
1487 update_attr(vc);
1488 }
1489 break;
1490 case 2: /* set color for half intensity mode */
1491 if (vc->vc_can_do_color &&
1492 vc->vc_par[1] < 16) {
1493 vc->vc_halfcolor = color_table[vc->vc_par[1]];
1494 if (vc->vc_intensity == 0)
1495 update_attr(vc);
1496 }
1497 break;
1498 case 8: /* store colors as defaults */
1499 vc->vc_def_color = vc->vc_attr;
1500 if (vc->vc_hi_font_mask == 0x100)
1501 vc->vc_def_color >>= 1;
1502 default_attr(vc);
1503 update_attr(vc);
1504 break;
1505 case 9: /* set blanking interval */
1506 blankinterval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60;
1507 poke_blanked_console();
1508 break;
1509 case 10: /* set bell frequency in Hz */
1510 if (vc->vc_npar >= 1)
1511 vc->vc_bell_pitch = vc->vc_par[1];
1512 else
1513 vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
1514 break;
1515 case 11: /* set bell duration in msec */
1516 if (vc->vc_npar >= 1)
1517 vc->vc_bell_duration = (vc->vc_par[1] < 2000) ?
1518 vc->vc_par[1] * HZ / 1000 : 0;
1519 else
1520 vc->vc_bell_duration = DEFAULT_BELL_DURATION;
1521 break;
1522 case 12: /* bring specified console to the front */
1523 if (vc->vc_par[1] >= 1 && vc_cons_allocated(vc->vc_par[1] - 1))
1524 set_console(vc->vc_par[1] - 1);
1525 break;
1526 case 13: /* unblank the screen */
1527 poke_blanked_console();
1528 break;
1529 case 14: /* set vesa powerdown interval */
1530 vesa_off_interval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60 * HZ;
1531 break;
1532 case 15: /* activate the previous console */
1533 set_console(last_console);
1534 break;
1535 }
1536}
1537
1538/* console_sem is held */
1539static void csi_at(struct vc_data *vc, unsigned int nr)
1540{
1541 if (nr > vc->vc_cols - vc->vc_x)
1542 nr = vc->vc_cols - vc->vc_x;
1543 else if (!nr)
1544 nr = 1;
1545 insert_char(vc, nr);
1546}
1547
1548/* console_sem is held */
1549static void csi_L(struct vc_data *vc, unsigned int nr)
1550{
1551 if (nr > vc->vc_rows - vc->vc_y)
1552 nr = vc->vc_rows - vc->vc_y;
1553 else if (!nr)
1554 nr = 1;
1555 scrdown(vc, vc->vc_y, vc->vc_bottom, nr);
1556 vc->vc_need_wrap = 0;
1557}
1558
1559/* console_sem is held */
1560static void csi_P(struct vc_data *vc, unsigned int nr)
1561{
1562 if (nr > vc->vc_cols - vc->vc_x)
1563 nr = vc->vc_cols - vc->vc_x;
1564 else if (!nr)
1565 nr = 1;
1566 delete_char(vc, nr);
1567}
1568
1569/* console_sem is held */
1570static void csi_M(struct vc_data *vc, unsigned int nr)
1571{
1572 if (nr > vc->vc_rows - vc->vc_y)
1573 nr = vc->vc_rows - vc->vc_y;
1574 else if (!nr)
1575 nr=1;
1576 scrup(vc, vc->vc_y, vc->vc_bottom, nr);
1577 vc->vc_need_wrap = 0;
1578}
1579
1580/* console_sem is held (except via vc_init->reset_terminal */
1581static void save_cur(struct vc_data *vc)
1582{
1583 vc->vc_saved_x = vc->vc_x;
1584 vc->vc_saved_y = vc->vc_y;
1585 vc->vc_s_intensity = vc->vc_intensity;
1586 vc->vc_s_italic = vc->vc_italic;
1587 vc->vc_s_underline = vc->vc_underline;
1588 vc->vc_s_blink = vc->vc_blink;
1589 vc->vc_s_reverse = vc->vc_reverse;
1590 vc->vc_s_charset = vc->vc_charset;
1591 vc->vc_s_color = vc->vc_color;
1592 vc->vc_saved_G0 = vc->vc_G0_charset;
1593 vc->vc_saved_G1 = vc->vc_G1_charset;
1594}
1595
1596/* console_sem is held */
1597static void restore_cur(struct vc_data *vc)
1598{
1599 gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y);
1600 vc->vc_intensity = vc->vc_s_intensity;
1601 vc->vc_italic = vc->vc_s_italic;
1602 vc->vc_underline = vc->vc_s_underline;
1603 vc->vc_blink = vc->vc_s_blink;
1604 vc->vc_reverse = vc->vc_s_reverse;
1605 vc->vc_charset = vc->vc_s_charset;
1606 vc->vc_color = vc->vc_s_color;
1607 vc->vc_G0_charset = vc->vc_saved_G0;
1608 vc->vc_G1_charset = vc->vc_saved_G1;
1609 vc->vc_translate = set_translate(vc->vc_charset ? vc->vc_G1_charset : vc->vc_G0_charset, vc);
1610 update_attr(vc);
1611 vc->vc_need_wrap = 0;
1612}
1613
1614enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
1615 EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
1616 ESpalette };
1617
1618/* console_sem is held (except via vc_init()) */
1619static void reset_terminal(struct vc_data *vc, int do_clear)
1620{
1621 vc->vc_top = 0;
1622 vc->vc_bottom = vc->vc_rows;
1623 vc->vc_state = ESnormal;
1624 vc->vc_ques = 0;
1625 vc->vc_translate = set_translate(LAT1_MAP, vc);
1626 vc->vc_G0_charset = LAT1_MAP;
1627 vc->vc_G1_charset = GRAF_MAP;
1628 vc->vc_charset = 0;
1629 vc->vc_need_wrap = 0;
1630 vc->vc_report_mouse = 0;
1631 vc->vc_utf = default_utf8;
1632 vc->vc_utf_count = 0;
1633
1634 vc->vc_disp_ctrl = 0;
1635 vc->vc_toggle_meta = 0;
1636
1637 vc->vc_decscnm = 0;
1638 vc->vc_decom = 0;
1639 vc->vc_decawm = 1;
1640 vc->vc_deccm = global_cursor_default;
1641 vc->vc_decim = 0;
1642
1643 set_kbd(vc, decarm);
1644 clr_kbd(vc, decckm);
1645 clr_kbd(vc, kbdapplic);
1646 clr_kbd(vc, lnm);
1647 kbd_table[vc->vc_num].lockstate = 0;
1648 kbd_table[vc->vc_num].slockstate = 0;
1649 kbd_table[vc->vc_num].ledmode = LED_SHOW_FLAGS;
1650 kbd_table[vc->vc_num].ledflagstate = kbd_table[vc->vc_num].default_ledflagstate;
1651 /* do not do set_leds here because this causes an endless tasklet loop
1652 when the keyboard hasn't been initialized yet */
1653
1654 vc->vc_cursor_type = cur_default;
1655 vc->vc_complement_mask = vc->vc_s_complement_mask;
1656
1657 default_attr(vc);
1658 update_attr(vc);
1659
1660 vc->vc_tab_stop[0] = 0x01010100;
1661 vc->vc_tab_stop[1] =
1662 vc->vc_tab_stop[2] =
1663 vc->vc_tab_stop[3] =
1664 vc->vc_tab_stop[4] =
1665 vc->vc_tab_stop[5] =
1666 vc->vc_tab_stop[6] =
1667 vc->vc_tab_stop[7] = 0x01010101;
1668
1669 vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
1670 vc->vc_bell_duration = DEFAULT_BELL_DURATION;
1671
1672 gotoxy(vc, 0, 0);
1673 save_cur(vc);
1674 if (do_clear)
1675 csi_J(vc, 2);
1676}
1677
1678/* console_sem is held */
1679static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
1680{
1681 /*
1682 * Control characters can be used in the _middle_
1683 * of an escape sequence.
1684 */
1685 switch (c) {
1686 case 0:
1687 return;
1688 case 7:
1689 if (vc->vc_bell_duration)
1690 kd_mksound(vc->vc_bell_pitch, vc->vc_bell_duration);
1691 return;
1692 case 8:
1693 bs(vc);
1694 return;
1695 case 9:
1696 vc->vc_pos -= (vc->vc_x << 1);
1697 while (vc->vc_x < vc->vc_cols - 1) {
1698 vc->vc_x++;
1699 if (vc->vc_tab_stop[vc->vc_x >> 5] & (1 << (vc->vc_x & 31)))
1700 break;
1701 }
1702 vc->vc_pos += (vc->vc_x << 1);
1703 notify_write(vc, '\t');
1704 return;
1705 case 10: case 11: case 12:
1706 lf(vc);
1707 if (!is_kbd(vc, lnm))
1708 return;
1709 case 13:
1710 cr(vc);
1711 return;
1712 case 14:
1713 vc->vc_charset = 1;
1714 vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
1715 vc->vc_disp_ctrl = 1;
1716 return;
1717 case 15:
1718 vc->vc_charset = 0;
1719 vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
1720 vc->vc_disp_ctrl = 0;
1721 return;
1722 case 24: case 26:
1723 vc->vc_state = ESnormal;
1724 return;
1725 case 27:
1726 vc->vc_state = ESesc;
1727 return;
1728 case 127:
1729 del(vc);
1730 return;
1731 case 128+27:
1732 vc->vc_state = ESsquare;
1733 return;
1734 }
1735 switch(vc->vc_state) {
1736 case ESesc:
1737 vc->vc_state = ESnormal;
1738 switch (c) {
1739 case '[':
1740 vc->vc_state = ESsquare;
1741 return;
1742 case ']':
1743 vc->vc_state = ESnonstd;
1744 return;
1745 case '%':
1746 vc->vc_state = ESpercent;
1747 return;
1748 case 'E':
1749 cr(vc);
1750 lf(vc);
1751 return;
1752 case 'M':
1753 ri(vc);
1754 return;
1755 case 'D':
1756 lf(vc);
1757 return;
1758 case 'H':
1759 vc->vc_tab_stop[vc->vc_x >> 5] |= (1 << (vc->vc_x & 31));
1760 return;
1761 case 'Z':
1762 respond_ID(tty);
1763 return;
1764 case '7':
1765 save_cur(vc);
1766 return;
1767 case '8':
1768 restore_cur(vc);
1769 return;
1770 case '(':
1771 vc->vc_state = ESsetG0;
1772 return;
1773 case ')':
1774 vc->vc_state = ESsetG1;
1775 return;
1776 case '#':
1777 vc->vc_state = EShash;
1778 return;
1779 case 'c':
1780 reset_terminal(vc, 1);
1781 return;
1782 case '>': /* Numeric keypad */
1783 clr_kbd(vc, kbdapplic);
1784 return;
1785 case '=': /* Appl. keypad */
1786 set_kbd(vc, kbdapplic);
1787 return;
1788 }
1789 return;
1790 case ESnonstd:
1791 if (c=='P') { /* palette escape sequence */
1792 for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
1793 vc->vc_par[vc->vc_npar] = 0;
1794 vc->vc_npar = 0;
1795 vc->vc_state = ESpalette;
1796 return;
1797 } else if (c=='R') { /* reset palette */
1798 reset_palette(vc);
1799 vc->vc_state = ESnormal;
1800 } else
1801 vc->vc_state = ESnormal;
1802 return;
1803 case ESpalette:
1804 if (isxdigit(c)) {
1805 vc->vc_par[vc->vc_npar++] = hex_to_bin(c);
1806 if (vc->vc_npar == 7) {
1807 int i = vc->vc_par[0] * 3, j = 1;
1808 vc->vc_palette[i] = 16 * vc->vc_par[j++];
1809 vc->vc_palette[i++] += vc->vc_par[j++];
1810 vc->vc_palette[i] = 16 * vc->vc_par[j++];
1811 vc->vc_palette[i++] += vc->vc_par[j++];
1812 vc->vc_palette[i] = 16 * vc->vc_par[j++];
1813 vc->vc_palette[i] += vc->vc_par[j];
1814 set_palette(vc);
1815 vc->vc_state = ESnormal;
1816 }
1817 } else
1818 vc->vc_state = ESnormal;
1819 return;
1820 case ESsquare:
1821 for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
1822 vc->vc_par[vc->vc_npar] = 0;
1823 vc->vc_npar = 0;
1824 vc->vc_state = ESgetpars;
1825 if (c == '[') { /* Function key */
1826 vc->vc_state=ESfunckey;
1827 return;
1828 }
1829 vc->vc_ques = (c == '?');
1830 if (vc->vc_ques)
1831 return;
1832 case ESgetpars:
1833 if (c == ';' && vc->vc_npar < NPAR - 1) {
1834 vc->vc_npar++;
1835 return;
1836 } else if (c>='0' && c<='9') {
1837 vc->vc_par[vc->vc_npar] *= 10;
1838 vc->vc_par[vc->vc_npar] += c - '0';
1839 return;
1840 } else
1841 vc->vc_state = ESgotpars;
1842 case ESgotpars:
1843 vc->vc_state = ESnormal;
1844 switch(c) {
1845 case 'h':
1846 set_mode(vc, 1);
1847 return;
1848 case 'l':
1849 set_mode(vc, 0);
1850 return;
1851 case 'c':
1852 if (vc->vc_ques) {
1853 if (vc->vc_par[0])
1854 vc->vc_cursor_type = vc->vc_par[0] | (vc->vc_par[1] << 8) | (vc->vc_par[2] << 16);
1855 else
1856 vc->vc_cursor_type = cur_default;
1857 return;
1858 }
1859 break;
1860 case 'm':
1861 if (vc->vc_ques) {
1862 clear_selection();
1863 if (vc->vc_par[0])
1864 vc->vc_complement_mask = vc->vc_par[0] << 8 | vc->vc_par[1];
1865 else
1866 vc->vc_complement_mask = vc->vc_s_complement_mask;
1867 return;
1868 }
1869 break;
1870 case 'n':
1871 if (!vc->vc_ques) {
1872 if (vc->vc_par[0] == 5)
1873 status_report(tty);
1874 else if (vc->vc_par[0] == 6)
1875 cursor_report(vc, tty);
1876 }
1877 return;
1878 }
1879 if (vc->vc_ques) {
1880 vc->vc_ques = 0;
1881 return;
1882 }
1883 switch(c) {
1884 case 'G': case '`':
1885 if (vc->vc_par[0])
1886 vc->vc_par[0]--;
1887 gotoxy(vc, vc->vc_par[0], vc->vc_y);
1888 return;
1889 case 'A':
1890 if (!vc->vc_par[0])
1891 vc->vc_par[0]++;
1892 gotoxy(vc, vc->vc_x, vc->vc_y - vc->vc_par[0]);
1893 return;
1894 case 'B': case 'e':
1895 if (!vc->vc_par[0])
1896 vc->vc_par[0]++;
1897 gotoxy(vc, vc->vc_x, vc->vc_y + vc->vc_par[0]);
1898 return;
1899 case 'C': case 'a':
1900 if (!vc->vc_par[0])
1901 vc->vc_par[0]++;
1902 gotoxy(vc, vc->vc_x + vc->vc_par[0], vc->vc_y);
1903 return;
1904 case 'D':
1905 if (!vc->vc_par[0])
1906 vc->vc_par[0]++;
1907 gotoxy(vc, vc->vc_x - vc->vc_par[0], vc->vc_y);
1908 return;
1909 case 'E':
1910 if (!vc->vc_par[0])
1911 vc->vc_par[0]++;
1912 gotoxy(vc, 0, vc->vc_y + vc->vc_par[0]);
1913 return;
1914 case 'F':
1915 if (!vc->vc_par[0])
1916 vc->vc_par[0]++;
1917 gotoxy(vc, 0, vc->vc_y - vc->vc_par[0]);
1918 return;
1919 case 'd':
1920 if (vc->vc_par[0])
1921 vc->vc_par[0]--;
1922 gotoxay(vc, vc->vc_x ,vc->vc_par[0]);
1923 return;
1924 case 'H': case 'f':
1925 if (vc->vc_par[0])
1926 vc->vc_par[0]--;
1927 if (vc->vc_par[1])
1928 vc->vc_par[1]--;
1929 gotoxay(vc, vc->vc_par[1], vc->vc_par[0]);
1930 return;
1931 case 'J':
1932 csi_J(vc, vc->vc_par[0]);
1933 return;
1934 case 'K':
1935 csi_K(vc, vc->vc_par[0]);
1936 return;
1937 case 'L':
1938 csi_L(vc, vc->vc_par[0]);
1939 return;
1940 case 'M':
1941 csi_M(vc, vc->vc_par[0]);
1942 return;
1943 case 'P':
1944 csi_P(vc, vc->vc_par[0]);
1945 return;
1946 case 'c':
1947 if (!vc->vc_par[0])
1948 respond_ID(tty);
1949 return;
1950 case 'g':
1951 if (!vc->vc_par[0])
1952 vc->vc_tab_stop[vc->vc_x >> 5] &= ~(1 << (vc->vc_x & 31));
1953 else if (vc->vc_par[0] == 3) {
1954 vc->vc_tab_stop[0] =
1955 vc->vc_tab_stop[1] =
1956 vc->vc_tab_stop[2] =
1957 vc->vc_tab_stop[3] =
1958 vc->vc_tab_stop[4] =
1959 vc->vc_tab_stop[5] =
1960 vc->vc_tab_stop[6] =
1961 vc->vc_tab_stop[7] = 0;
1962 }
1963 return;
1964 case 'm':
1965 csi_m(vc);
1966 return;
1967 case 'q': /* DECLL - but only 3 leds */
1968 /* map 0,1,2,3 to 0,1,2,4 */
1969 if (vc->vc_par[0] < 4)
1970 setledstate(kbd_table + vc->vc_num,
1971 (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4);
1972 return;
1973 case 'r':
1974 if (!vc->vc_par[0])
1975 vc->vc_par[0]++;
1976 if (!vc->vc_par[1])
1977 vc->vc_par[1] = vc->vc_rows;
1978 /* Minimum allowed region is 2 lines */
1979 if (vc->vc_par[0] < vc->vc_par[1] &&
1980 vc->vc_par[1] <= vc->vc_rows) {
1981 vc->vc_top = vc->vc_par[0] - 1;
1982 vc->vc_bottom = vc->vc_par[1];
1983 gotoxay(vc, 0, 0);
1984 }
1985 return;
1986 case 's':
1987 save_cur(vc);
1988 return;
1989 case 'u':
1990 restore_cur(vc);
1991 return;
1992 case 'X':
1993 csi_X(vc, vc->vc_par[0]);
1994 return;
1995 case '@':
1996 csi_at(vc, vc->vc_par[0]);
1997 return;
1998 case ']': /* setterm functions */
1999 setterm_command(vc);
2000 return;
2001 }
2002 return;
2003 case ESpercent:
2004 vc->vc_state = ESnormal;
2005 switch (c) {
2006 case '@': /* defined in ISO 2022 */
2007 vc->vc_utf = 0;
2008 return;
2009 case 'G': /* prelim official escape code */
2010 case '8': /* retained for compatibility */
2011 vc->vc_utf = 1;
2012 return;
2013 }
2014 return;
2015 case ESfunckey:
2016 vc->vc_state = ESnormal;
2017 return;
2018 case EShash:
2019 vc->vc_state = ESnormal;
2020 if (c == '8') {
2021 /* DEC screen alignment test. kludge :-) */
2022 vc->vc_video_erase_char =
2023 (vc->vc_video_erase_char & 0xff00) | 'E';
2024 csi_J(vc, 2);
2025 vc->vc_video_erase_char =
2026 (vc->vc_video_erase_char & 0xff00) | ' ';
2027 do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
2028 }
2029 return;
2030 case ESsetG0:
2031 if (c == '0')
2032 vc->vc_G0_charset = GRAF_MAP;
2033 else if (c == 'B')
2034 vc->vc_G0_charset = LAT1_MAP;
2035 else if (c == 'U')
2036 vc->vc_G0_charset = IBMPC_MAP;
2037 else if (c == 'K')
2038 vc->vc_G0_charset = USER_MAP;
2039 if (vc->vc_charset == 0)
2040 vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
2041 vc->vc_state = ESnormal;
2042 return;
2043 case ESsetG1:
2044 if (c == '0')
2045 vc->vc_G1_charset = GRAF_MAP;
2046 else if (c == 'B')
2047 vc->vc_G1_charset = LAT1_MAP;
2048 else if (c == 'U')
2049 vc->vc_G1_charset = IBMPC_MAP;
2050 else if (c == 'K')
2051 vc->vc_G1_charset = USER_MAP;
2052 if (vc->vc_charset == 1)
2053 vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
2054 vc->vc_state = ESnormal;
2055 return;
2056 default:
2057 vc->vc_state = ESnormal;
2058 }
2059}
2060
2061/* This is a temporary buffer used to prepare a tty console write
2062 * so that we can easily avoid touching user space while holding the
2063 * console spinlock. It is allocated in con_init and is shared by
2064 * this code and the vc_screen read/write tty calls.
2065 *
2066 * We have to allocate this statically in the kernel data section
2067 * since console_init (and thus con_init) are called before any
2068 * kernel memory allocation is available.
2069 */
2070char con_buf[CON_BUF_SIZE];
2071DEFINE_MUTEX(con_buf_mtx);
2072
2073/* is_double_width() is based on the wcwidth() implementation by
2074 * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
2075 * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
2076 */
2077struct interval {
2078 uint32_t first;
2079 uint32_t last;
2080};
2081
2082static int bisearch(uint32_t ucs, const struct interval *table, int max)
2083{
2084 int min = 0;
2085 int mid;
2086
2087 if (ucs < table[0].first || ucs > table[max].last)
2088 return 0;
2089 while (max >= min) {
2090 mid = (min + max) / 2;
2091 if (ucs > table[mid].last)
2092 min = mid + 1;
2093 else if (ucs < table[mid].first)
2094 max = mid - 1;
2095 else
2096 return 1;
2097 }
2098 return 0;
2099}
2100
2101static int is_double_width(uint32_t ucs)
2102{
2103 static const struct interval double_width[] = {
2104 { 0x1100, 0x115F }, { 0x2329, 0x232A }, { 0x2E80, 0x303E },
2105 { 0x3040, 0xA4CF }, { 0xAC00, 0xD7A3 }, { 0xF900, 0xFAFF },
2106 { 0xFE10, 0xFE19 }, { 0xFE30, 0xFE6F }, { 0xFF00, 0xFF60 },
2107 { 0xFFE0, 0xFFE6 }, { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD }
2108 };
2109 return bisearch(ucs, double_width, ARRAY_SIZE(double_width) - 1);
2110}
2111
2112/* acquires console_sem */
2113static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
2114{
2115#ifdef VT_BUF_VRAM_ONLY
2116#define FLUSH do { } while(0);
2117#else
2118#define FLUSH if (draw_x >= 0) { \
2119 vc->vc_sw->con_putcs(vc, (u16 *)draw_from, (u16 *)draw_to - (u16 *)draw_from, vc->vc_y, draw_x); \
2120 draw_x = -1; \
2121 }
2122#endif
2123
2124 int c, tc, ok, n = 0, draw_x = -1;
2125 unsigned int currcons;
2126 unsigned long draw_from = 0, draw_to = 0;
2127 struct vc_data *vc;
2128 unsigned char vc_attr;
2129 struct vt_notifier_param param;
2130 uint8_t rescan;
2131 uint8_t inverse;
2132 uint8_t width;
2133 u16 himask, charmask;
2134
2135 if (in_interrupt())
2136 return count;
2137
2138 might_sleep();
2139
2140 acquire_console_sem();
2141 vc = tty->driver_data;
2142 if (vc == NULL) {
2143 printk(KERN_ERR "vt: argh, driver_data is NULL !\n");
2144 release_console_sem();
2145 return 0;
2146 }
2147
2148 currcons = vc->vc_num;
2149 if (!vc_cons_allocated(currcons)) {
2150 /* could this happen? */
2151 printk_once("con_write: tty %d not allocated\n", currcons+1);
2152 release_console_sem();
2153 return 0;
2154 }
2155
2156 himask = vc->vc_hi_font_mask;
2157 charmask = himask ? 0x1ff : 0xff;
2158
2159 /* undraw cursor first */
2160 if (IS_FG(vc))
2161 hide_cursor(vc);
2162
2163 param.vc = vc;
2164
2165 while (!tty->stopped && count) {
2166 int orig = *buf;
2167 c = orig;
2168 buf++;
2169 n++;
2170 count--;
2171 rescan = 0;
2172 inverse = 0;
2173 width = 1;
2174
2175 /* Do no translation at all in control states */
2176 if (vc->vc_state != ESnormal) {
2177 tc = c;
2178 } else if (vc->vc_utf && !vc->vc_disp_ctrl) {
2179 /* Combine UTF-8 into Unicode in vc_utf_char.
2180 * vc_utf_count is the number of continuation bytes still
2181 * expected to arrive.
2182 * vc_npar is the number of continuation bytes arrived so
2183 * far
2184 */
2185rescan_last_byte:
2186 if ((c & 0xc0) == 0x80) {
2187 /* Continuation byte received */
2188 static const uint32_t utf8_length_changes[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff };
2189 if (vc->vc_utf_count) {
2190 vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
2191 vc->vc_npar++;
2192 if (--vc->vc_utf_count) {
2193 /* Still need some bytes */
2194 continue;
2195 }
2196 /* Got a whole character */
2197 c = vc->vc_utf_char;
2198 /* Reject overlong sequences */
2199 if (c <= utf8_length_changes[vc->vc_npar - 1] ||
2200 c > utf8_length_changes[vc->vc_npar])
2201 c = 0xfffd;
2202 } else {
2203 /* Unexpected continuation byte */
2204 vc->vc_utf_count = 0;
2205 c = 0xfffd;
2206 }
2207 } else {
2208 /* Single ASCII byte or first byte of a sequence received */
2209 if (vc->vc_utf_count) {
2210 /* Continuation byte expected */
2211 rescan = 1;
2212 vc->vc_utf_count = 0;
2213 c = 0xfffd;
2214 } else if (c > 0x7f) {
2215 /* First byte of a multibyte sequence received */
2216 vc->vc_npar = 0;
2217 if ((c & 0xe0) == 0xc0) {
2218 vc->vc_utf_count = 1;
2219 vc->vc_utf_char = (c & 0x1f);
2220 } else if ((c & 0xf0) == 0xe0) {
2221 vc->vc_utf_count = 2;
2222 vc->vc_utf_char = (c & 0x0f);
2223 } else if ((c & 0xf8) == 0xf0) {
2224 vc->vc_utf_count = 3;
2225 vc->vc_utf_char = (c & 0x07);
2226 } else if ((c & 0xfc) == 0xf8) {
2227 vc->vc_utf_count = 4;
2228 vc->vc_utf_char = (c & 0x03);
2229 } else if ((c & 0xfe) == 0xfc) {
2230 vc->vc_utf_count = 5;
2231 vc->vc_utf_char = (c & 0x01);
2232 } else {
2233 /* 254 and 255 are invalid */
2234 c = 0xfffd;
2235 }
2236 if (vc->vc_utf_count) {
2237 /* Still need some bytes */
2238 continue;
2239 }
2240 }
2241 /* Nothing to do if an ASCII byte was received */
2242 }
2243 /* End of UTF-8 decoding. */
2244 /* c is the received character, or U+FFFD for invalid sequences. */
2245 /* Replace invalid Unicode code points with U+FFFD too */
2246 if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
2247 c = 0xfffd;
2248 tc = c;
2249 } else { /* no utf or alternate charset mode */
2250 tc = vc_translate(vc, c);
2251 }
2252
2253 param.c = tc;
2254 if (atomic_notifier_call_chain(&vt_notifier_list, VT_PREWRITE,
2255 &param) == NOTIFY_STOP)
2256 continue;
2257
2258 /* If the original code was a control character we
2259 * only allow a glyph to be displayed if the code is
2260 * not normally used (such as for cursor movement) or
2261 * if the disp_ctrl mode has been explicitly enabled.
2262 * Certain characters (as given by the CTRL_ALWAYS
2263 * bitmap) are always displayed as control characters,
2264 * as the console would be pretty useless without
2265 * them; to display an arbitrary font position use the
2266 * direct-to-font zone in UTF-8 mode.
2267 */
2268 ok = tc && (c >= 32 ||
2269 !(vc->vc_disp_ctrl ? (CTRL_ALWAYS >> c) & 1 :
2270 vc->vc_utf || ((CTRL_ACTION >> c) & 1)))
2271 && (c != 127 || vc->vc_disp_ctrl)
2272 && (c != 128+27);
2273
2274 if (vc->vc_state == ESnormal && ok) {
2275 if (vc->vc_utf && !vc->vc_disp_ctrl) {
2276 if (is_double_width(c))
2277 width = 2;
2278 }
2279 /* Now try to find out how to display it */
2280 tc = conv_uni_to_pc(vc, tc);
2281 if (tc & ~charmask) {
2282 if (tc == -1 || tc == -2) {
2283 continue; /* nothing to display */
2284 }
2285 /* Glyph not found */
2286 if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) && !(c & ~charmask)) {
2287 /* In legacy mode use the glyph we get by a 1:1 mapping.
2288 This would make absolutely no sense with Unicode in mind,
2289 but do this for ASCII characters since a font may lack
2290 Unicode mapping info and we don't want to end up with
2291 having question marks only. */
2292 tc = c;
2293 } else {
2294 /* Display U+FFFD. If it's not found, display an inverse question mark. */
2295 tc = conv_uni_to_pc(vc, 0xfffd);
2296 if (tc < 0) {
2297 inverse = 1;
2298 tc = conv_uni_to_pc(vc, '?');
2299 if (tc < 0) tc = '?';
2300 }
2301 }
2302 }
2303
2304 if (!inverse) {
2305 vc_attr = vc->vc_attr;
2306 } else {
2307 /* invert vc_attr */
2308 if (!vc->vc_can_do_color) {
2309 vc_attr = (vc->vc_attr) ^ 0x08;
2310 } else if (vc->vc_hi_font_mask == 0x100) {
2311 vc_attr = ((vc->vc_attr) & 0x11) | (((vc->vc_attr) & 0xe0) >> 4) | (((vc->vc_attr) & 0x0e) << 4);
2312 } else {
2313 vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4);
2314 }
2315 FLUSH
2316 }
2317
2318 while (1) {
2319 if (vc->vc_need_wrap || vc->vc_decim)
2320 FLUSH
2321 if (vc->vc_need_wrap) {
2322 cr(vc);
2323 lf(vc);
2324 }
2325 if (vc->vc_decim)
2326 insert_char(vc, 1);
2327 scr_writew(himask ?
2328 ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
2329 (vc_attr << 8) + tc,
2330 (u16 *) vc->vc_pos);
2331 if (DO_UPDATE(vc) && draw_x < 0) {
2332 draw_x = vc->vc_x;
2333 draw_from = vc->vc_pos;
2334 }
2335 if (vc->vc_x == vc->vc_cols - 1) {
2336 vc->vc_need_wrap = vc->vc_decawm;
2337 draw_to = vc->vc_pos + 2;
2338 } else {
2339 vc->vc_x++;
2340 draw_to = (vc->vc_pos += 2);
2341 }
2342
2343 if (!--width) break;
2344
2345 tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
2346 if (tc < 0) tc = ' ';
2347 }
2348 notify_write(vc, c);
2349
2350 if (inverse) {
2351 FLUSH
2352 }
2353
2354 if (rescan) {
2355 rescan = 0;
2356 inverse = 0;
2357 width = 1;
2358 c = orig;
2359 goto rescan_last_byte;
2360 }
2361 continue;
2362 }
2363 FLUSH
2364 do_con_trol(tty, vc, orig);
2365 }
2366 FLUSH
2367 console_conditional_schedule();
2368 release_console_sem();
2369 notify_update(vc);
2370 return n;
2371#undef FLUSH
2372}
2373
2374/*
2375 * This is the console switching callback.
2376 *
2377 * Doing console switching in a process context allows
2378 * us to do the switches asynchronously (needed when we want
2379 * to switch due to a keyboard interrupt). Synchronization
2380 * with other console code and prevention of re-entrancy is
2381 * ensured with console_sem.
2382 */
2383static void console_callback(struct work_struct *ignored)
2384{
2385 acquire_console_sem();
2386
2387 if (want_console >= 0) {
2388 if (want_console != fg_console &&
2389 vc_cons_allocated(want_console)) {
2390 hide_cursor(vc_cons[fg_console].d);
2391 change_console(vc_cons[want_console].d);
2392 /* we only changed when the console had already
2393 been allocated - a new console is not created
2394 in an interrupt routine */
2395 }
2396 want_console = -1;
2397 }
2398 if (do_poke_blanked_console) { /* do not unblank for a LED change */
2399 do_poke_blanked_console = 0;
2400 poke_blanked_console();
2401 }
2402 if (scrollback_delta) {
2403 struct vc_data *vc = vc_cons[fg_console].d;
2404 clear_selection();
2405 if (vc->vc_mode == KD_TEXT)
2406 vc->vc_sw->con_scrolldelta(vc, scrollback_delta);
2407 scrollback_delta = 0;
2408 }
2409 if (blank_timer_expired) {
2410 do_blank_screen(0);
2411 blank_timer_expired = 0;
2412 }
2413 notify_update(vc_cons[fg_console].d);
2414
2415 release_console_sem();
2416}
2417
2418int set_console(int nr)
2419{
2420 struct vc_data *vc = vc_cons[fg_console].d;
2421
2422 if (!vc_cons_allocated(nr) || vt_dont_switch ||
2423 (vc->vt_mode.mode == VT_AUTO && vc->vc_mode == KD_GRAPHICS)) {
2424
2425 /*
2426 * Console switch will fail in console_callback() or
2427 * change_console() so there is no point scheduling
2428 * the callback
2429 *
2430 * Existing set_console() users don't check the return
2431 * value so this shouldn't break anything
2432 */
2433 return -EINVAL;
2434 }
2435
2436 want_console = nr;
2437 schedule_console_callback();
2438
2439 return 0;
2440}
2441
2442struct tty_driver *console_driver;
2443
2444#ifdef CONFIG_VT_CONSOLE
2445
2446/**
2447 * vt_kmsg_redirect() - Sets/gets the kernel message console
2448 * @new: The new virtual terminal number or -1 if the console should stay
2449 * unchanged
2450 *
2451 * By default, the kernel messages are always printed on the current virtual
2452 * console. However, the user may modify that default with the
2453 * TIOCL_SETKMSGREDIRECT ioctl call.
2454 *
2455 * This function sets the kernel message console to be @new. It returns the old
2456 * virtual console number. The virtual terminal number 0 (both as parameter and
2457 * return value) means no redirection (i.e. always printed on the currently
2458 * active console).
2459 *
2460 * The parameter -1 means that only the current console is returned, but the
2461 * value is not modified. You may use the macro vt_get_kmsg_redirect() in that
2462 * case to make the code more understandable.
2463 *
2464 * When the kernel is compiled without CONFIG_VT_CONSOLE, this function ignores
2465 * the parameter and always returns 0.
2466 */
2467int vt_kmsg_redirect(int new)
2468{
2469 static int kmsg_con;
2470
2471 if (new != -1)
2472 return xchg(&kmsg_con, new);
2473 else
2474 return kmsg_con;
2475}
2476
2477/*
2478 * Console on virtual terminal
2479 *
2480 * The console must be locked when we get here.
2481 */
2482
2483static void vt_console_print(struct console *co, const char *b, unsigned count)
2484{
2485 struct vc_data *vc = vc_cons[fg_console].d;
2486 unsigned char c;
2487 static DEFINE_SPINLOCK(printing_lock);
2488 const ushort *start;
2489 ushort cnt = 0;
2490 ushort myx;
2491 int kmsg_console;
2492
2493 /* console busy or not yet initialized */
2494 if (!printable)
2495 return;
2496 if (!spin_trylock(&printing_lock))
2497 return;
2498
2499 kmsg_console = vt_get_kmsg_redirect();
2500 if (kmsg_console && vc_cons_allocated(kmsg_console - 1))
2501 vc = vc_cons[kmsg_console - 1].d;
2502
2503 /* read `x' only after setting currcons properly (otherwise
2504 the `x' macro will read the x of the foreground console). */
2505 myx = vc->vc_x;
2506
2507 if (!vc_cons_allocated(fg_console)) {
2508 /* impossible */
2509 /* printk("vt_console_print: tty %d not allocated ??\n", currcons+1); */
2510 goto quit;
2511 }
2512
2513 if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc))
2514 goto quit;
2515
2516 /* undraw cursor first */
2517 if (IS_FG(vc))
2518 hide_cursor(vc);
2519
2520 start = (ushort *)vc->vc_pos;
2521
2522 /* Contrived structure to try to emulate original need_wrap behaviour
2523 * Problems caused when we have need_wrap set on '\n' character */
2524 while (count--) {
2525 c = *b++;
2526 if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
2527 if (cnt > 0) {
2528 if (CON_IS_VISIBLE(vc))
2529 vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
2530 vc->vc_x += cnt;
2531 if (vc->vc_need_wrap)
2532 vc->vc_x--;
2533 cnt = 0;
2534 }
2535 if (c == 8) { /* backspace */
2536 bs(vc);
2537 start = (ushort *)vc->vc_pos;
2538 myx = vc->vc_x;
2539 continue;
2540 }
2541 if (c != 13)
2542 lf(vc);
2543 cr(vc);
2544 start = (ushort *)vc->vc_pos;
2545 myx = vc->vc_x;
2546 if (c == 10 || c == 13)
2547 continue;
2548 }
2549 scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos);
2550 notify_write(vc, c);
2551 cnt++;
2552 if (myx == vc->vc_cols - 1) {
2553 vc->vc_need_wrap = 1;
2554 continue;
2555 }
2556 vc->vc_pos += 2;
2557 myx++;
2558 }
2559 if (cnt > 0) {
2560 if (CON_IS_VISIBLE(vc))
2561 vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
2562 vc->vc_x += cnt;
2563 if (vc->vc_x == vc->vc_cols) {
2564 vc->vc_x--;
2565 vc->vc_need_wrap = 1;
2566 }
2567 }
2568 set_cursor(vc);
2569 notify_update(vc);
2570
2571quit:
2572 spin_unlock(&printing_lock);
2573}
2574
2575static struct tty_driver *vt_console_device(struct console *c, int *index)
2576{
2577 *index = c->index ? c->index-1 : fg_console;
2578 return console_driver;
2579}
2580
2581static struct console vt_console_driver = {
2582 .name = "tty",
2583 .write = vt_console_print,
2584 .device = vt_console_device,
2585 .unblank = unblank_screen,
2586 .flags = CON_PRINTBUFFER,
2587 .index = -1,
2588};
2589#endif
2590
2591/*
2592 * Handling of Linux-specific VC ioctls
2593 */
2594
2595/*
2596 * Generally a bit racy with respect to console_sem().
2597 *
2598 * There are some functions which don't need it.
2599 *
2600 * There are some functions which can sleep for arbitrary periods
2601 * (paste_selection) but we don't need the lock there anyway.
2602 *
2603 * set_selection has locking, and definitely needs it
2604 */
2605
2606int tioclinux(struct tty_struct *tty, unsigned long arg)
2607{
2608 char type, data;
2609 char __user *p = (char __user *)arg;
2610 int lines;
2611 int ret;
2612
2613 if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN))
2614 return -EPERM;
2615 if (get_user(type, p))
2616 return -EFAULT;
2617 ret = 0;
2618
2619 switch (type)
2620 {
2621 case TIOCL_SETSEL:
2622 acquire_console_sem();
2623 ret = set_selection((struct tiocl_selection __user *)(p+1), tty);
2624 release_console_sem();
2625 break;
2626 case TIOCL_PASTESEL:
2627 ret = paste_selection(tty);
2628 break;
2629 case TIOCL_UNBLANKSCREEN:
2630 acquire_console_sem();
2631 unblank_screen();
2632 release_console_sem();
2633 break;
2634 case TIOCL_SELLOADLUT:
2635 ret = sel_loadlut(p);
2636 break;
2637 case TIOCL_GETSHIFTSTATE:
2638
2639 /*
2640 * Make it possible to react to Shift+Mousebutton.
2641 * Note that 'shift_state' is an undocumented
2642 * kernel-internal variable; programs not closely
2643 * related to the kernel should not use this.
2644 */
2645 data = shift_state;
2646 ret = __put_user(data, p);
2647 break;
2648 case TIOCL_GETMOUSEREPORTING:
2649 data = mouse_reporting();
2650 ret = __put_user(data, p);
2651 break;
2652 case TIOCL_SETVESABLANK:
2653 ret = set_vesa_blanking(p);
2654 break;
2655 case TIOCL_GETKMSGREDIRECT:
2656 data = vt_get_kmsg_redirect();
2657 ret = __put_user(data, p);
2658 break;
2659 case TIOCL_SETKMSGREDIRECT:
2660 if (!capable(CAP_SYS_ADMIN)) {
2661 ret = -EPERM;
2662 } else {
2663 if (get_user(data, p+1))
2664 ret = -EFAULT;
2665 else
2666 vt_kmsg_redirect(data);
2667 }
2668 break;
2669 case TIOCL_GETFGCONSOLE:
2670 ret = fg_console;
2671 break;
2672 case TIOCL_SCROLLCONSOLE:
2673 if (get_user(lines, (s32 __user *)(p+4))) {
2674 ret = -EFAULT;
2675 } else {
2676 scrollfront(vc_cons[fg_console].d, lines);
2677 ret = 0;
2678 }
2679 break;
2680 case TIOCL_BLANKSCREEN: /* until explicitly unblanked, not only poked */
2681 acquire_console_sem();
2682 ignore_poke = 1;
2683 do_blank_screen(0);
2684 release_console_sem();
2685 break;
2686 case TIOCL_BLANKEDSCREEN:
2687 ret = console_blanked;
2688 break;
2689 default:
2690 ret = -EINVAL;
2691 break;
2692 }
2693 return ret;
2694}
2695
2696/*
2697 * /dev/ttyN handling
2698 */
2699
2700static int con_write(struct tty_struct *tty, const unsigned char *buf, int count)
2701{
2702 int retval;
2703
2704 retval = do_con_write(tty, buf, count);
2705 con_flush_chars(tty);
2706
2707 return retval;
2708}
2709
2710static int con_put_char(struct tty_struct *tty, unsigned char ch)
2711{
2712 if (in_interrupt())
2713 return 0; /* n_r3964 calls put_char() from interrupt context */
2714 return do_con_write(tty, &ch, 1);
2715}
2716
2717static int con_write_room(struct tty_struct *tty)
2718{
2719 if (tty->stopped)
2720 return 0;
2721 return 32768; /* No limit, really; we're not buffering */
2722}
2723
2724static int con_chars_in_buffer(struct tty_struct *tty)
2725{
2726 return 0; /* we're not buffering */
2727}
2728
2729/*
2730 * con_throttle and con_unthrottle are only used for
2731 * paste_selection(), which has to stuff in a large number of
2732 * characters...
2733 */
2734static void con_throttle(struct tty_struct *tty)
2735{
2736}
2737
2738static void con_unthrottle(struct tty_struct *tty)
2739{
2740 struct vc_data *vc = tty->driver_data;
2741
2742 wake_up_interruptible(&vc->paste_wait);
2743}
2744
2745/*
2746 * Turn the Scroll-Lock LED on when the tty is stopped
2747 */
2748static void con_stop(struct tty_struct *tty)
2749{
2750 int console_num;
2751 if (!tty)
2752 return;
2753 console_num = tty->index;
2754 if (!vc_cons_allocated(console_num))
2755 return;
2756 set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
2757 set_leds();
2758}
2759
2760/*
2761 * Turn the Scroll-Lock LED off when the console is started
2762 */
2763static void con_start(struct tty_struct *tty)
2764{
2765 int console_num;
2766 if (!tty)
2767 return;
2768 console_num = tty->index;
2769 if (!vc_cons_allocated(console_num))
2770 return;
2771 clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK);
2772 set_leds();
2773}
2774
2775static void con_flush_chars(struct tty_struct *tty)
2776{
2777 struct vc_data *vc;
2778
2779 if (in_interrupt()) /* from flush_to_ldisc */
2780 return;
2781
2782 /* if we race with con_close(), vt may be null */
2783 acquire_console_sem();
2784 vc = tty->driver_data;
2785 if (vc)
2786 set_cursor(vc);
2787 release_console_sem();
2788}
2789
2790/*
2791 * Allocate the console screen memory.
2792 */
2793static int con_open(struct tty_struct *tty, struct file *filp)
2794{
2795 unsigned int currcons = tty->index;
2796 int ret = 0;
2797
2798 acquire_console_sem();
2799 if (tty->driver_data == NULL) {
2800 ret = vc_allocate(currcons);
2801 if (ret == 0) {
2802 struct vc_data *vc = vc_cons[currcons].d;
2803
2804 /* Still being freed */
2805 if (vc->port.tty) {
2806 release_console_sem();
2807 return -ERESTARTSYS;
2808 }
2809 tty->driver_data = vc;
2810 vc->port.tty = tty;
2811
2812 if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
2813 tty->winsize.ws_row = vc_cons[currcons].d->vc_rows;
2814 tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
2815 }
2816 if (vc->vc_utf)
2817 tty->termios->c_iflag |= IUTF8;
2818 else
2819 tty->termios->c_iflag &= ~IUTF8;
2820 release_console_sem();
2821 return ret;
2822 }
2823 }
2824 release_console_sem();
2825 return ret;
2826}
2827
2828static void con_close(struct tty_struct *tty, struct file *filp)
2829{
2830 /* Nothing to do - we defer to shutdown */
2831}
2832
2833static void con_shutdown(struct tty_struct *tty)
2834{
2835 struct vc_data *vc = tty->driver_data;
2836 BUG_ON(vc == NULL);
2837 acquire_console_sem();
2838 vc->port.tty = NULL;
2839 release_console_sem();
2840 tty_shutdown(tty);
2841}
2842
2843static int default_italic_color = 2; // green (ASCII)
2844static int default_underline_color = 3; // cyan (ASCII)
2845module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR);
2846module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR);
2847
2848static void vc_init(struct vc_data *vc, unsigned int rows,
2849 unsigned int cols, int do_clear)
2850{
2851 int j, k ;
2852
2853 vc->vc_cols = cols;
2854 vc->vc_rows = rows;
2855 vc->vc_size_row = cols << 1;
2856 vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;
2857
2858 set_origin(vc);
2859 vc->vc_pos = vc->vc_origin;
2860 reset_vc(vc);
2861 for (j=k=0; j<16; j++) {
2862 vc->vc_palette[k++] = default_red[j] ;
2863 vc->vc_palette[k++] = default_grn[j] ;
2864 vc->vc_palette[k++] = default_blu[j] ;
2865 }
2866 vc->vc_def_color = 0x07; /* white */
2867 vc->vc_ulcolor = default_underline_color;
2868 vc->vc_itcolor = default_italic_color;
2869 vc->vc_halfcolor = 0x08; /* grey */
2870 init_waitqueue_head(&vc->paste_wait);
2871 reset_terminal(vc, do_clear);
2872}
2873
2874/*
2875 * This routine initializes console interrupts, and does nothing
2876 * else. If you want the screen to clear, call tty_write with
2877 * the appropriate escape-sequence.
2878 */
2879
2880static int __init con_init(void)
2881{
2882 const char *display_desc = NULL;
2883 struct vc_data *vc;
2884 unsigned int currcons = 0, i;
2885
2886 acquire_console_sem();
2887
2888 if (conswitchp)
2889 display_desc = conswitchp->con_startup();
2890 if (!display_desc) {
2891 fg_console = 0;
2892 release_console_sem();
2893 return 0;
2894 }
2895
2896 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
2897 struct con_driver *con_driver = &registered_con_driver[i];
2898
2899 if (con_driver->con == NULL) {
2900 con_driver->con = conswitchp;
2901 con_driver->desc = display_desc;
2902 con_driver->flag = CON_DRIVER_FLAG_INIT;
2903 con_driver->first = 0;
2904 con_driver->last = MAX_NR_CONSOLES - 1;
2905 break;
2906 }
2907 }
2908
2909 for (i = 0; i < MAX_NR_CONSOLES; i++)
2910 con_driver_map[i] = conswitchp;
2911
2912 if (blankinterval) {
2913 blank_state = blank_normal_wait;
2914 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
2915 }
2916
2917 for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
2918 vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT);
2919 INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
2920 tty_port_init(&vc->port);
2921 visual_init(vc, currcons, 1);
2922 vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
2923 vc_init(vc, vc->vc_rows, vc->vc_cols,
2924 currcons || !vc->vc_sw->con_save_screen);
2925 }
2926 currcons = fg_console = 0;
2927 master_display_fg = vc = vc_cons[currcons].d;
2928 set_origin(vc);
2929 save_screen(vc);
2930 gotoxy(vc, vc->vc_x, vc->vc_y);
2931 csi_J(vc, 0);
2932 update_screen(vc);
2933 printk("Console: %s %s %dx%d",
2934 vc->vc_can_do_color ? "colour" : "mono",
2935 display_desc, vc->vc_cols, vc->vc_rows);
2936 printable = 1;
2937 printk("\n");
2938
2939 release_console_sem();
2940
2941#ifdef CONFIG_VT_CONSOLE
2942 register_console(&vt_console_driver);
2943#endif
2944 return 0;
2945}
2946console_initcall(con_init);
2947
2948static const struct tty_operations con_ops = {
2949 .open = con_open,
2950 .close = con_close,
2951 .write = con_write,
2952 .write_room = con_write_room,
2953 .put_char = con_put_char,
2954 .flush_chars = con_flush_chars,
2955 .chars_in_buffer = con_chars_in_buffer,
2956 .ioctl = vt_ioctl,
2957#ifdef CONFIG_COMPAT
2958 .compat_ioctl = vt_compat_ioctl,
2959#endif
2960 .stop = con_stop,
2961 .start = con_start,
2962 .throttle = con_throttle,
2963 .unthrottle = con_unthrottle,
2964 .resize = vt_resize,
2965 .shutdown = con_shutdown
2966};
2967
2968static struct cdev vc0_cdev;
2969
2970int __init vty_init(const struct file_operations *console_fops)
2971{
2972 cdev_init(&vc0_cdev, console_fops);
2973 if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
2974 register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
2975 panic("Couldn't register /dev/tty0 driver\n");
2976 device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
2977
2978 vcs_init();
2979
2980 console_driver = alloc_tty_driver(MAX_NR_CONSOLES);
2981 if (!console_driver)
2982 panic("Couldn't allocate console driver\n");
2983 console_driver->owner = THIS_MODULE;
2984 console_driver->name = "tty";
2985 console_driver->name_base = 1;
2986 console_driver->major = TTY_MAJOR;
2987 console_driver->minor_start = 1;
2988 console_driver->type = TTY_DRIVER_TYPE_CONSOLE;
2989 console_driver->init_termios = tty_std_termios;
2990 if (default_utf8)
2991 console_driver->init_termios.c_iflag |= IUTF8;
2992 console_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
2993 tty_set_operations(console_driver, &con_ops);
2994 if (tty_register_driver(console_driver))
2995 panic("Couldn't register console driver\n");
2996 kbd_init();
2997 console_map_init();
2998#ifdef CONFIG_MDA_CONSOLE
2999 mda_console_init();
3000#endif
3001 return 0;
3002}
3003
3004#ifndef VT_SINGLE_DRIVER
3005
3006static struct class *vtconsole_class;
3007
3008static int bind_con_driver(const struct consw *csw, int first, int last,
3009 int deflt)
3010{
3011 struct module *owner = csw->owner;
3012 const char *desc = NULL;
3013 struct con_driver *con_driver;
3014 int i, j = -1, k = -1, retval = -ENODEV;
3015
3016 if (!try_module_get(owner))
3017 return -ENODEV;
3018
3019 acquire_console_sem();
3020
3021 /* check if driver is registered */
3022 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3023 con_driver = &registered_con_driver[i];
3024
3025 if (con_driver->con == csw) {
3026 desc = con_driver->desc;
3027 retval = 0;
3028 break;
3029 }
3030 }
3031
3032 if (retval)
3033 goto err;
3034
3035 if (!(con_driver->flag & CON_DRIVER_FLAG_INIT)) {
3036 csw->con_startup();
3037 con_driver->flag |= CON_DRIVER_FLAG_INIT;
3038 }
3039
3040 if (deflt) {
3041 if (conswitchp)
3042 module_put(conswitchp->owner);
3043
3044 __module_get(owner);
3045 conswitchp = csw;
3046 }
3047
3048 first = max(first, con_driver->first);
3049 last = min(last, con_driver->last);
3050
3051 for (i = first; i <= last; i++) {
3052 int old_was_color;
3053 struct vc_data *vc = vc_cons[i].d;
3054
3055 if (con_driver_map[i])
3056 module_put(con_driver_map[i]->owner);
3057 __module_get(owner);
3058 con_driver_map[i] = csw;
3059
3060 if (!vc || !vc->vc_sw)
3061 continue;
3062
3063 j = i;
3064
3065 if (CON_IS_VISIBLE(vc)) {
3066 k = i;
3067 save_screen(vc);
3068 }
3069
3070 old_was_color = vc->vc_can_do_color;
3071 vc->vc_sw->con_deinit(vc);
3072 vc->vc_origin = (unsigned long)vc->vc_screenbuf;
3073 visual_init(vc, i, 0);
3074 set_origin(vc);
3075 update_attr(vc);
3076
3077 /* If the console changed between mono <-> color, then
3078 * the attributes in the screenbuf will be wrong. The
3079 * following resets all attributes to something sane.
3080 */
3081 if (old_was_color != vc->vc_can_do_color)
3082 clear_buffer_attributes(vc);
3083 }
3084
3085 printk("Console: switching ");
3086 if (!deflt)
3087 printk("consoles %d-%d ", first+1, last+1);
3088 if (j >= 0) {
3089 struct vc_data *vc = vc_cons[j].d;
3090
3091 printk("to %s %s %dx%d\n",
3092 vc->vc_can_do_color ? "colour" : "mono",
3093 desc, vc->vc_cols, vc->vc_rows);
3094
3095 if (k >= 0) {
3096 vc = vc_cons[k].d;
3097 update_screen(vc);
3098 }
3099 } else
3100 printk("to %s\n", desc);
3101
3102 retval = 0;
3103err:
3104 release_console_sem();
3105 module_put(owner);
3106 return retval;
3107};
3108
3109#ifdef CONFIG_VT_HW_CONSOLE_BINDING
3110static int con_is_graphics(const struct consw *csw, int first, int last)
3111{
3112 int i, retval = 0;
3113
3114 for (i = first; i <= last; i++) {
3115 struct vc_data *vc = vc_cons[i].d;
3116
3117 if (vc && vc->vc_mode == KD_GRAPHICS) {
3118 retval = 1;
3119 break;
3120 }
3121 }
3122
3123 return retval;
3124}
3125
3126/**
3127 * unbind_con_driver - unbind a console driver
3128 * @csw: pointer to console driver to unregister
3129 * @first: first in range of consoles that @csw should be unbound from
3130 * @last: last in range of consoles that @csw should be unbound from
3131 * @deflt: should next bound console driver be default after @csw is unbound?
3132 *
3133 * To unbind a driver from all possible consoles, pass 0 as @first and
3134 * %MAX_NR_CONSOLES as @last.
3135 *
3136 * @deflt controls whether the console that ends up replacing @csw should be
3137 * the default console.
3138 *
3139 * RETURNS:
3140 * -ENODEV if @csw isn't a registered console driver or can't be unregistered
3141 * or 0 on success.
3142 */
3143int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3144{
3145 struct module *owner = csw->owner;
3146 const struct consw *defcsw = NULL;
3147 struct con_driver *con_driver = NULL, *con_back = NULL;
3148 int i, retval = -ENODEV;
3149
3150 if (!try_module_get(owner))
3151 return -ENODEV;
3152
3153 acquire_console_sem();
3154
3155 /* check if driver is registered and if it is unbindable */
3156 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3157 con_driver = &registered_con_driver[i];
3158
3159 if (con_driver->con == csw &&
3160 con_driver->flag & CON_DRIVER_FLAG_MODULE) {
3161 retval = 0;
3162 break;
3163 }
3164 }
3165
3166 if (retval) {
3167 release_console_sem();
3168 goto err;
3169 }
3170
3171 retval = -ENODEV;
3172
3173 /* check if backup driver exists */
3174 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3175 con_back = &registered_con_driver[i];
3176
3177 if (con_back->con &&
3178 !(con_back->flag & CON_DRIVER_FLAG_MODULE)) {
3179 defcsw = con_back->con;
3180 retval = 0;
3181 break;
3182 }
3183 }
3184
3185 if (retval) {
3186 release_console_sem();
3187 goto err;
3188 }
3189
3190 if (!con_is_bound(csw)) {
3191 release_console_sem();
3192 goto err;
3193 }
3194
3195 first = max(first, con_driver->first);
3196 last = min(last, con_driver->last);
3197
3198 for (i = first; i <= last; i++) {
3199 if (con_driver_map[i] == csw) {
3200 module_put(csw->owner);
3201 con_driver_map[i] = NULL;
3202 }
3203 }
3204
3205 if (!con_is_bound(defcsw)) {
3206 const struct consw *defconsw = conswitchp;
3207
3208 defcsw->con_startup();
3209 con_back->flag |= CON_DRIVER_FLAG_INIT;
3210 /*
3211 * vgacon may change the default driver to point
3212 * to dummycon, we restore it here...
3213 */
3214 conswitchp = defconsw;
3215 }
3216
3217 if (!con_is_bound(csw))
3218 con_driver->flag &= ~CON_DRIVER_FLAG_INIT;
3219
3220 release_console_sem();
3221 /* ignore return value, binding should not fail */
3222 bind_con_driver(defcsw, first, last, deflt);
3223err:
3224 module_put(owner);
3225 return retval;
3226
3227}
3228EXPORT_SYMBOL(unbind_con_driver);
3229
3230static int vt_bind(struct con_driver *con)
3231{
3232 const struct consw *defcsw = NULL, *csw = NULL;
3233 int i, more = 1, first = -1, last = -1, deflt = 0;
3234
3235 if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) ||
3236 con_is_graphics(con->con, con->first, con->last))
3237 goto err;
3238
3239 csw = con->con;
3240
3241 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3242 struct con_driver *con = &registered_con_driver[i];
3243
3244 if (con->con && !(con->flag & CON_DRIVER_FLAG_MODULE)) {
3245 defcsw = con->con;
3246 break;
3247 }
3248 }
3249
3250 if (!defcsw)
3251 goto err;
3252
3253 while (more) {
3254 more = 0;
3255
3256 for (i = con->first; i <= con->last; i++) {
3257 if (con_driver_map[i] == defcsw) {
3258 if (first == -1)
3259 first = i;
3260 last = i;
3261 more = 1;
3262 } else if (first != -1)
3263 break;
3264 }
3265
3266 if (first == 0 && last == MAX_NR_CONSOLES -1)
3267 deflt = 1;
3268
3269 if (first != -1)
3270 bind_con_driver(csw, first, last, deflt);
3271
3272 first = -1;
3273 last = -1;
3274 deflt = 0;
3275 }
3276
3277err:
3278 return 0;
3279}
3280
3281static int vt_unbind(struct con_driver *con)
3282{
3283 const struct consw *csw = NULL;
3284 int i, more = 1, first = -1, last = -1, deflt = 0;
3285
3286 if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) ||
3287 con_is_graphics(con->con, con->first, con->last))
3288 goto err;
3289
3290 csw = con->con;
3291
3292 while (more) {
3293 more = 0;
3294
3295 for (i = con->first; i <= con->last; i++) {
3296 if (con_driver_map[i] == csw) {
3297 if (first == -1)
3298 first = i;
3299 last = i;
3300 more = 1;
3301 } else if (first != -1)
3302 break;
3303 }
3304
3305 if (first == 0 && last == MAX_NR_CONSOLES -1)
3306 deflt = 1;
3307
3308 if (first != -1)
3309 unbind_con_driver(csw, first, last, deflt);
3310
3311 first = -1;
3312 last = -1;
3313 deflt = 0;
3314 }
3315
3316err:
3317 return 0;
3318}
3319#else
3320static inline int vt_bind(struct con_driver *con)
3321{
3322 return 0;
3323}
3324static inline int vt_unbind(struct con_driver *con)
3325{
3326 return 0;
3327}
3328#endif /* CONFIG_VT_HW_CONSOLE_BINDING */
3329
3330static ssize_t store_bind(struct device *dev, struct device_attribute *attr,
3331 const char *buf, size_t count)
3332{
3333 struct con_driver *con = dev_get_drvdata(dev);
3334 int bind = simple_strtoul(buf, NULL, 0);
3335
3336 if (bind)
3337 vt_bind(con);
3338 else
3339 vt_unbind(con);
3340
3341 return count;
3342}
3343
3344static ssize_t show_bind(struct device *dev, struct device_attribute *attr,
3345 char *buf)
3346{
3347 struct con_driver *con = dev_get_drvdata(dev);
3348 int bind = con_is_bound(con->con);
3349
3350 return snprintf(buf, PAGE_SIZE, "%i\n", bind);
3351}
3352
3353static ssize_t show_name(struct device *dev, struct device_attribute *attr,
3354 char *buf)
3355{
3356 struct con_driver *con = dev_get_drvdata(dev);
3357
3358 return snprintf(buf, PAGE_SIZE, "%s %s\n",
3359 (con->flag & CON_DRIVER_FLAG_MODULE) ? "(M)" : "(S)",
3360 con->desc);
3361
3362}
3363
3364static struct device_attribute device_attrs[] = {
3365 __ATTR(bind, S_IRUGO|S_IWUSR, show_bind, store_bind),
3366 __ATTR(name, S_IRUGO, show_name, NULL),
3367};
3368
3369static int vtconsole_init_device(struct con_driver *con)
3370{
3371 int i;
3372 int error = 0;
3373
3374 con->flag |= CON_DRIVER_FLAG_ATTR;
3375 dev_set_drvdata(con->dev, con);
3376 for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
3377 error = device_create_file(con->dev, &device_attrs[i]);
3378 if (error)
3379 break;
3380 }
3381
3382 if (error) {
3383 while (--i >= 0)
3384 device_remove_file(con->dev, &device_attrs[i]);
3385 con->flag &= ~CON_DRIVER_FLAG_ATTR;
3386 }
3387
3388 return error;
3389}
3390
3391static void vtconsole_deinit_device(struct con_driver *con)
3392{
3393 int i;
3394
3395 if (con->flag & CON_DRIVER_FLAG_ATTR) {
3396 for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
3397 device_remove_file(con->dev, &device_attrs[i]);
3398 con->flag &= ~CON_DRIVER_FLAG_ATTR;
3399 }
3400}
3401
3402/**
3403 * con_is_bound - checks if driver is bound to the console
3404 * @csw: console driver
3405 *
3406 * RETURNS: zero if unbound, nonzero if bound
3407 *
3408 * Drivers can call this and if zero, they should release
3409 * all resources allocated on con_startup()
3410 */
3411int con_is_bound(const struct consw *csw)
3412{
3413 int i, bound = 0;
3414
3415 for (i = 0; i < MAX_NR_CONSOLES; i++) {
3416 if (con_driver_map[i] == csw) {
3417 bound = 1;
3418 break;
3419 }
3420 }
3421
3422 return bound;
3423}
3424EXPORT_SYMBOL(con_is_bound);
3425
3426/**
3427 * con_debug_enter - prepare the console for the kernel debugger
3428 * @sw: console driver
3429 *
3430 * Called when the console is taken over by the kernel debugger, this
3431 * function needs to save the current console state, then put the console
3432 * into a state suitable for the kernel debugger.
3433 *
3434 * RETURNS:
3435 * Zero on success, nonzero if a failure occurred when trying to prepare
3436 * the console for the debugger.
3437 */
3438int con_debug_enter(struct vc_data *vc)
3439{
3440 int ret = 0;
3441
3442 saved_fg_console = fg_console;
3443 saved_last_console = last_console;
3444 saved_want_console = want_console;
3445 saved_vc_mode = vc->vc_mode;
3446 saved_console_blanked = console_blanked;
3447 vc->vc_mode = KD_TEXT;
3448 console_blanked = 0;
3449 if (vc->vc_sw->con_debug_enter)
3450 ret = vc->vc_sw->con_debug_enter(vc);
3451#ifdef CONFIG_KGDB_KDB
3452 /* Set the initial LINES variable if it is not already set */
3453 if (vc->vc_rows < 999) {
3454 int linecount;
3455 char lns[4];
3456 const char *setargs[3] = {
3457 "set",
3458 "LINES",
3459 lns,
3460 };
3461 if (kdbgetintenv(setargs[0], &linecount)) {
3462 snprintf(lns, 4, "%i", vc->vc_rows);
3463 kdb_set(2, setargs);
3464 }
3465 }
3466#endif /* CONFIG_KGDB_KDB */
3467 return ret;
3468}
3469EXPORT_SYMBOL_GPL(con_debug_enter);
3470
3471/**
3472 * con_debug_leave - restore console state
3473 * @sw: console driver
3474 *
3475 * Restore the console state to what it was before the kernel debugger
3476 * was invoked.
3477 *
3478 * RETURNS:
3479 * Zero on success, nonzero if a failure occurred when trying to restore
3480 * the console.
3481 */
3482int con_debug_leave(void)
3483{
3484 struct vc_data *vc;
3485 int ret = 0;
3486
3487 fg_console = saved_fg_console;
3488 last_console = saved_last_console;
3489 want_console = saved_want_console;
3490 console_blanked = saved_console_blanked;
3491 vc_cons[fg_console].d->vc_mode = saved_vc_mode;
3492
3493 vc = vc_cons[fg_console].d;
3494 if (vc->vc_sw->con_debug_leave)
3495 ret = vc->vc_sw->con_debug_leave(vc);
3496 return ret;
3497}
3498EXPORT_SYMBOL_GPL(con_debug_leave);
3499
3500/**
3501 * register_con_driver - register console driver to console layer
3502 * @csw: console driver
3503 * @first: the first console to take over, minimum value is 0
3504 * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1
3505 *
3506 * DESCRIPTION: This function registers a console driver which can later
3507 * bind to a range of consoles specified by @first and @last. It will
3508 * also initialize the console driver by calling con_startup().
3509 */
3510int register_con_driver(const struct consw *csw, int first, int last)
3511{
3512 struct module *owner = csw->owner;
3513 struct con_driver *con_driver;
3514 const char *desc;
3515 int i, retval = 0;
3516
3517 if (!try_module_get(owner))
3518 return -ENODEV;
3519
3520 acquire_console_sem();
3521
3522 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3523 con_driver = &registered_con_driver[i];
3524
3525 /* already registered */
3526 if (con_driver->con == csw)
3527 retval = -EINVAL;
3528 }
3529
3530 if (retval)
3531 goto err;
3532
3533 desc = csw->con_startup();
3534
3535 if (!desc)
3536 goto err;
3537
3538 retval = -EINVAL;
3539
3540 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3541 con_driver = &registered_con_driver[i];
3542
3543 if (con_driver->con == NULL) {
3544 con_driver->con = csw;
3545 con_driver->desc = desc;
3546 con_driver->node = i;
3547 con_driver->flag = CON_DRIVER_FLAG_MODULE |
3548 CON_DRIVER_FLAG_INIT;
3549 con_driver->first = first;
3550 con_driver->last = last;
3551 retval = 0;
3552 break;
3553 }
3554 }
3555
3556 if (retval)
3557 goto err;
3558
3559 con_driver->dev = device_create(vtconsole_class, NULL,
3560 MKDEV(0, con_driver->node),
3561 NULL, "vtcon%i",
3562 con_driver->node);
3563
3564 if (IS_ERR(con_driver->dev)) {
3565 printk(KERN_WARNING "Unable to create device for %s; "
3566 "errno = %ld\n", con_driver->desc,
3567 PTR_ERR(con_driver->dev));
3568 con_driver->dev = NULL;
3569 } else {
3570 vtconsole_init_device(con_driver);
3571 }
3572
3573err:
3574 release_console_sem();
3575 module_put(owner);
3576 return retval;
3577}
3578EXPORT_SYMBOL(register_con_driver);
3579
3580/**
3581 * unregister_con_driver - unregister console driver from console layer
3582 * @csw: console driver
3583 *
3584 * DESCRIPTION: All drivers that registers to the console layer must
3585 * call this function upon exit, or if the console driver is in a state
3586 * where it won't be able to handle console services, such as the
3587 * framebuffer console without loaded framebuffer drivers.
3588 *
3589 * The driver must unbind first prior to unregistration.
3590 */
3591int unregister_con_driver(const struct consw *csw)
3592{
3593 int i, retval = -ENODEV;
3594
3595 acquire_console_sem();
3596
3597 /* cannot unregister a bound driver */
3598 if (con_is_bound(csw))
3599 goto err;
3600
3601 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3602 struct con_driver *con_driver = &registered_con_driver[i];
3603
3604 if (con_driver->con == csw &&
3605 con_driver->flag & CON_DRIVER_FLAG_MODULE) {
3606 vtconsole_deinit_device(con_driver);
3607 device_destroy(vtconsole_class,
3608 MKDEV(0, con_driver->node));
3609 con_driver->con = NULL;
3610 con_driver->desc = NULL;
3611 con_driver->dev = NULL;
3612 con_driver->node = 0;
3613 con_driver->flag = 0;
3614 con_driver->first = 0;
3615 con_driver->last = 0;
3616 retval = 0;
3617 break;
3618 }
3619 }
3620err:
3621 release_console_sem();
3622 return retval;
3623}
3624EXPORT_SYMBOL(unregister_con_driver);
3625
3626/*
3627 * If we support more console drivers, this function is used
3628 * when a driver wants to take over some existing consoles
3629 * and become default driver for newly opened ones.
3630 *
3631 * take_over_console is basically a register followed by unbind
3632 */
3633int take_over_console(const struct consw *csw, int first, int last, int deflt)
3634{
3635 int err;
3636
3637 err = register_con_driver(csw, first, last);
3638
3639 if (!err)
3640 bind_con_driver(csw, first, last, deflt);
3641
3642 return err;
3643}
3644
3645/*
3646 * give_up_console is a wrapper to unregister_con_driver. It will only
3647 * work if driver is fully unbound.
3648 */
3649void give_up_console(const struct consw *csw)
3650{
3651 unregister_con_driver(csw);
3652}
3653
3654static int __init vtconsole_class_init(void)
3655{
3656 int i;
3657
3658 vtconsole_class = class_create(THIS_MODULE, "vtconsole");
3659 if (IS_ERR(vtconsole_class)) {
3660 printk(KERN_WARNING "Unable to create vt console class; "
3661 "errno = %ld\n", PTR_ERR(vtconsole_class));
3662 vtconsole_class = NULL;
3663 }
3664
3665 /* Add system drivers to sysfs */
3666 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3667 struct con_driver *con = &registered_con_driver[i];
3668
3669 if (con->con && !con->dev) {
3670 con->dev = device_create(vtconsole_class, NULL,
3671 MKDEV(0, con->node),
3672 NULL, "vtcon%i",
3673 con->node);
3674
3675 if (IS_ERR(con->dev)) {
3676 printk(KERN_WARNING "Unable to create "
3677 "device for %s; errno = %ld\n",
3678 con->desc, PTR_ERR(con->dev));
3679 con->dev = NULL;
3680 } else {
3681 vtconsole_init_device(con);
3682 }
3683 }
3684 }
3685
3686 return 0;
3687}
3688postcore_initcall(vtconsole_class_init);
3689
3690#endif
3691
3692/*
3693 * Screen blanking
3694 */
3695
3696static int set_vesa_blanking(char __user *p)
3697{
3698 unsigned int mode;
3699
3700 if (get_user(mode, p + 1))
3701 return -EFAULT;
3702
3703 vesa_blank_mode = (mode < 4) ? mode : 0;
3704 return 0;
3705}
3706
3707void do_blank_screen(int entering_gfx)
3708{
3709 struct vc_data *vc = vc_cons[fg_console].d;
3710 int i;
3711
3712 WARN_CONSOLE_UNLOCKED();
3713
3714 if (console_blanked) {
3715 if (blank_state == blank_vesa_wait) {
3716 blank_state = blank_off;
3717 vc->vc_sw->con_blank(vc, vesa_blank_mode + 1, 0);
3718 }
3719 return;
3720 }
3721
3722 /* entering graphics mode? */
3723 if (entering_gfx) {
3724 hide_cursor(vc);
3725 save_screen(vc);
3726 vc->vc_sw->con_blank(vc, -1, 1);
3727 console_blanked = fg_console + 1;
3728 blank_state = blank_off;
3729 set_origin(vc);
3730 return;
3731 }
3732
3733 if (blank_state != blank_normal_wait)
3734 return;
3735 blank_state = blank_off;
3736
3737 /* don't blank graphics */
3738 if (vc->vc_mode != KD_TEXT) {
3739 console_blanked = fg_console + 1;
3740 return;
3741 }
3742
3743 hide_cursor(vc);
3744 del_timer_sync(&console_timer);
3745 blank_timer_expired = 0;
3746
3747 save_screen(vc);
3748 /* In case we need to reset origin, blanking hook returns 1 */
3749 i = vc->vc_sw->con_blank(vc, vesa_off_interval ? 1 : (vesa_blank_mode + 1), 0);
3750 console_blanked = fg_console + 1;
3751 if (i)
3752 set_origin(vc);
3753
3754 if (console_blank_hook && console_blank_hook(1))
3755 return;
3756
3757 if (vesa_off_interval && vesa_blank_mode) {
3758 blank_state = blank_vesa_wait;
3759 mod_timer(&console_timer, jiffies + vesa_off_interval);
3760 }
3761 vt_event_post(VT_EVENT_BLANK, vc->vc_num, vc->vc_num);
3762}
3763EXPORT_SYMBOL(do_blank_screen);
3764
3765/*
3766 * Called by timer as well as from vt_console_driver
3767 */
3768void do_unblank_screen(int leaving_gfx)
3769{
3770 struct vc_data *vc;
3771
3772 /* This should now always be called from a "sane" (read: can schedule)
3773 * context for the sake of the low level drivers, except in the special
3774 * case of oops_in_progress
3775 */
3776 if (!oops_in_progress)
3777 might_sleep();
3778
3779 WARN_CONSOLE_UNLOCKED();
3780
3781 ignore_poke = 0;
3782 if (!console_blanked)
3783 return;
3784 if (!vc_cons_allocated(fg_console)) {
3785 /* impossible */
3786 printk("unblank_screen: tty %d not allocated ??\n", fg_console+1);
3787 return;
3788 }
3789 vc = vc_cons[fg_console].d;
3790 /* Try to unblank in oops case too */
3791 if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc))
3792 return; /* but leave console_blanked != 0 */
3793
3794 if (blankinterval) {
3795 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
3796 blank_state = blank_normal_wait;
3797 }
3798
3799 console_blanked = 0;
3800 if (vc->vc_sw->con_blank(vc, 0, leaving_gfx) || vt_force_oops_output(vc))
3801 /* Low-level driver cannot restore -> do it ourselves */
3802 update_screen(vc);
3803 if (console_blank_hook)
3804 console_blank_hook(0);
3805 set_palette(vc);
3806 set_cursor(vc);
3807 vt_event_post(VT_EVENT_UNBLANK, vc->vc_num, vc->vc_num);
3808}
3809EXPORT_SYMBOL(do_unblank_screen);
3810
3811/*
3812 * This is called by the outside world to cause a forced unblank, mostly for
3813 * oopses. Currently, I just call do_unblank_screen(0), but we could eventually
3814 * call it with 1 as an argument and so force a mode restore... that may kill
3815 * X or at least garbage the screen but would also make the Oops visible...
3816 */
3817void unblank_screen(void)
3818{
3819 do_unblank_screen(0);
3820}
3821
3822/*
3823 * We defer the timer blanking to work queue so it can take the console mutex
3824 * (console operations can still happen at irq time, but only from printk which
3825 * has the console mutex. Not perfect yet, but better than no locking
3826 */
3827static void blank_screen_t(unsigned long dummy)
3828{
3829 if (unlikely(!keventd_up())) {
3830 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
3831 return;
3832 }
3833 blank_timer_expired = 1;
3834 schedule_work(&console_work);
3835}
3836
3837void poke_blanked_console(void)
3838{
3839 WARN_CONSOLE_UNLOCKED();
3840
3841 /* Add this so we quickly catch whoever might call us in a non
3842 * safe context. Nowadays, unblank_screen() isn't to be called in
3843 * atomic contexts and is allowed to schedule (with the special case
3844 * of oops_in_progress, but that isn't of any concern for this
3845 * function. --BenH.
3846 */
3847 might_sleep();
3848
3849 /* This isn't perfectly race free, but a race here would be mostly harmless,
3850 * at worse, we'll do a spurrious blank and it's unlikely
3851 */
3852 del_timer(&console_timer);
3853 blank_timer_expired = 0;
3854
3855 if (ignore_poke || !vc_cons[fg_console].d || vc_cons[fg_console].d->vc_mode == KD_GRAPHICS)
3856 return;
3857 if (console_blanked)
3858 unblank_screen();
3859 else if (blankinterval) {
3860 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
3861 blank_state = blank_normal_wait;
3862 }
3863}
3864
3865/*
3866 * Palettes
3867 */
3868
3869static void set_palette(struct vc_data *vc)
3870{
3871 WARN_CONSOLE_UNLOCKED();
3872
3873 if (vc->vc_mode != KD_GRAPHICS)
3874 vc->vc_sw->con_set_palette(vc, color_table);
3875}
3876
3877static int set_get_cmap(unsigned char __user *arg, int set)
3878{
3879 int i, j, k;
3880
3881 WARN_CONSOLE_UNLOCKED();
3882
3883 for (i = 0; i < 16; i++)
3884 if (set) {
3885 get_user(default_red[i], arg++);
3886 get_user(default_grn[i], arg++);
3887 get_user(default_blu[i], arg++);
3888 } else {
3889 put_user(default_red[i], arg++);
3890 put_user(default_grn[i], arg++);
3891 put_user(default_blu[i], arg++);
3892 }
3893 if (set) {
3894 for (i = 0; i < MAX_NR_CONSOLES; i++)
3895 if (vc_cons_allocated(i)) {
3896 for (j = k = 0; j < 16; j++) {
3897 vc_cons[i].d->vc_palette[k++] = default_red[j];
3898 vc_cons[i].d->vc_palette[k++] = default_grn[j];
3899 vc_cons[i].d->vc_palette[k++] = default_blu[j];
3900 }
3901 set_palette(vc_cons[i].d);
3902 }
3903 }
3904 return 0;
3905}
3906
3907/*
3908 * Load palette into the DAC registers. arg points to a colour
3909 * map, 3 bytes per colour, 16 colours, range from 0 to 255.
3910 */
3911
3912int con_set_cmap(unsigned char __user *arg)
3913{
3914 int rc;
3915
3916 acquire_console_sem();
3917 rc = set_get_cmap (arg,1);
3918 release_console_sem();
3919
3920 return rc;
3921}
3922
3923int con_get_cmap(unsigned char __user *arg)
3924{
3925 int rc;
3926
3927 acquire_console_sem();
3928 rc = set_get_cmap (arg,0);
3929 release_console_sem();
3930
3931 return rc;
3932}
3933
3934void reset_palette(struct vc_data *vc)
3935{
3936 int j, k;
3937 for (j=k=0; j<16; j++) {
3938 vc->vc_palette[k++] = default_red[j];
3939 vc->vc_palette[k++] = default_grn[j];
3940 vc->vc_palette[k++] = default_blu[j];
3941 }
3942 set_palette(vc);
3943}
3944
3945/*
3946 * Font switching
3947 *
3948 * Currently we only support fonts up to 32 pixels wide, at a maximum height
3949 * of 32 pixels. Userspace fontdata is stored with 32 bytes (shorts/ints,
3950 * depending on width) reserved for each character which is kinda wasty, but
3951 * this is done in order to maintain compatibility with the EGA/VGA fonts. It
3952 * is upto the actual low-level console-driver convert data into its favorite
3953 * format (maybe we should add a `fontoffset' field to the `display'
3954 * structure so we won't have to convert the fontdata all the time.
3955 * /Jes
3956 */
3957
3958#define max_font_size 65536
3959
3960static int con_font_get(struct vc_data *vc, struct console_font_op *op)
3961{
3962 struct console_font font;
3963 int rc = -EINVAL;
3964 int c;
3965
3966 if (vc->vc_mode != KD_TEXT)
3967 return -EINVAL;
3968
3969 if (op->data) {
3970 font.data = kmalloc(max_font_size, GFP_KERNEL);
3971 if (!font.data)
3972 return -ENOMEM;
3973 } else
3974 font.data = NULL;
3975
3976 acquire_console_sem();
3977 if (vc->vc_sw->con_font_get)
3978 rc = vc->vc_sw->con_font_get(vc, &font);
3979 else
3980 rc = -ENOSYS;
3981 release_console_sem();
3982
3983 if (rc)
3984 goto out;
3985
3986 c = (font.width+7)/8 * 32 * font.charcount;
3987
3988 if (op->data && font.charcount > op->charcount)
3989 rc = -ENOSPC;
3990 if (!(op->flags & KD_FONT_FLAG_OLD)) {
3991 if (font.width > op->width || font.height > op->height)
3992 rc = -ENOSPC;
3993 } else {
3994 if (font.width != 8)
3995 rc = -EIO;
3996 else if ((op->height && font.height > op->height) ||
3997 font.height > 32)
3998 rc = -ENOSPC;
3999 }
4000 if (rc)
4001 goto out;
4002
4003 op->height = font.height;
4004 op->width = font.width;
4005 op->charcount = font.charcount;
4006
4007 if (op->data && copy_to_user(op->data, font.data, c))
4008 rc = -EFAULT;
4009
4010out:
4011 kfree(font.data);
4012 return rc;
4013}
4014
4015static int con_font_set(struct vc_data *vc, struct console_font_op *op)
4016{
4017 struct console_font font;
4018 int rc = -EINVAL;
4019 int size;
4020
4021 if (vc->vc_mode != KD_TEXT)
4022 return -EINVAL;
4023 if (!op->data)
4024 return -EINVAL;
4025 if (op->charcount > 512)
4026 return -EINVAL;
4027 if (!op->height) { /* Need to guess font height [compat] */
4028 int h, i;
4029 u8 __user *charmap = op->data;
4030 u8 tmp;
4031
4032 /* If from KDFONTOP ioctl, don't allow things which can be done in userland,
4033 so that we can get rid of this soon */
4034 if (!(op->flags & KD_FONT_FLAG_OLD))
4035 return -EINVAL;
4036 for (h = 32; h > 0; h--)
4037 for (i = 0; i < op->charcount; i++) {
4038 if (get_user(tmp, &charmap[32*i+h-1]))
4039 return -EFAULT;
4040 if (tmp)
4041 goto nonzero;
4042 }
4043 return -EINVAL;
4044 nonzero:
4045 op->height = h;
4046 }
4047 if (op->width <= 0 || op->width > 32 || op->height > 32)
4048 return -EINVAL;
4049 size = (op->width+7)/8 * 32 * op->charcount;
4050 if (size > max_font_size)
4051 return -ENOSPC;
4052 font.charcount = op->charcount;
4053 font.height = op->height;
4054 font.width = op->width;
4055 font.data = memdup_user(op->data, size);
4056 if (IS_ERR(font.data))
4057 return PTR_ERR(font.data);
4058 acquire_console_sem();
4059 if (vc->vc_sw->con_font_set)
4060 rc = vc->vc_sw->con_font_set(vc, &font, op->flags);
4061 else
4062 rc = -ENOSYS;
4063 release_console_sem();
4064 kfree(font.data);
4065 return rc;
4066}
4067
4068static int con_font_default(struct vc_data *vc, struct console_font_op *op)
4069{
4070 struct console_font font = {.width = op->width, .height = op->height};
4071 char name[MAX_FONT_NAME];
4072 char *s = name;
4073 int rc;
4074
4075 if (vc->vc_mode != KD_TEXT)
4076 return -EINVAL;
4077
4078 if (!op->data)
4079 s = NULL;
4080 else if (strncpy_from_user(name, op->data, MAX_FONT_NAME - 1) < 0)
4081 return -EFAULT;
4082 else
4083 name[MAX_FONT_NAME - 1] = 0;
4084
4085 acquire_console_sem();
4086 if (vc->vc_sw->con_font_default)
4087 rc = vc->vc_sw->con_font_default(vc, &font, s);
4088 else
4089 rc = -ENOSYS;
4090 release_console_sem();
4091 if (!rc) {
4092 op->width = font.width;
4093 op->height = font.height;
4094 }
4095 return rc;
4096}
4097
4098static int con_font_copy(struct vc_data *vc, struct console_font_op *op)
4099{
4100 int con = op->height;
4101 int rc;
4102
4103 if (vc->vc_mode != KD_TEXT)
4104 return -EINVAL;
4105
4106 acquire_console_sem();
4107 if (!vc->vc_sw->con_font_copy)
4108 rc = -ENOSYS;
4109 else if (con < 0 || !vc_cons_allocated(con))
4110 rc = -ENOTTY;
4111 else if (con == vc->vc_num) /* nothing to do */
4112 rc = 0;
4113 else
4114 rc = vc->vc_sw->con_font_copy(vc, con);
4115 release_console_sem();
4116 return rc;
4117}
4118
4119int con_font_op(struct vc_data *vc, struct console_font_op *op)
4120{
4121 switch (op->op) {
4122 case KD_FONT_OP_SET:
4123 return con_font_set(vc, op);
4124 case KD_FONT_OP_GET:
4125 return con_font_get(vc, op);
4126 case KD_FONT_OP_SET_DEFAULT:
4127 return con_font_default(vc, op);
4128 case KD_FONT_OP_COPY:
4129 return con_font_copy(vc, op);
4130 }
4131 return -ENOSYS;
4132}
4133
4134/*
4135 * Interface exported to selection and vcs.
4136 */
4137
4138/* used by selection */
4139u16 screen_glyph(struct vc_data *vc, int offset)
4140{
4141 u16 w = scr_readw(screenpos(vc, offset, 1));
4142 u16 c = w & 0xff;
4143
4144 if (w & vc->vc_hi_font_mask)
4145 c |= 0x100;
4146 return c;
4147}
4148EXPORT_SYMBOL_GPL(screen_glyph);
4149
4150/* used by vcs - note the word offset */
4151unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed)
4152{
4153 return screenpos(vc, 2 * w_offset, viewed);
4154}
4155
4156void getconsxy(struct vc_data *vc, unsigned char *p)
4157{
4158 p[0] = vc->vc_x;
4159 p[1] = vc->vc_y;
4160}
4161
4162void putconsxy(struct vc_data *vc, unsigned char *p)
4163{
4164 hide_cursor(vc);
4165 gotoxy(vc, p[0], p[1]);
4166 set_cursor(vc);
4167}
4168
4169u16 vcs_scr_readw(struct vc_data *vc, const u16 *org)
4170{
4171 if ((unsigned long)org == vc->vc_pos && softcursor_original != -1)
4172 return softcursor_original;
4173 return scr_readw(org);
4174}
4175
4176void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org)
4177{
4178 scr_writew(val, org);
4179 if ((unsigned long)org == vc->vc_pos) {
4180 softcursor_original = -1;
4181 add_softcursor(vc);
4182 }
4183}
4184
4185void vcs_scr_updated(struct vc_data *vc)
4186{
4187 notify_update(vc);
4188}
4189
4190/*
4191 * Visible symbols for modules
4192 */
4193
4194EXPORT_SYMBOL(color_table);
4195EXPORT_SYMBOL(default_red);
4196EXPORT_SYMBOL(default_grn);
4197EXPORT_SYMBOL(default_blu);
4198EXPORT_SYMBOL(update_region);
4199EXPORT_SYMBOL(redraw_screen);
4200EXPORT_SYMBOL(vc_resize);
4201EXPORT_SYMBOL(fg_console);
4202EXPORT_SYMBOL(console_blank_hook);
4203EXPORT_SYMBOL(console_blanked);
4204EXPORT_SYMBOL(vc_cons);
4205EXPORT_SYMBOL(global_cursor_default);
4206#ifndef VT_SINGLE_DRIVER
4207EXPORT_SYMBOL(take_over_console);
4208EXPORT_SYMBOL(give_up_console);
4209#endif
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
new file mode 100644
index 000000000000..6b68a0fb4611
--- /dev/null
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -0,0 +1,1788 @@
1/*
2 * linux/drivers/char/vt_ioctl.c
3 *
4 * Copyright (C) 1992 obz under the linux copyright
5 *
6 * Dynamic diacritical handling - aeb@cwi.nl - Dec 1993
7 * Dynamic keymap and string allocation - aeb@cwi.nl - May 1994
8 * Restrict VT switching via ioctl() - grif@cs.ucr.edu - Dec 1995
9 * Some code moved for less code duplication - Andi Kleen - Mar 1997
10 * Check put/get_user, cleanups - acme@conectiva.com.br - Jun 2001
11 */
12
13#include <linux/types.h>
14#include <linux/errno.h>
15#include <linux/sched.h>
16#include <linux/tty.h>
17#include <linux/timer.h>
18#include <linux/kernel.h>
19#include <linux/compat.h>
20#include <linux/module.h>
21#include <linux/kd.h>
22#include <linux/vt.h>
23#include <linux/string.h>
24#include <linux/slab.h>
25#include <linux/major.h>
26#include <linux/fs.h>
27#include <linux/console.h>
28#include <linux/consolemap.h>
29#include <linux/signal.h>
30#include <linux/smp_lock.h>
31#include <linux/timex.h>
32
33#include <asm/io.h>
34#include <asm/uaccess.h>
35
36#include <linux/kbd_kern.h>
37#include <linux/vt_kern.h>
38#include <linux/kbd_diacr.h>
39#include <linux/selection.h>
40
41char vt_dont_switch;
42extern struct tty_driver *console_driver;
43
44#define VT_IS_IN_USE(i) (console_driver->ttys[i] && console_driver->ttys[i]->count)
45#define VT_BUSY(i) (VT_IS_IN_USE(i) || i == fg_console || vc_cons[i].d == sel_cons)
46
47/*
48 * Console (vt and kd) routines, as defined by USL SVR4 manual, and by
49 * experimentation and study of X386 SYSV handling.
50 *
51 * One point of difference: SYSV vt's are /dev/vtX, which X >= 0, and
52 * /dev/console is a separate ttyp. Under Linux, /dev/tty0 is /dev/console,
53 * and the vc start at /dev/ttyX, X >= 1. We maintain that here, so we will
54 * always treat our set of vt as numbered 1..MAX_NR_CONSOLES (corresponding to
55 * ttys 0..MAX_NR_CONSOLES-1). Explicitly naming VT 0 is illegal, but using
56 * /dev/tty0 (fg_console) as a target is legal, since an implicit aliasing
57 * to the current console is done by the main ioctl code.
58 */
59
60#ifdef CONFIG_X86
61#include <linux/syscalls.h>
62#endif
63
64static void complete_change_console(struct vc_data *vc);
65
66/*
67 * User space VT_EVENT handlers
68 */
69
70struct vt_event_wait {
71 struct list_head list;
72 struct vt_event event;
73 int done;
74};
75
76static LIST_HEAD(vt_events);
77static DEFINE_SPINLOCK(vt_event_lock);
78static DECLARE_WAIT_QUEUE_HEAD(vt_event_waitqueue);
79
80/**
81 * vt_event_post
82 * @event: the event that occurred
83 * @old: old console
84 * @new: new console
85 *
86 * Post an VT event to interested VT handlers
87 */
88
89void vt_event_post(unsigned int event, unsigned int old, unsigned int new)
90{
91 struct list_head *pos, *head;
92 unsigned long flags;
93 int wake = 0;
94
95 spin_lock_irqsave(&vt_event_lock, flags);
96 head = &vt_events;
97
98 list_for_each(pos, head) {
99 struct vt_event_wait *ve = list_entry(pos,
100 struct vt_event_wait, list);
101 if (!(ve->event.event & event))
102 continue;
103 ve->event.event = event;
104 /* kernel view is consoles 0..n-1, user space view is
105 console 1..n with 0 meaning current, so we must bias */
106 ve->event.oldev = old + 1;
107 ve->event.newev = new + 1;
108 wake = 1;
109 ve->done = 1;
110 }
111 spin_unlock_irqrestore(&vt_event_lock, flags);
112 if (wake)
113 wake_up_interruptible(&vt_event_waitqueue);
114}
115
116/**
117 * vt_event_wait - wait for an event
118 * @vw: our event
119 *
120 * Waits for an event to occur which completes our vt_event_wait
121 * structure. On return the structure has wv->done set to 1 for success
122 * or 0 if some event such as a signal ended the wait.
123 */
124
125static void vt_event_wait(struct vt_event_wait *vw)
126{
127 unsigned long flags;
128 /* Prepare the event */
129 INIT_LIST_HEAD(&vw->list);
130 vw->done = 0;
131 /* Queue our event */
132 spin_lock_irqsave(&vt_event_lock, flags);
133 list_add(&vw->list, &vt_events);
134 spin_unlock_irqrestore(&vt_event_lock, flags);
135 /* Wait for it to pass */
136 wait_event_interruptible_tty(vt_event_waitqueue, vw->done);
137 /* Dequeue it */
138 spin_lock_irqsave(&vt_event_lock, flags);
139 list_del(&vw->list);
140 spin_unlock_irqrestore(&vt_event_lock, flags);
141}
142
143/**
144 * vt_event_wait_ioctl - event ioctl handler
145 * @arg: argument to ioctl
146 *
147 * Implement the VT_WAITEVENT ioctl using the VT event interface
148 */
149
150static int vt_event_wait_ioctl(struct vt_event __user *event)
151{
152 struct vt_event_wait vw;
153
154 if (copy_from_user(&vw.event, event, sizeof(struct vt_event)))
155 return -EFAULT;
156 /* Highest supported event for now */
157 if (vw.event.event & ~VT_MAX_EVENT)
158 return -EINVAL;
159
160 vt_event_wait(&vw);
161 /* If it occurred report it */
162 if (vw.done) {
163 if (copy_to_user(event, &vw.event, sizeof(struct vt_event)))
164 return -EFAULT;
165 return 0;
166 }
167 return -EINTR;
168}
169
170/**
171 * vt_waitactive - active console wait
172 * @event: event code
173 * @n: new console
174 *
175 * Helper for event waits. Used to implement the legacy
176 * event waiting ioctls in terms of events
177 */
178
179int vt_waitactive(int n)
180{
181 struct vt_event_wait vw;
182 do {
183 if (n == fg_console + 1)
184 break;
185 vw.event.event = VT_EVENT_SWITCH;
186 vt_event_wait(&vw);
187 if (vw.done == 0)
188 return -EINTR;
189 } while (vw.event.newev != n);
190 return 0;
191}
192
193/*
194 * these are the valid i/o ports we're allowed to change. they map all the
195 * video ports
196 */
197#define GPFIRST 0x3b4
198#define GPLAST 0x3df
199#define GPNUM (GPLAST - GPFIRST + 1)
200
201#define i (tmp.kb_index)
202#define s (tmp.kb_table)
203#define v (tmp.kb_value)
204static inline int
205do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_struct *kbd)
206{
207 struct kbentry tmp;
208 ushort *key_map, val, ov;
209
210 if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
211 return -EFAULT;
212
213 if (!capable(CAP_SYS_TTY_CONFIG))
214 perm = 0;
215
216 switch (cmd) {
217 case KDGKBENT:
218 key_map = key_maps[s];
219 if (key_map) {
220 val = U(key_map[i]);
221 if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
222 val = K_HOLE;
223 } else
224 val = (i ? K_HOLE : K_NOSUCHMAP);
225 return put_user(val, &user_kbe->kb_value);
226 case KDSKBENT:
227 if (!perm)
228 return -EPERM;
229 if (!i && v == K_NOSUCHMAP) {
230 /* deallocate map */
231 key_map = key_maps[s];
232 if (s && key_map) {
233 key_maps[s] = NULL;
234 if (key_map[0] == U(K_ALLOCATED)) {
235 kfree(key_map);
236 keymap_count--;
237 }
238 }
239 break;
240 }
241
242 if (KTYP(v) < NR_TYPES) {
243 if (KVAL(v) > max_vals[KTYP(v)])
244 return -EINVAL;
245 } else
246 if (kbd->kbdmode != VC_UNICODE)
247 return -EINVAL;
248
249 /* ++Geert: non-PC keyboards may generate keycode zero */
250#if !defined(__mc68000__) && !defined(__powerpc__)
251 /* assignment to entry 0 only tests validity of args */
252 if (!i)
253 break;
254#endif
255
256 if (!(key_map = key_maps[s])) {
257 int j;
258
259 if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
260 !capable(CAP_SYS_RESOURCE))
261 return -EPERM;
262
263 key_map = kmalloc(sizeof(plain_map),
264 GFP_KERNEL);
265 if (!key_map)
266 return -ENOMEM;
267 key_maps[s] = key_map;
268 key_map[0] = U(K_ALLOCATED);
269 for (j = 1; j < NR_KEYS; j++)
270 key_map[j] = U(K_HOLE);
271 keymap_count++;
272 }
273 ov = U(key_map[i]);
274 if (v == ov)
275 break; /* nothing to do */
276 /*
277 * Attention Key.
278 */
279 if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN))
280 return -EPERM;
281 key_map[i] = U(v);
282 if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
283 compute_shiftstate();
284 break;
285 }
286 return 0;
287}
288#undef i
289#undef s
290#undef v
291
292static inline int
293do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc, int perm)
294{
295 struct kbkeycode tmp;
296 int kc = 0;
297
298 if (copy_from_user(&tmp, user_kbkc, sizeof(struct kbkeycode)))
299 return -EFAULT;
300 switch (cmd) {
301 case KDGETKEYCODE:
302 kc = getkeycode(tmp.scancode);
303 if (kc >= 0)
304 kc = put_user(kc, &user_kbkc->keycode);
305 break;
306 case KDSETKEYCODE:
307 if (!perm)
308 return -EPERM;
309 kc = setkeycode(tmp.scancode, tmp.keycode);
310 break;
311 }
312 return kc;
313}
314
315static inline int
316do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
317{
318 struct kbsentry *kbs;
319 char *p;
320 u_char *q;
321 u_char __user *up;
322 int sz;
323 int delta;
324 char *first_free, *fj, *fnw;
325 int i, j, k;
326 int ret;
327
328 if (!capable(CAP_SYS_TTY_CONFIG))
329 perm = 0;
330
331 kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
332 if (!kbs) {
333 ret = -ENOMEM;
334 goto reterr;
335 }
336
337 /* we mostly copy too much here (512bytes), but who cares ;) */
338 if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
339 ret = -EFAULT;
340 goto reterr;
341 }
342 kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
343 i = kbs->kb_func;
344
345 switch (cmd) {
346 case KDGKBSENT:
347 sz = sizeof(kbs->kb_string) - 1; /* sz should have been
348 a struct member */
349 up = user_kdgkb->kb_string;
350 p = func_table[i];
351 if(p)
352 for ( ; *p && sz; p++, sz--)
353 if (put_user(*p, up++)) {
354 ret = -EFAULT;
355 goto reterr;
356 }
357 if (put_user('\0', up)) {
358 ret = -EFAULT;
359 goto reterr;
360 }
361 kfree(kbs);
362 return ((p && *p) ? -EOVERFLOW : 0);
363 case KDSKBSENT:
364 if (!perm) {
365 ret = -EPERM;
366 goto reterr;
367 }
368
369 q = func_table[i];
370 first_free = funcbufptr + (funcbufsize - funcbufleft);
371 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
372 ;
373 if (j < MAX_NR_FUNC)
374 fj = func_table[j];
375 else
376 fj = first_free;
377
378 delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
379 if (delta <= funcbufleft) { /* it fits in current buf */
380 if (j < MAX_NR_FUNC) {
381 memmove(fj + delta, fj, first_free - fj);
382 for (k = j; k < MAX_NR_FUNC; k++)
383 if (func_table[k])
384 func_table[k] += delta;
385 }
386 if (!q)
387 func_table[i] = fj;
388 funcbufleft -= delta;
389 } else { /* allocate a larger buffer */
390 sz = 256;
391 while (sz < funcbufsize - funcbufleft + delta)
392 sz <<= 1;
393 fnw = kmalloc(sz, GFP_KERNEL);
394 if(!fnw) {
395 ret = -ENOMEM;
396 goto reterr;
397 }
398
399 if (!q)
400 func_table[i] = fj;
401 if (fj > funcbufptr)
402 memmove(fnw, funcbufptr, fj - funcbufptr);
403 for (k = 0; k < j; k++)
404 if (func_table[k])
405 func_table[k] = fnw + (func_table[k] - funcbufptr);
406
407 if (first_free > fj) {
408 memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
409 for (k = j; k < MAX_NR_FUNC; k++)
410 if (func_table[k])
411 func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
412 }
413 if (funcbufptr != func_buf)
414 kfree(funcbufptr);
415 funcbufptr = fnw;
416 funcbufleft = funcbufleft - delta + sz - funcbufsize;
417 funcbufsize = sz;
418 }
419 strcpy(func_table[i], kbs->kb_string);
420 break;
421 }
422 ret = 0;
423reterr:
424 kfree(kbs);
425 return ret;
426}
427
428static inline int
429do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op)
430{
431 struct consolefontdesc cfdarg;
432 int i;
433
434 if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc)))
435 return -EFAULT;
436
437 switch (cmd) {
438 case PIO_FONTX:
439 if (!perm)
440 return -EPERM;
441 op->op = KD_FONT_OP_SET;
442 op->flags = KD_FONT_FLAG_OLD;
443 op->width = 8;
444 op->height = cfdarg.charheight;
445 op->charcount = cfdarg.charcount;
446 op->data = cfdarg.chardata;
447 return con_font_op(vc_cons[fg_console].d, op);
448 case GIO_FONTX: {
449 op->op = KD_FONT_OP_GET;
450 op->flags = KD_FONT_FLAG_OLD;
451 op->width = 8;
452 op->height = cfdarg.charheight;
453 op->charcount = cfdarg.charcount;
454 op->data = cfdarg.chardata;
455 i = con_font_op(vc_cons[fg_console].d, op);
456 if (i)
457 return i;
458 cfdarg.charheight = op->height;
459 cfdarg.charcount = op->charcount;
460 if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc)))
461 return -EFAULT;
462 return 0;
463 }
464 }
465 return -EINVAL;
466}
467
468static inline int
469do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_data *vc)
470{
471 struct unimapdesc tmp;
472
473 if (copy_from_user(&tmp, user_ud, sizeof tmp))
474 return -EFAULT;
475 if (tmp.entries)
476 if (!access_ok(VERIFY_WRITE, tmp.entries,
477 tmp.entry_ct*sizeof(struct unipair)))
478 return -EFAULT;
479 switch (cmd) {
480 case PIO_UNIMAP:
481 if (!perm)
482 return -EPERM;
483 return con_set_unimap(vc, tmp.entry_ct, tmp.entries);
484 case GIO_UNIMAP:
485 if (!perm && fg_console != vc->vc_num)
486 return -EPERM;
487 return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp.entries);
488 }
489 return 0;
490}
491
492
493
494/*
495 * We handle the console-specific ioctl's here. We allow the
496 * capability to modify any console, not just the fg_console.
497 */
498int vt_ioctl(struct tty_struct *tty, struct file * file,
499 unsigned int cmd, unsigned long arg)
500{
501 struct vc_data *vc = tty->driver_data;
502 struct console_font_op op; /* used in multiple places here */
503 struct kbd_struct * kbd;
504 unsigned int console;
505 unsigned char ucval;
506 unsigned int uival;
507 void __user *up = (void __user *)arg;
508 int i, perm;
509 int ret = 0;
510
511 console = vc->vc_num;
512
513 tty_lock();
514
515 if (!vc_cons_allocated(console)) { /* impossible? */
516 ret = -ENOIOCTLCMD;
517 goto out;
518 }
519
520
521 /*
522 * To have permissions to do most of the vt ioctls, we either have
523 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
524 */
525 perm = 0;
526 if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
527 perm = 1;
528
529 kbd = kbd_table + console;
530 switch (cmd) {
531 case TIOCLINUX:
532 ret = tioclinux(tty, arg);
533 break;
534 case KIOCSOUND:
535 if (!perm)
536 goto eperm;
537 /*
538 * The use of PIT_TICK_RATE is historic, it used to be
539 * the platform-dependent CLOCK_TICK_RATE between 2.6.12
540 * and 2.6.36, which was a minor but unfortunate ABI
541 * change.
542 */
543 if (arg)
544 arg = PIT_TICK_RATE / arg;
545 kd_mksound(arg, 0);
546 break;
547
548 case KDMKTONE:
549 if (!perm)
550 goto eperm;
551 {
552 unsigned int ticks, count;
553
554 /*
555 * Generate the tone for the appropriate number of ticks.
556 * If the time is zero, turn off sound ourselves.
557 */
558 ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
559 count = ticks ? (arg & 0xffff) : 0;
560 if (count)
561 count = PIT_TICK_RATE / count;
562 kd_mksound(count, ticks);
563 break;
564 }
565
566 case KDGKBTYPE:
567 /*
568 * this is naive.
569 */
570 ucval = KB_101;
571 goto setchar;
572
573 /*
574 * These cannot be implemented on any machine that implements
575 * ioperm() in user level (such as Alpha PCs) or not at all.
576 *
577 * XXX: you should never use these, just call ioperm directly..
578 */
579#ifdef CONFIG_X86
580 case KDADDIO:
581 case KDDELIO:
582 /*
583 * KDADDIO and KDDELIO may be able to add ports beyond what
584 * we reject here, but to be safe...
585 */
586 if (arg < GPFIRST || arg > GPLAST) {
587 ret = -EINVAL;
588 break;
589 }
590 ret = sys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
591 break;
592
593 case KDENABIO:
594 case KDDISABIO:
595 ret = sys_ioperm(GPFIRST, GPNUM,
596 (cmd == KDENABIO)) ? -ENXIO : 0;
597 break;
598#endif
599
600 /* Linux m68k/i386 interface for setting the keyboard delay/repeat rate */
601
602 case KDKBDREP:
603 {
604 struct kbd_repeat kbrep;
605
606 if (!capable(CAP_SYS_TTY_CONFIG))
607 goto eperm;
608
609 if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) {
610 ret = -EFAULT;
611 break;
612 }
613 ret = kbd_rate(&kbrep);
614 if (ret)
615 break;
616 if (copy_to_user(up, &kbrep, sizeof(struct kbd_repeat)))
617 ret = -EFAULT;
618 break;
619 }
620
621 case KDSETMODE:
622 /*
623 * currently, setting the mode from KD_TEXT to KD_GRAPHICS
624 * doesn't do a whole lot. i'm not sure if it should do any
625 * restoration of modes or what...
626 *
627 * XXX It should at least call into the driver, fbdev's definitely
628 * need to restore their engine state. --BenH
629 */
630 if (!perm)
631 goto eperm;
632 switch (arg) {
633 case KD_GRAPHICS:
634 break;
635 case KD_TEXT0:
636 case KD_TEXT1:
637 arg = KD_TEXT;
638 case KD_TEXT:
639 break;
640 default:
641 ret = -EINVAL;
642 goto out;
643 }
644 if (vc->vc_mode == (unsigned char) arg)
645 break;
646 vc->vc_mode = (unsigned char) arg;
647 if (console != fg_console)
648 break;
649 /*
650 * explicitly blank/unblank the screen if switching modes
651 */
652 acquire_console_sem();
653 if (arg == KD_TEXT)
654 do_unblank_screen(1);
655 else
656 do_blank_screen(1);
657 release_console_sem();
658 break;
659
660 case KDGETMODE:
661 uival = vc->vc_mode;
662 goto setint;
663
664 case KDMAPDISP:
665 case KDUNMAPDISP:
666 /*
667 * these work like a combination of mmap and KDENABIO.
668 * this could be easily finished.
669 */
670 ret = -EINVAL;
671 break;
672
673 case KDSKBMODE:
674 if (!perm)
675 goto eperm;
676 switch(arg) {
677 case K_RAW:
678 kbd->kbdmode = VC_RAW;
679 break;
680 case K_MEDIUMRAW:
681 kbd->kbdmode = VC_MEDIUMRAW;
682 break;
683 case K_XLATE:
684 kbd->kbdmode = VC_XLATE;
685 compute_shiftstate();
686 break;
687 case K_UNICODE:
688 kbd->kbdmode = VC_UNICODE;
689 compute_shiftstate();
690 break;
691 default:
692 ret = -EINVAL;
693 goto out;
694 }
695 tty_ldisc_flush(tty);
696 break;
697
698 case KDGKBMODE:
699 uival = ((kbd->kbdmode == VC_RAW) ? K_RAW :
700 (kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW :
701 (kbd->kbdmode == VC_UNICODE) ? K_UNICODE :
702 K_XLATE);
703 goto setint;
704
705 /* this could be folded into KDSKBMODE, but for compatibility
706 reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
707 case KDSKBMETA:
708 switch(arg) {
709 case K_METABIT:
710 clr_vc_kbd_mode(kbd, VC_META);
711 break;
712 case K_ESCPREFIX:
713 set_vc_kbd_mode(kbd, VC_META);
714 break;
715 default:
716 ret = -EINVAL;
717 }
718 break;
719
720 case KDGKBMETA:
721 uival = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT);
722 setint:
723 ret = put_user(uival, (int __user *)arg);
724 break;
725
726 case KDGETKEYCODE:
727 case KDSETKEYCODE:
728 if(!capable(CAP_SYS_TTY_CONFIG))
729 perm = 0;
730 ret = do_kbkeycode_ioctl(cmd, up, perm);
731 break;
732
733 case KDGKBENT:
734 case KDSKBENT:
735 ret = do_kdsk_ioctl(cmd, up, perm, kbd);
736 break;
737
738 case KDGKBSENT:
739 case KDSKBSENT:
740 ret = do_kdgkb_ioctl(cmd, up, perm);
741 break;
742
743 case KDGKBDIACR:
744 {
745 struct kbdiacrs __user *a = up;
746 struct kbdiacr diacr;
747 int i;
748
749 if (put_user(accent_table_size, &a->kb_cnt)) {
750 ret = -EFAULT;
751 break;
752 }
753 for (i = 0; i < accent_table_size; i++) {
754 diacr.diacr = conv_uni_to_8bit(accent_table[i].diacr);
755 diacr.base = conv_uni_to_8bit(accent_table[i].base);
756 diacr.result = conv_uni_to_8bit(accent_table[i].result);
757 if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr))) {
758 ret = -EFAULT;
759 break;
760 }
761 }
762 break;
763 }
764 case KDGKBDIACRUC:
765 {
766 struct kbdiacrsuc __user *a = up;
767
768 if (put_user(accent_table_size, &a->kb_cnt))
769 ret = -EFAULT;
770 else if (copy_to_user(a->kbdiacruc, accent_table,
771 accent_table_size*sizeof(struct kbdiacruc)))
772 ret = -EFAULT;
773 break;
774 }
775
776 case KDSKBDIACR:
777 {
778 struct kbdiacrs __user *a = up;
779 struct kbdiacr diacr;
780 unsigned int ct;
781 int i;
782
783 if (!perm)
784 goto eperm;
785 if (get_user(ct,&a->kb_cnt)) {
786 ret = -EFAULT;
787 break;
788 }
789 if (ct >= MAX_DIACR) {
790 ret = -EINVAL;
791 break;
792 }
793 accent_table_size = ct;
794 for (i = 0; i < ct; i++) {
795 if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr))) {
796 ret = -EFAULT;
797 break;
798 }
799 accent_table[i].diacr = conv_8bit_to_uni(diacr.diacr);
800 accent_table[i].base = conv_8bit_to_uni(diacr.base);
801 accent_table[i].result = conv_8bit_to_uni(diacr.result);
802 }
803 break;
804 }
805
806 case KDSKBDIACRUC:
807 {
808 struct kbdiacrsuc __user *a = up;
809 unsigned int ct;
810
811 if (!perm)
812 goto eperm;
813 if (get_user(ct,&a->kb_cnt)) {
814 ret = -EFAULT;
815 break;
816 }
817 if (ct >= MAX_DIACR) {
818 ret = -EINVAL;
819 break;
820 }
821 accent_table_size = ct;
822 if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc)))
823 ret = -EFAULT;
824 break;
825 }
826
827 /* the ioctls below read/set the flags usually shown in the leds */
828 /* don't use them - they will go away without warning */
829 case KDGKBLED:
830 ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
831 goto setchar;
832
833 case KDSKBLED:
834 if (!perm)
835 goto eperm;
836 if (arg & ~0x77) {
837 ret = -EINVAL;
838 break;
839 }
840 kbd->ledflagstate = (arg & 7);
841 kbd->default_ledflagstate = ((arg >> 4) & 7);
842 set_leds();
843 break;
844
845 /* the ioctls below only set the lights, not the functions */
846 /* for those, see KDGKBLED and KDSKBLED above */
847 case KDGETLED:
848 ucval = getledstate();
849 setchar:
850 ret = put_user(ucval, (char __user *)arg);
851 break;
852
853 case KDSETLED:
854 if (!perm)
855 goto eperm;
856 setledstate(kbd, arg);
857 break;
858
859 /*
860 * A process can indicate its willingness to accept signals
861 * generated by pressing an appropriate key combination.
862 * Thus, one can have a daemon that e.g. spawns a new console
863 * upon a keypress and then changes to it.
864 * See also the kbrequest field of inittab(5).
865 */
866 case KDSIGACCEPT:
867 {
868 if (!perm || !capable(CAP_KILL))
869 goto eperm;
870 if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
871 ret = -EINVAL;
872 else {
873 spin_lock_irq(&vt_spawn_con.lock);
874 put_pid(vt_spawn_con.pid);
875 vt_spawn_con.pid = get_pid(task_pid(current));
876 vt_spawn_con.sig = arg;
877 spin_unlock_irq(&vt_spawn_con.lock);
878 }
879 break;
880 }
881
882 case VT_SETMODE:
883 {
884 struct vt_mode tmp;
885
886 if (!perm)
887 goto eperm;
888 if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) {
889 ret = -EFAULT;
890 goto out;
891 }
892 if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) {
893 ret = -EINVAL;
894 goto out;
895 }
896 acquire_console_sem();
897 vc->vt_mode = tmp;
898 /* the frsig is ignored, so we set it to 0 */
899 vc->vt_mode.frsig = 0;
900 put_pid(vc->vt_pid);
901 vc->vt_pid = get_pid(task_pid(current));
902 /* no switch is required -- saw@shade.msu.ru */
903 vc->vt_newvt = -1;
904 release_console_sem();
905 break;
906 }
907
908 case VT_GETMODE:
909 {
910 struct vt_mode tmp;
911 int rc;
912
913 acquire_console_sem();
914 memcpy(&tmp, &vc->vt_mode, sizeof(struct vt_mode));
915 release_console_sem();
916
917 rc = copy_to_user(up, &tmp, sizeof(struct vt_mode));
918 if (rc)
919 ret = -EFAULT;
920 break;
921 }
922
923 /*
924 * Returns global vt state. Note that VT 0 is always open, since
925 * it's an alias for the current VT, and people can't use it here.
926 * We cannot return state for more than 16 VTs, since v_state is short.
927 */
928 case VT_GETSTATE:
929 {
930 struct vt_stat __user *vtstat = up;
931 unsigned short state, mask;
932
933 if (put_user(fg_console + 1, &vtstat->v_active))
934 ret = -EFAULT;
935 else {
936 state = 1; /* /dev/tty0 is always open */
937 for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask;
938 ++i, mask <<= 1)
939 if (VT_IS_IN_USE(i))
940 state |= mask;
941 ret = put_user(state, &vtstat->v_state);
942 }
943 break;
944 }
945
946 /*
947 * Returns the first available (non-opened) console.
948 */
949 case VT_OPENQRY:
950 for (i = 0; i < MAX_NR_CONSOLES; ++i)
951 if (! VT_IS_IN_USE(i))
952 break;
953 uival = i < MAX_NR_CONSOLES ? (i+1) : -1;
954 goto setint;
955
956 /*
957 * ioctl(fd, VT_ACTIVATE, num) will cause us to switch to vt # num,
958 * with num >= 1 (switches to vt 0, our console, are not allowed, just
959 * to preserve sanity).
960 */
961 case VT_ACTIVATE:
962 if (!perm)
963 goto eperm;
964 if (arg == 0 || arg > MAX_NR_CONSOLES)
965 ret = -ENXIO;
966 else {
967 arg--;
968 acquire_console_sem();
969 ret = vc_allocate(arg);
970 release_console_sem();
971 if (ret)
972 break;
973 set_console(arg);
974 }
975 break;
976
977 case VT_SETACTIVATE:
978 {
979 struct vt_setactivate vsa;
980
981 if (!perm)
982 goto eperm;
983
984 if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
985 sizeof(struct vt_setactivate))) {
986 ret = -EFAULT;
987 goto out;
988 }
989 if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
990 ret = -ENXIO;
991 else {
992 vsa.console--;
993 acquire_console_sem();
994 ret = vc_allocate(vsa.console);
995 if (ret == 0) {
996 struct vc_data *nvc;
997 /* This is safe providing we don't drop the
998 console sem between vc_allocate and
999 finishing referencing nvc */
1000 nvc = vc_cons[vsa.console].d;
1001 nvc->vt_mode = vsa.mode;
1002 nvc->vt_mode.frsig = 0;
1003 put_pid(nvc->vt_pid);
1004 nvc->vt_pid = get_pid(task_pid(current));
1005 }
1006 release_console_sem();
1007 if (ret)
1008 break;
1009 /* Commence switch and lock */
1010 set_console(arg);
1011 }
1012 }
1013
1014 /*
1015 * wait until the specified VT has been activated
1016 */
1017 case VT_WAITACTIVE:
1018 if (!perm)
1019 goto eperm;
1020 if (arg == 0 || arg > MAX_NR_CONSOLES)
1021 ret = -ENXIO;
1022 else
1023 ret = vt_waitactive(arg);
1024 break;
1025
1026 /*
1027 * If a vt is under process control, the kernel will not switch to it
1028 * immediately, but postpone the operation until the process calls this
1029 * ioctl, allowing the switch to complete.
1030 *
1031 * According to the X sources this is the behavior:
1032 * 0: pending switch-from not OK
1033 * 1: pending switch-from OK
1034 * 2: completed switch-to OK
1035 */
1036 case VT_RELDISP:
1037 if (!perm)
1038 goto eperm;
1039
1040 if (vc->vt_mode.mode != VT_PROCESS) {
1041 ret = -EINVAL;
1042 break;
1043 }
1044 /*
1045 * Switching-from response
1046 */
1047 acquire_console_sem();
1048 if (vc->vt_newvt >= 0) {
1049 if (arg == 0)
1050 /*
1051 * Switch disallowed, so forget we were trying
1052 * to do it.
1053 */
1054 vc->vt_newvt = -1;
1055
1056 else {
1057 /*
1058 * The current vt has been released, so
1059 * complete the switch.
1060 */
1061 int newvt;
1062 newvt = vc->vt_newvt;
1063 vc->vt_newvt = -1;
1064 ret = vc_allocate(newvt);
1065 if (ret) {
1066 release_console_sem();
1067 break;
1068 }
1069 /*
1070 * When we actually do the console switch,
1071 * make sure we are atomic with respect to
1072 * other console switches..
1073 */
1074 complete_change_console(vc_cons[newvt].d);
1075 }
1076 } else {
1077 /*
1078 * Switched-to response
1079 */
1080 /*
1081 * If it's just an ACK, ignore it
1082 */
1083 if (arg != VT_ACKACQ)
1084 ret = -EINVAL;
1085 }
1086 release_console_sem();
1087 break;
1088
1089 /*
1090 * Disallocate memory associated to VT (but leave VT1)
1091 */
1092 case VT_DISALLOCATE:
1093 if (arg > MAX_NR_CONSOLES) {
1094 ret = -ENXIO;
1095 break;
1096 }
1097 if (arg == 0) {
1098 /* deallocate all unused consoles, but leave 0 */
1099 acquire_console_sem();
1100 for (i=1; i<MAX_NR_CONSOLES; i++)
1101 if (! VT_BUSY(i))
1102 vc_deallocate(i);
1103 release_console_sem();
1104 } else {
1105 /* deallocate a single console, if possible */
1106 arg--;
1107 if (VT_BUSY(arg))
1108 ret = -EBUSY;
1109 else if (arg) { /* leave 0 */
1110 acquire_console_sem();
1111 vc_deallocate(arg);
1112 release_console_sem();
1113 }
1114 }
1115 break;
1116
1117 case VT_RESIZE:
1118 {
1119 struct vt_sizes __user *vtsizes = up;
1120 struct vc_data *vc;
1121
1122 ushort ll,cc;
1123 if (!perm)
1124 goto eperm;
1125 if (get_user(ll, &vtsizes->v_rows) ||
1126 get_user(cc, &vtsizes->v_cols))
1127 ret = -EFAULT;
1128 else {
1129 acquire_console_sem();
1130 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1131 vc = vc_cons[i].d;
1132
1133 if (vc) {
1134 vc->vc_resize_user = 1;
1135 vc_resize(vc_cons[i].d, cc, ll);
1136 }
1137 }
1138 release_console_sem();
1139 }
1140 break;
1141 }
1142
1143 case VT_RESIZEX:
1144 {
1145 struct vt_consize __user *vtconsize = up;
1146 ushort ll,cc,vlin,clin,vcol,ccol;
1147 if (!perm)
1148 goto eperm;
1149 if (!access_ok(VERIFY_READ, vtconsize,
1150 sizeof(struct vt_consize))) {
1151 ret = -EFAULT;
1152 break;
1153 }
1154 /* FIXME: Should check the copies properly */
1155 __get_user(ll, &vtconsize->v_rows);
1156 __get_user(cc, &vtconsize->v_cols);
1157 __get_user(vlin, &vtconsize->v_vlin);
1158 __get_user(clin, &vtconsize->v_clin);
1159 __get_user(vcol, &vtconsize->v_vcol);
1160 __get_user(ccol, &vtconsize->v_ccol);
1161 vlin = vlin ? vlin : vc->vc_scan_lines;
1162 if (clin) {
1163 if (ll) {
1164 if (ll != vlin/clin) {
1165 /* Parameters don't add up */
1166 ret = -EINVAL;
1167 break;
1168 }
1169 } else
1170 ll = vlin/clin;
1171 }
1172 if (vcol && ccol) {
1173 if (cc) {
1174 if (cc != vcol/ccol) {
1175 ret = -EINVAL;
1176 break;
1177 }
1178 } else
1179 cc = vcol/ccol;
1180 }
1181
1182 if (clin > 32) {
1183 ret = -EINVAL;
1184 break;
1185 }
1186
1187 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1188 if (!vc_cons[i].d)
1189 continue;
1190 acquire_console_sem();
1191 if (vlin)
1192 vc_cons[i].d->vc_scan_lines = vlin;
1193 if (clin)
1194 vc_cons[i].d->vc_font.height = clin;
1195 vc_cons[i].d->vc_resize_user = 1;
1196 vc_resize(vc_cons[i].d, cc, ll);
1197 release_console_sem();
1198 }
1199 break;
1200 }
1201
1202 case PIO_FONT: {
1203 if (!perm)
1204 goto eperm;
1205 op.op = KD_FONT_OP_SET;
1206 op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */
1207 op.width = 8;
1208 op.height = 0;
1209 op.charcount = 256;
1210 op.data = up;
1211 ret = con_font_op(vc_cons[fg_console].d, &op);
1212 break;
1213 }
1214
1215 case GIO_FONT: {
1216 op.op = KD_FONT_OP_GET;
1217 op.flags = KD_FONT_FLAG_OLD;
1218 op.width = 8;
1219 op.height = 32;
1220 op.charcount = 256;
1221 op.data = up;
1222 ret = con_font_op(vc_cons[fg_console].d, &op);
1223 break;
1224 }
1225
1226 case PIO_CMAP:
1227 if (!perm)
1228 ret = -EPERM;
1229 else
1230 ret = con_set_cmap(up);
1231 break;
1232
1233 case GIO_CMAP:
1234 ret = con_get_cmap(up);
1235 break;
1236
1237 case PIO_FONTX:
1238 case GIO_FONTX:
1239 ret = do_fontx_ioctl(cmd, up, perm, &op);
1240 break;
1241
1242 case PIO_FONTRESET:
1243 {
1244 if (!perm)
1245 goto eperm;
1246
1247#ifdef BROKEN_GRAPHICS_PROGRAMS
1248 /* With BROKEN_GRAPHICS_PROGRAMS defined, the default
1249 font is not saved. */
1250 ret = -ENOSYS;
1251 break;
1252#else
1253 {
1254 op.op = KD_FONT_OP_SET_DEFAULT;
1255 op.data = NULL;
1256 ret = con_font_op(vc_cons[fg_console].d, &op);
1257 if (ret)
1258 break;
1259 con_set_default_unimap(vc_cons[fg_console].d);
1260 break;
1261 }
1262#endif
1263 }
1264
1265 case KDFONTOP: {
1266 if (copy_from_user(&op, up, sizeof(op))) {
1267 ret = -EFAULT;
1268 break;
1269 }
1270 if (!perm && op.op != KD_FONT_OP_GET)
1271 goto eperm;
1272 ret = con_font_op(vc, &op);
1273 if (ret)
1274 break;
1275 if (copy_to_user(up, &op, sizeof(op)))
1276 ret = -EFAULT;
1277 break;
1278 }
1279
1280 case PIO_SCRNMAP:
1281 if (!perm)
1282 ret = -EPERM;
1283 else
1284 ret = con_set_trans_old(up);
1285 break;
1286
1287 case GIO_SCRNMAP:
1288 ret = con_get_trans_old(up);
1289 break;
1290
1291 case PIO_UNISCRNMAP:
1292 if (!perm)
1293 ret = -EPERM;
1294 else
1295 ret = con_set_trans_new(up);
1296 break;
1297
1298 case GIO_UNISCRNMAP:
1299 ret = con_get_trans_new(up);
1300 break;
1301
1302 case PIO_UNIMAPCLR:
1303 { struct unimapinit ui;
1304 if (!perm)
1305 goto eperm;
1306 ret = copy_from_user(&ui, up, sizeof(struct unimapinit));
1307 if (ret)
1308 ret = -EFAULT;
1309 else
1310 con_clear_unimap(vc, &ui);
1311 break;
1312 }
1313
1314 case PIO_UNIMAP:
1315 case GIO_UNIMAP:
1316 ret = do_unimap_ioctl(cmd, up, perm, vc);
1317 break;
1318
1319 case VT_LOCKSWITCH:
1320 if (!capable(CAP_SYS_TTY_CONFIG))
1321 goto eperm;
1322 vt_dont_switch = 1;
1323 break;
1324 case VT_UNLOCKSWITCH:
1325 if (!capable(CAP_SYS_TTY_CONFIG))
1326 goto eperm;
1327 vt_dont_switch = 0;
1328 break;
1329 case VT_GETHIFONTMASK:
1330 ret = put_user(vc->vc_hi_font_mask,
1331 (unsigned short __user *)arg);
1332 break;
1333 case VT_WAITEVENT:
1334 ret = vt_event_wait_ioctl((struct vt_event __user *)arg);
1335 break;
1336 default:
1337 ret = -ENOIOCTLCMD;
1338 }
1339out:
1340 tty_unlock();
1341 return ret;
1342eperm:
1343 ret = -EPERM;
1344 goto out;
1345}
1346
1347void reset_vc(struct vc_data *vc)
1348{
1349 vc->vc_mode = KD_TEXT;
1350 kbd_table[vc->vc_num].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
1351 vc->vt_mode.mode = VT_AUTO;
1352 vc->vt_mode.waitv = 0;
1353 vc->vt_mode.relsig = 0;
1354 vc->vt_mode.acqsig = 0;
1355 vc->vt_mode.frsig = 0;
1356 put_pid(vc->vt_pid);
1357 vc->vt_pid = NULL;
1358 vc->vt_newvt = -1;
1359 if (!in_interrupt()) /* Via keyboard.c:SAK() - akpm */
1360 reset_palette(vc);
1361}
1362
1363void vc_SAK(struct work_struct *work)
1364{
1365 struct vc *vc_con =
1366 container_of(work, struct vc, SAK_work);
1367 struct vc_data *vc;
1368 struct tty_struct *tty;
1369
1370 acquire_console_sem();
1371 vc = vc_con->d;
1372 if (vc) {
1373 tty = vc->port.tty;
1374 /*
1375 * SAK should also work in all raw modes and reset
1376 * them properly.
1377 */
1378 if (tty)
1379 __do_SAK(tty);
1380 reset_vc(vc);
1381 }
1382 release_console_sem();
1383}
1384
1385#ifdef CONFIG_COMPAT
1386
1387struct compat_consolefontdesc {
1388 unsigned short charcount; /* characters in font (256 or 512) */
1389 unsigned short charheight; /* scan lines per character (1-32) */
1390 compat_caddr_t chardata; /* font data in expanded form */
1391};
1392
1393static inline int
1394compat_fontx_ioctl(int cmd, struct compat_consolefontdesc __user *user_cfd,
1395 int perm, struct console_font_op *op)
1396{
1397 struct compat_consolefontdesc cfdarg;
1398 int i;
1399
1400 if (copy_from_user(&cfdarg, user_cfd, sizeof(struct compat_consolefontdesc)))
1401 return -EFAULT;
1402
1403 switch (cmd) {
1404 case PIO_FONTX:
1405 if (!perm)
1406 return -EPERM;
1407 op->op = KD_FONT_OP_SET;
1408 op->flags = KD_FONT_FLAG_OLD;
1409 op->width = 8;
1410 op->height = cfdarg.charheight;
1411 op->charcount = cfdarg.charcount;
1412 op->data = compat_ptr(cfdarg.chardata);
1413 return con_font_op(vc_cons[fg_console].d, op);
1414 case GIO_FONTX:
1415 op->op = KD_FONT_OP_GET;
1416 op->flags = KD_FONT_FLAG_OLD;
1417 op->width = 8;
1418 op->height = cfdarg.charheight;
1419 op->charcount = cfdarg.charcount;
1420 op->data = compat_ptr(cfdarg.chardata);
1421 i = con_font_op(vc_cons[fg_console].d, op);
1422 if (i)
1423 return i;
1424 cfdarg.charheight = op->height;
1425 cfdarg.charcount = op->charcount;
1426 if (copy_to_user(user_cfd, &cfdarg, sizeof(struct compat_consolefontdesc)))
1427 return -EFAULT;
1428 return 0;
1429 }
1430 return -EINVAL;
1431}
1432
1433struct compat_console_font_op {
1434 compat_uint_t op; /* operation code KD_FONT_OP_* */
1435 compat_uint_t flags; /* KD_FONT_FLAG_* */
1436 compat_uint_t width, height; /* font size */
1437 compat_uint_t charcount;
1438 compat_caddr_t data; /* font data with height fixed to 32 */
1439};
1440
1441static inline int
1442compat_kdfontop_ioctl(struct compat_console_font_op __user *fontop,
1443 int perm, struct console_font_op *op, struct vc_data *vc)
1444{
1445 int i;
1446
1447 if (copy_from_user(op, fontop, sizeof(struct compat_console_font_op)))
1448 return -EFAULT;
1449 if (!perm && op->op != KD_FONT_OP_GET)
1450 return -EPERM;
1451 op->data = compat_ptr(((struct compat_console_font_op *)op)->data);
1452 op->flags |= KD_FONT_FLAG_OLD;
1453 i = con_font_op(vc, op);
1454 if (i)
1455 return i;
1456 ((struct compat_console_font_op *)op)->data = (unsigned long)op->data;
1457 if (copy_to_user(fontop, op, sizeof(struct compat_console_font_op)))
1458 return -EFAULT;
1459 return 0;
1460}
1461
1462struct compat_unimapdesc {
1463 unsigned short entry_ct;
1464 compat_caddr_t entries;
1465};
1466
1467static inline int
1468compat_unimap_ioctl(unsigned int cmd, struct compat_unimapdesc __user *user_ud,
1469 int perm, struct vc_data *vc)
1470{
1471 struct compat_unimapdesc tmp;
1472 struct unipair __user *tmp_entries;
1473
1474 if (copy_from_user(&tmp, user_ud, sizeof tmp))
1475 return -EFAULT;
1476 tmp_entries = compat_ptr(tmp.entries);
1477 if (tmp_entries)
1478 if (!access_ok(VERIFY_WRITE, tmp_entries,
1479 tmp.entry_ct*sizeof(struct unipair)))
1480 return -EFAULT;
1481 switch (cmd) {
1482 case PIO_UNIMAP:
1483 if (!perm)
1484 return -EPERM;
1485 return con_set_unimap(vc, tmp.entry_ct, tmp_entries);
1486 case GIO_UNIMAP:
1487 if (!perm && fg_console != vc->vc_num)
1488 return -EPERM;
1489 return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp_entries);
1490 }
1491 return 0;
1492}
1493
1494long vt_compat_ioctl(struct tty_struct *tty, struct file * file,
1495 unsigned int cmd, unsigned long arg)
1496{
1497 struct vc_data *vc = tty->driver_data;
1498 struct console_font_op op; /* used in multiple places here */
1499 struct kbd_struct *kbd;
1500 unsigned int console;
1501 void __user *up = (void __user *)arg;
1502 int perm;
1503 int ret = 0;
1504
1505 console = vc->vc_num;
1506
1507 tty_lock();
1508
1509 if (!vc_cons_allocated(console)) { /* impossible? */
1510 ret = -ENOIOCTLCMD;
1511 goto out;
1512 }
1513
1514 /*
1515 * To have permissions to do most of the vt ioctls, we either have
1516 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
1517 */
1518 perm = 0;
1519 if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
1520 perm = 1;
1521
1522 kbd = kbd_table + console;
1523 switch (cmd) {
1524 /*
1525 * these need special handlers for incompatible data structures
1526 */
1527 case PIO_FONTX:
1528 case GIO_FONTX:
1529 ret = compat_fontx_ioctl(cmd, up, perm, &op);
1530 break;
1531
1532 case KDFONTOP:
1533 ret = compat_kdfontop_ioctl(up, perm, &op, vc);
1534 break;
1535
1536 case PIO_UNIMAP:
1537 case GIO_UNIMAP:
1538 ret = compat_unimap_ioctl(cmd, up, perm, vc);
1539 break;
1540
1541 /*
1542 * all these treat 'arg' as an integer
1543 */
1544 case KIOCSOUND:
1545 case KDMKTONE:
1546#ifdef CONFIG_X86
1547 case KDADDIO:
1548 case KDDELIO:
1549#endif
1550 case KDSETMODE:
1551 case KDMAPDISP:
1552 case KDUNMAPDISP:
1553 case KDSKBMODE:
1554 case KDSKBMETA:
1555 case KDSKBLED:
1556 case KDSETLED:
1557 case KDSIGACCEPT:
1558 case VT_ACTIVATE:
1559 case VT_WAITACTIVE:
1560 case VT_RELDISP:
1561 case VT_DISALLOCATE:
1562 case VT_RESIZE:
1563 case VT_RESIZEX:
1564 goto fallback;
1565
1566 /*
1567 * the rest has a compatible data structure behind arg,
1568 * but we have to convert it to a proper 64 bit pointer.
1569 */
1570 default:
1571 arg = (unsigned long)compat_ptr(arg);
1572 goto fallback;
1573 }
1574out:
1575 tty_unlock();
1576 return ret;
1577
1578fallback:
1579 tty_unlock();
1580 return vt_ioctl(tty, file, cmd, arg);
1581}
1582
1583
1584#endif /* CONFIG_COMPAT */
1585
1586
1587/*
1588 * Performs the back end of a vt switch. Called under the console
1589 * semaphore.
1590 */
1591static void complete_change_console(struct vc_data *vc)
1592{
1593 unsigned char old_vc_mode;
1594 int old = fg_console;
1595
1596 last_console = fg_console;
1597
1598 /*
1599 * If we're switching, we could be going from KD_GRAPHICS to
1600 * KD_TEXT mode or vice versa, which means we need to blank or
1601 * unblank the screen later.
1602 */
1603 old_vc_mode = vc_cons[fg_console].d->vc_mode;
1604 switch_screen(vc);
1605
1606 /*
1607 * This can't appear below a successful kill_pid(). If it did,
1608 * then the *blank_screen operation could occur while X, having
1609 * received acqsig, is waking up on another processor. This
1610 * condition can lead to overlapping accesses to the VGA range
1611 * and the framebuffer (causing system lockups).
1612 *
1613 * To account for this we duplicate this code below only if the
1614 * controlling process is gone and we've called reset_vc.
1615 */
1616 if (old_vc_mode != vc->vc_mode) {
1617 if (vc->vc_mode == KD_TEXT)
1618 do_unblank_screen(1);
1619 else
1620 do_blank_screen(1);
1621 }
1622
1623 /*
1624 * If this new console is under process control, send it a signal
1625 * telling it that it has acquired. Also check if it has died and
1626 * clean up (similar to logic employed in change_console())
1627 */
1628 if (vc->vt_mode.mode == VT_PROCESS) {
1629 /*
1630 * Send the signal as privileged - kill_pid() will
1631 * tell us if the process has gone or something else
1632 * is awry
1633 */
1634 if (kill_pid(vc->vt_pid, vc->vt_mode.acqsig, 1) != 0) {
1635 /*
1636 * The controlling process has died, so we revert back to
1637 * normal operation. In this case, we'll also change back
1638 * to KD_TEXT mode. I'm not sure if this is strictly correct
1639 * but it saves the agony when the X server dies and the screen
1640 * remains blanked due to KD_GRAPHICS! It would be nice to do
1641 * this outside of VT_PROCESS but there is no single process
1642 * to account for and tracking tty count may be undesirable.
1643 */
1644 reset_vc(vc);
1645
1646 if (old_vc_mode != vc->vc_mode) {
1647 if (vc->vc_mode == KD_TEXT)
1648 do_unblank_screen(1);
1649 else
1650 do_blank_screen(1);
1651 }
1652 }
1653 }
1654
1655 /*
1656 * Wake anyone waiting for their VT to activate
1657 */
1658 vt_event_post(VT_EVENT_SWITCH, old, vc->vc_num);
1659 return;
1660}
1661
1662/*
1663 * Performs the front-end of a vt switch
1664 */
1665void change_console(struct vc_data *new_vc)
1666{
1667 struct vc_data *vc;
1668
1669 if (!new_vc || new_vc->vc_num == fg_console || vt_dont_switch)
1670 return;
1671
1672 /*
1673 * If this vt is in process mode, then we need to handshake with
1674 * that process before switching. Essentially, we store where that
1675 * vt wants to switch to and wait for it to tell us when it's done
1676 * (via VT_RELDISP ioctl).
1677 *
1678 * We also check to see if the controlling process still exists.
1679 * If it doesn't, we reset this vt to auto mode and continue.
1680 * This is a cheap way to track process control. The worst thing
1681 * that can happen is: we send a signal to a process, it dies, and
1682 * the switch gets "lost" waiting for a response; hopefully, the
1683 * user will try again, we'll detect the process is gone (unless
1684 * the user waits just the right amount of time :-) and revert the
1685 * vt to auto control.
1686 */
1687 vc = vc_cons[fg_console].d;
1688 if (vc->vt_mode.mode == VT_PROCESS) {
1689 /*
1690 * Send the signal as privileged - kill_pid() will
1691 * tell us if the process has gone or something else
1692 * is awry.
1693 *
1694 * We need to set vt_newvt *before* sending the signal or we
1695 * have a race.
1696 */
1697 vc->vt_newvt = new_vc->vc_num;
1698 if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
1699 /*
1700 * It worked. Mark the vt to switch to and
1701 * return. The process needs to send us a
1702 * VT_RELDISP ioctl to complete the switch.
1703 */
1704 return;
1705 }
1706
1707 /*
1708 * The controlling process has died, so we revert back to
1709 * normal operation. In this case, we'll also change back
1710 * to KD_TEXT mode. I'm not sure if this is strictly correct
1711 * but it saves the agony when the X server dies and the screen
1712 * remains blanked due to KD_GRAPHICS! It would be nice to do
1713 * this outside of VT_PROCESS but there is no single process
1714 * to account for and tracking tty count may be undesirable.
1715 */
1716 reset_vc(vc);
1717
1718 /*
1719 * Fall through to normal (VT_AUTO) handling of the switch...
1720 */
1721 }
1722
1723 /*
1724 * Ignore all switches in KD_GRAPHICS+VT_AUTO mode
1725 */
1726 if (vc->vc_mode == KD_GRAPHICS)
1727 return;
1728
1729 complete_change_console(new_vc);
1730}
1731
1732/* Perform a kernel triggered VT switch for suspend/resume */
1733
1734static int disable_vt_switch;
1735
1736int vt_move_to_console(unsigned int vt, int alloc)
1737{
1738 int prev;
1739
1740 acquire_console_sem();
1741 /* Graphics mode - up to X */
1742 if (disable_vt_switch) {
1743 release_console_sem();
1744 return 0;
1745 }
1746 prev = fg_console;
1747
1748 if (alloc && vc_allocate(vt)) {
1749 /* we can't have a free VC for now. Too bad,
1750 * we don't want to mess the screen for now. */
1751 release_console_sem();
1752 return -ENOSPC;
1753 }
1754
1755 if (set_console(vt)) {
1756 /*
1757 * We're unable to switch to the SUSPEND_CONSOLE.
1758 * Let the calling function know so it can decide
1759 * what to do.
1760 */
1761 release_console_sem();
1762 return -EIO;
1763 }
1764 release_console_sem();
1765 tty_lock();
1766 if (vt_waitactive(vt + 1)) {
1767 pr_debug("Suspend: Can't switch VCs.");
1768 tty_unlock();
1769 return -EINTR;
1770 }
1771 tty_unlock();
1772 return prev;
1773}
1774
1775/*
1776 * Normally during a suspend, we allocate a new console and switch to it.
1777 * When we resume, we switch back to the original console. This switch
1778 * can be slow, so on systems where the framebuffer can handle restoration
1779 * of video registers anyways, there's little point in doing the console
1780 * switch. This function allows you to disable it by passing it '0'.
1781 */
1782void pm_set_vt_switch(int do_switch)
1783{
1784 acquire_console_sem();
1785 disable_vt_switch = !do_switch;
1786 release_console_sem();
1787}
1788EXPORT_SYMBOL(pm_set_vt_switch);