aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/vt
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/tty/vt
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/tty/vt')
-rw-r--r--drivers/tty/vt/.gitignore2
-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.c1453
-rw-r--r--drivers/tty/vt/selection.c345
-rw-r--r--drivers/tty/vt/vc_screen.c665
-rw-r--r--drivers/tty/vt/vt.c4226
-rw-r--r--drivers/tty/vt/vt_ioctl.c1800
11 files changed, 10180 insertions, 0 deletions
diff --git a/drivers/tty/vt/.gitignore b/drivers/tty/vt/.gitignore
new file mode 100644
index 000000000000..83683a2d8e6a
--- /dev/null
+++ b/drivers/tty/vt/.gitignore
@@ -0,0 +1,2 @@
1consolemap_deftbl.c
2defkeymap.c
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..3761ccf0f340
--- /dev/null
+++ b/drivers/tty/vt/keyboard.c
@@ -0,0 +1,1453 @@
1/*
2 * Written for linux by Johan Myreen as a translation from
3 * the assembly version by Linus (with diacriticals added)
4 *
5 * Some additional features added by Christoph Niemann (ChN), March 1993
6 *
7 * Loadable keymaps by Risto Kankkunen, May 1993
8 *
9 * Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
10 * Added decr/incr_console, dynamic keymaps, Unicode support,
11 * dynamic function/string keys, led setting, Sept 1994
12 * `Sticky' modifier keys, 951006.
13 *
14 * 11-11-96: SAK should now work in the raw mode (Martin Mares)
15 *
16 * Modified to provide 'generic' keyboard support by Hamish Macdonald
17 * Merge with the m68k keyboard driver and split-off of the PC low-level
18 * parts by Geert Uytterhoeven, May 1997
19 *
20 * 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
21 * 30-07-98: Dead keys redone, aeb@cwi.nl.
22 * 21-08-02: Converted to input API, major cleanup. (Vojtech Pavlik)
23 */
24
25#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
26
27#include <linux/consolemap.h>
28#include <linux/module.h>
29#include <linux/sched.h>
30#include <linux/tty.h>
31#include <linux/tty_flip.h>
32#include <linux/mm.h>
33#include <linux/string.h>
34#include <linux/init.h>
35#include <linux/slab.h>
36#include <linux/irq.h>
37
38#include <linux/kbd_kern.h>
39#include <linux/kbd_diacr.h>
40#include <linux/vt_kern.h>
41#include <linux/input.h>
42#include <linux/reboot.h>
43#include <linux/notifier.h>
44#include <linux/jiffies.h>
45
46extern void ctrl_alt_del(void);
47
48/*
49 * Exported functions/variables
50 */
51
52#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
53
54/*
55 * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
56 * This seems a good reason to start with NumLock off. On HIL keyboards
57 * of PARISC machines however there is no NumLock key and everyone expects the keypad
58 * to be used for numbers.
59 */
60
61#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
62#define KBD_DEFLEDS (1 << VC_NUMLOCK)
63#else
64#define KBD_DEFLEDS 0
65#endif
66
67#define KBD_DEFLOCK 0
68
69void compute_shiftstate(void);
70
71/*
72 * Handler Tables.
73 */
74
75#define K_HANDLERS\
76 k_self, k_fn, k_spec, k_pad,\
77 k_dead, k_cons, k_cur, k_shift,\
78 k_meta, k_ascii, k_lock, k_lowercase,\
79 k_slock, k_dead2, k_brl, k_ignore
80
81typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
82 char up_flag);
83static k_handler_fn K_HANDLERS;
84static k_handler_fn *k_handler[16] = { K_HANDLERS };
85
86#define FN_HANDLERS\
87 fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\
88 fn_show_state, fn_send_intr, fn_lastcons, fn_caps_toggle,\
89 fn_num, fn_hold, fn_scroll_forw, fn_scroll_back,\
90 fn_boot_it, fn_caps_on, fn_compose, fn_SAK,\
91 fn_dec_console, fn_inc_console, fn_spawn_con, fn_bare_num
92
93typedef void (fn_handler_fn)(struct vc_data *vc);
94static fn_handler_fn FN_HANDLERS;
95static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
96
97/*
98 * Variables exported for vt_ioctl.c
99 */
100
101/* maximum values each key_handler can handle */
102const int max_vals[] = {
103 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
104 NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
105 255, NR_LOCK - 1, 255, NR_BRL - 1
106};
107
108const int NR_TYPES = ARRAY_SIZE(max_vals);
109
110struct kbd_struct kbd_table[MAX_NR_CONSOLES];
111EXPORT_SYMBOL_GPL(kbd_table);
112static struct kbd_struct *kbd = kbd_table;
113
114struct vt_spawn_console vt_spawn_con = {
115 .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock),
116 .pid = NULL,
117 .sig = 0,
118};
119
120/*
121 * Variables exported for vt.c
122 */
123
124int shift_state = 0;
125
126/*
127 * Internal Data.
128 */
129
130static struct input_handler kbd_handler;
131static DEFINE_SPINLOCK(kbd_event_lock);
132static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
133static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
134static bool dead_key_next;
135static int npadch = -1; /* -1 or number assembled on pad */
136static unsigned int diacr;
137static char rep; /* flag telling character repeat */
138
139static unsigned char ledstate = 0xff; /* undefined */
140static unsigned char ledioctl;
141
142static struct ledptr {
143 unsigned int *addr;
144 unsigned int mask;
145 unsigned char valid:1;
146} ledptrs[3];
147
148/*
149 * Notifier list for console keyboard events
150 */
151static ATOMIC_NOTIFIER_HEAD(keyboard_notifier_list);
152
153int register_keyboard_notifier(struct notifier_block *nb)
154{
155 return atomic_notifier_chain_register(&keyboard_notifier_list, nb);
156}
157EXPORT_SYMBOL_GPL(register_keyboard_notifier);
158
159int unregister_keyboard_notifier(struct notifier_block *nb)
160{
161 return atomic_notifier_chain_unregister(&keyboard_notifier_list, nb);
162}
163EXPORT_SYMBOL_GPL(unregister_keyboard_notifier);
164
165/*
166 * Translation of scancodes to keycodes. We set them on only the first
167 * keyboard in the list that accepts the scancode and keycode.
168 * Explanation for not choosing the first attached keyboard anymore:
169 * USB keyboards for example have two event devices: one for all "normal"
170 * keys and one for extra function keys (like "volume up", "make coffee",
171 * etc.). So this means that scancodes for the extra function keys won't
172 * be valid for the first event device, but will be for the second.
173 */
174
175struct getset_keycode_data {
176 struct input_keymap_entry ke;
177 int error;
178};
179
180static int getkeycode_helper(struct input_handle *handle, void *data)
181{
182 struct getset_keycode_data *d = data;
183
184 d->error = input_get_keycode(handle->dev, &d->ke);
185
186 return d->error == 0; /* stop as soon as we successfully get one */
187}
188
189int getkeycode(unsigned int scancode)
190{
191 struct getset_keycode_data d = {
192 .ke = {
193 .flags = 0,
194 .len = sizeof(scancode),
195 .keycode = 0,
196 },
197 .error = -ENODEV,
198 };
199
200 memcpy(d.ke.scancode, &scancode, sizeof(scancode));
201
202 input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper);
203
204 return d.error ?: d.ke.keycode;
205}
206
207static int setkeycode_helper(struct input_handle *handle, void *data)
208{
209 struct getset_keycode_data *d = data;
210
211 d->error = input_set_keycode(handle->dev, &d->ke);
212
213 return d->error == 0; /* stop as soon as we successfully set one */
214}
215
216int setkeycode(unsigned int scancode, unsigned int keycode)
217{
218 struct getset_keycode_data d = {
219 .ke = {
220 .flags = 0,
221 .len = sizeof(scancode),
222 .keycode = keycode,
223 },
224 .error = -ENODEV,
225 };
226
227 memcpy(d.ke.scancode, &scancode, sizeof(scancode));
228
229 input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper);
230
231 return d.error;
232}
233
234/*
235 * Making beeps and bells. Note that we prefer beeps to bells, but when
236 * shutting the sound off we do both.
237 */
238
239static int kd_sound_helper(struct input_handle *handle, void *data)
240{
241 unsigned int *hz = data;
242 struct input_dev *dev = handle->dev;
243
244 if (test_bit(EV_SND, dev->evbit)) {
245 if (test_bit(SND_TONE, dev->sndbit)) {
246 input_inject_event(handle, EV_SND, SND_TONE, *hz);
247 if (*hz)
248 return 0;
249 }
250 if (test_bit(SND_BELL, dev->sndbit))
251 input_inject_event(handle, EV_SND, SND_BELL, *hz ? 1 : 0);
252 }
253
254 return 0;
255}
256
257static void kd_nosound(unsigned long ignored)
258{
259 static unsigned int zero;
260
261 input_handler_for_each_handle(&kbd_handler, &zero, kd_sound_helper);
262}
263
264static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0);
265
266void kd_mksound(unsigned int hz, unsigned int ticks)
267{
268 del_timer_sync(&kd_mksound_timer);
269
270 input_handler_for_each_handle(&kbd_handler, &hz, kd_sound_helper);
271
272 if (hz && ticks)
273 mod_timer(&kd_mksound_timer, jiffies + ticks);
274}
275EXPORT_SYMBOL(kd_mksound);
276
277/*
278 * Setting the keyboard rate.
279 */
280
281static int kbd_rate_helper(struct input_handle *handle, void *data)
282{
283 struct input_dev *dev = handle->dev;
284 struct kbd_repeat *rep = data;
285
286 if (test_bit(EV_REP, dev->evbit)) {
287
288 if (rep[0].delay > 0)
289 input_inject_event(handle,
290 EV_REP, REP_DELAY, rep[0].delay);
291 if (rep[0].period > 0)
292 input_inject_event(handle,
293 EV_REP, REP_PERIOD, rep[0].period);
294
295 rep[1].delay = dev->rep[REP_DELAY];
296 rep[1].period = dev->rep[REP_PERIOD];
297 }
298
299 return 0;
300}
301
302int kbd_rate(struct kbd_repeat *rep)
303{
304 struct kbd_repeat data[2] = { *rep };
305
306 input_handler_for_each_handle(&kbd_handler, data, kbd_rate_helper);
307 *rep = data[1]; /* Copy currently used settings */
308
309 return 0;
310}
311
312/*
313 * Helper Functions.
314 */
315static void put_queue(struct vc_data *vc, int ch)
316{
317 struct tty_struct *tty = vc->port.tty;
318
319 if (tty) {
320 tty_insert_flip_char(tty, ch, 0);
321 con_schedule_flip(tty);
322 }
323}
324
325static void puts_queue(struct vc_data *vc, char *cp)
326{
327 struct tty_struct *tty = vc->port.tty;
328
329 if (!tty)
330 return;
331
332 while (*cp) {
333 tty_insert_flip_char(tty, *cp, 0);
334 cp++;
335 }
336 con_schedule_flip(tty);
337}
338
339static void applkey(struct vc_data *vc, int key, char mode)
340{
341 static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
342
343 buf[1] = (mode ? 'O' : '[');
344 buf[2] = key;
345 puts_queue(vc, buf);
346}
347
348/*
349 * Many other routines do put_queue, but I think either
350 * they produce ASCII, or they produce some user-assigned
351 * string, and in both cases we might assume that it is
352 * in utf-8 already.
353 */
354static void to_utf8(struct vc_data *vc, uint c)
355{
356 if (c < 0x80)
357 /* 0******* */
358 put_queue(vc, c);
359 else if (c < 0x800) {
360 /* 110***** 10****** */
361 put_queue(vc, 0xc0 | (c >> 6));
362 put_queue(vc, 0x80 | (c & 0x3f));
363 } else if (c < 0x10000) {
364 if (c >= 0xD800 && c < 0xE000)
365 return;
366 if (c == 0xFFFF)
367 return;
368 /* 1110**** 10****** 10****** */
369 put_queue(vc, 0xe0 | (c >> 12));
370 put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
371 put_queue(vc, 0x80 | (c & 0x3f));
372 } else if (c < 0x110000) {
373 /* 11110*** 10****** 10****** 10****** */
374 put_queue(vc, 0xf0 | (c >> 18));
375 put_queue(vc, 0x80 | ((c >> 12) & 0x3f));
376 put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
377 put_queue(vc, 0x80 | (c & 0x3f));
378 }
379}
380
381/*
382 * Called after returning from RAW mode or when changing consoles - recompute
383 * shift_down[] and shift_state from key_down[] maybe called when keymap is
384 * undefined, so that shiftkey release is seen
385 */
386void compute_shiftstate(void)
387{
388 unsigned int i, j, k, sym, val;
389
390 shift_state = 0;
391 memset(shift_down, 0, sizeof(shift_down));
392
393 for (i = 0; i < ARRAY_SIZE(key_down); i++) {
394
395 if (!key_down[i])
396 continue;
397
398 k = i * BITS_PER_LONG;
399
400 for (j = 0; j < BITS_PER_LONG; j++, k++) {
401
402 if (!test_bit(k, key_down))
403 continue;
404
405 sym = U(key_maps[0][k]);
406 if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
407 continue;
408
409 val = KVAL(sym);
410 if (val == KVAL(K_CAPSSHIFT))
411 val = KVAL(K_SHIFT);
412
413 shift_down[val]++;
414 shift_state |= (1 << val);
415 }
416 }
417}
418
419/*
420 * We have a combining character DIACR here, followed by the character CH.
421 * If the combination occurs in the table, return the corresponding value.
422 * Otherwise, if CH is a space or equals DIACR, return DIACR.
423 * Otherwise, conclude that DIACR was not combining after all,
424 * queue it and return CH.
425 */
426static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch)
427{
428 unsigned int d = diacr;
429 unsigned int i;
430
431 diacr = 0;
432
433 if ((d & ~0xff) == BRL_UC_ROW) {
434 if ((ch & ~0xff) == BRL_UC_ROW)
435 return d | ch;
436 } else {
437 for (i = 0; i < accent_table_size; i++)
438 if (accent_table[i].diacr == d && accent_table[i].base == ch)
439 return accent_table[i].result;
440 }
441
442 if (ch == ' ' || ch == (BRL_UC_ROW|0) || ch == d)
443 return d;
444
445 if (kbd->kbdmode == VC_UNICODE)
446 to_utf8(vc, d);
447 else {
448 int c = conv_uni_to_8bit(d);
449 if (c != -1)
450 put_queue(vc, c);
451 }
452
453 return ch;
454}
455
456/*
457 * Special function handlers
458 */
459static void fn_enter(struct vc_data *vc)
460{
461 if (diacr) {
462 if (kbd->kbdmode == VC_UNICODE)
463 to_utf8(vc, diacr);
464 else {
465 int c = conv_uni_to_8bit(diacr);
466 if (c != -1)
467 put_queue(vc, c);
468 }
469 diacr = 0;
470 }
471
472 put_queue(vc, 13);
473 if (vc_kbd_mode(kbd, VC_CRLF))
474 put_queue(vc, 10);
475}
476
477static void fn_caps_toggle(struct vc_data *vc)
478{
479 if (rep)
480 return;
481
482 chg_vc_kbd_led(kbd, VC_CAPSLOCK);
483}
484
485static void fn_caps_on(struct vc_data *vc)
486{
487 if (rep)
488 return;
489
490 set_vc_kbd_led(kbd, VC_CAPSLOCK);
491}
492
493static void fn_show_ptregs(struct vc_data *vc)
494{
495 struct pt_regs *regs = get_irq_regs();
496
497 if (regs)
498 show_regs(regs);
499}
500
501static void fn_hold(struct vc_data *vc)
502{
503 struct tty_struct *tty = vc->port.tty;
504
505 if (rep || !tty)
506 return;
507
508 /*
509 * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty);
510 * these routines are also activated by ^S/^Q.
511 * (And SCROLLOCK can also be set by the ioctl KDSKBLED.)
512 */
513 if (tty->stopped)
514 start_tty(tty);
515 else
516 stop_tty(tty);
517}
518
519static void fn_num(struct vc_data *vc)
520{
521 if (vc_kbd_mode(kbd, VC_APPLIC))
522 applkey(vc, 'P', 1);
523 else
524 fn_bare_num(vc);
525}
526
527/*
528 * Bind this to Shift-NumLock if you work in application keypad mode
529 * but want to be able to change the NumLock flag.
530 * Bind this to NumLock if you prefer that the NumLock key always
531 * changes the NumLock flag.
532 */
533static void fn_bare_num(struct vc_data *vc)
534{
535 if (!rep)
536 chg_vc_kbd_led(kbd, VC_NUMLOCK);
537}
538
539static void fn_lastcons(struct vc_data *vc)
540{
541 /* switch to the last used console, ChN */
542 set_console(last_console);
543}
544
545static void fn_dec_console(struct vc_data *vc)
546{
547 int i, cur = fg_console;
548
549 /* Currently switching? Queue this next switch relative to that. */
550 if (want_console != -1)
551 cur = want_console;
552
553 for (i = cur - 1; i != cur; i--) {
554 if (i == -1)
555 i = MAX_NR_CONSOLES - 1;
556 if (vc_cons_allocated(i))
557 break;
558 }
559 set_console(i);
560}
561
562static void fn_inc_console(struct vc_data *vc)
563{
564 int i, cur = fg_console;
565
566 /* Currently switching? Queue this next switch relative to that. */
567 if (want_console != -1)
568 cur = want_console;
569
570 for (i = cur+1; i != cur; i++) {
571 if (i == MAX_NR_CONSOLES)
572 i = 0;
573 if (vc_cons_allocated(i))
574 break;
575 }
576 set_console(i);
577}
578
579static void fn_send_intr(struct vc_data *vc)
580{
581 struct tty_struct *tty = vc->port.tty;
582
583 if (!tty)
584 return;
585 tty_insert_flip_char(tty, 0, TTY_BREAK);
586 con_schedule_flip(tty);
587}
588
589static void fn_scroll_forw(struct vc_data *vc)
590{
591 scrollfront(vc, 0);
592}
593
594static void fn_scroll_back(struct vc_data *vc)
595{
596 scrollback(vc, 0);
597}
598
599static void fn_show_mem(struct vc_data *vc)
600{
601 show_mem(0);
602}
603
604static void fn_show_state(struct vc_data *vc)
605{
606 show_state();
607}
608
609static void fn_boot_it(struct vc_data *vc)
610{
611 ctrl_alt_del();
612}
613
614static void fn_compose(struct vc_data *vc)
615{
616 dead_key_next = true;
617}
618
619static void fn_spawn_con(struct vc_data *vc)
620{
621 spin_lock(&vt_spawn_con.lock);
622 if (vt_spawn_con.pid)
623 if (kill_pid(vt_spawn_con.pid, vt_spawn_con.sig, 1)) {
624 put_pid(vt_spawn_con.pid);
625 vt_spawn_con.pid = NULL;
626 }
627 spin_unlock(&vt_spawn_con.lock);
628}
629
630static void fn_SAK(struct vc_data *vc)
631{
632 struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
633 schedule_work(SAK_work);
634}
635
636static void fn_null(struct vc_data *vc)
637{
638 compute_shiftstate();
639}
640
641/*
642 * Special key handlers
643 */
644static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag)
645{
646}
647
648static void k_spec(struct vc_data *vc, unsigned char value, char up_flag)
649{
650 if (up_flag)
651 return;
652 if (value >= ARRAY_SIZE(fn_handler))
653 return;
654 if ((kbd->kbdmode == VC_RAW ||
655 kbd->kbdmode == VC_MEDIUMRAW ||
656 kbd->kbdmode == VC_OFF) &&
657 value != KVAL(K_SAK))
658 return; /* SAK is allowed even in raw mode */
659 fn_handler[value](vc);
660}
661
662static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag)
663{
664 pr_err("k_lowercase was called - impossible\n");
665}
666
667static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag)
668{
669 if (up_flag)
670 return; /* no action, if this is a key release */
671
672 if (diacr)
673 value = handle_diacr(vc, value);
674
675 if (dead_key_next) {
676 dead_key_next = false;
677 diacr = value;
678 return;
679 }
680 if (kbd->kbdmode == VC_UNICODE)
681 to_utf8(vc, value);
682 else {
683 int c = conv_uni_to_8bit(value);
684 if (c != -1)
685 put_queue(vc, c);
686 }
687}
688
689/*
690 * Handle dead key. Note that we now may have several
691 * dead keys modifying the same character. Very useful
692 * for Vietnamese.
693 */
694static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag)
695{
696 if (up_flag)
697 return;
698
699 diacr = (diacr ? handle_diacr(vc, value) : value);
700}
701
702static void k_self(struct vc_data *vc, unsigned char value, char up_flag)
703{
704 k_unicode(vc, conv_8bit_to_uni(value), up_flag);
705}
706
707static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag)
708{
709 k_deadunicode(vc, value, up_flag);
710}
711
712/*
713 * Obsolete - for backwards compatibility only
714 */
715static void k_dead(struct vc_data *vc, unsigned char value, char up_flag)
716{
717 static const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' };
718
719 k_deadunicode(vc, ret_diacr[value], up_flag);
720}
721
722static void k_cons(struct vc_data *vc, unsigned char value, char up_flag)
723{
724 if (up_flag)
725 return;
726
727 set_console(value);
728}
729
730static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
731{
732 if (up_flag)
733 return;
734
735 if ((unsigned)value < ARRAY_SIZE(func_table)) {
736 if (func_table[value])
737 puts_queue(vc, func_table[value]);
738 } else
739 pr_err("k_fn called with value=%d\n", value);
740}
741
742static void k_cur(struct vc_data *vc, unsigned char value, char up_flag)
743{
744 static const char cur_chars[] = "BDCA";
745
746 if (up_flag)
747 return;
748
749 applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE));
750}
751
752static void k_pad(struct vc_data *vc, unsigned char value, char up_flag)
753{
754 static const char pad_chars[] = "0123456789+-*/\015,.?()#";
755 static const char app_map[] = "pqrstuvwxylSRQMnnmPQS";
756
757 if (up_flag)
758 return; /* no action, if this is a key release */
759
760 /* kludge... shift forces cursor/number keys */
761 if (vc_kbd_mode(kbd, VC_APPLIC) && !shift_down[KG_SHIFT]) {
762 applkey(vc, app_map[value], 1);
763 return;
764 }
765
766 if (!vc_kbd_led(kbd, VC_NUMLOCK)) {
767
768 switch (value) {
769 case KVAL(K_PCOMMA):
770 case KVAL(K_PDOT):
771 k_fn(vc, KVAL(K_REMOVE), 0);
772 return;
773 case KVAL(K_P0):
774 k_fn(vc, KVAL(K_INSERT), 0);
775 return;
776 case KVAL(K_P1):
777 k_fn(vc, KVAL(K_SELECT), 0);
778 return;
779 case KVAL(K_P2):
780 k_cur(vc, KVAL(K_DOWN), 0);
781 return;
782 case KVAL(K_P3):
783 k_fn(vc, KVAL(K_PGDN), 0);
784 return;
785 case KVAL(K_P4):
786 k_cur(vc, KVAL(K_LEFT), 0);
787 return;
788 case KVAL(K_P6):
789 k_cur(vc, KVAL(K_RIGHT), 0);
790 return;
791 case KVAL(K_P7):
792 k_fn(vc, KVAL(K_FIND), 0);
793 return;
794 case KVAL(K_P8):
795 k_cur(vc, KVAL(K_UP), 0);
796 return;
797 case KVAL(K_P9):
798 k_fn(vc, KVAL(K_PGUP), 0);
799 return;
800 case KVAL(K_P5):
801 applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC));
802 return;
803 }
804 }
805
806 put_queue(vc, pad_chars[value]);
807 if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
808 put_queue(vc, 10);
809}
810
811static void k_shift(struct vc_data *vc, unsigned char value, char up_flag)
812{
813 int old_state = shift_state;
814
815 if (rep)
816 return;
817 /*
818 * Mimic typewriter:
819 * a CapsShift key acts like Shift but undoes CapsLock
820 */
821 if (value == KVAL(K_CAPSSHIFT)) {
822 value = KVAL(K_SHIFT);
823 if (!up_flag)
824 clr_vc_kbd_led(kbd, VC_CAPSLOCK);
825 }
826
827 if (up_flag) {
828 /*
829 * handle the case that two shift or control
830 * keys are depressed simultaneously
831 */
832 if (shift_down[value])
833 shift_down[value]--;
834 } else
835 shift_down[value]++;
836
837 if (shift_down[value])
838 shift_state |= (1 << value);
839 else
840 shift_state &= ~(1 << value);
841
842 /* kludge */
843 if (up_flag && shift_state != old_state && npadch != -1) {
844 if (kbd->kbdmode == VC_UNICODE)
845 to_utf8(vc, npadch);
846 else
847 put_queue(vc, npadch & 0xff);
848 npadch = -1;
849 }
850}
851
852static void k_meta(struct vc_data *vc, unsigned char value, char up_flag)
853{
854 if (up_flag)
855 return;
856
857 if (vc_kbd_mode(kbd, VC_META)) {
858 put_queue(vc, '\033');
859 put_queue(vc, value);
860 } else
861 put_queue(vc, value | 0x80);
862}
863
864static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag)
865{
866 int base;
867
868 if (up_flag)
869 return;
870
871 if (value < 10) {
872 /* decimal input of code, while Alt depressed */
873 base = 10;
874 } else {
875 /* hexadecimal input of code, while AltGr depressed */
876 value -= 10;
877 base = 16;
878 }
879
880 if (npadch == -1)
881 npadch = value;
882 else
883 npadch = npadch * base + value;
884}
885
886static void k_lock(struct vc_data *vc, unsigned char value, char up_flag)
887{
888 if (up_flag || rep)
889 return;
890
891 chg_vc_kbd_lock(kbd, value);
892}
893
894static void k_slock(struct vc_data *vc, unsigned char value, char up_flag)
895{
896 k_shift(vc, value, up_flag);
897 if (up_flag || rep)
898 return;
899
900 chg_vc_kbd_slock(kbd, value);
901 /* try to make Alt, oops, AltGr and such work */
902 if (!key_maps[kbd->lockstate ^ kbd->slockstate]) {
903 kbd->slockstate = 0;
904 chg_vc_kbd_slock(kbd, value);
905 }
906}
907
908/* by default, 300ms interval for combination release */
909static unsigned brl_timeout = 300;
910MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for commit on first key release)");
911module_param(brl_timeout, uint, 0644);
912
913static unsigned brl_nbchords = 1;
914MODULE_PARM_DESC(brl_nbchords, "Number of chords that produce a braille pattern (0 for dead chords)");
915module_param(brl_nbchords, uint, 0644);
916
917static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag)
918{
919 static unsigned long chords;
920 static unsigned committed;
921
922 if (!brl_nbchords)
923 k_deadunicode(vc, BRL_UC_ROW | pattern, up_flag);
924 else {
925 committed |= pattern;
926 chords++;
927 if (chords == brl_nbchords) {
928 k_unicode(vc, BRL_UC_ROW | committed, up_flag);
929 chords = 0;
930 committed = 0;
931 }
932 }
933}
934
935static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
936{
937 static unsigned pressed, committing;
938 static unsigned long releasestart;
939
940 if (kbd->kbdmode != VC_UNICODE) {
941 if (!up_flag)
942 pr_warning("keyboard mode must be unicode for braille patterns\n");
943 return;
944 }
945
946 if (!value) {
947 k_unicode(vc, BRL_UC_ROW, up_flag);
948 return;
949 }
950
951 if (value > 8)
952 return;
953
954 if (!up_flag) {
955 pressed |= 1 << (value - 1);
956 if (!brl_timeout)
957 committing = pressed;
958 } else if (brl_timeout) {
959 if (!committing ||
960 time_after(jiffies,
961 releasestart + msecs_to_jiffies(brl_timeout))) {
962 committing = pressed;
963 releasestart = jiffies;
964 }
965 pressed &= ~(1 << (value - 1));
966 if (!pressed && committing) {
967 k_brlcommit(vc, committing, 0);
968 committing = 0;
969 }
970 } else {
971 if (committing) {
972 k_brlcommit(vc, committing, 0);
973 committing = 0;
974 }
975 pressed &= ~(1 << (value - 1));
976 }
977}
978
979/*
980 * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
981 * or (ii) whatever pattern of lights people want to show using KDSETLED,
982 * or (iii) specified bits of specified words in kernel memory.
983 */
984unsigned char getledstate(void)
985{
986 return ledstate;
987}
988
989void setledstate(struct kbd_struct *kbd, unsigned int led)
990{
991 if (!(led & ~7)) {
992 ledioctl = led;
993 kbd->ledmode = LED_SHOW_IOCTL;
994 } else
995 kbd->ledmode = LED_SHOW_FLAGS;
996
997 set_leds();
998}
999
1000static inline unsigned char getleds(void)
1001{
1002 struct kbd_struct *kbd = kbd_table + fg_console;
1003 unsigned char leds;
1004 int i;
1005
1006 if (kbd->ledmode == LED_SHOW_IOCTL)
1007 return ledioctl;
1008
1009 leds = kbd->ledflagstate;
1010
1011 if (kbd->ledmode == LED_SHOW_MEM) {
1012 for (i = 0; i < 3; i++)
1013 if (ledptrs[i].valid) {
1014 if (*ledptrs[i].addr & ledptrs[i].mask)
1015 leds |= (1 << i);
1016 else
1017 leds &= ~(1 << i);
1018 }
1019 }
1020 return leds;
1021}
1022
1023static int kbd_update_leds_helper(struct input_handle *handle, void *data)
1024{
1025 unsigned char leds = *(unsigned char *)data;
1026
1027 if (test_bit(EV_LED, handle->dev->evbit)) {
1028 input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
1029 input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
1030 input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
1031 input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
1032 }
1033
1034 return 0;
1035}
1036
1037/*
1038 * This is the tasklet that updates LED state on all keyboards
1039 * attached to the box. The reason we use tasklet is that we
1040 * need to handle the scenario when keyboard handler is not
1041 * registered yet but we already getting updates form VT to
1042 * update led state.
1043 */
1044static void kbd_bh(unsigned long dummy)
1045{
1046 unsigned char leds = getleds();
1047
1048 if (leds != ledstate) {
1049 input_handler_for_each_handle(&kbd_handler, &leds,
1050 kbd_update_leds_helper);
1051 ledstate = leds;
1052 }
1053}
1054
1055DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
1056
1057#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
1058 defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
1059 defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
1060 (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC)) ||\
1061 defined(CONFIG_AVR32)
1062
1063#define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
1064 ((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
1065
1066static const unsigned short x86_keycodes[256] =
1067 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1068 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1069 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
1070 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
1071 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
1072 80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92,
1073 284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339,
1074 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349,
1075 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355,
1076 103,104,105,275,287,279,258,106,274,107,294,364,358,363,362,361,
1077 291,108,381,281,290,272,292,305,280, 99,112,257,306,359,113,114,
1078 264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116,
1079 377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307,
1080 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
1081 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 };
1082
1083#ifdef CONFIG_SPARC
1084static int sparc_l1_a_state;
1085extern void sun_do_break(void);
1086#endif
1087
1088static int emulate_raw(struct vc_data *vc, unsigned int keycode,
1089 unsigned char up_flag)
1090{
1091 int code;
1092
1093 switch (keycode) {
1094
1095 case KEY_PAUSE:
1096 put_queue(vc, 0xe1);
1097 put_queue(vc, 0x1d | up_flag);
1098 put_queue(vc, 0x45 | up_flag);
1099 break;
1100
1101 case KEY_HANGEUL:
1102 if (!up_flag)
1103 put_queue(vc, 0xf2);
1104 break;
1105
1106 case KEY_HANJA:
1107 if (!up_flag)
1108 put_queue(vc, 0xf1);
1109 break;
1110
1111 case KEY_SYSRQ:
1112 /*
1113 * Real AT keyboards (that's what we're trying
1114 * to emulate here emit 0xe0 0x2a 0xe0 0x37 when
1115 * pressing PrtSc/SysRq alone, but simply 0x54
1116 * when pressing Alt+PrtSc/SysRq.
1117 */
1118 if (test_bit(KEY_LEFTALT, key_down) ||
1119 test_bit(KEY_RIGHTALT, key_down)) {
1120 put_queue(vc, 0x54 | up_flag);
1121 } else {
1122 put_queue(vc, 0xe0);
1123 put_queue(vc, 0x2a | up_flag);
1124 put_queue(vc, 0xe0);
1125 put_queue(vc, 0x37 | up_flag);
1126 }
1127 break;
1128
1129 default:
1130 if (keycode > 255)
1131 return -1;
1132
1133 code = x86_keycodes[keycode];
1134 if (!code)
1135 return -1;
1136
1137 if (code & 0x100)
1138 put_queue(vc, 0xe0);
1139 put_queue(vc, (code & 0x7f) | up_flag);
1140
1141 break;
1142 }
1143
1144 return 0;
1145}
1146
1147#else
1148
1149#define HW_RAW(dev) 0
1150
1151static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
1152{
1153 if (keycode > 127)
1154 return -1;
1155
1156 put_queue(vc, keycode | up_flag);
1157 return 0;
1158}
1159#endif
1160
1161static void kbd_rawcode(unsigned char data)
1162{
1163 struct vc_data *vc = vc_cons[fg_console].d;
1164
1165 kbd = kbd_table + vc->vc_num;
1166 if (kbd->kbdmode == VC_RAW)
1167 put_queue(vc, data);
1168}
1169
1170static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
1171{
1172 struct vc_data *vc = vc_cons[fg_console].d;
1173 unsigned short keysym, *key_map;
1174 unsigned char type;
1175 bool raw_mode;
1176 struct tty_struct *tty;
1177 int shift_final;
1178 struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down };
1179 int rc;
1180
1181 tty = vc->port.tty;
1182
1183 if (tty && (!tty->driver_data)) {
1184 /* No driver data? Strange. Okay we fix it then. */
1185 tty->driver_data = vc;
1186 }
1187
1188 kbd = kbd_table + vc->vc_num;
1189
1190#ifdef CONFIG_SPARC
1191 if (keycode == KEY_STOP)
1192 sparc_l1_a_state = down;
1193#endif
1194
1195 rep = (down == 2);
1196
1197 raw_mode = (kbd->kbdmode == VC_RAW);
1198 if (raw_mode && !hw_raw)
1199 if (emulate_raw(vc, keycode, !down << 7))
1200 if (keycode < BTN_MISC && printk_ratelimit())
1201 pr_warning("can't emulate rawmode for keycode %d\n",
1202 keycode);
1203
1204#ifdef CONFIG_SPARC
1205 if (keycode == KEY_A && sparc_l1_a_state) {
1206 sparc_l1_a_state = false;
1207 sun_do_break();
1208 }
1209#endif
1210
1211 if (kbd->kbdmode == VC_MEDIUMRAW) {
1212 /*
1213 * This is extended medium raw mode, with keys above 127
1214 * encoded as 0, high 7 bits, low 7 bits, with the 0 bearing
1215 * the 'up' flag if needed. 0 is reserved, so this shouldn't
1216 * interfere with anything else. The two bytes after 0 will
1217 * always have the up flag set not to interfere with older
1218 * applications. This allows for 16384 different keycodes,
1219 * which should be enough.
1220 */
1221 if (keycode < 128) {
1222 put_queue(vc, keycode | (!down << 7));
1223 } else {
1224 put_queue(vc, !down << 7);
1225 put_queue(vc, (keycode >> 7) | 0x80);
1226 put_queue(vc, keycode | 0x80);
1227 }
1228 raw_mode = true;
1229 }
1230
1231 if (down)
1232 set_bit(keycode, key_down);
1233 else
1234 clear_bit(keycode, key_down);
1235
1236 if (rep &&
1237 (!vc_kbd_mode(kbd, VC_REPEAT) ||
1238 (tty && !L_ECHO(tty) && tty_chars_in_buffer(tty)))) {
1239 /*
1240 * Don't repeat a key if the input buffers are not empty and the
1241 * characters get aren't echoed locally. This makes key repeat
1242 * usable with slow applications and under heavy loads.
1243 */
1244 return;
1245 }
1246
1247 param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
1248 param.ledstate = kbd->ledflagstate;
1249 key_map = key_maps[shift_final];
1250
1251 rc = atomic_notifier_call_chain(&keyboard_notifier_list,
1252 KBD_KEYCODE, &param);
1253 if (rc == NOTIFY_STOP || !key_map) {
1254 atomic_notifier_call_chain(&keyboard_notifier_list,
1255 KBD_UNBOUND_KEYCODE, &param);
1256 compute_shiftstate();
1257 kbd->slockstate = 0;
1258 return;
1259 }
1260
1261 if (keycode < NR_KEYS)
1262 keysym = key_map[keycode];
1263 else if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
1264 keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1));
1265 else
1266 return;
1267
1268 type = KTYP(keysym);
1269
1270 if (type < 0xf0) {
1271 param.value = keysym;
1272 rc = atomic_notifier_call_chain(&keyboard_notifier_list,
1273 KBD_UNICODE, &param);
1274 if (rc != NOTIFY_STOP)
1275 if (down && !raw_mode)
1276 to_utf8(vc, keysym);
1277 return;
1278 }
1279
1280 type -= 0xf0;
1281
1282 if (type == KT_LETTER) {
1283 type = KT_LATIN;
1284 if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
1285 key_map = key_maps[shift_final ^ (1 << KG_SHIFT)];
1286 if (key_map)
1287 keysym = key_map[keycode];
1288 }
1289 }
1290
1291 param.value = keysym;
1292 rc = atomic_notifier_call_chain(&keyboard_notifier_list,
1293 KBD_KEYSYM, &param);
1294 if (rc == NOTIFY_STOP)
1295 return;
1296
1297 if ((raw_mode || kbd->kbdmode == VC_OFF) && type != KT_SPEC && type != KT_SHIFT)
1298 return;
1299
1300 (*k_handler[type])(vc, keysym & 0xff, !down);
1301
1302 param.ledstate = kbd->ledflagstate;
1303 atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, &param);
1304
1305 if (type != KT_SLOCK)
1306 kbd->slockstate = 0;
1307}
1308
1309static void kbd_event(struct input_handle *handle, unsigned int event_type,
1310 unsigned int event_code, int value)
1311{
1312 /* We are called with interrupts disabled, just take the lock */
1313 spin_lock(&kbd_event_lock);
1314
1315 if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
1316 kbd_rawcode(value);
1317 if (event_type == EV_KEY)
1318 kbd_keycode(event_code, value, HW_RAW(handle->dev));
1319
1320 spin_unlock(&kbd_event_lock);
1321
1322 tasklet_schedule(&keyboard_tasklet);
1323 do_poke_blanked_console = 1;
1324 schedule_console_callback();
1325}
1326
1327static bool kbd_match(struct input_handler *handler, struct input_dev *dev)
1328{
1329 int i;
1330
1331 if (test_bit(EV_SND, dev->evbit))
1332 return true;
1333
1334 if (test_bit(EV_KEY, dev->evbit)) {
1335 for (i = KEY_RESERVED; i < BTN_MISC; i++)
1336 if (test_bit(i, dev->keybit))
1337 return true;
1338 for (i = KEY_BRL_DOT1; i <= KEY_BRL_DOT10; i++)
1339 if (test_bit(i, dev->keybit))
1340 return true;
1341 }
1342
1343 return false;
1344}
1345
1346/*
1347 * When a keyboard (or other input device) is found, the kbd_connect
1348 * function is called. The function then looks at the device, and if it
1349 * likes it, it can open it and get events from it. In this (kbd_connect)
1350 * function, we should decide which VT to bind that keyboard to initially.
1351 */
1352static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
1353 const struct input_device_id *id)
1354{
1355 struct input_handle *handle;
1356 int error;
1357
1358 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
1359 if (!handle)
1360 return -ENOMEM;
1361
1362 handle->dev = dev;
1363 handle->handler = handler;
1364 handle->name = "kbd";
1365
1366 error = input_register_handle(handle);
1367 if (error)
1368 goto err_free_handle;
1369
1370 error = input_open_device(handle);
1371 if (error)
1372 goto err_unregister_handle;
1373
1374 return 0;
1375
1376 err_unregister_handle:
1377 input_unregister_handle(handle);
1378 err_free_handle:
1379 kfree(handle);
1380 return error;
1381}
1382
1383static void kbd_disconnect(struct input_handle *handle)
1384{
1385 input_close_device(handle);
1386 input_unregister_handle(handle);
1387 kfree(handle);
1388}
1389
1390/*
1391 * Start keyboard handler on the new keyboard by refreshing LED state to
1392 * match the rest of the system.
1393 */
1394static void kbd_start(struct input_handle *handle)
1395{
1396 tasklet_disable(&keyboard_tasklet);
1397
1398 if (ledstate != 0xff)
1399 kbd_update_leds_helper(handle, &ledstate);
1400
1401 tasklet_enable(&keyboard_tasklet);
1402}
1403
1404static const struct input_device_id kbd_ids[] = {
1405 {
1406 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
1407 .evbit = { BIT_MASK(EV_KEY) },
1408 },
1409
1410 {
1411 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
1412 .evbit = { BIT_MASK(EV_SND) },
1413 },
1414
1415 { }, /* Terminating entry */
1416};
1417
1418MODULE_DEVICE_TABLE(input, kbd_ids);
1419
1420static struct input_handler kbd_handler = {
1421 .event = kbd_event,
1422 .match = kbd_match,
1423 .connect = kbd_connect,
1424 .disconnect = kbd_disconnect,
1425 .start = kbd_start,
1426 .name = "kbd",
1427 .id_table = kbd_ids,
1428};
1429
1430int __init kbd_init(void)
1431{
1432 int i;
1433 int error;
1434
1435 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1436 kbd_table[i].ledflagstate = KBD_DEFLEDS;
1437 kbd_table[i].default_ledflagstate = KBD_DEFLEDS;
1438 kbd_table[i].ledmode = LED_SHOW_FLAGS;
1439 kbd_table[i].lockstate = KBD_DEFLOCK;
1440 kbd_table[i].slockstate = 0;
1441 kbd_table[i].modeflags = KBD_DEFMODE;
1442 kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
1443 }
1444
1445 error = input_register_handler(&kbd_handler);
1446 if (error)
1447 return error;
1448
1449 tasklet_enable(&keyboard_tasklet);
1450 tasklet_schedule(&keyboard_tasklet);
1451
1452 return 0;
1453}
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c
new file mode 100644
index 000000000000..fb864e7fcd13
--- /dev/null
+++ b/drivers/tty/vt/selection.c
@@ -0,0 +1,345 @@
1/*
2 * This module exports the functions:
3 *
4 * 'int set_selection(struct tiocl_selection __user *, struct tty_struct *)'
5 * 'void clear_selection(void)'
6 * 'int paste_selection(struct tty_struct *)'
7 * 'int sel_loadlut(char __user *)'
8 *
9 * Now that /dev/vcs exists, most of this can disappear again.
10 */
11
12#include <linux/module.h>
13#include <linux/tty.h>
14#include <linux/sched.h>
15#include <linux/mm.h>
16#include <linux/slab.h>
17#include <linux/types.h>
18
19#include <asm/uaccess.h>
20
21#include <linux/kbd_kern.h>
22#include <linux/vt_kern.h>
23#include <linux/consolemap.h>
24#include <linux/selection.h>
25#include <linux/tiocl.h>
26#include <linux/console.h>
27
28/* Don't take this from <ctype.h>: 011-015 on the screen aren't spaces */
29#define isspace(c) ((c) == ' ')
30
31extern void poke_blanked_console(void);
32
33/* Variables for selection control. */
34/* Use a dynamic buffer, instead of static (Dec 1994) */
35struct vc_data *sel_cons; /* must not be deallocated */
36static int use_unicode;
37static volatile int sel_start = -1; /* cleared by clear_selection */
38static int sel_end;
39static int sel_buffer_lth;
40static char *sel_buffer;
41
42/* clear_selection, highlight and highlight_pointer can be called
43 from interrupt (via scrollback/front) */
44
45/* set reverse video on characters s-e of console with selection. */
46static inline void highlight(const int s, const int e)
47{
48 invert_screen(sel_cons, s, e-s+2, 1);
49}
50
51/* use complementary color to show the pointer */
52static inline void highlight_pointer(const int where)
53{
54 complement_pos(sel_cons, where);
55}
56
57static u16
58sel_pos(int n)
59{
60 return inverse_translate(sel_cons, screen_glyph(sel_cons, n),
61 use_unicode);
62}
63
64/* remove the current selection highlight, if any,
65 from the console holding the selection. */
66void
67clear_selection(void) {
68 highlight_pointer(-1); /* hide the pointer */
69 if (sel_start != -1) {
70 highlight(sel_start, sel_end);
71 sel_start = -1;
72 }
73}
74
75/*
76 * User settable table: what characters are to be considered alphabetic?
77 * 256 bits
78 */
79static u32 inwordLut[8]={
80 0x00000000, /* control chars */
81 0x03FF0000, /* digits */
82 0x87FFFFFE, /* uppercase and '_' */
83 0x07FFFFFE, /* lowercase */
84 0x00000000,
85 0x00000000,
86 0xFF7FFFFF, /* latin-1 accented letters, not multiplication sign */
87 0xFF7FFFFF /* latin-1 accented letters, not division sign */
88};
89
90static inline int inword(const u16 c) {
91 return c > 0xff || (( inwordLut[c>>5] >> (c & 0x1F) ) & 1);
92}
93
94/* set inwordLut contents. Invoked by ioctl(). */
95int sel_loadlut(char __user *p)
96{
97 return copy_from_user(inwordLut, (u32 __user *)(p+4), 32) ? -EFAULT : 0;
98}
99
100/* does screen address p correspond to character at LH/RH edge of screen? */
101static inline int atedge(const int p, int size_row)
102{
103 return (!(p % size_row) || !((p + 2) % size_row));
104}
105
106/* constrain v such that v <= u */
107static inline unsigned short limit(const unsigned short v, const unsigned short u)
108{
109 return (v > u) ? u : v;
110}
111
112/* stores the char in UTF8 and returns the number of bytes used (1-3) */
113static int store_utf8(u16 c, char *p)
114{
115 if (c < 0x80) {
116 /* 0******* */
117 p[0] = c;
118 return 1;
119 } else if (c < 0x800) {
120 /* 110***** 10****** */
121 p[0] = 0xc0 | (c >> 6);
122 p[1] = 0x80 | (c & 0x3f);
123 return 2;
124 } else {
125 /* 1110**** 10****** 10****** */
126 p[0] = 0xe0 | (c >> 12);
127 p[1] = 0x80 | ((c >> 6) & 0x3f);
128 p[2] = 0x80 | (c & 0x3f);
129 return 3;
130 }
131}
132
133/* set the current selection. Invoked by ioctl() or by kernel code. */
134int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty)
135{
136 struct vc_data *vc = vc_cons[fg_console].d;
137 int sel_mode, new_sel_start, new_sel_end, spc;
138 char *bp, *obp;
139 int i, ps, pe, multiplier;
140 u16 c;
141 struct kbd_struct *kbd = kbd_table + fg_console;
142
143 poke_blanked_console();
144
145 { unsigned short xs, ys, xe, ye;
146
147 if (!access_ok(VERIFY_READ, sel, sizeof(*sel)))
148 return -EFAULT;
149 __get_user(xs, &sel->xs);
150 __get_user(ys, &sel->ys);
151 __get_user(xe, &sel->xe);
152 __get_user(ye, &sel->ye);
153 __get_user(sel_mode, &sel->sel_mode);
154 xs--; ys--; xe--; ye--;
155 xs = limit(xs, vc->vc_cols - 1);
156 ys = limit(ys, vc->vc_rows - 1);
157 xe = limit(xe, vc->vc_cols - 1);
158 ye = limit(ye, vc->vc_rows - 1);
159 ps = ys * vc->vc_size_row + (xs << 1);
160 pe = ye * vc->vc_size_row + (xe << 1);
161
162 if (sel_mode == TIOCL_SELCLEAR) {
163 /* useful for screendump without selection highlights */
164 clear_selection();
165 return 0;
166 }
167
168 if (mouse_reporting() && (sel_mode & TIOCL_SELMOUSEREPORT)) {
169 mouse_report(tty, sel_mode & TIOCL_SELBUTTONMASK, xs, ys);
170 return 0;
171 }
172 }
173
174 if (ps > pe) /* make sel_start <= sel_end */
175 {
176 int tmp = ps;
177 ps = pe;
178 pe = tmp;
179 }
180
181 if (sel_cons != vc_cons[fg_console].d) {
182 clear_selection();
183 sel_cons = vc_cons[fg_console].d;
184 }
185 use_unicode = kbd && kbd->kbdmode == VC_UNICODE;
186
187 switch (sel_mode)
188 {
189 case TIOCL_SELCHAR: /* character-by-character selection */
190 new_sel_start = ps;
191 new_sel_end = pe;
192 break;
193 case TIOCL_SELWORD: /* word-by-word selection */
194 spc = isspace(sel_pos(ps));
195 for (new_sel_start = ps; ; ps -= 2)
196 {
197 if ((spc && !isspace(sel_pos(ps))) ||
198 (!spc && !inword(sel_pos(ps))))
199 break;
200 new_sel_start = ps;
201 if (!(ps % vc->vc_size_row))
202 break;
203 }
204 spc = isspace(sel_pos(pe));
205 for (new_sel_end = pe; ; pe += 2)
206 {
207 if ((spc && !isspace(sel_pos(pe))) ||
208 (!spc && !inword(sel_pos(pe))))
209 break;
210 new_sel_end = pe;
211 if (!((pe + 2) % vc->vc_size_row))
212 break;
213 }
214 break;
215 case TIOCL_SELLINE: /* line-by-line selection */
216 new_sel_start = ps - ps % vc->vc_size_row;
217 new_sel_end = pe + vc->vc_size_row
218 - pe % vc->vc_size_row - 2;
219 break;
220 case TIOCL_SELPOINTER:
221 highlight_pointer(pe);
222 return 0;
223 default:
224 return -EINVAL;
225 }
226
227 /* remove the pointer */
228 highlight_pointer(-1);
229
230 /* select to end of line if on trailing space */
231 if (new_sel_end > new_sel_start &&
232 !atedge(new_sel_end, vc->vc_size_row) &&
233 isspace(sel_pos(new_sel_end))) {
234 for (pe = new_sel_end + 2; ; pe += 2)
235 if (!isspace(sel_pos(pe)) ||
236 atedge(pe, vc->vc_size_row))
237 break;
238 if (isspace(sel_pos(pe)))
239 new_sel_end = pe;
240 }
241 if (sel_start == -1) /* no current selection */
242 highlight(new_sel_start, new_sel_end);
243 else if (new_sel_start == sel_start)
244 {
245 if (new_sel_end == sel_end) /* no action required */
246 return 0;
247 else if (new_sel_end > sel_end) /* extend to right */
248 highlight(sel_end + 2, new_sel_end);
249 else /* contract from right */
250 highlight(new_sel_end + 2, sel_end);
251 }
252 else if (new_sel_end == sel_end)
253 {
254 if (new_sel_start < sel_start) /* extend to left */
255 highlight(new_sel_start, sel_start - 2);
256 else /* contract from left */
257 highlight(sel_start, new_sel_start - 2);
258 }
259 else /* some other case; start selection from scratch */
260 {
261 clear_selection();
262 highlight(new_sel_start, new_sel_end);
263 }
264 sel_start = new_sel_start;
265 sel_end = new_sel_end;
266
267 /* Allocate a new buffer before freeing the old one ... */
268 multiplier = use_unicode ? 3 : 1; /* chars can take up to 3 bytes */
269 bp = kmalloc(((sel_end-sel_start)/2+1)*multiplier, GFP_KERNEL);
270 if (!bp) {
271 printk(KERN_WARNING "selection: kmalloc() failed\n");
272 clear_selection();
273 return -ENOMEM;
274 }
275 kfree(sel_buffer);
276 sel_buffer = bp;
277
278 obp = bp;
279 for (i = sel_start; i <= sel_end; i += 2) {
280 c = sel_pos(i);
281 if (use_unicode)
282 bp += store_utf8(c, bp);
283 else
284 *bp++ = c;
285 if (!isspace(c))
286 obp = bp;
287 if (! ((i + 2) % vc->vc_size_row)) {
288 /* strip trailing blanks from line and add newline,
289 unless non-space at end of line. */
290 if (obp != bp) {
291 bp = obp;
292 *bp++ = '\r';
293 }
294 obp = bp;
295 }
296 }
297 sel_buffer_lth = bp - sel_buffer;
298 return 0;
299}
300
301/* Insert the contents of the selection buffer into the
302 * queue of the tty associated with the current console.
303 * Invoked by ioctl().
304 */
305int paste_selection(struct tty_struct *tty)
306{
307 struct vc_data *vc = tty->driver_data;
308 int pasted = 0;
309 unsigned int count;
310 struct tty_ldisc *ld;
311 DECLARE_WAITQUEUE(wait, current);
312
313 /* always called with BTM from vt_ioctl */
314 WARN_ON(!tty_locked());
315
316 console_lock();
317 poke_blanked_console();
318 console_unlock();
319
320 ld = tty_ldisc_ref(tty);
321 if (!ld) {
322 tty_unlock();
323 ld = tty_ldisc_ref_wait(tty);
324 tty_lock();
325 }
326
327 add_wait_queue(&vc->paste_wait, &wait);
328 while (sel_buffer && sel_buffer_lth > pasted) {
329 set_current_state(TASK_INTERRUPTIBLE);
330 if (test_bit(TTY_THROTTLED, &tty->flags)) {
331 schedule();
332 continue;
333 }
334 count = sel_buffer_lth - pasted;
335 count = min(count, tty->receive_room);
336 tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
337 NULL, count);
338 pasted += count;
339 }
340 remove_wait_queue(&vc->paste_wait, &wait);
341 __set_current_state(TASK_RUNNING);
342
343 tty_ldisc_deref(ld);
344 return 0;
345}
diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c
new file mode 100644
index 000000000000..66825c9f516a
--- /dev/null
+++ b/drivers/tty/vt/vc_screen.c
@@ -0,0 +1,665 @@
1/*
2 * Provide access to virtual console memory.
3 * /dev/vcs0: the screen as it is being viewed right now (possibly scrolled)
4 * /dev/vcsN: the screen of /dev/ttyN (1 <= N <= 63)
5 * [minor: N]
6 *
7 * /dev/vcsaN: idem, but including attributes, and prefixed with
8 * the 4 bytes lines,columns,x,y (as screendump used to give).
9 * Attribute/character pair is in native endianity.
10 * [minor: N+128]
11 *
12 * This replaces screendump and part of selection, so that the system
13 * administrator can control access using file system permissions.
14 *
15 * aeb@cwi.nl - efter Friedas begravelse - 950211
16 *
17 * machek@k332.feld.cvut.cz - modified not to send characters to wrong console
18 * - fixed some fatal off-by-one bugs (0-- no longer == -1 -> looping and looping and looping...)
19 * - making it shorter - scr_readw are macros which expand in PRETTY long code
20 */
21
22#include <linux/kernel.h>
23#include <linux/major.h>
24#include <linux/errno.h>
25#include <linux/tty.h>
26#include <linux/interrupt.h>
27#include <linux/mm.h>
28#include <linux/init.h>
29#include <linux/vt_kern.h>
30#include <linux/selection.h>
31#include <linux/kbd_kern.h>
32#include <linux/console.h>
33#include <linux/device.h>
34#include <linux/sched.h>
35#include <linux/fs.h>
36#include <linux/poll.h>
37#include <linux/signal.h>
38#include <linux/slab.h>
39#include <linux/notifier.h>
40
41#include <asm/uaccess.h>
42#include <asm/byteorder.h>
43#include <asm/unaligned.h>
44
45#undef attr
46#undef org
47#undef addr
48#define HEADER_SIZE 4
49
50#define CON_BUF_SIZE (CONFIG_BASE_SMALL ? 256 : PAGE_SIZE)
51
52struct vcs_poll_data {
53 struct notifier_block notifier;
54 unsigned int cons_num;
55 bool seen_last_update;
56 wait_queue_head_t waitq;
57 struct fasync_struct *fasync;
58};
59
60static int
61vcs_notifier(struct notifier_block *nb, unsigned long code, void *_param)
62{
63 struct vt_notifier_param *param = _param;
64 struct vc_data *vc = param->vc;
65 struct vcs_poll_data *poll =
66 container_of(nb, struct vcs_poll_data, notifier);
67 int currcons = poll->cons_num;
68
69 if (code != VT_UPDATE)
70 return NOTIFY_DONE;
71
72 if (currcons == 0)
73 currcons = fg_console;
74 else
75 currcons--;
76 if (currcons != vc->vc_num)
77 return NOTIFY_DONE;
78
79 poll->seen_last_update = false;
80 wake_up_interruptible(&poll->waitq);
81 kill_fasync(&poll->fasync, SIGIO, POLL_IN);
82 return NOTIFY_OK;
83}
84
85static void
86vcs_poll_data_free(struct vcs_poll_data *poll)
87{
88 unregister_vt_notifier(&poll->notifier);
89 kfree(poll);
90}
91
92static struct vcs_poll_data *
93vcs_poll_data_get(struct file *file)
94{
95 struct vcs_poll_data *poll = file->private_data;
96
97 if (poll)
98 return poll;
99
100 poll = kzalloc(sizeof(*poll), GFP_KERNEL);
101 if (!poll)
102 return NULL;
103 poll->cons_num = iminor(file->f_path.dentry->d_inode) & 127;
104 init_waitqueue_head(&poll->waitq);
105 poll->notifier.notifier_call = vcs_notifier;
106 if (register_vt_notifier(&poll->notifier) != 0) {
107 kfree(poll);
108 return NULL;
109 }
110
111 /*
112 * This code may be called either through ->poll() or ->fasync().
113 * If we have two threads using the same file descriptor, they could
114 * both enter this function, both notice that the structure hasn't
115 * been allocated yet and go ahead allocating it in parallel, but
116 * only one of them must survive and be shared otherwise we'd leak
117 * memory with a dangling notifier callback.
118 */
119 spin_lock(&file->f_lock);
120 if (!file->private_data) {
121 file->private_data = poll;
122 } else {
123 /* someone else raced ahead of us */
124 vcs_poll_data_free(poll);
125 poll = file->private_data;
126 }
127 spin_unlock(&file->f_lock);
128
129 return poll;
130}
131
132/*
133 * Returns VC for inode.
134 * Must be called with console_lock.
135 */
136static struct vc_data*
137vcs_vc(struct inode *inode, int *viewed)
138{
139 unsigned int currcons = iminor(inode) & 127;
140
141 WARN_CONSOLE_UNLOCKED();
142
143 if (currcons == 0) {
144 currcons = fg_console;
145 if (viewed)
146 *viewed = 1;
147 } else {
148 currcons--;
149 if (viewed)
150 *viewed = 0;
151 }
152 return vc_cons[currcons].d;
153}
154
155/*
156 * Returns size for VC carried by inode.
157 * Must be called with console_lock.
158 */
159static int
160vcs_size(struct inode *inode)
161{
162 int size;
163 int minor = iminor(inode);
164 struct vc_data *vc;
165
166 WARN_CONSOLE_UNLOCKED();
167
168 vc = vcs_vc(inode, NULL);
169 if (!vc)
170 return -ENXIO;
171
172 size = vc->vc_rows * vc->vc_cols;
173
174 if (minor & 128)
175 size = 2*size + HEADER_SIZE;
176 return size;
177}
178
179static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
180{
181 int size;
182
183 console_lock();
184 size = vcs_size(file->f_path.dentry->d_inode);
185 console_unlock();
186 if (size < 0)
187 return size;
188 switch (orig) {
189 default:
190 return -EINVAL;
191 case 2:
192 offset += size;
193 break;
194 case 1:
195 offset += file->f_pos;
196 case 0:
197 break;
198 }
199 if (offset < 0 || offset > size) {
200 return -EINVAL;
201 }
202 file->f_pos = offset;
203 return file->f_pos;
204}
205
206
207static ssize_t
208vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
209{
210 struct inode *inode = file->f_path.dentry->d_inode;
211 unsigned int currcons = iminor(inode);
212 struct vc_data *vc;
213 struct vcs_poll_data *poll;
214 long pos;
215 long attr, read;
216 int col, maxcol, viewed;
217 unsigned short *org = NULL;
218 ssize_t ret;
219 char *con_buf;
220
221 con_buf = (char *) __get_free_page(GFP_KERNEL);
222 if (!con_buf)
223 return -ENOMEM;
224
225 pos = *ppos;
226
227 /* Select the proper current console and verify
228 * sanity of the situation under the console lock.
229 */
230 console_lock();
231
232 attr = (currcons & 128);
233 ret = -ENXIO;
234 vc = vcs_vc(inode, &viewed);
235 if (!vc)
236 goto unlock_out;
237
238 ret = -EINVAL;
239 if (pos < 0)
240 goto unlock_out;
241 poll = file->private_data;
242 if (count && poll)
243 poll->seen_last_update = true;
244 read = 0;
245 ret = 0;
246 while (count) {
247 char *con_buf0, *con_buf_start;
248 long this_round, size;
249 ssize_t orig_count;
250 long p = pos;
251
252 /* Check whether we are above size each round,
253 * as copy_to_user at the end of this loop
254 * could sleep.
255 */
256 size = vcs_size(inode);
257 if (size < 0) {
258 if (read)
259 break;
260 ret = size;
261 goto unlock_out;
262 }
263 if (pos >= size)
264 break;
265 if (count > size - pos)
266 count = size - pos;
267
268 this_round = count;
269 if (this_round > CON_BUF_SIZE)
270 this_round = CON_BUF_SIZE;
271
272 /* Perform the whole read into the local con_buf.
273 * Then we can drop the console spinlock and safely
274 * attempt to move it to userspace.
275 */
276
277 con_buf_start = con_buf0 = con_buf;
278 orig_count = this_round;
279 maxcol = vc->vc_cols;
280 if (!attr) {
281 org = screen_pos(vc, p, viewed);
282 col = p % maxcol;
283 p += maxcol - col;
284 while (this_round-- > 0) {
285 *con_buf0++ = (vcs_scr_readw(vc, org++) & 0xff);
286 if (++col == maxcol) {
287 org = screen_pos(vc, p, viewed);
288 col = 0;
289 p += maxcol;
290 }
291 }
292 } else {
293 if (p < HEADER_SIZE) {
294 size_t tmp_count;
295
296 con_buf0[0] = (char)vc->vc_rows;
297 con_buf0[1] = (char)vc->vc_cols;
298 getconsxy(vc, con_buf0 + 2);
299
300 con_buf_start += p;
301 this_round += p;
302 if (this_round > CON_BUF_SIZE) {
303 this_round = CON_BUF_SIZE;
304 orig_count = this_round - p;
305 }
306
307 tmp_count = HEADER_SIZE;
308 if (tmp_count > this_round)
309 tmp_count = this_round;
310
311 /* Advance state pointers and move on. */
312 this_round -= tmp_count;
313 p = HEADER_SIZE;
314 con_buf0 = con_buf + HEADER_SIZE;
315 /* If this_round >= 0, then p is even... */
316 } else if (p & 1) {
317 /* Skip first byte for output if start address is odd
318 * Update region sizes up/down depending on free
319 * space in buffer.
320 */
321 con_buf_start++;
322 if (this_round < CON_BUF_SIZE)
323 this_round++;
324 else
325 orig_count--;
326 }
327 if (this_round > 0) {
328 unsigned short *tmp_buf = (unsigned short *)con_buf0;
329
330 p -= HEADER_SIZE;
331 p /= 2;
332 col = p % maxcol;
333
334 org = screen_pos(vc, p, viewed);
335 p += maxcol - col;
336
337 /* Buffer has even length, so we can always copy
338 * character + attribute. We do not copy last byte
339 * to userspace if this_round is odd.
340 */
341 this_round = (this_round + 1) >> 1;
342
343 while (this_round) {
344 *tmp_buf++ = vcs_scr_readw(vc, org++);
345 this_round --;
346 if (++col == maxcol) {
347 org = screen_pos(vc, p, viewed);
348 col = 0;
349 p += maxcol;
350 }
351 }
352 }
353 }
354
355 /* Finally, release the console semaphore while we push
356 * all the data to userspace from our temporary buffer.
357 *
358 * AKPM: Even though it's a semaphore, we should drop it because
359 * the pagefault handling code may want to call printk().
360 */
361
362 console_unlock();
363 ret = copy_to_user(buf, con_buf_start, orig_count);
364 console_lock();
365
366 if (ret) {
367 read += (orig_count - ret);
368 ret = -EFAULT;
369 break;
370 }
371 buf += orig_count;
372 pos += orig_count;
373 read += orig_count;
374 count -= orig_count;
375 }
376 *ppos += read;
377 if (read)
378 ret = read;
379unlock_out:
380 console_unlock();
381 free_page((unsigned long) con_buf);
382 return ret;
383}
384
385static ssize_t
386vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
387{
388 struct inode *inode = file->f_path.dentry->d_inode;
389 unsigned int currcons = iminor(inode);
390 struct vc_data *vc;
391 long pos;
392 long attr, size, written;
393 char *con_buf0;
394 int col, maxcol, viewed;
395 u16 *org0 = NULL, *org = NULL;
396 size_t ret;
397 char *con_buf;
398
399 con_buf = (char *) __get_free_page(GFP_KERNEL);
400 if (!con_buf)
401 return -ENOMEM;
402
403 pos = *ppos;
404
405 /* Select the proper current console and verify
406 * sanity of the situation under the console lock.
407 */
408 console_lock();
409
410 attr = (currcons & 128);
411 ret = -ENXIO;
412 vc = vcs_vc(inode, &viewed);
413 if (!vc)
414 goto unlock_out;
415
416 size = vcs_size(inode);
417 ret = -EINVAL;
418 if (pos < 0 || pos > size)
419 goto unlock_out;
420 if (count > size - pos)
421 count = size - pos;
422 written = 0;
423 while (count) {
424 long this_round = count;
425 size_t orig_count;
426 long p;
427
428 if (this_round > CON_BUF_SIZE)
429 this_round = CON_BUF_SIZE;
430
431 /* Temporarily drop the console lock so that we can read
432 * in the write data from userspace safely.
433 */
434 console_unlock();
435 ret = copy_from_user(con_buf, buf, this_round);
436 console_lock();
437
438 if (ret) {
439 this_round -= ret;
440 if (!this_round) {
441 /* Abort loop if no data were copied. Otherwise
442 * fail with -EFAULT.
443 */
444 if (written)
445 break;
446 ret = -EFAULT;
447 goto unlock_out;
448 }
449 }
450
451 /* The vcs_size might have changed while we slept to grab
452 * the user buffer, so recheck.
453 * Return data written up to now on failure.
454 */
455 size = vcs_size(inode);
456 if (size < 0) {
457 if (written)
458 break;
459 ret = size;
460 goto unlock_out;
461 }
462 if (pos >= size)
463 break;
464 if (this_round > size - pos)
465 this_round = size - pos;
466
467 /* OK, now actually push the write to the console
468 * under the lock using the local kernel buffer.
469 */
470
471 con_buf0 = con_buf;
472 orig_count = this_round;
473 maxcol = vc->vc_cols;
474 p = pos;
475 if (!attr) {
476 org0 = org = screen_pos(vc, p, viewed);
477 col = p % maxcol;
478 p += maxcol - col;
479
480 while (this_round > 0) {
481 unsigned char c = *con_buf0++;
482
483 this_round--;
484 vcs_scr_writew(vc,
485 (vcs_scr_readw(vc, org) & 0xff00) | c, org);
486 org++;
487 if (++col == maxcol) {
488 org = screen_pos(vc, p, viewed);
489 col = 0;
490 p += maxcol;
491 }
492 }
493 } else {
494 if (p < HEADER_SIZE) {
495 char header[HEADER_SIZE];
496
497 getconsxy(vc, header + 2);
498 while (p < HEADER_SIZE && this_round > 0) {
499 this_round--;
500 header[p++] = *con_buf0++;
501 }
502 if (!viewed)
503 putconsxy(vc, header + 2);
504 }
505 p -= HEADER_SIZE;
506 col = (p/2) % maxcol;
507 if (this_round > 0) {
508 org0 = org = screen_pos(vc, p/2, viewed);
509 if ((p & 1) && this_round > 0) {
510 char c;
511
512 this_round--;
513 c = *con_buf0++;
514#ifdef __BIG_ENDIAN
515 vcs_scr_writew(vc, c |
516 (vcs_scr_readw(vc, org) & 0xff00), org);
517#else
518 vcs_scr_writew(vc, (c << 8) |
519 (vcs_scr_readw(vc, org) & 0xff), org);
520#endif
521 org++;
522 p++;
523 if (++col == maxcol) {
524 org = screen_pos(vc, p/2, viewed);
525 col = 0;
526 }
527 }
528 p /= 2;
529 p += maxcol - col;
530 }
531 while (this_round > 1) {
532 unsigned short w;
533
534 w = get_unaligned(((unsigned short *)con_buf0));
535 vcs_scr_writew(vc, w, org++);
536 con_buf0 += 2;
537 this_round -= 2;
538 if (++col == maxcol) {
539 org = screen_pos(vc, p, viewed);
540 col = 0;
541 p += maxcol;
542 }
543 }
544 if (this_round > 0) {
545 unsigned char c;
546
547 c = *con_buf0++;
548#ifdef __BIG_ENDIAN
549 vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff) | (c << 8), org);
550#else
551 vcs_scr_writew(vc, (vcs_scr_readw(vc, org) & 0xff00) | c, org);
552#endif
553 }
554 }
555 count -= orig_count;
556 written += orig_count;
557 buf += orig_count;
558 pos += orig_count;
559 if (org0)
560 update_region(vc, (unsigned long)(org0), org - org0);
561 }
562 *ppos += written;
563 ret = written;
564 if (written)
565 vcs_scr_updated(vc);
566
567unlock_out:
568 console_unlock();
569 free_page((unsigned long) con_buf);
570 return ret;
571}
572
573static unsigned int
574vcs_poll(struct file *file, poll_table *wait)
575{
576 struct vcs_poll_data *poll = vcs_poll_data_get(file);
577 int ret = DEFAULT_POLLMASK|POLLERR|POLLPRI;
578
579 if (poll) {
580 poll_wait(file, &poll->waitq, wait);
581 if (poll->seen_last_update)
582 ret = DEFAULT_POLLMASK;
583 }
584 return ret;
585}
586
587static int
588vcs_fasync(int fd, struct file *file, int on)
589{
590 struct vcs_poll_data *poll = file->private_data;
591
592 if (!poll) {
593 /* don't allocate anything if all we want is disable fasync */
594 if (!on)
595 return 0;
596 poll = vcs_poll_data_get(file);
597 if (!poll)
598 return -ENOMEM;
599 }
600
601 return fasync_helper(fd, file, on, &poll->fasync);
602}
603
604static int
605vcs_open(struct inode *inode, struct file *filp)
606{
607 unsigned int currcons = iminor(inode) & 127;
608 int ret = 0;
609
610 tty_lock();
611 if(currcons && !vc_cons_allocated(currcons-1))
612 ret = -ENXIO;
613 tty_unlock();
614 return ret;
615}
616
617static int vcs_release(struct inode *inode, struct file *file)
618{
619 struct vcs_poll_data *poll = file->private_data;
620
621 if (poll)
622 vcs_poll_data_free(poll);
623 return 0;
624}
625
626static const struct file_operations vcs_fops = {
627 .llseek = vcs_lseek,
628 .read = vcs_read,
629 .write = vcs_write,
630 .poll = vcs_poll,
631 .fasync = vcs_fasync,
632 .open = vcs_open,
633 .release = vcs_release,
634};
635
636static struct class *vc_class;
637
638void vcs_make_sysfs(int index)
639{
640 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 1), NULL,
641 "vcs%u", index + 1);
642 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 129), NULL,
643 "vcsa%u", index + 1);
644}
645
646void vcs_remove_sysfs(int index)
647{
648 device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 1));
649 device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 129));
650}
651
652int __init vcs_init(void)
653{
654 unsigned int i;
655
656 if (register_chrdev(VCS_MAJOR, "vcs", &vcs_fops))
657 panic("unable to get major %d for vcs device", VCS_MAJOR);
658 vc_class = class_create(THIS_MODULE, "vc");
659
660 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
661 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
662 for (i = 0; i < MIN_NR_CONSOLES; i++)
663 vcs_make_sysfs(i);
664 return 0;
665}
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
new file mode 100644
index 000000000000..b3915b7ad3e2
--- /dev/null
+++ b/drivers/tty/vt/vt.c
@@ -0,0 +1,4226 @@
1/*
2 * Copyright (C) 1991, 1992 Linus Torvalds
3 */
4
5/*
6 * Hopefully this will be a rather complete VT102 implementation.
7 *
8 * Beeping thanks to John T Kohl.
9 *
10 * Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics
11 * Chars, and VT100 enhancements by Peter MacDonald.
12 *
13 * Copy and paste function by Andrew Haylett,
14 * some enhancements by Alessandro Rubini.
15 *
16 * Code to check for different video-cards mostly by Galen Hunt,
17 * <g-hunt@ee.utah.edu>
18 *
19 * Rudimentary ISO 10646/Unicode/UTF-8 character set support by
20 * Markus Kuhn, <mskuhn@immd4.informatik.uni-erlangen.de>.
21 *
22 * Dynamic allocation of consoles, aeb@cwi.nl, May 1994
23 * Resizing of consoles, aeb, 940926
24 *
25 * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
26 * <poe@daimi.aau.dk>
27 *
28 * User-defined bell sound, new setterm control sequences and printk
29 * redirection by Martin Mares <mj@k332.feld.cvut.cz> 19-Nov-95
30 *
31 * APM screenblank bug fixed Takashi Manabe <manabe@roy.dsl.tutics.tut.jp>
32 *
33 * Merge with the abstract console driver by Geert Uytterhoeven
34 * <geert@linux-m68k.org>, Jan 1997.
35 *
36 * Original m68k console driver modifications by
37 *
38 * - Arno Griffioen <arno@usn.nl>
39 * - David Carter <carter@cs.bris.ac.uk>
40 *
41 * The abstract console driver provides a generic interface for a text
42 * console. It supports VGA text mode, frame buffer based graphical consoles
43 * and special graphics processors that are only accessible through some
44 * registers (e.g. a TMS340x0 GSP).
45 *
46 * The interface to the hardware is specified using a special structure
47 * (struct consw) which contains function pointers to console operations
48 * (see <linux/console.h> for more information).
49 *
50 * Support for changeable cursor shape
51 * by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>, August 1997
52 *
53 * Ported to i386 and con_scrolldelta fixed
54 * by Emmanuel Marty <core@ggi-project.org>, April 1998
55 *
56 * Resurrected character buffers in videoram plus lots of other trickery
57 * by Martin Mares <mj@atrey.karlin.mff.cuni.cz>, July 1998
58 *
59 * Removed old-style timers, introduced console_timer, made timer
60 * deletion SMP-safe. 17Jun00, Andrew Morton
61 *
62 * Removed console_lock, enabled interrupts across all console operations
63 * 13 March 2001, Andrew Morton
64 *
65 * Fixed UTF-8 mode so alternate charset modes always work according
66 * to control sequences interpreted in do_con_trol function
67 * preserving backward VT100 semigraphics compatibility,
68 * malformed UTF sequences represented as sequences of replacement glyphs,
69 * original codes or '?' as a last resort if replacement glyph is undefined
70 * by Adam Tla/lka <atlka@pg.gda.pl>, Aug 2006
71 */
72
73#include <linux/module.h>
74#include <linux/types.h>
75#include <linux/sched.h>
76#include <linux/tty.h>
77#include <linux/tty_flip.h>
78#include <linux/kernel.h>
79#include <linux/string.h>
80#include <linux/errno.h>
81#include <linux/kd.h>
82#include <linux/slab.h>
83#include <linux/major.h>
84#include <linux/mm.h>
85#include <linux/console.h>
86#include <linux/init.h>
87#include <linux/mutex.h>
88#include <linux/vt_kern.h>
89#include <linux/selection.h>
90#include <linux/tiocl.h>
91#include <linux/kbd_kern.h>
92#include <linux/consolemap.h>
93#include <linux/timer.h>
94#include <linux/interrupt.h>
95#include <linux/workqueue.h>
96#include <linux/pm.h>
97#include <linux/font.h>
98#include <linux/bitops.h>
99#include <linux/notifier.h>
100#include <linux/device.h>
101#include <linux/io.h>
102#include <asm/system.h>
103#include <linux/uaccess.h>
104#include <linux/kdb.h>
105#include <linux/ctype.h>
106
107#define MAX_NR_CON_DRIVER 16
108
109#define CON_DRIVER_FLAG_MODULE 1
110#define CON_DRIVER_FLAG_INIT 2
111#define CON_DRIVER_FLAG_ATTR 4
112
113struct con_driver {
114 const struct consw *con;
115 const char *desc;
116 struct device *dev;
117 int node;
118 int first;
119 int last;
120 int flag;
121};
122
123static struct con_driver registered_con_driver[MAX_NR_CON_DRIVER];
124const struct consw *conswitchp;
125
126/* A bitmap for codes <32. A bit of 1 indicates that the code
127 * corresponding to that bit number invokes some special action
128 * (such as cursor movement) and should not be displayed as a
129 * glyph unless the disp_ctrl mode is explicitly enabled.
130 */
131#define CTRL_ACTION 0x0d00ff81
132#define CTRL_ALWAYS 0x0800f501 /* Cannot be overridden by disp_ctrl */
133
134/*
135 * Here is the default bell parameters: 750HZ, 1/8th of a second
136 */
137#define DEFAULT_BELL_PITCH 750
138#define DEFAULT_BELL_DURATION (HZ/8)
139
140struct vc vc_cons [MAX_NR_CONSOLES];
141
142#ifndef VT_SINGLE_DRIVER
143static const struct consw *con_driver_map[MAX_NR_CONSOLES];
144#endif
145
146static int con_open(struct tty_struct *, struct file *);
147static void vc_init(struct vc_data *vc, unsigned int rows,
148 unsigned int cols, int do_clear);
149static void gotoxy(struct vc_data *vc, int new_x, int new_y);
150static void save_cur(struct vc_data *vc);
151static void reset_terminal(struct vc_data *vc, int do_clear);
152static void con_flush_chars(struct tty_struct *tty);
153static int set_vesa_blanking(char __user *p);
154static void set_cursor(struct vc_data *vc);
155static void hide_cursor(struct vc_data *vc);
156static void console_callback(struct work_struct *ignored);
157static void blank_screen_t(unsigned long dummy);
158static void set_palette(struct vc_data *vc);
159
160static int printable; /* Is console ready for printing? */
161int default_utf8 = true;
162module_param(default_utf8, int, S_IRUGO | S_IWUSR);
163int global_cursor_default = -1;
164module_param(global_cursor_default, int, S_IRUGO | S_IWUSR);
165
166static int cur_default = CUR_DEFAULT;
167module_param(cur_default, int, S_IRUGO | S_IWUSR);
168
169/*
170 * ignore_poke: don't unblank the screen when things are typed. This is
171 * mainly for the privacy of braille terminal users.
172 */
173static int ignore_poke;
174
175int do_poke_blanked_console;
176int console_blanked;
177
178static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
179static int vesa_off_interval;
180static int blankinterval = 10*60;
181core_param(consoleblank, blankinterval, int, 0444);
182
183static DECLARE_WORK(console_work, console_callback);
184
185/*
186 * fg_console is the current virtual console,
187 * last_console is the last used one,
188 * want_console is the console we want to switch to,
189 * saved_* variants are for save/restore around kernel debugger enter/leave
190 */
191int fg_console;
192int last_console;
193int want_console = -1;
194static int saved_fg_console;
195static int saved_last_console;
196static int saved_want_console;
197static int saved_vc_mode;
198static int saved_console_blanked;
199
200/*
201 * For each existing display, we have a pointer to console currently visible
202 * on that display, allowing consoles other than fg_console to be refreshed
203 * appropriately. Unless the low-level driver supplies its own display_fg
204 * variable, we use this one for the "master display".
205 */
206static struct vc_data *master_display_fg;
207
208/*
209 * Unfortunately, we need to delay tty echo when we're currently writing to the
210 * console since the code is (and always was) not re-entrant, so we schedule
211 * all flip requests to process context with schedule-task() and run it from
212 * console_callback().
213 */
214
215/*
216 * For the same reason, we defer scrollback to the console callback.
217 */
218static int scrollback_delta;
219
220/*
221 * Hook so that the power management routines can (un)blank
222 * the console on our behalf.
223 */
224int (*console_blank_hook)(int);
225
226static DEFINE_TIMER(console_timer, blank_screen_t, 0, 0);
227static int blank_state;
228static int blank_timer_expired;
229enum {
230 blank_off = 0,
231 blank_normal_wait,
232 blank_vesa_wait,
233};
234
235/*
236 * /sys/class/tty/tty0/
237 *
238 * the attribute 'active' contains the name of the current vc
239 * console and it supports poll() to detect vc switches
240 */
241static struct device *tty0dev;
242
243/*
244 * Notifier list for console events.
245 */
246static ATOMIC_NOTIFIER_HEAD(vt_notifier_list);
247
248int register_vt_notifier(struct notifier_block *nb)
249{
250 return atomic_notifier_chain_register(&vt_notifier_list, nb);
251}
252EXPORT_SYMBOL_GPL(register_vt_notifier);
253
254int unregister_vt_notifier(struct notifier_block *nb)
255{
256 return atomic_notifier_chain_unregister(&vt_notifier_list, nb);
257}
258EXPORT_SYMBOL_GPL(unregister_vt_notifier);
259
260static void notify_write(struct vc_data *vc, unsigned int unicode)
261{
262 struct vt_notifier_param param = { .vc = vc, unicode = unicode };
263 atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, &param);
264}
265
266static void notify_update(struct vc_data *vc)
267{
268 struct vt_notifier_param param = { .vc = vc };
269 atomic_notifier_call_chain(&vt_notifier_list, VT_UPDATE, &param);
270}
271/*
272 * Low-Level Functions
273 */
274
275#define IS_FG(vc) ((vc)->vc_num == fg_console)
276
277#ifdef VT_BUF_VRAM_ONLY
278#define DO_UPDATE(vc) 0
279#else
280#define DO_UPDATE(vc) (CON_IS_VISIBLE(vc) && !console_blanked)
281#endif
282
283static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed)
284{
285 unsigned short *p;
286
287 if (!viewed)
288 p = (unsigned short *)(vc->vc_origin + offset);
289 else if (!vc->vc_sw->con_screen_pos)
290 p = (unsigned short *)(vc->vc_visible_origin + offset);
291 else
292 p = vc->vc_sw->con_screen_pos(vc, offset);
293 return p;
294}
295
296/* Called from the keyboard irq path.. */
297static inline void scrolldelta(int lines)
298{
299 /* FIXME */
300 /* scrolldelta needs some kind of consistency lock, but the BKL was
301 and still is not protecting versus the scheduled back end */
302 scrollback_delta += lines;
303 schedule_console_callback();
304}
305
306void schedule_console_callback(void)
307{
308 schedule_work(&console_work);
309}
310
311static void scrup(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
312{
313 unsigned short *d, *s;
314
315 if (t+nr >= b)
316 nr = b - t - 1;
317 if (b > vc->vc_rows || t >= b || nr < 1)
318 return;
319 if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_UP, nr))
320 return;
321 d = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
322 s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * (t + nr));
323 scr_memmovew(d, s, (b - t - nr) * vc->vc_size_row);
324 scr_memsetw(d + (b - t - nr) * vc->vc_cols, vc->vc_video_erase_char,
325 vc->vc_size_row * nr);
326}
327
328static void scrdown(struct vc_data *vc, unsigned int t, unsigned int b, int nr)
329{
330 unsigned short *s;
331 unsigned int step;
332
333 if (t+nr >= b)
334 nr = b - t - 1;
335 if (b > vc->vc_rows || t >= b || nr < 1)
336 return;
337 if (CON_IS_VISIBLE(vc) && vc->vc_sw->con_scroll(vc, t, b, SM_DOWN, nr))
338 return;
339 s = (unsigned short *)(vc->vc_origin + vc->vc_size_row * t);
340 step = vc->vc_cols * nr;
341 scr_memmovew(s + step, s, (b - t - nr) * vc->vc_size_row);
342 scr_memsetw(s, vc->vc_video_erase_char, 2 * step);
343}
344
345static void do_update_region(struct vc_data *vc, unsigned long start, int count)
346{
347#ifndef VT_BUF_VRAM_ONLY
348 unsigned int xx, yy, offset;
349 u16 *p;
350
351 p = (u16 *) start;
352 if (!vc->vc_sw->con_getxy) {
353 offset = (start - vc->vc_origin) / 2;
354 xx = offset % vc->vc_cols;
355 yy = offset / vc->vc_cols;
356 } else {
357 int nxx, nyy;
358 start = vc->vc_sw->con_getxy(vc, start, &nxx, &nyy);
359 xx = nxx; yy = nyy;
360 }
361 for(;;) {
362 u16 attrib = scr_readw(p) & 0xff00;
363 int startx = xx;
364 u16 *q = p;
365 while (xx < vc->vc_cols && count) {
366 if (attrib != (scr_readw(p) & 0xff00)) {
367 if (p > q)
368 vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
369 startx = xx;
370 q = p;
371 attrib = scr_readw(p) & 0xff00;
372 }
373 p++;
374 xx++;
375 count--;
376 }
377 if (p > q)
378 vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
379 if (!count)
380 break;
381 xx = 0;
382 yy++;
383 if (vc->vc_sw->con_getxy) {
384 p = (u16 *)start;
385 start = vc->vc_sw->con_getxy(vc, start, NULL, NULL);
386 }
387 }
388#endif
389}
390
391void update_region(struct vc_data *vc, unsigned long start, int count)
392{
393 WARN_CONSOLE_UNLOCKED();
394
395 if (DO_UPDATE(vc)) {
396 hide_cursor(vc);
397 do_update_region(vc, start, count);
398 set_cursor(vc);
399 }
400}
401
402/* Structure of attributes is hardware-dependent */
403
404static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
405 u8 _underline, u8 _reverse, u8 _italic)
406{
407 if (vc->vc_sw->con_build_attr)
408 return vc->vc_sw->con_build_attr(vc, _color, _intensity,
409 _blink, _underline, _reverse, _italic);
410
411#ifndef VT_BUF_VRAM_ONLY
412/*
413 * ++roman: I completely changed the attribute format for monochrome
414 * mode (!can_do_color). The formerly used MDA (monochrome display
415 * adapter) format didn't allow the combination of certain effects.
416 * Now the attribute is just a bit vector:
417 * Bit 0..1: intensity (0..2)
418 * Bit 2 : underline
419 * Bit 3 : reverse
420 * Bit 7 : blink
421 */
422 {
423 u8 a = _color;
424 if (!vc->vc_can_do_color)
425 return _intensity |
426 (_italic ? 2 : 0) |
427 (_underline ? 4 : 0) |
428 (_reverse ? 8 : 0) |
429 (_blink ? 0x80 : 0);
430 if (_italic)
431 a = (a & 0xF0) | vc->vc_itcolor;
432 else if (_underline)
433 a = (a & 0xf0) | vc->vc_ulcolor;
434 else if (_intensity == 0)
435 a = (a & 0xf0) | vc->vc_ulcolor;
436 if (_reverse)
437 a = ((a) & 0x88) | ((((a) >> 4) | ((a) << 4)) & 0x77);
438 if (_blink)
439 a ^= 0x80;
440 if (_intensity == 2)
441 a ^= 0x08;
442 if (vc->vc_hi_font_mask == 0x100)
443 a <<= 1;
444 return a;
445 }
446#else
447 return 0;
448#endif
449}
450
451static void update_attr(struct vc_data *vc)
452{
453 vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity,
454 vc->vc_blink, vc->vc_underline,
455 vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
456 vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' ';
457}
458
459/* Note: inverting the screen twice should revert to the original state */
460void invert_screen(struct vc_data *vc, int offset, int count, int viewed)
461{
462 unsigned short *p;
463
464 WARN_CONSOLE_UNLOCKED();
465
466 count /= 2;
467 p = screenpos(vc, offset, viewed);
468 if (vc->vc_sw->con_invert_region)
469 vc->vc_sw->con_invert_region(vc, p, count);
470#ifndef VT_BUF_VRAM_ONLY
471 else {
472 u16 *q = p;
473 int cnt = count;
474 u16 a;
475
476 if (!vc->vc_can_do_color) {
477 while (cnt--) {
478 a = scr_readw(q);
479 a ^= 0x0800;
480 scr_writew(a, q);
481 q++;
482 }
483 } else if (vc->vc_hi_font_mask == 0x100) {
484 while (cnt--) {
485 a = scr_readw(q);
486 a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4);
487 scr_writew(a, q);
488 q++;
489 }
490 } else {
491 while (cnt--) {
492 a = scr_readw(q);
493 a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
494 scr_writew(a, q);
495 q++;
496 }
497 }
498 }
499#endif
500 if (DO_UPDATE(vc))
501 do_update_region(vc, (unsigned long) p, count);
502}
503
504/* used by selection: complement pointer position */
505void complement_pos(struct vc_data *vc, int offset)
506{
507 static int old_offset = -1;
508 static unsigned short old;
509 static unsigned short oldx, oldy;
510
511 WARN_CONSOLE_UNLOCKED();
512
513 if (old_offset != -1 && old_offset >= 0 &&
514 old_offset < vc->vc_screenbuf_size) {
515 scr_writew(old, screenpos(vc, old_offset, 1));
516 if (DO_UPDATE(vc))
517 vc->vc_sw->con_putc(vc, old, oldy, oldx);
518 }
519
520 old_offset = offset;
521
522 if (offset != -1 && offset >= 0 &&
523 offset < vc->vc_screenbuf_size) {
524 unsigned short new;
525 unsigned short *p;
526 p = screenpos(vc, offset, 1);
527 old = scr_readw(p);
528 new = old ^ vc->vc_complement_mask;
529 scr_writew(new, p);
530 if (DO_UPDATE(vc)) {
531 oldx = (offset >> 1) % vc->vc_cols;
532 oldy = (offset >> 1) / vc->vc_cols;
533 vc->vc_sw->con_putc(vc, new, oldy, oldx);
534 }
535 }
536
537}
538
539static void insert_char(struct vc_data *vc, unsigned int nr)
540{
541 unsigned short *p, *q = (unsigned short *)vc->vc_pos;
542
543 p = q + vc->vc_cols - nr - vc->vc_x;
544 while (--p >= q)
545 scr_writew(scr_readw(p), p + nr);
546 scr_memsetw(q, vc->vc_video_erase_char, nr * 2);
547 vc->vc_need_wrap = 0;
548 if (DO_UPDATE(vc)) {
549 unsigned short oldattr = vc->vc_attr;
550 vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x, vc->vc_y, vc->vc_x + nr, 1,
551 vc->vc_cols - vc->vc_x - nr);
552 vc->vc_attr = vc->vc_video_erase_char >> 8;
553 while (nr--)
554 vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y, vc->vc_x + nr);
555 vc->vc_attr = oldattr;
556 }
557}
558
559static void delete_char(struct vc_data *vc, unsigned int nr)
560{
561 unsigned int i = vc->vc_x;
562 unsigned short *p = (unsigned short *)vc->vc_pos;
563
564 while (++i <= vc->vc_cols - nr) {
565 scr_writew(scr_readw(p+nr), p);
566 p++;
567 }
568 scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
569 vc->vc_need_wrap = 0;
570 if (DO_UPDATE(vc)) {
571 unsigned short oldattr = vc->vc_attr;
572 vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x + nr, vc->vc_y, vc->vc_x, 1,
573 vc->vc_cols - vc->vc_x - nr);
574 vc->vc_attr = vc->vc_video_erase_char >> 8;
575 while (nr--)
576 vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y,
577 vc->vc_cols - 1 - nr);
578 vc->vc_attr = oldattr;
579 }
580}
581
582static int softcursor_original;
583
584static void add_softcursor(struct vc_data *vc)
585{
586 int i = scr_readw((u16 *) vc->vc_pos);
587 u32 type = vc->vc_cursor_type;
588
589 if (! (type & 0x10)) return;
590 if (softcursor_original != -1) return;
591 softcursor_original = i;
592 i |= ((type >> 8) & 0xff00 );
593 i ^= ((type) & 0xff00 );
594 if ((type & 0x20) && ((softcursor_original & 0x7000) == (i & 0x7000))) i ^= 0x7000;
595 if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700;
596 scr_writew(i, (u16 *) vc->vc_pos);
597 if (DO_UPDATE(vc))
598 vc->vc_sw->con_putc(vc, i, vc->vc_y, vc->vc_x);
599}
600
601static void hide_softcursor(struct vc_data *vc)
602{
603 if (softcursor_original != -1) {
604 scr_writew(softcursor_original, (u16 *)vc->vc_pos);
605 if (DO_UPDATE(vc))
606 vc->vc_sw->con_putc(vc, softcursor_original,
607 vc->vc_y, vc->vc_x);
608 softcursor_original = -1;
609 }
610}
611
612static void hide_cursor(struct vc_data *vc)
613{
614 if (vc == sel_cons)
615 clear_selection();
616 vc->vc_sw->con_cursor(vc, CM_ERASE);
617 hide_softcursor(vc);
618}
619
620static void set_cursor(struct vc_data *vc)
621{
622 if (!IS_FG(vc) || console_blanked ||
623 vc->vc_mode == KD_GRAPHICS)
624 return;
625 if (vc->vc_deccm) {
626 if (vc == sel_cons)
627 clear_selection();
628 add_softcursor(vc);
629 if ((vc->vc_cursor_type & 0x0f) != 1)
630 vc->vc_sw->con_cursor(vc, CM_DRAW);
631 } else
632 hide_cursor(vc);
633}
634
635static void set_origin(struct vc_data *vc)
636{
637 WARN_CONSOLE_UNLOCKED();
638
639 if (!CON_IS_VISIBLE(vc) ||
640 !vc->vc_sw->con_set_origin ||
641 !vc->vc_sw->con_set_origin(vc))
642 vc->vc_origin = (unsigned long)vc->vc_screenbuf;
643 vc->vc_visible_origin = vc->vc_origin;
644 vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size;
645 vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->vc_y + 2 * vc->vc_x;
646}
647
648static inline void save_screen(struct vc_data *vc)
649{
650 WARN_CONSOLE_UNLOCKED();
651
652 if (vc->vc_sw->con_save_screen)
653 vc->vc_sw->con_save_screen(vc);
654}
655
656/*
657 * Redrawing of screen
658 */
659
660static void clear_buffer_attributes(struct vc_data *vc)
661{
662 unsigned short *p = (unsigned short *)vc->vc_origin;
663 int count = vc->vc_screenbuf_size / 2;
664 int mask = vc->vc_hi_font_mask | 0xff;
665
666 for (; count > 0; count--, p++) {
667 scr_writew((scr_readw(p)&mask) | (vc->vc_video_erase_char & ~mask), p);
668 }
669}
670
671void redraw_screen(struct vc_data *vc, int is_switch)
672{
673 int redraw = 0;
674
675 WARN_CONSOLE_UNLOCKED();
676
677 if (!vc) {
678 /* strange ... */
679 /* printk("redraw_screen: tty %d not allocated ??\n", new_console+1); */
680 return;
681 }
682
683 if (is_switch) {
684 struct vc_data *old_vc = vc_cons[fg_console].d;
685 if (old_vc == vc)
686 return;
687 if (!CON_IS_VISIBLE(vc))
688 redraw = 1;
689 *vc->vc_display_fg = vc;
690 fg_console = vc->vc_num;
691 hide_cursor(old_vc);
692 if (!CON_IS_VISIBLE(old_vc)) {
693 save_screen(old_vc);
694 set_origin(old_vc);
695 }
696 if (tty0dev)
697 sysfs_notify(&tty0dev->kobj, NULL, "active");
698 } else {
699 hide_cursor(vc);
700 redraw = 1;
701 }
702
703 if (redraw) {
704 int update;
705 int old_was_color = vc->vc_can_do_color;
706
707 set_origin(vc);
708 update = vc->vc_sw->con_switch(vc);
709 set_palette(vc);
710 /*
711 * If console changed from mono<->color, the best we can do
712 * is to clear the buffer attributes. As it currently stands,
713 * rebuilding new attributes from the old buffer is not doable
714 * without overly complex code.
715 */
716 if (old_was_color != vc->vc_can_do_color) {
717 update_attr(vc);
718 clear_buffer_attributes(vc);
719 }
720
721 /* Forcibly update if we're panicing */
722 if ((update && vc->vc_mode != KD_GRAPHICS) ||
723 vt_force_oops_output(vc))
724 do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
725 }
726 set_cursor(vc);
727 if (is_switch) {
728 set_leds();
729 compute_shiftstate();
730 notify_update(vc);
731 }
732}
733
734/*
735 * Allocation, freeing and resizing of VTs.
736 */
737
738int vc_cons_allocated(unsigned int i)
739{
740 return (i < MAX_NR_CONSOLES && vc_cons[i].d);
741}
742
743static void visual_init(struct vc_data *vc, int num, int init)
744{
745 /* ++Geert: vc->vc_sw->con_init determines console size */
746 if (vc->vc_sw)
747 module_put(vc->vc_sw->owner);
748 vc->vc_sw = conswitchp;
749#ifndef VT_SINGLE_DRIVER
750 if (con_driver_map[num])
751 vc->vc_sw = con_driver_map[num];
752#endif
753 __module_get(vc->vc_sw->owner);
754 vc->vc_num = num;
755 vc->vc_display_fg = &master_display_fg;
756 vc->vc_uni_pagedir_loc = &vc->vc_uni_pagedir;
757 vc->vc_uni_pagedir = 0;
758 vc->vc_hi_font_mask = 0;
759 vc->vc_complement_mask = 0;
760 vc->vc_can_do_color = 0;
761 vc->vc_panic_force_write = false;
762 vc->vc_sw->con_init(vc, init);
763 if (!vc->vc_complement_mask)
764 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
765 vc->vc_s_complement_mask = vc->vc_complement_mask;
766 vc->vc_size_row = vc->vc_cols << 1;
767 vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;
768}
769
770int vc_allocate(unsigned int currcons) /* return 0 on success */
771{
772 WARN_CONSOLE_UNLOCKED();
773
774 if (currcons >= MAX_NR_CONSOLES)
775 return -ENXIO;
776 if (!vc_cons[currcons].d) {
777 struct vc_data *vc;
778 struct vt_notifier_param param;
779
780 /* prevent users from taking too much memory */
781 if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE))
782 return -EPERM;
783
784 /* due to the granularity of kmalloc, we waste some memory here */
785 /* the alloc is done in two steps, to optimize the common situation
786 of a 25x80 console (structsize=216, screenbuf_size=4000) */
787 /* although the numbers above are not valid since long ago, the
788 point is still up-to-date and the comment still has its value
789 even if only as a historical artifact. --mj, July 1998 */
790 param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL);
791 if (!vc)
792 return -ENOMEM;
793 vc_cons[currcons].d = vc;
794 tty_port_init(&vc->port);
795 INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
796 visual_init(vc, currcons, 1);
797 if (!*vc->vc_uni_pagedir_loc)
798 con_set_default_unimap(vc);
799 vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
800 if (!vc->vc_screenbuf) {
801 kfree(vc);
802 vc_cons[currcons].d = NULL;
803 return -ENOMEM;
804 }
805
806 /* If no drivers have overridden us and the user didn't pass a
807 boot option, default to displaying the cursor */
808 if (global_cursor_default == -1)
809 global_cursor_default = 1;
810
811 vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
812 vcs_make_sysfs(currcons);
813 atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
814 }
815 return 0;
816}
817
818static inline int resize_screen(struct vc_data *vc, int width, int height,
819 int user)
820{
821 /* Resizes the resolution of the display adapater */
822 int err = 0;
823
824 if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_resize)
825 err = vc->vc_sw->con_resize(vc, width, height, user);
826
827 return err;
828}
829
830/*
831 * Change # of rows and columns (0 means unchanged/the size of fg_console)
832 * [this is to be used together with some user program
833 * like resize that changes the hardware videomode]
834 */
835#define VC_RESIZE_MAXCOL (32767)
836#define VC_RESIZE_MAXROW (32767)
837
838/**
839 * vc_do_resize - resizing method for the tty
840 * @tty: tty being resized
841 * @real_tty: real tty (different to tty if a pty/tty pair)
842 * @vc: virtual console private data
843 * @cols: columns
844 * @lines: lines
845 *
846 * Resize a virtual console, clipping according to the actual constraints.
847 * If the caller passes a tty structure then update the termios winsize
848 * information and perform any necessary signal handling.
849 *
850 * Caller must hold the console semaphore. Takes the termios mutex and
851 * ctrl_lock of the tty IFF a tty is passed.
852 */
853
854static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
855 unsigned int cols, unsigned int lines)
856{
857 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
858 unsigned long end;
859 unsigned int old_rows, old_row_size;
860 unsigned int new_cols, new_rows, new_row_size, new_screen_size;
861 unsigned int user;
862 unsigned short *newscreen;
863
864 WARN_CONSOLE_UNLOCKED();
865
866 if (!vc)
867 return -ENXIO;
868
869 user = vc->vc_resize_user;
870 vc->vc_resize_user = 0;
871
872 if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW)
873 return -EINVAL;
874
875 new_cols = (cols ? cols : vc->vc_cols);
876 new_rows = (lines ? lines : vc->vc_rows);
877 new_row_size = new_cols << 1;
878 new_screen_size = new_row_size * new_rows;
879
880 if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
881 return 0;
882
883 newscreen = kmalloc(new_screen_size, GFP_USER);
884 if (!newscreen)
885 return -ENOMEM;
886
887 old_rows = vc->vc_rows;
888 old_row_size = vc->vc_size_row;
889
890 err = resize_screen(vc, new_cols, new_rows, user);
891 if (err) {
892 kfree(newscreen);
893 return err;
894 }
895
896 vc->vc_rows = new_rows;
897 vc->vc_cols = new_cols;
898 vc->vc_size_row = new_row_size;
899 vc->vc_screenbuf_size = new_screen_size;
900
901 rlth = min(old_row_size, new_row_size);
902 rrem = new_row_size - rlth;
903 old_origin = vc->vc_origin;
904 new_origin = (long) newscreen;
905 new_scr_end = new_origin + new_screen_size;
906
907 if (vc->vc_y > new_rows) {
908 if (old_rows - vc->vc_y < new_rows) {
909 /*
910 * Cursor near the bottom, copy contents from the
911 * bottom of buffer
912 */
913 old_origin += (old_rows - new_rows) * old_row_size;
914 } else {
915 /*
916 * Cursor is in no man's land, copy 1/2 screenful
917 * from the top and bottom of cursor position
918 */
919 old_origin += (vc->vc_y - new_rows/2) * old_row_size;
920 }
921 }
922
923 end = old_origin + old_row_size * min(old_rows, new_rows);
924
925 update_attr(vc);
926
927 while (old_origin < end) {
928 scr_memcpyw((unsigned short *) new_origin,
929 (unsigned short *) old_origin, rlth);
930 if (rrem)
931 scr_memsetw((void *)(new_origin + rlth),
932 vc->vc_video_erase_char, rrem);
933 old_origin += old_row_size;
934 new_origin += new_row_size;
935 }
936 if (new_scr_end > new_origin)
937 scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
938 new_scr_end - new_origin);
939 kfree(vc->vc_screenbuf);
940 vc->vc_screenbuf = newscreen;
941 vc->vc_screenbuf_size = new_screen_size;
942 set_origin(vc);
943
944 /* do part of a reset_terminal() */
945 vc->vc_top = 0;
946 vc->vc_bottom = vc->vc_rows;
947 gotoxy(vc, vc->vc_x, vc->vc_y);
948 save_cur(vc);
949
950 if (tty) {
951 /* Rewrite the requested winsize data with the actual
952 resulting sizes */
953 struct winsize ws;
954 memset(&ws, 0, sizeof(ws));
955 ws.ws_row = vc->vc_rows;
956 ws.ws_col = vc->vc_cols;
957 ws.ws_ypixel = vc->vc_scan_lines;
958 tty_do_resize(tty, &ws);
959 }
960
961 if (CON_IS_VISIBLE(vc))
962 update_screen(vc);
963 vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num);
964 return err;
965}
966
967/**
968 * vc_resize - resize a VT
969 * @vc: virtual console
970 * @cols: columns
971 * @rows: rows
972 *
973 * Resize a virtual console as seen from the console end of things. We
974 * use the common vc_do_resize methods to update the structures. The
975 * caller must hold the console sem to protect console internals and
976 * vc->port.tty
977 */
978
979int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows)
980{
981 return vc_do_resize(vc->port.tty, vc, cols, rows);
982}
983
984/**
985 * vt_resize - resize a VT
986 * @tty: tty to resize
987 * @ws: winsize attributes
988 *
989 * Resize a virtual terminal. This is called by the tty layer as we
990 * register our own handler for resizing. The mutual helper does all
991 * the actual work.
992 *
993 * Takes the console sem and the called methods then take the tty
994 * termios_mutex and the tty ctrl_lock in that order.
995 */
996static int vt_resize(struct tty_struct *tty, struct winsize *ws)
997{
998 struct vc_data *vc = tty->driver_data;
999 int ret;
1000
1001 console_lock();
1002 ret = vc_do_resize(tty, vc, ws->ws_col, ws->ws_row);
1003 console_unlock();
1004 return ret;
1005}
1006
1007void vc_deallocate(unsigned int currcons)
1008{
1009 WARN_CONSOLE_UNLOCKED();
1010
1011 if (vc_cons_allocated(currcons)) {
1012 struct vc_data *vc = vc_cons[currcons].d;
1013 struct vt_notifier_param param = { .vc = vc };
1014
1015 atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
1016 vcs_remove_sysfs(currcons);
1017 vc->vc_sw->con_deinit(vc);
1018 put_pid(vc->vt_pid);
1019 module_put(vc->vc_sw->owner);
1020 kfree(vc->vc_screenbuf);
1021 if (currcons >= MIN_NR_CONSOLES)
1022 kfree(vc);
1023 vc_cons[currcons].d = NULL;
1024 }
1025}
1026
1027/*
1028 * VT102 emulator
1029 */
1030
1031#define set_kbd(vc, x) set_vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
1032#define clr_kbd(vc, x) clr_vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
1033#define is_kbd(vc, x) vc_kbd_mode(kbd_table + (vc)->vc_num, (x))
1034
1035#define decarm VC_REPEAT
1036#define decckm VC_CKMODE
1037#define kbdapplic VC_APPLIC
1038#define lnm VC_CRLF
1039
1040/*
1041 * this is what the terminal answers to a ESC-Z or csi0c query.
1042 */
1043#define VT100ID "\033[?1;2c"
1044#define VT102ID "\033[?6c"
1045
1046unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
1047 8,12,10,14, 9,13,11,15 };
1048
1049/* the default colour table, for VGA+ colour systems */
1050int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,
1051 0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
1052int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
1053 0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
1054int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
1055 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
1056
1057module_param_array(default_red, int, NULL, S_IRUGO | S_IWUSR);
1058module_param_array(default_grn, int, NULL, S_IRUGO | S_IWUSR);
1059module_param_array(default_blu, int, NULL, S_IRUGO | S_IWUSR);
1060
1061/*
1062 * gotoxy() must verify all boundaries, because the arguments
1063 * might also be negative. If the given position is out of
1064 * bounds, the cursor is placed at the nearest margin.
1065 */
1066static void gotoxy(struct vc_data *vc, int new_x, int new_y)
1067{
1068 int min_y, max_y;
1069
1070 if (new_x < 0)
1071 vc->vc_x = 0;
1072 else {
1073 if (new_x >= vc->vc_cols)
1074 vc->vc_x = vc->vc_cols - 1;
1075 else
1076 vc->vc_x = new_x;
1077 }
1078
1079 if (vc->vc_decom) {
1080 min_y = vc->vc_top;
1081 max_y = vc->vc_bottom;
1082 } else {
1083 min_y = 0;
1084 max_y = vc->vc_rows;
1085 }
1086 if (new_y < min_y)
1087 vc->vc_y = min_y;
1088 else if (new_y >= max_y)
1089 vc->vc_y = max_y - 1;
1090 else
1091 vc->vc_y = new_y;
1092 vc->vc_pos = vc->vc_origin + vc->vc_y * vc->vc_size_row + (vc->vc_x<<1);
1093 vc->vc_need_wrap = 0;
1094}
1095
1096/* for absolute user moves, when decom is set */
1097static void gotoxay(struct vc_data *vc, int new_x, int new_y)
1098{
1099 gotoxy(vc, new_x, vc->vc_decom ? (vc->vc_top + new_y) : new_y);
1100}
1101
1102void scrollback(struct vc_data *vc, int lines)
1103{
1104 if (!lines)
1105 lines = vc->vc_rows / 2;
1106 scrolldelta(-lines);
1107}
1108
1109void scrollfront(struct vc_data *vc, int lines)
1110{
1111 if (!lines)
1112 lines = vc->vc_rows / 2;
1113 scrolldelta(lines);
1114}
1115
1116static void lf(struct vc_data *vc)
1117{
1118 /* don't scroll if above bottom of scrolling region, or
1119 * if below scrolling region
1120 */
1121 if (vc->vc_y + 1 == vc->vc_bottom)
1122 scrup(vc, vc->vc_top, vc->vc_bottom, 1);
1123 else if (vc->vc_y < vc->vc_rows - 1) {
1124 vc->vc_y++;
1125 vc->vc_pos += vc->vc_size_row;
1126 }
1127 vc->vc_need_wrap = 0;
1128 notify_write(vc, '\n');
1129}
1130
1131static void ri(struct vc_data *vc)
1132{
1133 /* don't scroll if below top of scrolling region, or
1134 * if above scrolling region
1135 */
1136 if (vc->vc_y == vc->vc_top)
1137 scrdown(vc, vc->vc_top, vc->vc_bottom, 1);
1138 else if (vc->vc_y > 0) {
1139 vc->vc_y--;
1140 vc->vc_pos -= vc->vc_size_row;
1141 }
1142 vc->vc_need_wrap = 0;
1143}
1144
1145static inline void cr(struct vc_data *vc)
1146{
1147 vc->vc_pos -= vc->vc_x << 1;
1148 vc->vc_need_wrap = vc->vc_x = 0;
1149 notify_write(vc, '\r');
1150}
1151
1152static inline void bs(struct vc_data *vc)
1153{
1154 if (vc->vc_x) {
1155 vc->vc_pos -= 2;
1156 vc->vc_x--;
1157 vc->vc_need_wrap = 0;
1158 notify_write(vc, '\b');
1159 }
1160}
1161
1162static inline void del(struct vc_data *vc)
1163{
1164 /* ignored */
1165}
1166
1167static void csi_J(struct vc_data *vc, int vpar)
1168{
1169 unsigned int count;
1170 unsigned short * start;
1171
1172 switch (vpar) {
1173 case 0: /* erase from cursor to end of display */
1174 count = (vc->vc_scr_end - vc->vc_pos) >> 1;
1175 start = (unsigned short *)vc->vc_pos;
1176 if (DO_UPDATE(vc)) {
1177 /* do in two stages */
1178 vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
1179 vc->vc_cols - vc->vc_x);
1180 vc->vc_sw->con_clear(vc, vc->vc_y + 1, 0,
1181 vc->vc_rows - vc->vc_y - 1,
1182 vc->vc_cols);
1183 }
1184 break;
1185 case 1: /* erase from start to cursor */
1186 count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1;
1187 start = (unsigned short *)vc->vc_origin;
1188 if (DO_UPDATE(vc)) {
1189 /* do in two stages */
1190 vc->vc_sw->con_clear(vc, 0, 0, vc->vc_y,
1191 vc->vc_cols);
1192 vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
1193 vc->vc_x + 1);
1194 }
1195 break;
1196 case 3: /* erase scroll-back buffer (and whole display) */
1197 scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
1198 vc->vc_screenbuf_size >> 1);
1199 set_origin(vc);
1200 if (CON_IS_VISIBLE(vc))
1201 update_screen(vc);
1202 /* fall through */
1203 case 2: /* erase whole display */
1204 count = vc->vc_cols * vc->vc_rows;
1205 start = (unsigned short *)vc->vc_origin;
1206 if (DO_UPDATE(vc))
1207 vc->vc_sw->con_clear(vc, 0, 0,
1208 vc->vc_rows,
1209 vc->vc_cols);
1210 break;
1211 default:
1212 return;
1213 }
1214 scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
1215 vc->vc_need_wrap = 0;
1216}
1217
1218static void csi_K(struct vc_data *vc, int vpar)
1219{
1220 unsigned int count;
1221 unsigned short * start;
1222
1223 switch (vpar) {
1224 case 0: /* erase from cursor to end of line */
1225 count = vc->vc_cols - vc->vc_x;
1226 start = (unsigned short *)vc->vc_pos;
1227 if (DO_UPDATE(vc))
1228 vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1,
1229 vc->vc_cols - vc->vc_x);
1230 break;
1231 case 1: /* erase from start of line to cursor */
1232 start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
1233 count = vc->vc_x + 1;
1234 if (DO_UPDATE(vc))
1235 vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
1236 vc->vc_x + 1);
1237 break;
1238 case 2: /* erase whole line */
1239 start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1));
1240 count = vc->vc_cols;
1241 if (DO_UPDATE(vc))
1242 vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1,
1243 vc->vc_cols);
1244 break;
1245 default:
1246 return;
1247 }
1248 scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
1249 vc->vc_need_wrap = 0;
1250}
1251
1252static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */
1253{ /* not vt100? */
1254 int count;
1255
1256 if (!vpar)
1257 vpar++;
1258 count = (vpar > vc->vc_cols - vc->vc_x) ? (vc->vc_cols - vc->vc_x) : vpar;
1259
1260 scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count);
1261 if (DO_UPDATE(vc))
1262 vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, count);
1263 vc->vc_need_wrap = 0;
1264}
1265
1266static void default_attr(struct vc_data *vc)
1267{
1268 vc->vc_intensity = 1;
1269 vc->vc_italic = 0;
1270 vc->vc_underline = 0;
1271 vc->vc_reverse = 0;
1272 vc->vc_blink = 0;
1273 vc->vc_color = vc->vc_def_color;
1274}
1275
1276/* console_lock is held */
1277static void csi_m(struct vc_data *vc)
1278{
1279 int i;
1280
1281 for (i = 0; i <= vc->vc_npar; i++)
1282 switch (vc->vc_par[i]) {
1283 case 0: /* all attributes off */
1284 default_attr(vc);
1285 break;
1286 case 1:
1287 vc->vc_intensity = 2;
1288 break;
1289 case 2:
1290 vc->vc_intensity = 0;
1291 break;
1292 case 3:
1293 vc->vc_italic = 1;
1294 break;
1295 case 4:
1296 vc->vc_underline = 1;
1297 break;
1298 case 5:
1299 vc->vc_blink = 1;
1300 break;
1301 case 7:
1302 vc->vc_reverse = 1;
1303 break;
1304 case 10: /* ANSI X3.64-1979 (SCO-ish?)
1305 * Select primary font, don't display
1306 * control chars if defined, don't set
1307 * bit 8 on output.
1308 */
1309 vc->vc_translate = set_translate(vc->vc_charset == 0
1310 ? vc->vc_G0_charset
1311 : vc->vc_G1_charset, vc);
1312 vc->vc_disp_ctrl = 0;
1313 vc->vc_toggle_meta = 0;
1314 break;
1315 case 11: /* ANSI X3.64-1979 (SCO-ish?)
1316 * Select first alternate font, lets
1317 * chars < 32 be displayed as ROM chars.
1318 */
1319 vc->vc_translate = set_translate(IBMPC_MAP, vc);
1320 vc->vc_disp_ctrl = 1;
1321 vc->vc_toggle_meta = 0;
1322 break;
1323 case 12: /* ANSI X3.64-1979 (SCO-ish?)
1324 * Select second alternate font, toggle
1325 * high bit before displaying as ROM char.
1326 */
1327 vc->vc_translate = set_translate(IBMPC_MAP, vc);
1328 vc->vc_disp_ctrl = 1;
1329 vc->vc_toggle_meta = 1;
1330 break;
1331 case 21:
1332 case 22:
1333 vc->vc_intensity = 1;
1334 break;
1335 case 23:
1336 vc->vc_italic = 0;
1337 break;
1338 case 24:
1339 vc->vc_underline = 0;
1340 break;
1341 case 25:
1342 vc->vc_blink = 0;
1343 break;
1344 case 27:
1345 vc->vc_reverse = 0;
1346 break;
1347 case 38: /* ANSI X3.64-1979 (SCO-ish?)
1348 * Enables underscore, white foreground
1349 * with white underscore (Linux - use
1350 * default foreground).
1351 */
1352 vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
1353 vc->vc_underline = 1;
1354 break;
1355 case 39: /* ANSI X3.64-1979 (SCO-ish?)
1356 * Disable underline option.
1357 * Reset colour to default? It did this
1358 * before...
1359 */
1360 vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
1361 vc->vc_underline = 0;
1362 break;
1363 case 49:
1364 vc->vc_color = (vc->vc_def_color & 0xf0) | (vc->vc_color & 0x0f);
1365 break;
1366 default:
1367 if (vc->vc_par[i] >= 30 && vc->vc_par[i] <= 37)
1368 vc->vc_color = color_table[vc->vc_par[i] - 30]
1369 | (vc->vc_color & 0xf0);
1370 else if (vc->vc_par[i] >= 40 && vc->vc_par[i] <= 47)
1371 vc->vc_color = (color_table[vc->vc_par[i] - 40] << 4)
1372 | (vc->vc_color & 0x0f);
1373 break;
1374 }
1375 update_attr(vc);
1376}
1377
1378static void respond_string(const char *p, struct tty_struct *tty)
1379{
1380 while (*p) {
1381 tty_insert_flip_char(tty, *p, 0);
1382 p++;
1383 }
1384 con_schedule_flip(tty);
1385}
1386
1387static void cursor_report(struct vc_data *vc, struct tty_struct *tty)
1388{
1389 char buf[40];
1390
1391 sprintf(buf, "\033[%d;%dR", vc->vc_y + (vc->vc_decom ? vc->vc_top + 1 : 1), vc->vc_x + 1);
1392 respond_string(buf, tty);
1393}
1394
1395static inline void status_report(struct tty_struct *tty)
1396{
1397 respond_string("\033[0n", tty); /* Terminal ok */
1398}
1399
1400static inline void respond_ID(struct tty_struct * tty)
1401{
1402 respond_string(VT102ID, tty);
1403}
1404
1405void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry)
1406{
1407 char buf[8];
1408
1409 sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
1410 (char)('!' + mry));
1411 respond_string(buf, tty);
1412}
1413
1414/* invoked via ioctl(TIOCLINUX) and through set_selection */
1415int mouse_reporting(void)
1416{
1417 return vc_cons[fg_console].d->vc_report_mouse;
1418}
1419
1420/* console_lock is held */
1421static void set_mode(struct vc_data *vc, int on_off)
1422{
1423 int i;
1424
1425 for (i = 0; i <= vc->vc_npar; i++)
1426 if (vc->vc_ques) {
1427 switch(vc->vc_par[i]) { /* DEC private modes set/reset */
1428 case 1: /* Cursor keys send ^[Ox/^[[x */
1429 if (on_off)
1430 set_kbd(vc, decckm);
1431 else
1432 clr_kbd(vc, decckm);
1433 break;
1434 case 3: /* 80/132 mode switch unimplemented */
1435 vc->vc_deccolm = on_off;
1436#if 0
1437 vc_resize(deccolm ? 132 : 80, vc->vc_rows);
1438 /* this alone does not suffice; some user mode
1439 utility has to change the hardware regs */
1440#endif
1441 break;
1442 case 5: /* Inverted screen on/off */
1443 if (vc->vc_decscnm != on_off) {
1444 vc->vc_decscnm = on_off;
1445 invert_screen(vc, 0, vc->vc_screenbuf_size, 0);
1446 update_attr(vc);
1447 }
1448 break;
1449 case 6: /* Origin relative/absolute */
1450 vc->vc_decom = on_off;
1451 gotoxay(vc, 0, 0);
1452 break;
1453 case 7: /* Autowrap on/off */
1454 vc->vc_decawm = on_off;
1455 break;
1456 case 8: /* Autorepeat on/off */
1457 if (on_off)
1458 set_kbd(vc, decarm);
1459 else
1460 clr_kbd(vc, decarm);
1461 break;
1462 case 9:
1463 vc->vc_report_mouse = on_off ? 1 : 0;
1464 break;
1465 case 25: /* Cursor on/off */
1466 vc->vc_deccm = on_off;
1467 break;
1468 case 1000:
1469 vc->vc_report_mouse = on_off ? 2 : 0;
1470 break;
1471 }
1472 } else {
1473 switch(vc->vc_par[i]) { /* ANSI modes set/reset */
1474 case 3: /* Monitor (display ctrls) */
1475 vc->vc_disp_ctrl = on_off;
1476 break;
1477 case 4: /* Insert Mode on/off */
1478 vc->vc_decim = on_off;
1479 break;
1480 case 20: /* Lf, Enter == CrLf/Lf */
1481 if (on_off)
1482 set_kbd(vc, lnm);
1483 else
1484 clr_kbd(vc, lnm);
1485 break;
1486 }
1487 }
1488}
1489
1490/* console_lock is held */
1491static void setterm_command(struct vc_data *vc)
1492{
1493 switch(vc->vc_par[0]) {
1494 case 1: /* set color for underline mode */
1495 if (vc->vc_can_do_color &&
1496 vc->vc_par[1] < 16) {
1497 vc->vc_ulcolor = color_table[vc->vc_par[1]];
1498 if (vc->vc_underline)
1499 update_attr(vc);
1500 }
1501 break;
1502 case 2: /* set color for half intensity mode */
1503 if (vc->vc_can_do_color &&
1504 vc->vc_par[1] < 16) {
1505 vc->vc_halfcolor = color_table[vc->vc_par[1]];
1506 if (vc->vc_intensity == 0)
1507 update_attr(vc);
1508 }
1509 break;
1510 case 8: /* store colors as defaults */
1511 vc->vc_def_color = vc->vc_attr;
1512 if (vc->vc_hi_font_mask == 0x100)
1513 vc->vc_def_color >>= 1;
1514 default_attr(vc);
1515 update_attr(vc);
1516 break;
1517 case 9: /* set blanking interval */
1518 blankinterval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60;
1519 poke_blanked_console();
1520 break;
1521 case 10: /* set bell frequency in Hz */
1522 if (vc->vc_npar >= 1)
1523 vc->vc_bell_pitch = vc->vc_par[1];
1524 else
1525 vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
1526 break;
1527 case 11: /* set bell duration in msec */
1528 if (vc->vc_npar >= 1)
1529 vc->vc_bell_duration = (vc->vc_par[1] < 2000) ?
1530 vc->vc_par[1] * HZ / 1000 : 0;
1531 else
1532 vc->vc_bell_duration = DEFAULT_BELL_DURATION;
1533 break;
1534 case 12: /* bring specified console to the front */
1535 if (vc->vc_par[1] >= 1 && vc_cons_allocated(vc->vc_par[1] - 1))
1536 set_console(vc->vc_par[1] - 1);
1537 break;
1538 case 13: /* unblank the screen */
1539 poke_blanked_console();
1540 break;
1541 case 14: /* set vesa powerdown interval */
1542 vesa_off_interval = ((vc->vc_par[1] < 60) ? vc->vc_par[1] : 60) * 60 * HZ;
1543 break;
1544 case 15: /* activate the previous console */
1545 set_console(last_console);
1546 break;
1547 }
1548}
1549
1550/* console_lock is held */
1551static void csi_at(struct vc_data *vc, unsigned int nr)
1552{
1553 if (nr > vc->vc_cols - vc->vc_x)
1554 nr = vc->vc_cols - vc->vc_x;
1555 else if (!nr)
1556 nr = 1;
1557 insert_char(vc, nr);
1558}
1559
1560/* console_lock is held */
1561static void csi_L(struct vc_data *vc, unsigned int nr)
1562{
1563 if (nr > vc->vc_rows - vc->vc_y)
1564 nr = vc->vc_rows - vc->vc_y;
1565 else if (!nr)
1566 nr = 1;
1567 scrdown(vc, vc->vc_y, vc->vc_bottom, nr);
1568 vc->vc_need_wrap = 0;
1569}
1570
1571/* console_lock is held */
1572static void csi_P(struct vc_data *vc, unsigned int nr)
1573{
1574 if (nr > vc->vc_cols - vc->vc_x)
1575 nr = vc->vc_cols - vc->vc_x;
1576 else if (!nr)
1577 nr = 1;
1578 delete_char(vc, nr);
1579}
1580
1581/* console_lock is held */
1582static void csi_M(struct vc_data *vc, unsigned int nr)
1583{
1584 if (nr > vc->vc_rows - vc->vc_y)
1585 nr = vc->vc_rows - vc->vc_y;
1586 else if (!nr)
1587 nr=1;
1588 scrup(vc, vc->vc_y, vc->vc_bottom, nr);
1589 vc->vc_need_wrap = 0;
1590}
1591
1592/* console_lock is held (except via vc_init->reset_terminal */
1593static void save_cur(struct vc_data *vc)
1594{
1595 vc->vc_saved_x = vc->vc_x;
1596 vc->vc_saved_y = vc->vc_y;
1597 vc->vc_s_intensity = vc->vc_intensity;
1598 vc->vc_s_italic = vc->vc_italic;
1599 vc->vc_s_underline = vc->vc_underline;
1600 vc->vc_s_blink = vc->vc_blink;
1601 vc->vc_s_reverse = vc->vc_reverse;
1602 vc->vc_s_charset = vc->vc_charset;
1603 vc->vc_s_color = vc->vc_color;
1604 vc->vc_saved_G0 = vc->vc_G0_charset;
1605 vc->vc_saved_G1 = vc->vc_G1_charset;
1606}
1607
1608/* console_lock is held */
1609static void restore_cur(struct vc_data *vc)
1610{
1611 gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y);
1612 vc->vc_intensity = vc->vc_s_intensity;
1613 vc->vc_italic = vc->vc_s_italic;
1614 vc->vc_underline = vc->vc_s_underline;
1615 vc->vc_blink = vc->vc_s_blink;
1616 vc->vc_reverse = vc->vc_s_reverse;
1617 vc->vc_charset = vc->vc_s_charset;
1618 vc->vc_color = vc->vc_s_color;
1619 vc->vc_G0_charset = vc->vc_saved_G0;
1620 vc->vc_G1_charset = vc->vc_saved_G1;
1621 vc->vc_translate = set_translate(vc->vc_charset ? vc->vc_G1_charset : vc->vc_G0_charset, vc);
1622 update_attr(vc);
1623 vc->vc_need_wrap = 0;
1624}
1625
1626enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
1627 EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
1628 ESpalette };
1629
1630/* console_lock is held (except via vc_init()) */
1631static void reset_terminal(struct vc_data *vc, int do_clear)
1632{
1633 vc->vc_top = 0;
1634 vc->vc_bottom = vc->vc_rows;
1635 vc->vc_state = ESnormal;
1636 vc->vc_ques = 0;
1637 vc->vc_translate = set_translate(LAT1_MAP, vc);
1638 vc->vc_G0_charset = LAT1_MAP;
1639 vc->vc_G1_charset = GRAF_MAP;
1640 vc->vc_charset = 0;
1641 vc->vc_need_wrap = 0;
1642 vc->vc_report_mouse = 0;
1643 vc->vc_utf = default_utf8;
1644 vc->vc_utf_count = 0;
1645
1646 vc->vc_disp_ctrl = 0;
1647 vc->vc_toggle_meta = 0;
1648
1649 vc->vc_decscnm = 0;
1650 vc->vc_decom = 0;
1651 vc->vc_decawm = 1;
1652 vc->vc_deccm = global_cursor_default;
1653 vc->vc_decim = 0;
1654
1655 set_kbd(vc, decarm);
1656 clr_kbd(vc, decckm);
1657 clr_kbd(vc, kbdapplic);
1658 clr_kbd(vc, lnm);
1659 kbd_table[vc->vc_num].lockstate = 0;
1660 kbd_table[vc->vc_num].slockstate = 0;
1661 kbd_table[vc->vc_num].ledmode = LED_SHOW_FLAGS;
1662 kbd_table[vc->vc_num].ledflagstate = kbd_table[vc->vc_num].default_ledflagstate;
1663 /* do not do set_leds here because this causes an endless tasklet loop
1664 when the keyboard hasn't been initialized yet */
1665
1666 vc->vc_cursor_type = cur_default;
1667 vc->vc_complement_mask = vc->vc_s_complement_mask;
1668
1669 default_attr(vc);
1670 update_attr(vc);
1671
1672 vc->vc_tab_stop[0] = 0x01010100;
1673 vc->vc_tab_stop[1] =
1674 vc->vc_tab_stop[2] =
1675 vc->vc_tab_stop[3] =
1676 vc->vc_tab_stop[4] =
1677 vc->vc_tab_stop[5] =
1678 vc->vc_tab_stop[6] =
1679 vc->vc_tab_stop[7] = 0x01010101;
1680
1681 vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
1682 vc->vc_bell_duration = DEFAULT_BELL_DURATION;
1683
1684 gotoxy(vc, 0, 0);
1685 save_cur(vc);
1686 if (do_clear)
1687 csi_J(vc, 2);
1688}
1689
1690/* console_lock is held */
1691static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
1692{
1693 /*
1694 * Control characters can be used in the _middle_
1695 * of an escape sequence.
1696 */
1697 switch (c) {
1698 case 0:
1699 return;
1700 case 7:
1701 if (vc->vc_bell_duration)
1702 kd_mksound(vc->vc_bell_pitch, vc->vc_bell_duration);
1703 return;
1704 case 8:
1705 bs(vc);
1706 return;
1707 case 9:
1708 vc->vc_pos -= (vc->vc_x << 1);
1709 while (vc->vc_x < vc->vc_cols - 1) {
1710 vc->vc_x++;
1711 if (vc->vc_tab_stop[vc->vc_x >> 5] & (1 << (vc->vc_x & 31)))
1712 break;
1713 }
1714 vc->vc_pos += (vc->vc_x << 1);
1715 notify_write(vc, '\t');
1716 return;
1717 case 10: case 11: case 12:
1718 lf(vc);
1719 if (!is_kbd(vc, lnm))
1720 return;
1721 case 13:
1722 cr(vc);
1723 return;
1724 case 14:
1725 vc->vc_charset = 1;
1726 vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
1727 vc->vc_disp_ctrl = 1;
1728 return;
1729 case 15:
1730 vc->vc_charset = 0;
1731 vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
1732 vc->vc_disp_ctrl = 0;
1733 return;
1734 case 24: case 26:
1735 vc->vc_state = ESnormal;
1736 return;
1737 case 27:
1738 vc->vc_state = ESesc;
1739 return;
1740 case 127:
1741 del(vc);
1742 return;
1743 case 128+27:
1744 vc->vc_state = ESsquare;
1745 return;
1746 }
1747 switch(vc->vc_state) {
1748 case ESesc:
1749 vc->vc_state = ESnormal;
1750 switch (c) {
1751 case '[':
1752 vc->vc_state = ESsquare;
1753 return;
1754 case ']':
1755 vc->vc_state = ESnonstd;
1756 return;
1757 case '%':
1758 vc->vc_state = ESpercent;
1759 return;
1760 case 'E':
1761 cr(vc);
1762 lf(vc);
1763 return;
1764 case 'M':
1765 ri(vc);
1766 return;
1767 case 'D':
1768 lf(vc);
1769 return;
1770 case 'H':
1771 vc->vc_tab_stop[vc->vc_x >> 5] |= (1 << (vc->vc_x & 31));
1772 return;
1773 case 'Z':
1774 respond_ID(tty);
1775 return;
1776 case '7':
1777 save_cur(vc);
1778 return;
1779 case '8':
1780 restore_cur(vc);
1781 return;
1782 case '(':
1783 vc->vc_state = ESsetG0;
1784 return;
1785 case ')':
1786 vc->vc_state = ESsetG1;
1787 return;
1788 case '#':
1789 vc->vc_state = EShash;
1790 return;
1791 case 'c':
1792 reset_terminal(vc, 1);
1793 return;
1794 case '>': /* Numeric keypad */
1795 clr_kbd(vc, kbdapplic);
1796 return;
1797 case '=': /* Appl. keypad */
1798 set_kbd(vc, kbdapplic);
1799 return;
1800 }
1801 return;
1802 case ESnonstd:
1803 if (c=='P') { /* palette escape sequence */
1804 for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
1805 vc->vc_par[vc->vc_npar] = 0;
1806 vc->vc_npar = 0;
1807 vc->vc_state = ESpalette;
1808 return;
1809 } else if (c=='R') { /* reset palette */
1810 reset_palette(vc);
1811 vc->vc_state = ESnormal;
1812 } else
1813 vc->vc_state = ESnormal;
1814 return;
1815 case ESpalette:
1816 if (isxdigit(c)) {
1817 vc->vc_par[vc->vc_npar++] = hex_to_bin(c);
1818 if (vc->vc_npar == 7) {
1819 int i = vc->vc_par[0] * 3, j = 1;
1820 vc->vc_palette[i] = 16 * vc->vc_par[j++];
1821 vc->vc_palette[i++] += vc->vc_par[j++];
1822 vc->vc_palette[i] = 16 * vc->vc_par[j++];
1823 vc->vc_palette[i++] += vc->vc_par[j++];
1824 vc->vc_palette[i] = 16 * vc->vc_par[j++];
1825 vc->vc_palette[i] += vc->vc_par[j];
1826 set_palette(vc);
1827 vc->vc_state = ESnormal;
1828 }
1829 } else
1830 vc->vc_state = ESnormal;
1831 return;
1832 case ESsquare:
1833 for (vc->vc_npar = 0; vc->vc_npar < NPAR; vc->vc_npar++)
1834 vc->vc_par[vc->vc_npar] = 0;
1835 vc->vc_npar = 0;
1836 vc->vc_state = ESgetpars;
1837 if (c == '[') { /* Function key */
1838 vc->vc_state=ESfunckey;
1839 return;
1840 }
1841 vc->vc_ques = (c == '?');
1842 if (vc->vc_ques)
1843 return;
1844 case ESgetpars:
1845 if (c == ';' && vc->vc_npar < NPAR - 1) {
1846 vc->vc_npar++;
1847 return;
1848 } else if (c>='0' && c<='9') {
1849 vc->vc_par[vc->vc_npar] *= 10;
1850 vc->vc_par[vc->vc_npar] += c - '0';
1851 return;
1852 } else
1853 vc->vc_state = ESgotpars;
1854 case ESgotpars:
1855 vc->vc_state = ESnormal;
1856 switch(c) {
1857 case 'h':
1858 set_mode(vc, 1);
1859 return;
1860 case 'l':
1861 set_mode(vc, 0);
1862 return;
1863 case 'c':
1864 if (vc->vc_ques) {
1865 if (vc->vc_par[0])
1866 vc->vc_cursor_type = vc->vc_par[0] | (vc->vc_par[1] << 8) | (vc->vc_par[2] << 16);
1867 else
1868 vc->vc_cursor_type = cur_default;
1869 return;
1870 }
1871 break;
1872 case 'm':
1873 if (vc->vc_ques) {
1874 clear_selection();
1875 if (vc->vc_par[0])
1876 vc->vc_complement_mask = vc->vc_par[0] << 8 | vc->vc_par[1];
1877 else
1878 vc->vc_complement_mask = vc->vc_s_complement_mask;
1879 return;
1880 }
1881 break;
1882 case 'n':
1883 if (!vc->vc_ques) {
1884 if (vc->vc_par[0] == 5)
1885 status_report(tty);
1886 else if (vc->vc_par[0] == 6)
1887 cursor_report(vc, tty);
1888 }
1889 return;
1890 }
1891 if (vc->vc_ques) {
1892 vc->vc_ques = 0;
1893 return;
1894 }
1895 switch(c) {
1896 case 'G': case '`':
1897 if (vc->vc_par[0])
1898 vc->vc_par[0]--;
1899 gotoxy(vc, vc->vc_par[0], vc->vc_y);
1900 return;
1901 case 'A':
1902 if (!vc->vc_par[0])
1903 vc->vc_par[0]++;
1904 gotoxy(vc, vc->vc_x, vc->vc_y - vc->vc_par[0]);
1905 return;
1906 case 'B': case 'e':
1907 if (!vc->vc_par[0])
1908 vc->vc_par[0]++;
1909 gotoxy(vc, vc->vc_x, vc->vc_y + vc->vc_par[0]);
1910 return;
1911 case 'C': case 'a':
1912 if (!vc->vc_par[0])
1913 vc->vc_par[0]++;
1914 gotoxy(vc, vc->vc_x + vc->vc_par[0], vc->vc_y);
1915 return;
1916 case 'D':
1917 if (!vc->vc_par[0])
1918 vc->vc_par[0]++;
1919 gotoxy(vc, vc->vc_x - vc->vc_par[0], vc->vc_y);
1920 return;
1921 case 'E':
1922 if (!vc->vc_par[0])
1923 vc->vc_par[0]++;
1924 gotoxy(vc, 0, vc->vc_y + vc->vc_par[0]);
1925 return;
1926 case 'F':
1927 if (!vc->vc_par[0])
1928 vc->vc_par[0]++;
1929 gotoxy(vc, 0, vc->vc_y - vc->vc_par[0]);
1930 return;
1931 case 'd':
1932 if (vc->vc_par[0])
1933 vc->vc_par[0]--;
1934 gotoxay(vc, vc->vc_x ,vc->vc_par[0]);
1935 return;
1936 case 'H': case 'f':
1937 if (vc->vc_par[0])
1938 vc->vc_par[0]--;
1939 if (vc->vc_par[1])
1940 vc->vc_par[1]--;
1941 gotoxay(vc, vc->vc_par[1], vc->vc_par[0]);
1942 return;
1943 case 'J':
1944 csi_J(vc, vc->vc_par[0]);
1945 return;
1946 case 'K':
1947 csi_K(vc, vc->vc_par[0]);
1948 return;
1949 case 'L':
1950 csi_L(vc, vc->vc_par[0]);
1951 return;
1952 case 'M':
1953 csi_M(vc, vc->vc_par[0]);
1954 return;
1955 case 'P':
1956 csi_P(vc, vc->vc_par[0]);
1957 return;
1958 case 'c':
1959 if (!vc->vc_par[0])
1960 respond_ID(tty);
1961 return;
1962 case 'g':
1963 if (!vc->vc_par[0])
1964 vc->vc_tab_stop[vc->vc_x >> 5] &= ~(1 << (vc->vc_x & 31));
1965 else if (vc->vc_par[0] == 3) {
1966 vc->vc_tab_stop[0] =
1967 vc->vc_tab_stop[1] =
1968 vc->vc_tab_stop[2] =
1969 vc->vc_tab_stop[3] =
1970 vc->vc_tab_stop[4] =
1971 vc->vc_tab_stop[5] =
1972 vc->vc_tab_stop[6] =
1973 vc->vc_tab_stop[7] = 0;
1974 }
1975 return;
1976 case 'm':
1977 csi_m(vc);
1978 return;
1979 case 'q': /* DECLL - but only 3 leds */
1980 /* map 0,1,2,3 to 0,1,2,4 */
1981 if (vc->vc_par[0] < 4)
1982 setledstate(kbd_table + vc->vc_num,
1983 (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4);
1984 return;
1985 case 'r':
1986 if (!vc->vc_par[0])
1987 vc->vc_par[0]++;
1988 if (!vc->vc_par[1])
1989 vc->vc_par[1] = vc->vc_rows;
1990 /* Minimum allowed region is 2 lines */
1991 if (vc->vc_par[0] < vc->vc_par[1] &&
1992 vc->vc_par[1] <= vc->vc_rows) {
1993 vc->vc_top = vc->vc_par[0] - 1;
1994 vc->vc_bottom = vc->vc_par[1];
1995 gotoxay(vc, 0, 0);
1996 }
1997 return;
1998 case 's':
1999 save_cur(vc);
2000 return;
2001 case 'u':
2002 restore_cur(vc);
2003 return;
2004 case 'X':
2005 csi_X(vc, vc->vc_par[0]);
2006 return;
2007 case '@':
2008 csi_at(vc, vc->vc_par[0]);
2009 return;
2010 case ']': /* setterm functions */
2011 setterm_command(vc);
2012 return;
2013 }
2014 return;
2015 case ESpercent:
2016 vc->vc_state = ESnormal;
2017 switch (c) {
2018 case '@': /* defined in ISO 2022 */
2019 vc->vc_utf = 0;
2020 return;
2021 case 'G': /* prelim official escape code */
2022 case '8': /* retained for compatibility */
2023 vc->vc_utf = 1;
2024 return;
2025 }
2026 return;
2027 case ESfunckey:
2028 vc->vc_state = ESnormal;
2029 return;
2030 case EShash:
2031 vc->vc_state = ESnormal;
2032 if (c == '8') {
2033 /* DEC screen alignment test. kludge :-) */
2034 vc->vc_video_erase_char =
2035 (vc->vc_video_erase_char & 0xff00) | 'E';
2036 csi_J(vc, 2);
2037 vc->vc_video_erase_char =
2038 (vc->vc_video_erase_char & 0xff00) | ' ';
2039 do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
2040 }
2041 return;
2042 case ESsetG0:
2043 if (c == '0')
2044 vc->vc_G0_charset = GRAF_MAP;
2045 else if (c == 'B')
2046 vc->vc_G0_charset = LAT1_MAP;
2047 else if (c == 'U')
2048 vc->vc_G0_charset = IBMPC_MAP;
2049 else if (c == 'K')
2050 vc->vc_G0_charset = USER_MAP;
2051 if (vc->vc_charset == 0)
2052 vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
2053 vc->vc_state = ESnormal;
2054 return;
2055 case ESsetG1:
2056 if (c == '0')
2057 vc->vc_G1_charset = GRAF_MAP;
2058 else if (c == 'B')
2059 vc->vc_G1_charset = LAT1_MAP;
2060 else if (c == 'U')
2061 vc->vc_G1_charset = IBMPC_MAP;
2062 else if (c == 'K')
2063 vc->vc_G1_charset = USER_MAP;
2064 if (vc->vc_charset == 1)
2065 vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
2066 vc->vc_state = ESnormal;
2067 return;
2068 default:
2069 vc->vc_state = ESnormal;
2070 }
2071}
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_lock */
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 console_lock();
2141 vc = tty->driver_data;
2142 if (vc == NULL) {
2143 printk(KERN_ERR "vt: argh, driver_data is NULL !\n");
2144 console_unlock();
2145 return 0;
2146 }
2147
2148 currcons = vc->vc_num;
2149 if (!vc_cons_allocated(currcons)) {
2150 /* could this happen? */
2151 pr_warn_once("con_write: tty %d not allocated\n", currcons+1);
2152 console_unlock();
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 console_unlock();
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_lock.
2382 */
2383static void console_callback(struct work_struct *ignored)
2384{
2385 console_lock();
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 console_unlock();
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_lock();.
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 console_lock();
2623 ret = set_selection((struct tiocl_selection __user *)(p+1), tty);
2624 console_unlock();
2625 break;
2626 case TIOCL_PASTESEL:
2627 ret = paste_selection(tty);
2628 break;
2629 case TIOCL_UNBLANKSCREEN:
2630 console_lock();
2631 unblank_screen();
2632 console_unlock();
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 console_lock();
2682 ignore_poke = 1;
2683 do_blank_screen(0);
2684 console_unlock();
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 console_lock();
2784 vc = tty->driver_data;
2785 if (vc)
2786 set_cursor(vc);
2787 console_unlock();
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 console_lock();
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 console_unlock();
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 console_unlock();
2821 return ret;
2822 }
2823 }
2824 console_unlock();
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 console_lock();
2838 vc->port.tty = NULL;
2839 console_unlock();
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 console_lock();
2887
2888 if (conswitchp)
2889 display_desc = conswitchp->con_startup();
2890 if (!display_desc) {
2891 fg_console = 0;
2892 console_unlock();
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 pr_info("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 console_unlock();
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
2970static ssize_t show_tty_active(struct device *dev,
2971 struct device_attribute *attr, char *buf)
2972{
2973 return sprintf(buf, "tty%d\n", fg_console + 1);
2974}
2975static DEVICE_ATTR(active, S_IRUGO, show_tty_active, NULL);
2976
2977int __init vty_init(const struct file_operations *console_fops)
2978{
2979 cdev_init(&vc0_cdev, console_fops);
2980 if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
2981 register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
2982 panic("Couldn't register /dev/tty0 driver\n");
2983 tty0dev = device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
2984 if (IS_ERR(tty0dev))
2985 tty0dev = NULL;
2986 else
2987 WARN_ON(device_create_file(tty0dev, &dev_attr_active) < 0);
2988
2989 vcs_init();
2990
2991 console_driver = alloc_tty_driver(MAX_NR_CONSOLES);
2992 if (!console_driver)
2993 panic("Couldn't allocate console driver\n");
2994 console_driver->owner = THIS_MODULE;
2995 console_driver->name = "tty";
2996 console_driver->name_base = 1;
2997 console_driver->major = TTY_MAJOR;
2998 console_driver->minor_start = 1;
2999 console_driver->type = TTY_DRIVER_TYPE_CONSOLE;
3000 console_driver->init_termios = tty_std_termios;
3001 if (default_utf8)
3002 console_driver->init_termios.c_iflag |= IUTF8;
3003 console_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
3004 tty_set_operations(console_driver, &con_ops);
3005 if (tty_register_driver(console_driver))
3006 panic("Couldn't register console driver\n");
3007 kbd_init();
3008 console_map_init();
3009#ifdef CONFIG_MDA_CONSOLE
3010 mda_console_init();
3011#endif
3012 return 0;
3013}
3014
3015#ifndef VT_SINGLE_DRIVER
3016
3017static struct class *vtconsole_class;
3018
3019static int bind_con_driver(const struct consw *csw, int first, int last,
3020 int deflt)
3021{
3022 struct module *owner = csw->owner;
3023 const char *desc = NULL;
3024 struct con_driver *con_driver;
3025 int i, j = -1, k = -1, retval = -ENODEV;
3026
3027 if (!try_module_get(owner))
3028 return -ENODEV;
3029
3030 console_lock();
3031
3032 /* check if driver is registered */
3033 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3034 con_driver = &registered_con_driver[i];
3035
3036 if (con_driver->con == csw) {
3037 desc = con_driver->desc;
3038 retval = 0;
3039 break;
3040 }
3041 }
3042
3043 if (retval)
3044 goto err;
3045
3046 if (!(con_driver->flag & CON_DRIVER_FLAG_INIT)) {
3047 csw->con_startup();
3048 con_driver->flag |= CON_DRIVER_FLAG_INIT;
3049 }
3050
3051 if (deflt) {
3052 if (conswitchp)
3053 module_put(conswitchp->owner);
3054
3055 __module_get(owner);
3056 conswitchp = csw;
3057 }
3058
3059 first = max(first, con_driver->first);
3060 last = min(last, con_driver->last);
3061
3062 for (i = first; i <= last; i++) {
3063 int old_was_color;
3064 struct vc_data *vc = vc_cons[i].d;
3065
3066 if (con_driver_map[i])
3067 module_put(con_driver_map[i]->owner);
3068 __module_get(owner);
3069 con_driver_map[i] = csw;
3070
3071 if (!vc || !vc->vc_sw)
3072 continue;
3073
3074 j = i;
3075
3076 if (CON_IS_VISIBLE(vc)) {
3077 k = i;
3078 save_screen(vc);
3079 }
3080
3081 old_was_color = vc->vc_can_do_color;
3082 vc->vc_sw->con_deinit(vc);
3083 vc->vc_origin = (unsigned long)vc->vc_screenbuf;
3084 visual_init(vc, i, 0);
3085 set_origin(vc);
3086 update_attr(vc);
3087
3088 /* If the console changed between mono <-> color, then
3089 * the attributes in the screenbuf will be wrong. The
3090 * following resets all attributes to something sane.
3091 */
3092 if (old_was_color != vc->vc_can_do_color)
3093 clear_buffer_attributes(vc);
3094 }
3095
3096 pr_info("Console: switching ");
3097 if (!deflt)
3098 printk("consoles %d-%d ", first+1, last+1);
3099 if (j >= 0) {
3100 struct vc_data *vc = vc_cons[j].d;
3101
3102 printk("to %s %s %dx%d\n",
3103 vc->vc_can_do_color ? "colour" : "mono",
3104 desc, vc->vc_cols, vc->vc_rows);
3105
3106 if (k >= 0) {
3107 vc = vc_cons[k].d;
3108 update_screen(vc);
3109 }
3110 } else
3111 printk("to %s\n", desc);
3112
3113 retval = 0;
3114err:
3115 console_unlock();
3116 module_put(owner);
3117 return retval;
3118};
3119
3120#ifdef CONFIG_VT_HW_CONSOLE_BINDING
3121static int con_is_graphics(const struct consw *csw, int first, int last)
3122{
3123 int i, retval = 0;
3124
3125 for (i = first; i <= last; i++) {
3126 struct vc_data *vc = vc_cons[i].d;
3127
3128 if (vc && vc->vc_mode == KD_GRAPHICS) {
3129 retval = 1;
3130 break;
3131 }
3132 }
3133
3134 return retval;
3135}
3136
3137/**
3138 * unbind_con_driver - unbind a console driver
3139 * @csw: pointer to console driver to unregister
3140 * @first: first in range of consoles that @csw should be unbound from
3141 * @last: last in range of consoles that @csw should be unbound from
3142 * @deflt: should next bound console driver be default after @csw is unbound?
3143 *
3144 * To unbind a driver from all possible consoles, pass 0 as @first and
3145 * %MAX_NR_CONSOLES as @last.
3146 *
3147 * @deflt controls whether the console that ends up replacing @csw should be
3148 * the default console.
3149 *
3150 * RETURNS:
3151 * -ENODEV if @csw isn't a registered console driver or can't be unregistered
3152 * or 0 on success.
3153 */
3154int unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3155{
3156 struct module *owner = csw->owner;
3157 const struct consw *defcsw = NULL;
3158 struct con_driver *con_driver = NULL, *con_back = NULL;
3159 int i, retval = -ENODEV;
3160
3161 if (!try_module_get(owner))
3162 return -ENODEV;
3163
3164 console_lock();
3165
3166 /* check if driver is registered and if it is unbindable */
3167 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3168 con_driver = &registered_con_driver[i];
3169
3170 if (con_driver->con == csw &&
3171 con_driver->flag & CON_DRIVER_FLAG_MODULE) {
3172 retval = 0;
3173 break;
3174 }
3175 }
3176
3177 if (retval) {
3178 console_unlock();
3179 goto err;
3180 }
3181
3182 retval = -ENODEV;
3183
3184 /* check if backup driver exists */
3185 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3186 con_back = &registered_con_driver[i];
3187
3188 if (con_back->con &&
3189 !(con_back->flag & CON_DRIVER_FLAG_MODULE)) {
3190 defcsw = con_back->con;
3191 retval = 0;
3192 break;
3193 }
3194 }
3195
3196 if (retval) {
3197 console_unlock();
3198 goto err;
3199 }
3200
3201 if (!con_is_bound(csw)) {
3202 console_unlock();
3203 goto err;
3204 }
3205
3206 first = max(first, con_driver->first);
3207 last = min(last, con_driver->last);
3208
3209 for (i = first; i <= last; i++) {
3210 if (con_driver_map[i] == csw) {
3211 module_put(csw->owner);
3212 con_driver_map[i] = NULL;
3213 }
3214 }
3215
3216 if (!con_is_bound(defcsw)) {
3217 const struct consw *defconsw = conswitchp;
3218
3219 defcsw->con_startup();
3220 con_back->flag |= CON_DRIVER_FLAG_INIT;
3221 /*
3222 * vgacon may change the default driver to point
3223 * to dummycon, we restore it here...
3224 */
3225 conswitchp = defconsw;
3226 }
3227
3228 if (!con_is_bound(csw))
3229 con_driver->flag &= ~CON_DRIVER_FLAG_INIT;
3230
3231 console_unlock();
3232 /* ignore return value, binding should not fail */
3233 bind_con_driver(defcsw, first, last, deflt);
3234err:
3235 module_put(owner);
3236 return retval;
3237
3238}
3239EXPORT_SYMBOL(unbind_con_driver);
3240
3241static int vt_bind(struct con_driver *con)
3242{
3243 const struct consw *defcsw = NULL, *csw = NULL;
3244 int i, more = 1, first = -1, last = -1, deflt = 0;
3245
3246 if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) ||
3247 con_is_graphics(con->con, con->first, con->last))
3248 goto err;
3249
3250 csw = con->con;
3251
3252 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3253 struct con_driver *con = &registered_con_driver[i];
3254
3255 if (con->con && !(con->flag & CON_DRIVER_FLAG_MODULE)) {
3256 defcsw = con->con;
3257 break;
3258 }
3259 }
3260
3261 if (!defcsw)
3262 goto err;
3263
3264 while (more) {
3265 more = 0;
3266
3267 for (i = con->first; i <= con->last; i++) {
3268 if (con_driver_map[i] == defcsw) {
3269 if (first == -1)
3270 first = i;
3271 last = i;
3272 more = 1;
3273 } else if (first != -1)
3274 break;
3275 }
3276
3277 if (first == 0 && last == MAX_NR_CONSOLES -1)
3278 deflt = 1;
3279
3280 if (first != -1)
3281 bind_con_driver(csw, first, last, deflt);
3282
3283 first = -1;
3284 last = -1;
3285 deflt = 0;
3286 }
3287
3288err:
3289 return 0;
3290}
3291
3292static int vt_unbind(struct con_driver *con)
3293{
3294 const struct consw *csw = NULL;
3295 int i, more = 1, first = -1, last = -1, deflt = 0;
3296
3297 if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE) ||
3298 con_is_graphics(con->con, con->first, con->last))
3299 goto err;
3300
3301 csw = con->con;
3302
3303 while (more) {
3304 more = 0;
3305
3306 for (i = con->first; i <= con->last; i++) {
3307 if (con_driver_map[i] == csw) {
3308 if (first == -1)
3309 first = i;
3310 last = i;
3311 more = 1;
3312 } else if (first != -1)
3313 break;
3314 }
3315
3316 if (first == 0 && last == MAX_NR_CONSOLES -1)
3317 deflt = 1;
3318
3319 if (first != -1)
3320 unbind_con_driver(csw, first, last, deflt);
3321
3322 first = -1;
3323 last = -1;
3324 deflt = 0;
3325 }
3326
3327err:
3328 return 0;
3329}
3330#else
3331static inline int vt_bind(struct con_driver *con)
3332{
3333 return 0;
3334}
3335static inline int vt_unbind(struct con_driver *con)
3336{
3337 return 0;
3338}
3339#endif /* CONFIG_VT_HW_CONSOLE_BINDING */
3340
3341static ssize_t store_bind(struct device *dev, struct device_attribute *attr,
3342 const char *buf, size_t count)
3343{
3344 struct con_driver *con = dev_get_drvdata(dev);
3345 int bind = simple_strtoul(buf, NULL, 0);
3346
3347 if (bind)
3348 vt_bind(con);
3349 else
3350 vt_unbind(con);
3351
3352 return count;
3353}
3354
3355static ssize_t show_bind(struct device *dev, struct device_attribute *attr,
3356 char *buf)
3357{
3358 struct con_driver *con = dev_get_drvdata(dev);
3359 int bind = con_is_bound(con->con);
3360
3361 return snprintf(buf, PAGE_SIZE, "%i\n", bind);
3362}
3363
3364static ssize_t show_name(struct device *dev, struct device_attribute *attr,
3365 char *buf)
3366{
3367 struct con_driver *con = dev_get_drvdata(dev);
3368
3369 return snprintf(buf, PAGE_SIZE, "%s %s\n",
3370 (con->flag & CON_DRIVER_FLAG_MODULE) ? "(M)" : "(S)",
3371 con->desc);
3372
3373}
3374
3375static struct device_attribute device_attrs[] = {
3376 __ATTR(bind, S_IRUGO|S_IWUSR, show_bind, store_bind),
3377 __ATTR(name, S_IRUGO, show_name, NULL),
3378};
3379
3380static int vtconsole_init_device(struct con_driver *con)
3381{
3382 int i;
3383 int error = 0;
3384
3385 con->flag |= CON_DRIVER_FLAG_ATTR;
3386 dev_set_drvdata(con->dev, con);
3387 for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
3388 error = device_create_file(con->dev, &device_attrs[i]);
3389 if (error)
3390 break;
3391 }
3392
3393 if (error) {
3394 while (--i >= 0)
3395 device_remove_file(con->dev, &device_attrs[i]);
3396 con->flag &= ~CON_DRIVER_FLAG_ATTR;
3397 }
3398
3399 return error;
3400}
3401
3402static void vtconsole_deinit_device(struct con_driver *con)
3403{
3404 int i;
3405
3406 if (con->flag & CON_DRIVER_FLAG_ATTR) {
3407 for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
3408 device_remove_file(con->dev, &device_attrs[i]);
3409 con->flag &= ~CON_DRIVER_FLAG_ATTR;
3410 }
3411}
3412
3413/**
3414 * con_is_bound - checks if driver is bound to the console
3415 * @csw: console driver
3416 *
3417 * RETURNS: zero if unbound, nonzero if bound
3418 *
3419 * Drivers can call this and if zero, they should release
3420 * all resources allocated on con_startup()
3421 */
3422int con_is_bound(const struct consw *csw)
3423{
3424 int i, bound = 0;
3425
3426 for (i = 0; i < MAX_NR_CONSOLES; i++) {
3427 if (con_driver_map[i] == csw) {
3428 bound = 1;
3429 break;
3430 }
3431 }
3432
3433 return bound;
3434}
3435EXPORT_SYMBOL(con_is_bound);
3436
3437/**
3438 * con_debug_enter - prepare the console for the kernel debugger
3439 * @sw: console driver
3440 *
3441 * Called when the console is taken over by the kernel debugger, this
3442 * function needs to save the current console state, then put the console
3443 * into a state suitable for the kernel debugger.
3444 *
3445 * RETURNS:
3446 * Zero on success, nonzero if a failure occurred when trying to prepare
3447 * the console for the debugger.
3448 */
3449int con_debug_enter(struct vc_data *vc)
3450{
3451 int ret = 0;
3452
3453 saved_fg_console = fg_console;
3454 saved_last_console = last_console;
3455 saved_want_console = want_console;
3456 saved_vc_mode = vc->vc_mode;
3457 saved_console_blanked = console_blanked;
3458 vc->vc_mode = KD_TEXT;
3459 console_blanked = 0;
3460 if (vc->vc_sw->con_debug_enter)
3461 ret = vc->vc_sw->con_debug_enter(vc);
3462#ifdef CONFIG_KGDB_KDB
3463 /* Set the initial LINES variable if it is not already set */
3464 if (vc->vc_rows < 999) {
3465 int linecount;
3466 char lns[4];
3467 const char *setargs[3] = {
3468 "set",
3469 "LINES",
3470 lns,
3471 };
3472 if (kdbgetintenv(setargs[0], &linecount)) {
3473 snprintf(lns, 4, "%i", vc->vc_rows);
3474 kdb_set(2, setargs);
3475 }
3476 }
3477#endif /* CONFIG_KGDB_KDB */
3478 return ret;
3479}
3480EXPORT_SYMBOL_GPL(con_debug_enter);
3481
3482/**
3483 * con_debug_leave - restore console state
3484 * @sw: console driver
3485 *
3486 * Restore the console state to what it was before the kernel debugger
3487 * was invoked.
3488 *
3489 * RETURNS:
3490 * Zero on success, nonzero if a failure occurred when trying to restore
3491 * the console.
3492 */
3493int con_debug_leave(void)
3494{
3495 struct vc_data *vc;
3496 int ret = 0;
3497
3498 fg_console = saved_fg_console;
3499 last_console = saved_last_console;
3500 want_console = saved_want_console;
3501 console_blanked = saved_console_blanked;
3502 vc_cons[fg_console].d->vc_mode = saved_vc_mode;
3503
3504 vc = vc_cons[fg_console].d;
3505 if (vc->vc_sw->con_debug_leave)
3506 ret = vc->vc_sw->con_debug_leave(vc);
3507 return ret;
3508}
3509EXPORT_SYMBOL_GPL(con_debug_leave);
3510
3511/**
3512 * register_con_driver - register console driver to console layer
3513 * @csw: console driver
3514 * @first: the first console to take over, minimum value is 0
3515 * @last: the last console to take over, maximum value is MAX_NR_CONSOLES -1
3516 *
3517 * DESCRIPTION: This function registers a console driver which can later
3518 * bind to a range of consoles specified by @first and @last. It will
3519 * also initialize the console driver by calling con_startup().
3520 */
3521int register_con_driver(const struct consw *csw, int first, int last)
3522{
3523 struct module *owner = csw->owner;
3524 struct con_driver *con_driver;
3525 const char *desc;
3526 int i, retval = 0;
3527
3528 if (!try_module_get(owner))
3529 return -ENODEV;
3530
3531 console_lock();
3532
3533 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3534 con_driver = &registered_con_driver[i];
3535
3536 /* already registered */
3537 if (con_driver->con == csw)
3538 retval = -EBUSY;
3539 }
3540
3541 if (retval)
3542 goto err;
3543
3544 desc = csw->con_startup();
3545
3546 if (!desc)
3547 goto err;
3548
3549 retval = -EINVAL;
3550
3551 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3552 con_driver = &registered_con_driver[i];
3553
3554 if (con_driver->con == NULL) {
3555 con_driver->con = csw;
3556 con_driver->desc = desc;
3557 con_driver->node = i;
3558 con_driver->flag = CON_DRIVER_FLAG_MODULE |
3559 CON_DRIVER_FLAG_INIT;
3560 con_driver->first = first;
3561 con_driver->last = last;
3562 retval = 0;
3563 break;
3564 }
3565 }
3566
3567 if (retval)
3568 goto err;
3569
3570 con_driver->dev = device_create(vtconsole_class, NULL,
3571 MKDEV(0, con_driver->node),
3572 NULL, "vtcon%i",
3573 con_driver->node);
3574
3575 if (IS_ERR(con_driver->dev)) {
3576 printk(KERN_WARNING "Unable to create device for %s; "
3577 "errno = %ld\n", con_driver->desc,
3578 PTR_ERR(con_driver->dev));
3579 con_driver->dev = NULL;
3580 } else {
3581 vtconsole_init_device(con_driver);
3582 }
3583
3584err:
3585 console_unlock();
3586 module_put(owner);
3587 return retval;
3588}
3589EXPORT_SYMBOL(register_con_driver);
3590
3591/**
3592 * unregister_con_driver - unregister console driver from console layer
3593 * @csw: console driver
3594 *
3595 * DESCRIPTION: All drivers that registers to the console layer must
3596 * call this function upon exit, or if the console driver is in a state
3597 * where it won't be able to handle console services, such as the
3598 * framebuffer console without loaded framebuffer drivers.
3599 *
3600 * The driver must unbind first prior to unregistration.
3601 */
3602int unregister_con_driver(const struct consw *csw)
3603{
3604 int i, retval = -ENODEV;
3605
3606 console_lock();
3607
3608 /* cannot unregister a bound driver */
3609 if (con_is_bound(csw))
3610 goto err;
3611
3612 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3613 struct con_driver *con_driver = &registered_con_driver[i];
3614
3615 if (con_driver->con == csw &&
3616 con_driver->flag & CON_DRIVER_FLAG_MODULE) {
3617 vtconsole_deinit_device(con_driver);
3618 device_destroy(vtconsole_class,
3619 MKDEV(0, con_driver->node));
3620 con_driver->con = NULL;
3621 con_driver->desc = NULL;
3622 con_driver->dev = NULL;
3623 con_driver->node = 0;
3624 con_driver->flag = 0;
3625 con_driver->first = 0;
3626 con_driver->last = 0;
3627 retval = 0;
3628 break;
3629 }
3630 }
3631err:
3632 console_unlock();
3633 return retval;
3634}
3635EXPORT_SYMBOL(unregister_con_driver);
3636
3637/*
3638 * If we support more console drivers, this function is used
3639 * when a driver wants to take over some existing consoles
3640 * and become default driver for newly opened ones.
3641 *
3642 * take_over_console is basically a register followed by unbind
3643 */
3644int take_over_console(const struct consw *csw, int first, int last, int deflt)
3645{
3646 int err;
3647
3648 err = register_con_driver(csw, first, last);
3649 /* if we get an busy error we still want to bind the console driver
3650 * and return success, as we may have unbound the console driver
3651  * but not unregistered it.
3652 */
3653 if (err == -EBUSY)
3654 err = 0;
3655 if (!err)
3656 bind_con_driver(csw, first, last, deflt);
3657
3658 return err;
3659}
3660
3661/*
3662 * give_up_console is a wrapper to unregister_con_driver. It will only
3663 * work if driver is fully unbound.
3664 */
3665void give_up_console(const struct consw *csw)
3666{
3667 unregister_con_driver(csw);
3668}
3669
3670static int __init vtconsole_class_init(void)
3671{
3672 int i;
3673
3674 vtconsole_class = class_create(THIS_MODULE, "vtconsole");
3675 if (IS_ERR(vtconsole_class)) {
3676 printk(KERN_WARNING "Unable to create vt console class; "
3677 "errno = %ld\n", PTR_ERR(vtconsole_class));
3678 vtconsole_class = NULL;
3679 }
3680
3681 /* Add system drivers to sysfs */
3682 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3683 struct con_driver *con = &registered_con_driver[i];
3684
3685 if (con->con && !con->dev) {
3686 con->dev = device_create(vtconsole_class, NULL,
3687 MKDEV(0, con->node),
3688 NULL, "vtcon%i",
3689 con->node);
3690
3691 if (IS_ERR(con->dev)) {
3692 printk(KERN_WARNING "Unable to create "
3693 "device for %s; errno = %ld\n",
3694 con->desc, PTR_ERR(con->dev));
3695 con->dev = NULL;
3696 } else {
3697 vtconsole_init_device(con);
3698 }
3699 }
3700 }
3701
3702 return 0;
3703}
3704postcore_initcall(vtconsole_class_init);
3705
3706#endif
3707
3708/*
3709 * Screen blanking
3710 */
3711
3712static int set_vesa_blanking(char __user *p)
3713{
3714 unsigned int mode;
3715
3716 if (get_user(mode, p + 1))
3717 return -EFAULT;
3718
3719 vesa_blank_mode = (mode < 4) ? mode : 0;
3720 return 0;
3721}
3722
3723void do_blank_screen(int entering_gfx)
3724{
3725 struct vc_data *vc = vc_cons[fg_console].d;
3726 int i;
3727
3728 WARN_CONSOLE_UNLOCKED();
3729
3730 if (console_blanked) {
3731 if (blank_state == blank_vesa_wait) {
3732 blank_state = blank_off;
3733 vc->vc_sw->con_blank(vc, vesa_blank_mode + 1, 0);
3734 }
3735 return;
3736 }
3737
3738 /* entering graphics mode? */
3739 if (entering_gfx) {
3740 hide_cursor(vc);
3741 save_screen(vc);
3742 vc->vc_sw->con_blank(vc, -1, 1);
3743 console_blanked = fg_console + 1;
3744 blank_state = blank_off;
3745 set_origin(vc);
3746 return;
3747 }
3748
3749 if (blank_state != blank_normal_wait)
3750 return;
3751 blank_state = blank_off;
3752
3753 /* don't blank graphics */
3754 if (vc->vc_mode != KD_TEXT) {
3755 console_blanked = fg_console + 1;
3756 return;
3757 }
3758
3759 hide_cursor(vc);
3760 del_timer_sync(&console_timer);
3761 blank_timer_expired = 0;
3762
3763 save_screen(vc);
3764 /* In case we need to reset origin, blanking hook returns 1 */
3765 i = vc->vc_sw->con_blank(vc, vesa_off_interval ? 1 : (vesa_blank_mode + 1), 0);
3766 console_blanked = fg_console + 1;
3767 if (i)
3768 set_origin(vc);
3769
3770 if (console_blank_hook && console_blank_hook(1))
3771 return;
3772
3773 if (vesa_off_interval && vesa_blank_mode) {
3774 blank_state = blank_vesa_wait;
3775 mod_timer(&console_timer, jiffies + vesa_off_interval);
3776 }
3777 vt_event_post(VT_EVENT_BLANK, vc->vc_num, vc->vc_num);
3778}
3779EXPORT_SYMBOL(do_blank_screen);
3780
3781/*
3782 * Called by timer as well as from vt_console_driver
3783 */
3784void do_unblank_screen(int leaving_gfx)
3785{
3786 struct vc_data *vc;
3787
3788 /* This should now always be called from a "sane" (read: can schedule)
3789 * context for the sake of the low level drivers, except in the special
3790 * case of oops_in_progress
3791 */
3792 if (!oops_in_progress)
3793 might_sleep();
3794
3795 WARN_CONSOLE_UNLOCKED();
3796
3797 ignore_poke = 0;
3798 if (!console_blanked)
3799 return;
3800 if (!vc_cons_allocated(fg_console)) {
3801 /* impossible */
3802 pr_warning("unblank_screen: tty %d not allocated ??\n",
3803 fg_console+1);
3804 return;
3805 }
3806 vc = vc_cons[fg_console].d;
3807 /* Try to unblank in oops case too */
3808 if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc))
3809 return; /* but leave console_blanked != 0 */
3810
3811 if (blankinterval) {
3812 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
3813 blank_state = blank_normal_wait;
3814 }
3815
3816 console_blanked = 0;
3817 if (vc->vc_sw->con_blank(vc, 0, leaving_gfx) || vt_force_oops_output(vc))
3818 /* Low-level driver cannot restore -> do it ourselves */
3819 update_screen(vc);
3820 if (console_blank_hook)
3821 console_blank_hook(0);
3822 set_palette(vc);
3823 set_cursor(vc);
3824 vt_event_post(VT_EVENT_UNBLANK, vc->vc_num, vc->vc_num);
3825}
3826EXPORT_SYMBOL(do_unblank_screen);
3827
3828/*
3829 * This is called by the outside world to cause a forced unblank, mostly for
3830 * oopses. Currently, I just call do_unblank_screen(0), but we could eventually
3831 * call it with 1 as an argument and so force a mode restore... that may kill
3832 * X or at least garbage the screen but would also make the Oops visible...
3833 */
3834void unblank_screen(void)
3835{
3836 do_unblank_screen(0);
3837}
3838
3839/*
3840 * We defer the timer blanking to work queue so it can take the console mutex
3841 * (console operations can still happen at irq time, but only from printk which
3842 * has the console mutex. Not perfect yet, but better than no locking
3843 */
3844static void blank_screen_t(unsigned long dummy)
3845{
3846 if (unlikely(!keventd_up())) {
3847 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
3848 return;
3849 }
3850 blank_timer_expired = 1;
3851 schedule_work(&console_work);
3852}
3853
3854void poke_blanked_console(void)
3855{
3856 WARN_CONSOLE_UNLOCKED();
3857
3858 /* Add this so we quickly catch whoever might call us in a non
3859 * safe context. Nowadays, unblank_screen() isn't to be called in
3860 * atomic contexts and is allowed to schedule (with the special case
3861 * of oops_in_progress, but that isn't of any concern for this
3862 * function. --BenH.
3863 */
3864 might_sleep();
3865
3866 /* This isn't perfectly race free, but a race here would be mostly harmless,
3867 * at worse, we'll do a spurrious blank and it's unlikely
3868 */
3869 del_timer(&console_timer);
3870 blank_timer_expired = 0;
3871
3872 if (ignore_poke || !vc_cons[fg_console].d || vc_cons[fg_console].d->vc_mode == KD_GRAPHICS)
3873 return;
3874 if (console_blanked)
3875 unblank_screen();
3876 else if (blankinterval) {
3877 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
3878 blank_state = blank_normal_wait;
3879 }
3880}
3881
3882/*
3883 * Palettes
3884 */
3885
3886static void set_palette(struct vc_data *vc)
3887{
3888 WARN_CONSOLE_UNLOCKED();
3889
3890 if (vc->vc_mode != KD_GRAPHICS)
3891 vc->vc_sw->con_set_palette(vc, color_table);
3892}
3893
3894static int set_get_cmap(unsigned char __user *arg, int set)
3895{
3896 int i, j, k;
3897
3898 WARN_CONSOLE_UNLOCKED();
3899
3900 for (i = 0; i < 16; i++)
3901 if (set) {
3902 get_user(default_red[i], arg++);
3903 get_user(default_grn[i], arg++);
3904 get_user(default_blu[i], arg++);
3905 } else {
3906 put_user(default_red[i], arg++);
3907 put_user(default_grn[i], arg++);
3908 put_user(default_blu[i], arg++);
3909 }
3910 if (set) {
3911 for (i = 0; i < MAX_NR_CONSOLES; i++)
3912 if (vc_cons_allocated(i)) {
3913 for (j = k = 0; j < 16; j++) {
3914 vc_cons[i].d->vc_palette[k++] = default_red[j];
3915 vc_cons[i].d->vc_palette[k++] = default_grn[j];
3916 vc_cons[i].d->vc_palette[k++] = default_blu[j];
3917 }
3918 set_palette(vc_cons[i].d);
3919 }
3920 }
3921 return 0;
3922}
3923
3924/*
3925 * Load palette into the DAC registers. arg points to a colour
3926 * map, 3 bytes per colour, 16 colours, range from 0 to 255.
3927 */
3928
3929int con_set_cmap(unsigned char __user *arg)
3930{
3931 int rc;
3932
3933 console_lock();
3934 rc = set_get_cmap (arg,1);
3935 console_unlock();
3936
3937 return rc;
3938}
3939
3940int con_get_cmap(unsigned char __user *arg)
3941{
3942 int rc;
3943
3944 console_lock();
3945 rc = set_get_cmap (arg,0);
3946 console_unlock();
3947
3948 return rc;
3949}
3950
3951void reset_palette(struct vc_data *vc)
3952{
3953 int j, k;
3954 for (j=k=0; j<16; j++) {
3955 vc->vc_palette[k++] = default_red[j];
3956 vc->vc_palette[k++] = default_grn[j];
3957 vc->vc_palette[k++] = default_blu[j];
3958 }
3959 set_palette(vc);
3960}
3961
3962/*
3963 * Font switching
3964 *
3965 * Currently we only support fonts up to 32 pixels wide, at a maximum height
3966 * of 32 pixels. Userspace fontdata is stored with 32 bytes (shorts/ints,
3967 * depending on width) reserved for each character which is kinda wasty, but
3968 * this is done in order to maintain compatibility with the EGA/VGA fonts. It
3969 * is up to the actual low-level console-driver convert data into its favorite
3970 * format (maybe we should add a `fontoffset' field to the `display'
3971 * structure so we won't have to convert the fontdata all the time.
3972 * /Jes
3973 */
3974
3975#define max_font_size 65536
3976
3977static int con_font_get(struct vc_data *vc, struct console_font_op *op)
3978{
3979 struct console_font font;
3980 int rc = -EINVAL;
3981 int c;
3982
3983 if (vc->vc_mode != KD_TEXT)
3984 return -EINVAL;
3985
3986 if (op->data) {
3987 font.data = kmalloc(max_font_size, GFP_KERNEL);
3988 if (!font.data)
3989 return -ENOMEM;
3990 } else
3991 font.data = NULL;
3992
3993 console_lock();
3994 if (vc->vc_sw->con_font_get)
3995 rc = vc->vc_sw->con_font_get(vc, &font);
3996 else
3997 rc = -ENOSYS;
3998 console_unlock();
3999
4000 if (rc)
4001 goto out;
4002
4003 c = (font.width+7)/8 * 32 * font.charcount;
4004
4005 if (op->data && font.charcount > op->charcount)
4006 rc = -ENOSPC;
4007 if (!(op->flags & KD_FONT_FLAG_OLD)) {
4008 if (font.width > op->width || font.height > op->height)
4009 rc = -ENOSPC;
4010 } else {
4011 if (font.width != 8)
4012 rc = -EIO;
4013 else if ((op->height && font.height > op->height) ||
4014 font.height > 32)
4015 rc = -ENOSPC;
4016 }
4017 if (rc)
4018 goto out;
4019
4020 op->height = font.height;
4021 op->width = font.width;
4022 op->charcount = font.charcount;
4023
4024 if (op->data && copy_to_user(op->data, font.data, c))
4025 rc = -EFAULT;
4026
4027out:
4028 kfree(font.data);
4029 return rc;
4030}
4031
4032static int con_font_set(struct vc_data *vc, struct console_font_op *op)
4033{
4034 struct console_font font;
4035 int rc = -EINVAL;
4036 int size;
4037
4038 if (vc->vc_mode != KD_TEXT)
4039 return -EINVAL;
4040 if (!op->data)
4041 return -EINVAL;
4042 if (op->charcount > 512)
4043 return -EINVAL;
4044 if (!op->height) { /* Need to guess font height [compat] */
4045 int h, i;
4046 u8 __user *charmap = op->data;
4047 u8 tmp;
4048
4049 /* If from KDFONTOP ioctl, don't allow things which can be done in userland,
4050 so that we can get rid of this soon */
4051 if (!(op->flags & KD_FONT_FLAG_OLD))
4052 return -EINVAL;
4053 for (h = 32; h > 0; h--)
4054 for (i = 0; i < op->charcount; i++) {
4055 if (get_user(tmp, &charmap[32*i+h-1]))
4056 return -EFAULT;
4057 if (tmp)
4058 goto nonzero;
4059 }
4060 return -EINVAL;
4061 nonzero:
4062 op->height = h;
4063 }
4064 if (op->width <= 0 || op->width > 32 || op->height > 32)
4065 return -EINVAL;
4066 size = (op->width+7)/8 * 32 * op->charcount;
4067 if (size > max_font_size)
4068 return -ENOSPC;
4069 font.charcount = op->charcount;
4070 font.height = op->height;
4071 font.width = op->width;
4072 font.data = memdup_user(op->data, size);
4073 if (IS_ERR(font.data))
4074 return PTR_ERR(font.data);
4075 console_lock();
4076 if (vc->vc_sw->con_font_set)
4077 rc = vc->vc_sw->con_font_set(vc, &font, op->flags);
4078 else
4079 rc = -ENOSYS;
4080 console_unlock();
4081 kfree(font.data);
4082 return rc;
4083}
4084
4085static int con_font_default(struct vc_data *vc, struct console_font_op *op)
4086{
4087 struct console_font font = {.width = op->width, .height = op->height};
4088 char name[MAX_FONT_NAME];
4089 char *s = name;
4090 int rc;
4091
4092 if (vc->vc_mode != KD_TEXT)
4093 return -EINVAL;
4094
4095 if (!op->data)
4096 s = NULL;
4097 else if (strncpy_from_user(name, op->data, MAX_FONT_NAME - 1) < 0)
4098 return -EFAULT;
4099 else
4100 name[MAX_FONT_NAME - 1] = 0;
4101
4102 console_lock();
4103 if (vc->vc_sw->con_font_default)
4104 rc = vc->vc_sw->con_font_default(vc, &font, s);
4105 else
4106 rc = -ENOSYS;
4107 console_unlock();
4108 if (!rc) {
4109 op->width = font.width;
4110 op->height = font.height;
4111 }
4112 return rc;
4113}
4114
4115static int con_font_copy(struct vc_data *vc, struct console_font_op *op)
4116{
4117 int con = op->height;
4118 int rc;
4119
4120 if (vc->vc_mode != KD_TEXT)
4121 return -EINVAL;
4122
4123 console_lock();
4124 if (!vc->vc_sw->con_font_copy)
4125 rc = -ENOSYS;
4126 else if (con < 0 || !vc_cons_allocated(con))
4127 rc = -ENOTTY;
4128 else if (con == vc->vc_num) /* nothing to do */
4129 rc = 0;
4130 else
4131 rc = vc->vc_sw->con_font_copy(vc, con);
4132 console_unlock();
4133 return rc;
4134}
4135
4136int con_font_op(struct vc_data *vc, struct console_font_op *op)
4137{
4138 switch (op->op) {
4139 case KD_FONT_OP_SET:
4140 return con_font_set(vc, op);
4141 case KD_FONT_OP_GET:
4142 return con_font_get(vc, op);
4143 case KD_FONT_OP_SET_DEFAULT:
4144 return con_font_default(vc, op);
4145 case KD_FONT_OP_COPY:
4146 return con_font_copy(vc, op);
4147 }
4148 return -ENOSYS;
4149}
4150
4151/*
4152 * Interface exported to selection and vcs.
4153 */
4154
4155/* used by selection */
4156u16 screen_glyph(struct vc_data *vc, int offset)
4157{
4158 u16 w = scr_readw(screenpos(vc, offset, 1));
4159 u16 c = w & 0xff;
4160
4161 if (w & vc->vc_hi_font_mask)
4162 c |= 0x100;
4163 return c;
4164}
4165EXPORT_SYMBOL_GPL(screen_glyph);
4166
4167/* used by vcs - note the word offset */
4168unsigned short *screen_pos(struct vc_data *vc, int w_offset, int viewed)
4169{
4170 return screenpos(vc, 2 * w_offset, viewed);
4171}
4172
4173void getconsxy(struct vc_data *vc, unsigned char *p)
4174{
4175 p[0] = vc->vc_x;
4176 p[1] = vc->vc_y;
4177}
4178
4179void putconsxy(struct vc_data *vc, unsigned char *p)
4180{
4181 hide_cursor(vc);
4182 gotoxy(vc, p[0], p[1]);
4183 set_cursor(vc);
4184}
4185
4186u16 vcs_scr_readw(struct vc_data *vc, const u16 *org)
4187{
4188 if ((unsigned long)org == vc->vc_pos && softcursor_original != -1)
4189 return softcursor_original;
4190 return scr_readw(org);
4191}
4192
4193void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org)
4194{
4195 scr_writew(val, org);
4196 if ((unsigned long)org == vc->vc_pos) {
4197 softcursor_original = -1;
4198 add_softcursor(vc);
4199 }
4200}
4201
4202void vcs_scr_updated(struct vc_data *vc)
4203{
4204 notify_update(vc);
4205}
4206
4207/*
4208 * Visible symbols for modules
4209 */
4210
4211EXPORT_SYMBOL(color_table);
4212EXPORT_SYMBOL(default_red);
4213EXPORT_SYMBOL(default_grn);
4214EXPORT_SYMBOL(default_blu);
4215EXPORT_SYMBOL(update_region);
4216EXPORT_SYMBOL(redraw_screen);
4217EXPORT_SYMBOL(vc_resize);
4218EXPORT_SYMBOL(fg_console);
4219EXPORT_SYMBOL(console_blank_hook);
4220EXPORT_SYMBOL(console_blanked);
4221EXPORT_SYMBOL(vc_cons);
4222EXPORT_SYMBOL(global_cursor_default);
4223#ifndef VT_SINGLE_DRIVER
4224EXPORT_SYMBOL(take_over_console);
4225EXPORT_SYMBOL(give_up_console);
4226#endif
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
new file mode 100644
index 000000000000..5e096f43bcea
--- /dev/null
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -0,0 +1,1800 @@
1/*
2 * Copyright (C) 1992 obz under the linux copyright
3 *
4 * Dynamic diacritical handling - aeb@cwi.nl - Dec 1993
5 * Dynamic keymap and string allocation - aeb@cwi.nl - May 1994
6 * Restrict VT switching via ioctl() - grif@cs.ucr.edu - Dec 1995
7 * Some code moved for less code duplication - Andi Kleen - Mar 1997
8 * Check put/get_user, cleanups - acme@conectiva.com.br - Jun 2001
9 */
10
11#include <linux/types.h>
12#include <linux/errno.h>
13#include <linux/sched.h>
14#include <linux/tty.h>
15#include <linux/timer.h>
16#include <linux/kernel.h>
17#include <linux/compat.h>
18#include <linux/module.h>
19#include <linux/kd.h>
20#include <linux/vt.h>
21#include <linux/string.h>
22#include <linux/slab.h>
23#include <linux/major.h>
24#include <linux/fs.h>
25#include <linux/console.h>
26#include <linux/consolemap.h>
27#include <linux/signal.h>
28#include <linux/timex.h>
29
30#include <asm/io.h>
31#include <asm/uaccess.h>
32
33#include <linux/kbd_kern.h>
34#include <linux/vt_kern.h>
35#include <linux/kbd_diacr.h>
36#include <linux/selection.h>
37
38char vt_dont_switch;
39extern struct tty_driver *console_driver;
40
41#define VT_IS_IN_USE(i) (console_driver->ttys[i] && console_driver->ttys[i]->count)
42#define VT_BUSY(i) (VT_IS_IN_USE(i) || i == fg_console || vc_cons[i].d == sel_cons)
43
44/*
45 * Console (vt and kd) routines, as defined by USL SVR4 manual, and by
46 * experimentation and study of X386 SYSV handling.
47 *
48 * One point of difference: SYSV vt's are /dev/vtX, which X >= 0, and
49 * /dev/console is a separate ttyp. Under Linux, /dev/tty0 is /dev/console,
50 * and the vc start at /dev/ttyX, X >= 1. We maintain that here, so we will
51 * always treat our set of vt as numbered 1..MAX_NR_CONSOLES (corresponding to
52 * ttys 0..MAX_NR_CONSOLES-1). Explicitly naming VT 0 is illegal, but using
53 * /dev/tty0 (fg_console) as a target is legal, since an implicit aliasing
54 * to the current console is done by the main ioctl code.
55 */
56
57#ifdef CONFIG_X86
58#include <linux/syscalls.h>
59#endif
60
61static void complete_change_console(struct vc_data *vc);
62
63/*
64 * User space VT_EVENT handlers
65 */
66
67struct vt_event_wait {
68 struct list_head list;
69 struct vt_event event;
70 int done;
71};
72
73static LIST_HEAD(vt_events);
74static DEFINE_SPINLOCK(vt_event_lock);
75static DECLARE_WAIT_QUEUE_HEAD(vt_event_waitqueue);
76
77/**
78 * vt_event_post
79 * @event: the event that occurred
80 * @old: old console
81 * @new: new console
82 *
83 * Post an VT event to interested VT handlers
84 */
85
86void vt_event_post(unsigned int event, unsigned int old, unsigned int new)
87{
88 struct list_head *pos, *head;
89 unsigned long flags;
90 int wake = 0;
91
92 spin_lock_irqsave(&vt_event_lock, flags);
93 head = &vt_events;
94
95 list_for_each(pos, head) {
96 struct vt_event_wait *ve = list_entry(pos,
97 struct vt_event_wait, list);
98 if (!(ve->event.event & event))
99 continue;
100 ve->event.event = event;
101 /* kernel view is consoles 0..n-1, user space view is
102 console 1..n with 0 meaning current, so we must bias */
103 ve->event.oldev = old + 1;
104 ve->event.newev = new + 1;
105 wake = 1;
106 ve->done = 1;
107 }
108 spin_unlock_irqrestore(&vt_event_lock, flags);
109 if (wake)
110 wake_up_interruptible(&vt_event_waitqueue);
111}
112
113/**
114 * vt_event_wait - wait for an event
115 * @vw: our event
116 *
117 * Waits for an event to occur which completes our vt_event_wait
118 * structure. On return the structure has wv->done set to 1 for success
119 * or 0 if some event such as a signal ended the wait.
120 */
121
122static void vt_event_wait(struct vt_event_wait *vw)
123{
124 unsigned long flags;
125 /* Prepare the event */
126 INIT_LIST_HEAD(&vw->list);
127 vw->done = 0;
128 /* Queue our event */
129 spin_lock_irqsave(&vt_event_lock, flags);
130 list_add(&vw->list, &vt_events);
131 spin_unlock_irqrestore(&vt_event_lock, flags);
132 /* Wait for it to pass */
133 wait_event_interruptible_tty(vt_event_waitqueue, vw->done);
134 /* Dequeue it */
135 spin_lock_irqsave(&vt_event_lock, flags);
136 list_del(&vw->list);
137 spin_unlock_irqrestore(&vt_event_lock, flags);
138}
139
140/**
141 * vt_event_wait_ioctl - event ioctl handler
142 * @arg: argument to ioctl
143 *
144 * Implement the VT_WAITEVENT ioctl using the VT event interface
145 */
146
147static int vt_event_wait_ioctl(struct vt_event __user *event)
148{
149 struct vt_event_wait vw;
150
151 if (copy_from_user(&vw.event, event, sizeof(struct vt_event)))
152 return -EFAULT;
153 /* Highest supported event for now */
154 if (vw.event.event & ~VT_MAX_EVENT)
155 return -EINVAL;
156
157 vt_event_wait(&vw);
158 /* If it occurred report it */
159 if (vw.done) {
160 if (copy_to_user(event, &vw.event, sizeof(struct vt_event)))
161 return -EFAULT;
162 return 0;
163 }
164 return -EINTR;
165}
166
167/**
168 * vt_waitactive - active console wait
169 * @event: event code
170 * @n: new console
171 *
172 * Helper for event waits. Used to implement the legacy
173 * event waiting ioctls in terms of events
174 */
175
176int vt_waitactive(int n)
177{
178 struct vt_event_wait vw;
179 do {
180 if (n == fg_console + 1)
181 break;
182 vw.event.event = VT_EVENT_SWITCH;
183 vt_event_wait(&vw);
184 if (vw.done == 0)
185 return -EINTR;
186 } while (vw.event.newev != n);
187 return 0;
188}
189
190/*
191 * these are the valid i/o ports we're allowed to change. they map all the
192 * video ports
193 */
194#define GPFIRST 0x3b4
195#define GPLAST 0x3df
196#define GPNUM (GPLAST - GPFIRST + 1)
197
198#define i (tmp.kb_index)
199#define s (tmp.kb_table)
200#define v (tmp.kb_value)
201static inline int
202do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_struct *kbd)
203{
204 struct kbentry tmp;
205 ushort *key_map, val, ov;
206
207 if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
208 return -EFAULT;
209
210 if (!capable(CAP_SYS_TTY_CONFIG))
211 perm = 0;
212
213 switch (cmd) {
214 case KDGKBENT:
215 key_map = key_maps[s];
216 if (key_map) {
217 val = U(key_map[i]);
218 if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
219 val = K_HOLE;
220 } else
221 val = (i ? K_HOLE : K_NOSUCHMAP);
222 return put_user(val, &user_kbe->kb_value);
223 case KDSKBENT:
224 if (!perm)
225 return -EPERM;
226 if (!i && v == K_NOSUCHMAP) {
227 /* deallocate map */
228 key_map = key_maps[s];
229 if (s && key_map) {
230 key_maps[s] = NULL;
231 if (key_map[0] == U(K_ALLOCATED)) {
232 kfree(key_map);
233 keymap_count--;
234 }
235 }
236 break;
237 }
238
239 if (KTYP(v) < NR_TYPES) {
240 if (KVAL(v) > max_vals[KTYP(v)])
241 return -EINVAL;
242 } else
243 if (kbd->kbdmode != VC_UNICODE)
244 return -EINVAL;
245
246 /* ++Geert: non-PC keyboards may generate keycode zero */
247#if !defined(__mc68000__) && !defined(__powerpc__)
248 /* assignment to entry 0 only tests validity of args */
249 if (!i)
250 break;
251#endif
252
253 if (!(key_map = key_maps[s])) {
254 int j;
255
256 if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
257 !capable(CAP_SYS_RESOURCE))
258 return -EPERM;
259
260 key_map = kmalloc(sizeof(plain_map),
261 GFP_KERNEL);
262 if (!key_map)
263 return -ENOMEM;
264 key_maps[s] = key_map;
265 key_map[0] = U(K_ALLOCATED);
266 for (j = 1; j < NR_KEYS; j++)
267 key_map[j] = U(K_HOLE);
268 keymap_count++;
269 }
270 ov = U(key_map[i]);
271 if (v == ov)
272 break; /* nothing to do */
273 /*
274 * Attention Key.
275 */
276 if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN))
277 return -EPERM;
278 key_map[i] = U(v);
279 if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
280 compute_shiftstate();
281 break;
282 }
283 return 0;
284}
285#undef i
286#undef s
287#undef v
288
289static inline int
290do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc, int perm)
291{
292 struct kbkeycode tmp;
293 int kc = 0;
294
295 if (copy_from_user(&tmp, user_kbkc, sizeof(struct kbkeycode)))
296 return -EFAULT;
297 switch (cmd) {
298 case KDGETKEYCODE:
299 kc = getkeycode(tmp.scancode);
300 if (kc >= 0)
301 kc = put_user(kc, &user_kbkc->keycode);
302 break;
303 case KDSETKEYCODE:
304 if (!perm)
305 return -EPERM;
306 kc = setkeycode(tmp.scancode, tmp.keycode);
307 break;
308 }
309 return kc;
310}
311
312static inline int
313do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
314{
315 struct kbsentry *kbs;
316 char *p;
317 u_char *q;
318 u_char __user *up;
319 int sz;
320 int delta;
321 char *first_free, *fj, *fnw;
322 int i, j, k;
323 int ret;
324
325 if (!capable(CAP_SYS_TTY_CONFIG))
326 perm = 0;
327
328 kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
329 if (!kbs) {
330 ret = -ENOMEM;
331 goto reterr;
332 }
333
334 /* we mostly copy too much here (512bytes), but who cares ;) */
335 if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
336 ret = -EFAULT;
337 goto reterr;
338 }
339 kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
340 i = kbs->kb_func;
341
342 switch (cmd) {
343 case KDGKBSENT:
344 sz = sizeof(kbs->kb_string) - 1; /* sz should have been
345 a struct member */
346 up = user_kdgkb->kb_string;
347 p = func_table[i];
348 if(p)
349 for ( ; *p && sz; p++, sz--)
350 if (put_user(*p, up++)) {
351 ret = -EFAULT;
352 goto reterr;
353 }
354 if (put_user('\0', up)) {
355 ret = -EFAULT;
356 goto reterr;
357 }
358 kfree(kbs);
359 return ((p && *p) ? -EOVERFLOW : 0);
360 case KDSKBSENT:
361 if (!perm) {
362 ret = -EPERM;
363 goto reterr;
364 }
365
366 q = func_table[i];
367 first_free = funcbufptr + (funcbufsize - funcbufleft);
368 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
369 ;
370 if (j < MAX_NR_FUNC)
371 fj = func_table[j];
372 else
373 fj = first_free;
374
375 delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
376 if (delta <= funcbufleft) { /* it fits in current buf */
377 if (j < MAX_NR_FUNC) {
378 memmove(fj + delta, fj, first_free - fj);
379 for (k = j; k < MAX_NR_FUNC; k++)
380 if (func_table[k])
381 func_table[k] += delta;
382 }
383 if (!q)
384 func_table[i] = fj;
385 funcbufleft -= delta;
386 } else { /* allocate a larger buffer */
387 sz = 256;
388 while (sz < funcbufsize - funcbufleft + delta)
389 sz <<= 1;
390 fnw = kmalloc(sz, GFP_KERNEL);
391 if(!fnw) {
392 ret = -ENOMEM;
393 goto reterr;
394 }
395
396 if (!q)
397 func_table[i] = fj;
398 if (fj > funcbufptr)
399 memmove(fnw, funcbufptr, fj - funcbufptr);
400 for (k = 0; k < j; k++)
401 if (func_table[k])
402 func_table[k] = fnw + (func_table[k] - funcbufptr);
403
404 if (first_free > fj) {
405 memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
406 for (k = j; k < MAX_NR_FUNC; k++)
407 if (func_table[k])
408 func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
409 }
410 if (funcbufptr != func_buf)
411 kfree(funcbufptr);
412 funcbufptr = fnw;
413 funcbufleft = funcbufleft - delta + sz - funcbufsize;
414 funcbufsize = sz;
415 }
416 strcpy(func_table[i], kbs->kb_string);
417 break;
418 }
419 ret = 0;
420reterr:
421 kfree(kbs);
422 return ret;
423}
424
425static inline int
426do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op)
427{
428 struct consolefontdesc cfdarg;
429 int i;
430
431 if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc)))
432 return -EFAULT;
433
434 switch (cmd) {
435 case PIO_FONTX:
436 if (!perm)
437 return -EPERM;
438 op->op = KD_FONT_OP_SET;
439 op->flags = KD_FONT_FLAG_OLD;
440 op->width = 8;
441 op->height = cfdarg.charheight;
442 op->charcount = cfdarg.charcount;
443 op->data = cfdarg.chardata;
444 return con_font_op(vc_cons[fg_console].d, op);
445 case GIO_FONTX: {
446 op->op = KD_FONT_OP_GET;
447 op->flags = KD_FONT_FLAG_OLD;
448 op->width = 8;
449 op->height = cfdarg.charheight;
450 op->charcount = cfdarg.charcount;
451 op->data = cfdarg.chardata;
452 i = con_font_op(vc_cons[fg_console].d, op);
453 if (i)
454 return i;
455 cfdarg.charheight = op->height;
456 cfdarg.charcount = op->charcount;
457 if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc)))
458 return -EFAULT;
459 return 0;
460 }
461 }
462 return -EINVAL;
463}
464
465static inline int
466do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_data *vc)
467{
468 struct unimapdesc tmp;
469
470 if (copy_from_user(&tmp, user_ud, sizeof tmp))
471 return -EFAULT;
472 if (tmp.entries)
473 if (!access_ok(VERIFY_WRITE, tmp.entries,
474 tmp.entry_ct*sizeof(struct unipair)))
475 return -EFAULT;
476 switch (cmd) {
477 case PIO_UNIMAP:
478 if (!perm)
479 return -EPERM;
480 return con_set_unimap(vc, tmp.entry_ct, tmp.entries);
481 case GIO_UNIMAP:
482 if (!perm && fg_console != vc->vc_num)
483 return -EPERM;
484 return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp.entries);
485 }
486 return 0;
487}
488
489
490
491/*
492 * We handle the console-specific ioctl's here. We allow the
493 * capability to modify any console, not just the fg_console.
494 */
495int vt_ioctl(struct tty_struct *tty,
496 unsigned int cmd, unsigned long arg)
497{
498 struct vc_data *vc = tty->driver_data;
499 struct console_font_op op; /* used in multiple places here */
500 struct kbd_struct * kbd;
501 unsigned int console;
502 unsigned char ucval;
503 unsigned int uival;
504 void __user *up = (void __user *)arg;
505 int i, perm;
506 int ret = 0;
507
508 console = vc->vc_num;
509
510 tty_lock();
511
512 if (!vc_cons_allocated(console)) { /* impossible? */
513 ret = -ENOIOCTLCMD;
514 goto out;
515 }
516
517
518 /*
519 * To have permissions to do most of the vt ioctls, we either have
520 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
521 */
522 perm = 0;
523 if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
524 perm = 1;
525
526 kbd = kbd_table + console;
527 switch (cmd) {
528 case TIOCLINUX:
529 ret = tioclinux(tty, arg);
530 break;
531 case KIOCSOUND:
532 if (!perm)
533 goto eperm;
534 /*
535 * The use of PIT_TICK_RATE is historic, it used to be
536 * the platform-dependent CLOCK_TICK_RATE between 2.6.12
537 * and 2.6.36, which was a minor but unfortunate ABI
538 * change.
539 */
540 if (arg)
541 arg = PIT_TICK_RATE / arg;
542 kd_mksound(arg, 0);
543 break;
544
545 case KDMKTONE:
546 if (!perm)
547 goto eperm;
548 {
549 unsigned int ticks, count;
550
551 /*
552 * Generate the tone for the appropriate number of ticks.
553 * If the time is zero, turn off sound ourselves.
554 */
555 ticks = HZ * ((arg >> 16) & 0xffff) / 1000;
556 count = ticks ? (arg & 0xffff) : 0;
557 if (count)
558 count = PIT_TICK_RATE / count;
559 kd_mksound(count, ticks);
560 break;
561 }
562
563 case KDGKBTYPE:
564 /*
565 * this is naive.
566 */
567 ucval = KB_101;
568 goto setchar;
569
570 /*
571 * These cannot be implemented on any machine that implements
572 * ioperm() in user level (such as Alpha PCs) or not at all.
573 *
574 * XXX: you should never use these, just call ioperm directly..
575 */
576#ifdef CONFIG_X86
577 case KDADDIO:
578 case KDDELIO:
579 /*
580 * KDADDIO and KDDELIO may be able to add ports beyond what
581 * we reject here, but to be safe...
582 */
583 if (arg < GPFIRST || arg > GPLAST) {
584 ret = -EINVAL;
585 break;
586 }
587 ret = sys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
588 break;
589
590 case KDENABIO:
591 case KDDISABIO:
592 ret = sys_ioperm(GPFIRST, GPNUM,
593 (cmd == KDENABIO)) ? -ENXIO : 0;
594 break;
595#endif
596
597 /* Linux m68k/i386 interface for setting the keyboard delay/repeat rate */
598
599 case KDKBDREP:
600 {
601 struct kbd_repeat kbrep;
602
603 if (!capable(CAP_SYS_TTY_CONFIG))
604 goto eperm;
605
606 if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) {
607 ret = -EFAULT;
608 break;
609 }
610 ret = kbd_rate(&kbrep);
611 if (ret)
612 break;
613 if (copy_to_user(up, &kbrep, sizeof(struct kbd_repeat)))
614 ret = -EFAULT;
615 break;
616 }
617
618 case KDSETMODE:
619 /*
620 * currently, setting the mode from KD_TEXT to KD_GRAPHICS
621 * doesn't do a whole lot. i'm not sure if it should do any
622 * restoration of modes or what...
623 *
624 * XXX It should at least call into the driver, fbdev's definitely
625 * need to restore their engine state. --BenH
626 */
627 if (!perm)
628 goto eperm;
629 switch (arg) {
630 case KD_GRAPHICS:
631 break;
632 case KD_TEXT0:
633 case KD_TEXT1:
634 arg = KD_TEXT;
635 case KD_TEXT:
636 break;
637 default:
638 ret = -EINVAL;
639 goto out;
640 }
641 if (vc->vc_mode == (unsigned char) arg)
642 break;
643 vc->vc_mode = (unsigned char) arg;
644 if (console != fg_console)
645 break;
646 /*
647 * explicitly blank/unblank the screen if switching modes
648 */
649 console_lock();
650 if (arg == KD_TEXT)
651 do_unblank_screen(1);
652 else
653 do_blank_screen(1);
654 console_unlock();
655 break;
656
657 case KDGETMODE:
658 uival = vc->vc_mode;
659 goto setint;
660
661 case KDMAPDISP:
662 case KDUNMAPDISP:
663 /*
664 * these work like a combination of mmap and KDENABIO.
665 * this could be easily finished.
666 */
667 ret = -EINVAL;
668 break;
669
670 case KDSKBMODE:
671 if (!perm)
672 goto eperm;
673 switch(arg) {
674 case K_RAW:
675 kbd->kbdmode = VC_RAW;
676 break;
677 case K_MEDIUMRAW:
678 kbd->kbdmode = VC_MEDIUMRAW;
679 break;
680 case K_XLATE:
681 kbd->kbdmode = VC_XLATE;
682 compute_shiftstate();
683 break;
684 case K_UNICODE:
685 kbd->kbdmode = VC_UNICODE;
686 compute_shiftstate();
687 break;
688 case K_OFF:
689 kbd->kbdmode = VC_OFF;
690 break;
691 default:
692 ret = -EINVAL;
693 goto out;
694 }
695 tty_ldisc_flush(tty);
696 break;
697
698 case KDGKBMODE:
699 switch (kbd->kbdmode) {
700 case VC_RAW:
701 uival = K_RAW;
702 break;
703 case VC_MEDIUMRAW:
704 uival = K_MEDIUMRAW;
705 break;
706 case VC_UNICODE:
707 uival = K_UNICODE;
708 break;
709 case VC_OFF:
710 uival = K_OFF;
711 break;
712 default:
713 uival = K_XLATE;
714 break;
715 }
716 goto setint;
717
718 /* this could be folded into KDSKBMODE, but for compatibility
719 reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
720 case KDSKBMETA:
721 switch(arg) {
722 case K_METABIT:
723 clr_vc_kbd_mode(kbd, VC_META);
724 break;
725 case K_ESCPREFIX:
726 set_vc_kbd_mode(kbd, VC_META);
727 break;
728 default:
729 ret = -EINVAL;
730 }
731 break;
732
733 case KDGKBMETA:
734 uival = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT);
735 setint:
736 ret = put_user(uival, (int __user *)arg);
737 break;
738
739 case KDGETKEYCODE:
740 case KDSETKEYCODE:
741 if(!capable(CAP_SYS_TTY_CONFIG))
742 perm = 0;
743 ret = do_kbkeycode_ioctl(cmd, up, perm);
744 break;
745
746 case KDGKBENT:
747 case KDSKBENT:
748 ret = do_kdsk_ioctl(cmd, up, perm, kbd);
749 break;
750
751 case KDGKBSENT:
752 case KDSKBSENT:
753 ret = do_kdgkb_ioctl(cmd, up, perm);
754 break;
755
756 case KDGKBDIACR:
757 {
758 struct kbdiacrs __user *a = up;
759 struct kbdiacr diacr;
760 int i;
761
762 if (put_user(accent_table_size, &a->kb_cnt)) {
763 ret = -EFAULT;
764 break;
765 }
766 for (i = 0; i < accent_table_size; i++) {
767 diacr.diacr = conv_uni_to_8bit(accent_table[i].diacr);
768 diacr.base = conv_uni_to_8bit(accent_table[i].base);
769 diacr.result = conv_uni_to_8bit(accent_table[i].result);
770 if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr))) {
771 ret = -EFAULT;
772 break;
773 }
774 }
775 break;
776 }
777 case KDGKBDIACRUC:
778 {
779 struct kbdiacrsuc __user *a = up;
780
781 if (put_user(accent_table_size, &a->kb_cnt))
782 ret = -EFAULT;
783 else if (copy_to_user(a->kbdiacruc, accent_table,
784 accent_table_size*sizeof(struct kbdiacruc)))
785 ret = -EFAULT;
786 break;
787 }
788
789 case KDSKBDIACR:
790 {
791 struct kbdiacrs __user *a = up;
792 struct kbdiacr diacr;
793 unsigned int ct;
794 int i;
795
796 if (!perm)
797 goto eperm;
798 if (get_user(ct,&a->kb_cnt)) {
799 ret = -EFAULT;
800 break;
801 }
802 if (ct >= MAX_DIACR) {
803 ret = -EINVAL;
804 break;
805 }
806 accent_table_size = ct;
807 for (i = 0; i < ct; i++) {
808 if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr))) {
809 ret = -EFAULT;
810 break;
811 }
812 accent_table[i].diacr = conv_8bit_to_uni(diacr.diacr);
813 accent_table[i].base = conv_8bit_to_uni(diacr.base);
814 accent_table[i].result = conv_8bit_to_uni(diacr.result);
815 }
816 break;
817 }
818
819 case KDSKBDIACRUC:
820 {
821 struct kbdiacrsuc __user *a = up;
822 unsigned int ct;
823
824 if (!perm)
825 goto eperm;
826 if (get_user(ct,&a->kb_cnt)) {
827 ret = -EFAULT;
828 break;
829 }
830 if (ct >= MAX_DIACR) {
831 ret = -EINVAL;
832 break;
833 }
834 accent_table_size = ct;
835 if (copy_from_user(accent_table, a->kbdiacruc, ct*sizeof(struct kbdiacruc)))
836 ret = -EFAULT;
837 break;
838 }
839
840 /* the ioctls below read/set the flags usually shown in the leds */
841 /* don't use them - they will go away without warning */
842 case KDGKBLED:
843 ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
844 goto setchar;
845
846 case KDSKBLED:
847 if (!perm)
848 goto eperm;
849 if (arg & ~0x77) {
850 ret = -EINVAL;
851 break;
852 }
853 kbd->ledflagstate = (arg & 7);
854 kbd->default_ledflagstate = ((arg >> 4) & 7);
855 set_leds();
856 break;
857
858 /* the ioctls below only set the lights, not the functions */
859 /* for those, see KDGKBLED and KDSKBLED above */
860 case KDGETLED:
861 ucval = getledstate();
862 setchar:
863 ret = put_user(ucval, (char __user *)arg);
864 break;
865
866 case KDSETLED:
867 if (!perm)
868 goto eperm;
869 setledstate(kbd, arg);
870 break;
871
872 /*
873 * A process can indicate its willingness to accept signals
874 * generated by pressing an appropriate key combination.
875 * Thus, one can have a daemon that e.g. spawns a new console
876 * upon a keypress and then changes to it.
877 * See also the kbrequest field of inittab(5).
878 */
879 case KDSIGACCEPT:
880 {
881 if (!perm || !capable(CAP_KILL))
882 goto eperm;
883 if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
884 ret = -EINVAL;
885 else {
886 spin_lock_irq(&vt_spawn_con.lock);
887 put_pid(vt_spawn_con.pid);
888 vt_spawn_con.pid = get_pid(task_pid(current));
889 vt_spawn_con.sig = arg;
890 spin_unlock_irq(&vt_spawn_con.lock);
891 }
892 break;
893 }
894
895 case VT_SETMODE:
896 {
897 struct vt_mode tmp;
898
899 if (!perm)
900 goto eperm;
901 if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) {
902 ret = -EFAULT;
903 goto out;
904 }
905 if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) {
906 ret = -EINVAL;
907 goto out;
908 }
909 console_lock();
910 vc->vt_mode = tmp;
911 /* the frsig is ignored, so we set it to 0 */
912 vc->vt_mode.frsig = 0;
913 put_pid(vc->vt_pid);
914 vc->vt_pid = get_pid(task_pid(current));
915 /* no switch is required -- saw@shade.msu.ru */
916 vc->vt_newvt = -1;
917 console_unlock();
918 break;
919 }
920
921 case VT_GETMODE:
922 {
923 struct vt_mode tmp;
924 int rc;
925
926 console_lock();
927 memcpy(&tmp, &vc->vt_mode, sizeof(struct vt_mode));
928 console_unlock();
929
930 rc = copy_to_user(up, &tmp, sizeof(struct vt_mode));
931 if (rc)
932 ret = -EFAULT;
933 break;
934 }
935
936 /*
937 * Returns global vt state. Note that VT 0 is always open, since
938 * it's an alias for the current VT, and people can't use it here.
939 * We cannot return state for more than 16 VTs, since v_state is short.
940 */
941 case VT_GETSTATE:
942 {
943 struct vt_stat __user *vtstat = up;
944 unsigned short state, mask;
945
946 if (put_user(fg_console + 1, &vtstat->v_active))
947 ret = -EFAULT;
948 else {
949 state = 1; /* /dev/tty0 is always open */
950 for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask;
951 ++i, mask <<= 1)
952 if (VT_IS_IN_USE(i))
953 state |= mask;
954 ret = put_user(state, &vtstat->v_state);
955 }
956 break;
957 }
958
959 /*
960 * Returns the first available (non-opened) console.
961 */
962 case VT_OPENQRY:
963 for (i = 0; i < MAX_NR_CONSOLES; ++i)
964 if (! VT_IS_IN_USE(i))
965 break;
966 uival = i < MAX_NR_CONSOLES ? (i+1) : -1;
967 goto setint;
968
969 /*
970 * ioctl(fd, VT_ACTIVATE, num) will cause us to switch to vt # num,
971 * with num >= 1 (switches to vt 0, our console, are not allowed, just
972 * to preserve sanity).
973 */
974 case VT_ACTIVATE:
975 if (!perm)
976 goto eperm;
977 if (arg == 0 || arg > MAX_NR_CONSOLES)
978 ret = -ENXIO;
979 else {
980 arg--;
981 console_lock();
982 ret = vc_allocate(arg);
983 console_unlock();
984 if (ret)
985 break;
986 set_console(arg);
987 }
988 break;
989
990 case VT_SETACTIVATE:
991 {
992 struct vt_setactivate vsa;
993
994 if (!perm)
995 goto eperm;
996
997 if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
998 sizeof(struct vt_setactivate))) {
999 ret = -EFAULT;
1000 goto out;
1001 }
1002 if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
1003 ret = -ENXIO;
1004 else {
1005 vsa.console--;
1006 console_lock();
1007 ret = vc_allocate(vsa.console);
1008 if (ret == 0) {
1009 struct vc_data *nvc;
1010 /* This is safe providing we don't drop the
1011 console sem between vc_allocate and
1012 finishing referencing nvc */
1013 nvc = vc_cons[vsa.console].d;
1014 nvc->vt_mode = vsa.mode;
1015 nvc->vt_mode.frsig = 0;
1016 put_pid(nvc->vt_pid);
1017 nvc->vt_pid = get_pid(task_pid(current));
1018 }
1019 console_unlock();
1020 if (ret)
1021 break;
1022 /* Commence switch and lock */
1023 set_console(vsa.console);
1024 }
1025 break;
1026 }
1027
1028 /*
1029 * wait until the specified VT has been activated
1030 */
1031 case VT_WAITACTIVE:
1032 if (!perm)
1033 goto eperm;
1034 if (arg == 0 || arg > MAX_NR_CONSOLES)
1035 ret = -ENXIO;
1036 else
1037 ret = vt_waitactive(arg);
1038 break;
1039
1040 /*
1041 * If a vt is under process control, the kernel will not switch to it
1042 * immediately, but postpone the operation until the process calls this
1043 * ioctl, allowing the switch to complete.
1044 *
1045 * According to the X sources this is the behavior:
1046 * 0: pending switch-from not OK
1047 * 1: pending switch-from OK
1048 * 2: completed switch-to OK
1049 */
1050 case VT_RELDISP:
1051 if (!perm)
1052 goto eperm;
1053
1054 if (vc->vt_mode.mode != VT_PROCESS) {
1055 ret = -EINVAL;
1056 break;
1057 }
1058 /*
1059 * Switching-from response
1060 */
1061 console_lock();
1062 if (vc->vt_newvt >= 0) {
1063 if (arg == 0)
1064 /*
1065 * Switch disallowed, so forget we were trying
1066 * to do it.
1067 */
1068 vc->vt_newvt = -1;
1069
1070 else {
1071 /*
1072 * The current vt has been released, so
1073 * complete the switch.
1074 */
1075 int newvt;
1076 newvt = vc->vt_newvt;
1077 vc->vt_newvt = -1;
1078 ret = vc_allocate(newvt);
1079 if (ret) {
1080 console_unlock();
1081 break;
1082 }
1083 /*
1084 * When we actually do the console switch,
1085 * make sure we are atomic with respect to
1086 * other console switches..
1087 */
1088 complete_change_console(vc_cons[newvt].d);
1089 }
1090 } else {
1091 /*
1092 * Switched-to response
1093 */
1094 /*
1095 * If it's just an ACK, ignore it
1096 */
1097 if (arg != VT_ACKACQ)
1098 ret = -EINVAL;
1099 }
1100 console_unlock();
1101 break;
1102
1103 /*
1104 * Disallocate memory associated to VT (but leave VT1)
1105 */
1106 case VT_DISALLOCATE:
1107 if (arg > MAX_NR_CONSOLES) {
1108 ret = -ENXIO;
1109 break;
1110 }
1111 if (arg == 0) {
1112 /* deallocate all unused consoles, but leave 0 */
1113 console_lock();
1114 for (i=1; i<MAX_NR_CONSOLES; i++)
1115 if (! VT_BUSY(i))
1116 vc_deallocate(i);
1117 console_unlock();
1118 } else {
1119 /* deallocate a single console, if possible */
1120 arg--;
1121 if (VT_BUSY(arg))
1122 ret = -EBUSY;
1123 else if (arg) { /* leave 0 */
1124 console_lock();
1125 vc_deallocate(arg);
1126 console_unlock();
1127 }
1128 }
1129 break;
1130
1131 case VT_RESIZE:
1132 {
1133 struct vt_sizes __user *vtsizes = up;
1134 struct vc_data *vc;
1135
1136 ushort ll,cc;
1137 if (!perm)
1138 goto eperm;
1139 if (get_user(ll, &vtsizes->v_rows) ||
1140 get_user(cc, &vtsizes->v_cols))
1141 ret = -EFAULT;
1142 else {
1143 console_lock();
1144 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1145 vc = vc_cons[i].d;
1146
1147 if (vc) {
1148 vc->vc_resize_user = 1;
1149 vc_resize(vc_cons[i].d, cc, ll);
1150 }
1151 }
1152 console_unlock();
1153 }
1154 break;
1155 }
1156
1157 case VT_RESIZEX:
1158 {
1159 struct vt_consize __user *vtconsize = up;
1160 ushort ll,cc,vlin,clin,vcol,ccol;
1161 if (!perm)
1162 goto eperm;
1163 if (!access_ok(VERIFY_READ, vtconsize,
1164 sizeof(struct vt_consize))) {
1165 ret = -EFAULT;
1166 break;
1167 }
1168 /* FIXME: Should check the copies properly */
1169 __get_user(ll, &vtconsize->v_rows);
1170 __get_user(cc, &vtconsize->v_cols);
1171 __get_user(vlin, &vtconsize->v_vlin);
1172 __get_user(clin, &vtconsize->v_clin);
1173 __get_user(vcol, &vtconsize->v_vcol);
1174 __get_user(ccol, &vtconsize->v_ccol);
1175 vlin = vlin ? vlin : vc->vc_scan_lines;
1176 if (clin) {
1177 if (ll) {
1178 if (ll != vlin/clin) {
1179 /* Parameters don't add up */
1180 ret = -EINVAL;
1181 break;
1182 }
1183 } else
1184 ll = vlin/clin;
1185 }
1186 if (vcol && ccol) {
1187 if (cc) {
1188 if (cc != vcol/ccol) {
1189 ret = -EINVAL;
1190 break;
1191 }
1192 } else
1193 cc = vcol/ccol;
1194 }
1195
1196 if (clin > 32) {
1197 ret = -EINVAL;
1198 break;
1199 }
1200
1201 for (i = 0; i < MAX_NR_CONSOLES; i++) {
1202 if (!vc_cons[i].d)
1203 continue;
1204 console_lock();
1205 if (vlin)
1206 vc_cons[i].d->vc_scan_lines = vlin;
1207 if (clin)
1208 vc_cons[i].d->vc_font.height = clin;
1209 vc_cons[i].d->vc_resize_user = 1;
1210 vc_resize(vc_cons[i].d, cc, ll);
1211 console_unlock();
1212 }
1213 break;
1214 }
1215
1216 case PIO_FONT: {
1217 if (!perm)
1218 goto eperm;
1219 op.op = KD_FONT_OP_SET;
1220 op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC; /* Compatibility */
1221 op.width = 8;
1222 op.height = 0;
1223 op.charcount = 256;
1224 op.data = up;
1225 ret = con_font_op(vc_cons[fg_console].d, &op);
1226 break;
1227 }
1228
1229 case GIO_FONT: {
1230 op.op = KD_FONT_OP_GET;
1231 op.flags = KD_FONT_FLAG_OLD;
1232 op.width = 8;
1233 op.height = 32;
1234 op.charcount = 256;
1235 op.data = up;
1236 ret = con_font_op(vc_cons[fg_console].d, &op);
1237 break;
1238 }
1239
1240 case PIO_CMAP:
1241 if (!perm)
1242 ret = -EPERM;
1243 else
1244 ret = con_set_cmap(up);
1245 break;
1246
1247 case GIO_CMAP:
1248 ret = con_get_cmap(up);
1249 break;
1250
1251 case PIO_FONTX:
1252 case GIO_FONTX:
1253 ret = do_fontx_ioctl(cmd, up, perm, &op);
1254 break;
1255
1256 case PIO_FONTRESET:
1257 {
1258 if (!perm)
1259 goto eperm;
1260
1261#ifdef BROKEN_GRAPHICS_PROGRAMS
1262 /* With BROKEN_GRAPHICS_PROGRAMS defined, the default
1263 font is not saved. */
1264 ret = -ENOSYS;
1265 break;
1266#else
1267 {
1268 op.op = KD_FONT_OP_SET_DEFAULT;
1269 op.data = NULL;
1270 ret = con_font_op(vc_cons[fg_console].d, &op);
1271 if (ret)
1272 break;
1273 con_set_default_unimap(vc_cons[fg_console].d);
1274 break;
1275 }
1276#endif
1277 }
1278
1279 case KDFONTOP: {
1280 if (copy_from_user(&op, up, sizeof(op))) {
1281 ret = -EFAULT;
1282 break;
1283 }
1284 if (!perm && op.op != KD_FONT_OP_GET)
1285 goto eperm;
1286 ret = con_font_op(vc, &op);
1287 if (ret)
1288 break;
1289 if (copy_to_user(up, &op, sizeof(op)))
1290 ret = -EFAULT;
1291 break;
1292 }
1293
1294 case PIO_SCRNMAP:
1295 if (!perm)
1296 ret = -EPERM;
1297 else
1298 ret = con_set_trans_old(up);
1299 break;
1300
1301 case GIO_SCRNMAP:
1302 ret = con_get_trans_old(up);
1303 break;
1304
1305 case PIO_UNISCRNMAP:
1306 if (!perm)
1307 ret = -EPERM;
1308 else
1309 ret = con_set_trans_new(up);
1310 break;
1311
1312 case GIO_UNISCRNMAP:
1313 ret = con_get_trans_new(up);
1314 break;
1315
1316 case PIO_UNIMAPCLR:
1317 { struct unimapinit ui;
1318 if (!perm)
1319 goto eperm;
1320 ret = copy_from_user(&ui, up, sizeof(struct unimapinit));
1321 if (ret)
1322 ret = -EFAULT;
1323 else
1324 con_clear_unimap(vc, &ui);
1325 break;
1326 }
1327
1328 case PIO_UNIMAP:
1329 case GIO_UNIMAP:
1330 ret = do_unimap_ioctl(cmd, up, perm, vc);
1331 break;
1332
1333 case VT_LOCKSWITCH:
1334 if (!capable(CAP_SYS_TTY_CONFIG))
1335 goto eperm;
1336 vt_dont_switch = 1;
1337 break;
1338 case VT_UNLOCKSWITCH:
1339 if (!capable(CAP_SYS_TTY_CONFIG))
1340 goto eperm;
1341 vt_dont_switch = 0;
1342 break;
1343 case VT_GETHIFONTMASK:
1344 ret = put_user(vc->vc_hi_font_mask,
1345 (unsigned short __user *)arg);
1346 break;
1347 case VT_WAITEVENT:
1348 ret = vt_event_wait_ioctl((struct vt_event __user *)arg);
1349 break;
1350 default:
1351 ret = -ENOIOCTLCMD;
1352 }
1353out:
1354 tty_unlock();
1355 return ret;
1356eperm:
1357 ret = -EPERM;
1358 goto out;
1359}
1360
1361void reset_vc(struct vc_data *vc)
1362{
1363 vc->vc_mode = KD_TEXT;
1364 kbd_table[vc->vc_num].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
1365 vc->vt_mode.mode = VT_AUTO;
1366 vc->vt_mode.waitv = 0;
1367 vc->vt_mode.relsig = 0;
1368 vc->vt_mode.acqsig = 0;
1369 vc->vt_mode.frsig = 0;
1370 put_pid(vc->vt_pid);
1371 vc->vt_pid = NULL;
1372 vc->vt_newvt = -1;
1373 if (!in_interrupt()) /* Via keyboard.c:SAK() - akpm */
1374 reset_palette(vc);
1375}
1376
1377void vc_SAK(struct work_struct *work)
1378{
1379 struct vc *vc_con =
1380 container_of(work, struct vc, SAK_work);
1381 struct vc_data *vc;
1382 struct tty_struct *tty;
1383
1384 console_lock();
1385 vc = vc_con->d;
1386 if (vc) {
1387 tty = vc->port.tty;
1388 /*
1389 * SAK should also work in all raw modes and reset
1390 * them properly.
1391 */
1392 if (tty)
1393 __do_SAK(tty);
1394 reset_vc(vc);
1395 }
1396 console_unlock();
1397}
1398
1399#ifdef CONFIG_COMPAT
1400
1401struct compat_consolefontdesc {
1402 unsigned short charcount; /* characters in font (256 or 512) */
1403 unsigned short charheight; /* scan lines per character (1-32) */
1404 compat_caddr_t chardata; /* font data in expanded form */
1405};
1406
1407static inline int
1408compat_fontx_ioctl(int cmd, struct compat_consolefontdesc __user *user_cfd,
1409 int perm, struct console_font_op *op)
1410{
1411 struct compat_consolefontdesc cfdarg;
1412 int i;
1413
1414 if (copy_from_user(&cfdarg, user_cfd, sizeof(struct compat_consolefontdesc)))
1415 return -EFAULT;
1416
1417 switch (cmd) {
1418 case PIO_FONTX:
1419 if (!perm)
1420 return -EPERM;
1421 op->op = KD_FONT_OP_SET;
1422 op->flags = KD_FONT_FLAG_OLD;
1423 op->width = 8;
1424 op->height = cfdarg.charheight;
1425 op->charcount = cfdarg.charcount;
1426 op->data = compat_ptr(cfdarg.chardata);
1427 return con_font_op(vc_cons[fg_console].d, op);
1428 case GIO_FONTX:
1429 op->op = KD_FONT_OP_GET;
1430 op->flags = KD_FONT_FLAG_OLD;
1431 op->width = 8;
1432 op->height = cfdarg.charheight;
1433 op->charcount = cfdarg.charcount;
1434 op->data = compat_ptr(cfdarg.chardata);
1435 i = con_font_op(vc_cons[fg_console].d, op);
1436 if (i)
1437 return i;
1438 cfdarg.charheight = op->height;
1439 cfdarg.charcount = op->charcount;
1440 if (copy_to_user(user_cfd, &cfdarg, sizeof(struct compat_consolefontdesc)))
1441 return -EFAULT;
1442 return 0;
1443 }
1444 return -EINVAL;
1445}
1446
1447struct compat_console_font_op {
1448 compat_uint_t op; /* operation code KD_FONT_OP_* */
1449 compat_uint_t flags; /* KD_FONT_FLAG_* */
1450 compat_uint_t width, height; /* font size */
1451 compat_uint_t charcount;
1452 compat_caddr_t data; /* font data with height fixed to 32 */
1453};
1454
1455static inline int
1456compat_kdfontop_ioctl(struct compat_console_font_op __user *fontop,
1457 int perm, struct console_font_op *op, struct vc_data *vc)
1458{
1459 int i;
1460
1461 if (copy_from_user(op, fontop, sizeof(struct compat_console_font_op)))
1462 return -EFAULT;
1463 if (!perm && op->op != KD_FONT_OP_GET)
1464 return -EPERM;
1465 op->data = compat_ptr(((struct compat_console_font_op *)op)->data);
1466 op->flags |= KD_FONT_FLAG_OLD;
1467 i = con_font_op(vc, op);
1468 if (i)
1469 return i;
1470 ((struct compat_console_font_op *)op)->data = (unsigned long)op->data;
1471 if (copy_to_user(fontop, op, sizeof(struct compat_console_font_op)))
1472 return -EFAULT;
1473 return 0;
1474}
1475
1476struct compat_unimapdesc {
1477 unsigned short entry_ct;
1478 compat_caddr_t entries;
1479};
1480
1481static inline int
1482compat_unimap_ioctl(unsigned int cmd, struct compat_unimapdesc __user *user_ud,
1483 int perm, struct vc_data *vc)
1484{
1485 struct compat_unimapdesc tmp;
1486 struct unipair __user *tmp_entries;
1487
1488 if (copy_from_user(&tmp, user_ud, sizeof tmp))
1489 return -EFAULT;
1490 tmp_entries = compat_ptr(tmp.entries);
1491 if (tmp_entries)
1492 if (!access_ok(VERIFY_WRITE, tmp_entries,
1493 tmp.entry_ct*sizeof(struct unipair)))
1494 return -EFAULT;
1495 switch (cmd) {
1496 case PIO_UNIMAP:
1497 if (!perm)
1498 return -EPERM;
1499 return con_set_unimap(vc, tmp.entry_ct, tmp_entries);
1500 case GIO_UNIMAP:
1501 if (!perm && fg_console != vc->vc_num)
1502 return -EPERM;
1503 return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp_entries);
1504 }
1505 return 0;
1506}
1507
1508long vt_compat_ioctl(struct tty_struct *tty,
1509 unsigned int cmd, unsigned long arg)
1510{
1511 struct vc_data *vc = tty->driver_data;
1512 struct console_font_op op; /* used in multiple places here */
1513 unsigned int console;
1514 void __user *up = (void __user *)arg;
1515 int perm;
1516 int ret = 0;
1517
1518 console = vc->vc_num;
1519
1520 tty_lock();
1521
1522 if (!vc_cons_allocated(console)) { /* impossible? */
1523 ret = -ENOIOCTLCMD;
1524 goto out;
1525 }
1526
1527 /*
1528 * To have permissions to do most of the vt ioctls, we either have
1529 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
1530 */
1531 perm = 0;
1532 if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
1533 perm = 1;
1534
1535 switch (cmd) {
1536 /*
1537 * these need special handlers for incompatible data structures
1538 */
1539 case PIO_FONTX:
1540 case GIO_FONTX:
1541 ret = compat_fontx_ioctl(cmd, up, perm, &op);
1542 break;
1543
1544 case KDFONTOP:
1545 ret = compat_kdfontop_ioctl(up, perm, &op, vc);
1546 break;
1547
1548 case PIO_UNIMAP:
1549 case GIO_UNIMAP:
1550 ret = compat_unimap_ioctl(cmd, up, perm, vc);
1551 break;
1552
1553 /*
1554 * all these treat 'arg' as an integer
1555 */
1556 case KIOCSOUND:
1557 case KDMKTONE:
1558#ifdef CONFIG_X86
1559 case KDADDIO:
1560 case KDDELIO:
1561#endif
1562 case KDSETMODE:
1563 case KDMAPDISP:
1564 case KDUNMAPDISP:
1565 case KDSKBMODE:
1566 case KDSKBMETA:
1567 case KDSKBLED:
1568 case KDSETLED:
1569 case KDSIGACCEPT:
1570 case VT_ACTIVATE:
1571 case VT_WAITACTIVE:
1572 case VT_RELDISP:
1573 case VT_DISALLOCATE:
1574 case VT_RESIZE:
1575 case VT_RESIZEX:
1576 goto fallback;
1577
1578 /*
1579 * the rest has a compatible data structure behind arg,
1580 * but we have to convert it to a proper 64 bit pointer.
1581 */
1582 default:
1583 arg = (unsigned long)compat_ptr(arg);
1584 goto fallback;
1585 }
1586out:
1587 tty_unlock();
1588 return ret;
1589
1590fallback:
1591 tty_unlock();
1592 return vt_ioctl(tty, cmd, arg);
1593}
1594
1595
1596#endif /* CONFIG_COMPAT */
1597
1598
1599/*
1600 * Performs the back end of a vt switch. Called under the console
1601 * semaphore.
1602 */
1603static void complete_change_console(struct vc_data *vc)
1604{
1605 unsigned char old_vc_mode;
1606 int old = fg_console;
1607
1608 last_console = fg_console;
1609
1610 /*
1611 * If we're switching, we could be going from KD_GRAPHICS to
1612 * KD_TEXT mode or vice versa, which means we need to blank or
1613 * unblank the screen later.
1614 */
1615 old_vc_mode = vc_cons[fg_console].d->vc_mode;
1616 switch_screen(vc);
1617
1618 /*
1619 * This can't appear below a successful kill_pid(). If it did,
1620 * then the *blank_screen operation could occur while X, having
1621 * received acqsig, is waking up on another processor. This
1622 * condition can lead to overlapping accesses to the VGA range
1623 * and the framebuffer (causing system lockups).
1624 *
1625 * To account for this we duplicate this code below only if the
1626 * controlling process is gone and we've called reset_vc.
1627 */
1628 if (old_vc_mode != vc->vc_mode) {
1629 if (vc->vc_mode == KD_TEXT)
1630 do_unblank_screen(1);
1631 else
1632 do_blank_screen(1);
1633 }
1634
1635 /*
1636 * If this new console is under process control, send it a signal
1637 * telling it that it has acquired. Also check if it has died and
1638 * clean up (similar to logic employed in change_console())
1639 */
1640 if (vc->vt_mode.mode == VT_PROCESS) {
1641 /*
1642 * Send the signal as privileged - kill_pid() will
1643 * tell us if the process has gone or something else
1644 * is awry
1645 */
1646 if (kill_pid(vc->vt_pid, vc->vt_mode.acqsig, 1) != 0) {
1647 /*
1648 * The controlling process has died, so we revert back to
1649 * normal operation. In this case, we'll also change back
1650 * to KD_TEXT mode. I'm not sure if this is strictly correct
1651 * but it saves the agony when the X server dies and the screen
1652 * remains blanked due to KD_GRAPHICS! It would be nice to do
1653 * this outside of VT_PROCESS but there is no single process
1654 * to account for and tracking tty count may be undesirable.
1655 */
1656 reset_vc(vc);
1657
1658 if (old_vc_mode != vc->vc_mode) {
1659 if (vc->vc_mode == KD_TEXT)
1660 do_unblank_screen(1);
1661 else
1662 do_blank_screen(1);
1663 }
1664 }
1665 }
1666
1667 /*
1668 * Wake anyone waiting for their VT to activate
1669 */
1670 vt_event_post(VT_EVENT_SWITCH, old, vc->vc_num);
1671 return;
1672}
1673
1674/*
1675 * Performs the front-end of a vt switch
1676 */
1677void change_console(struct vc_data *new_vc)
1678{
1679 struct vc_data *vc;
1680
1681 if (!new_vc || new_vc->vc_num == fg_console || vt_dont_switch)
1682 return;
1683
1684 /*
1685 * If this vt is in process mode, then we need to handshake with
1686 * that process before switching. Essentially, we store where that
1687 * vt wants to switch to and wait for it to tell us when it's done
1688 * (via VT_RELDISP ioctl).
1689 *
1690 * We also check to see if the controlling process still exists.
1691 * If it doesn't, we reset this vt to auto mode and continue.
1692 * This is a cheap way to track process control. The worst thing
1693 * that can happen is: we send a signal to a process, it dies, and
1694 * the switch gets "lost" waiting for a response; hopefully, the
1695 * user will try again, we'll detect the process is gone (unless
1696 * the user waits just the right amount of time :-) and revert the
1697 * vt to auto control.
1698 */
1699 vc = vc_cons[fg_console].d;
1700 if (vc->vt_mode.mode == VT_PROCESS) {
1701 /*
1702 * Send the signal as privileged - kill_pid() will
1703 * tell us if the process has gone or something else
1704 * is awry.
1705 *
1706 * We need to set vt_newvt *before* sending the signal or we
1707 * have a race.
1708 */
1709 vc->vt_newvt = new_vc->vc_num;
1710 if (kill_pid(vc->vt_pid, vc->vt_mode.relsig, 1) == 0) {
1711 /*
1712 * It worked. Mark the vt to switch to and
1713 * return. The process needs to send us a
1714 * VT_RELDISP ioctl to complete the switch.
1715 */
1716 return;
1717 }
1718
1719 /*
1720 * The controlling process has died, so we revert back to
1721 * normal operation. In this case, we'll also change back
1722 * to KD_TEXT mode. I'm not sure if this is strictly correct
1723 * but it saves the agony when the X server dies and the screen
1724 * remains blanked due to KD_GRAPHICS! It would be nice to do
1725 * this outside of VT_PROCESS but there is no single process
1726 * to account for and tracking tty count may be undesirable.
1727 */
1728 reset_vc(vc);
1729
1730 /*
1731 * Fall through to normal (VT_AUTO) handling of the switch...
1732 */
1733 }
1734
1735 /*
1736 * Ignore all switches in KD_GRAPHICS+VT_AUTO mode
1737 */
1738 if (vc->vc_mode == KD_GRAPHICS)
1739 return;
1740
1741 complete_change_console(new_vc);
1742}
1743
1744/* Perform a kernel triggered VT switch for suspend/resume */
1745
1746static int disable_vt_switch;
1747
1748int vt_move_to_console(unsigned int vt, int alloc)
1749{
1750 int prev;
1751
1752 console_lock();
1753 /* Graphics mode - up to X */
1754 if (disable_vt_switch) {
1755 console_unlock();
1756 return 0;
1757 }
1758 prev = fg_console;
1759
1760 if (alloc && vc_allocate(vt)) {
1761 /* we can't have a free VC for now. Too bad,
1762 * we don't want to mess the screen for now. */
1763 console_unlock();
1764 return -ENOSPC;
1765 }
1766
1767 if (set_console(vt)) {
1768 /*
1769 * We're unable to switch to the SUSPEND_CONSOLE.
1770 * Let the calling function know so it can decide
1771 * what to do.
1772 */
1773 console_unlock();
1774 return -EIO;
1775 }
1776 console_unlock();
1777 tty_lock();
1778 if (vt_waitactive(vt + 1)) {
1779 pr_debug("Suspend: Can't switch VCs.");
1780 tty_unlock();
1781 return -EINTR;
1782 }
1783 tty_unlock();
1784 return prev;
1785}
1786
1787/*
1788 * Normally during a suspend, we allocate a new console and switch to it.
1789 * When we resume, we switch back to the original console. This switch
1790 * can be slow, so on systems where the framebuffer can handle restoration
1791 * of video registers anyways, there's little point in doing the console
1792 * switch. This function allows you to disable it by passing it '0'.
1793 */
1794void pm_set_vt_switch(int do_switch)
1795{
1796 console_lock();
1797 disable_vt_switch = !do_switch;
1798 console_unlock();
1799}
1800EXPORT_SYMBOL(pm_set_vt_switch);