These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / tty / vt / consolemap.c
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/console.h>
23 #include <linux/consolemap.h>
24 #include <linux/vt_kern.h>
25
26 static unsigned short translations[][256] = {
27   /* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
28   {
29     0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
30     0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
31     0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
32     0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
33     0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
34     0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
35     0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
36     0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
37     0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
38     0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
39     0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
40     0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
41     0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
42     0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
43     0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
44     0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
45     0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
46     0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
47     0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
48     0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
49     0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
50     0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
51     0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
52     0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
53     0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
54     0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
55     0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
56     0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
57     0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
58     0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
59     0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
60     0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
61   }, 
62   /* VT100 graphics mapped to Unicode */
63   {
64     0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
65     0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
66     0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
67     0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
68     0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
69     0x0028, 0x0029, 0x002a, 0x2192, 0x2190, 0x2191, 0x2193, 0x002f,
70     0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
71     0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
72     0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
73     0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
74     0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
75     0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0,
76     0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
77     0x2591, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
78     0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
79     0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f,
80     0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
81     0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
82     0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
83     0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
84     0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
85     0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
86     0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
87     0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
88     0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
89     0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
90     0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
91     0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
92     0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
93     0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
94     0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
95     0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
96   },
97   /* IBM Codepage 437 mapped to Unicode */
98   {
99     0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, 
100     0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c,
101     0x25b6, 0x25c0, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x25ac, 0x21a8,
102     0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc,
103     0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
104     0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
105     0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
106     0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
107     0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
108     0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
109     0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
110     0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
111     0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
112     0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
113     0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
114     0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302,
115     0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
116     0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
117     0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
118     0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
119     0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
120     0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
121     0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
122     0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
123     0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
124     0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
125     0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
126     0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
127     0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
128     0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
129     0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
130     0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
131   }, 
132   /* User mapping -- default to codes for direct font mapping */
133   {
134     0xf000, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007,
135     0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f,
136     0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017,
137     0xf018, 0xf019, 0xf01a, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
138     0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
139     0xf028, 0xf029, 0xf02a, 0xf02b, 0xf02c, 0xf02d, 0xf02e, 0xf02f,
140     0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
141     0xf038, 0xf039, 0xf03a, 0xf03b, 0xf03c, 0xf03d, 0xf03e, 0xf03f,
142     0xf040, 0xf041, 0xf042, 0xf043, 0xf044, 0xf045, 0xf046, 0xf047,
143     0xf048, 0xf049, 0xf04a, 0xf04b, 0xf04c, 0xf04d, 0xf04e, 0xf04f,
144     0xf050, 0xf051, 0xf052, 0xf053, 0xf054, 0xf055, 0xf056, 0xf057,
145     0xf058, 0xf059, 0xf05a, 0xf05b, 0xf05c, 0xf05d, 0xf05e, 0xf05f,
146     0xf060, 0xf061, 0xf062, 0xf063, 0xf064, 0xf065, 0xf066, 0xf067,
147     0xf068, 0xf069, 0xf06a, 0xf06b, 0xf06c, 0xf06d, 0xf06e, 0xf06f,
148     0xf070, 0xf071, 0xf072, 0xf073, 0xf074, 0xf075, 0xf076, 0xf077,
149     0xf078, 0xf079, 0xf07a, 0xf07b, 0xf07c, 0xf07d, 0xf07e, 0xf07f,
150     0xf080, 0xf081, 0xf082, 0xf083, 0xf084, 0xf085, 0xf086, 0xf087,
151     0xf088, 0xf089, 0xf08a, 0xf08b, 0xf08c, 0xf08d, 0xf08e, 0xf08f,
152     0xf090, 0xf091, 0xf092, 0xf093, 0xf094, 0xf095, 0xf096, 0xf097,
153     0xf098, 0xf099, 0xf09a, 0xf09b, 0xf09c, 0xf09d, 0xf09e, 0xf09f,
154     0xf0a0, 0xf0a1, 0xf0a2, 0xf0a3, 0xf0a4, 0xf0a5, 0xf0a6, 0xf0a7,
155     0xf0a8, 0xf0a9, 0xf0aa, 0xf0ab, 0xf0ac, 0xf0ad, 0xf0ae, 0xf0af,
156     0xf0b0, 0xf0b1, 0xf0b2, 0xf0b3, 0xf0b4, 0xf0b5, 0xf0b6, 0xf0b7,
157     0xf0b8, 0xf0b9, 0xf0ba, 0xf0bb, 0xf0bc, 0xf0bd, 0xf0be, 0xf0bf,
158     0xf0c0, 0xf0c1, 0xf0c2, 0xf0c3, 0xf0c4, 0xf0c5, 0xf0c6, 0xf0c7,
159     0xf0c8, 0xf0c9, 0xf0ca, 0xf0cb, 0xf0cc, 0xf0cd, 0xf0ce, 0xf0cf,
160     0xf0d0, 0xf0d1, 0xf0d2, 0xf0d3, 0xf0d4, 0xf0d5, 0xf0d6, 0xf0d7,
161     0xf0d8, 0xf0d9, 0xf0da, 0xf0db, 0xf0dc, 0xf0dd, 0xf0de, 0xf0df,
162     0xf0e0, 0xf0e1, 0xf0e2, 0xf0e3, 0xf0e4, 0xf0e5, 0xf0e6, 0xf0e7,
163     0xf0e8, 0xf0e9, 0xf0ea, 0xf0eb, 0xf0ec, 0xf0ed, 0xf0ee, 0xf0ef,
164     0xf0f0, 0xf0f1, 0xf0f2, 0xf0f3, 0xf0f4, 0xf0f5, 0xf0f6, 0xf0f7,
165     0xf0f8, 0xf0f9, 0xf0fa, 0xf0fb, 0xf0fc, 0xf0fd, 0xf0fe, 0xf0ff
166   }
167 };
168
169 /* The standard kernel character-to-font mappings are not invertible
170    -- this is just a best effort. */
171
172 #define MAX_GLYPH 512           /* Max possible glyph value */
173
174 static int inv_translate[MAX_NR_CONSOLES];
175
176 struct uni_pagedir {
177         u16             **uni_pgdir[32];
178         unsigned long   refcount;
179         unsigned long   sum;
180         unsigned char   *inverse_translations[4];
181         u16             *inverse_trans_unicode;
182 };
183
184 static struct uni_pagedir *dflt;
185
186 static 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] = kmalloc(MAX_GLYPH, GFP_KERNEL);
197                 if (!q) return;
198         }
199         memset(q, 0, MAX_GLYPH);
200
201         for (j = 0; j < E_TABSZ; j++) {
202                 glyph = conv_uni_to_pc(conp, t[j]);
203                 if (glyph >= 0 && glyph < MAX_GLYPH && q[glyph] < 32) {
204                         /* prefer '-' above SHY etc. */
205                         q[glyph] = j;
206                 }
207         }
208 }
209
210 static void set_inverse_trans_unicode(struct vc_data *conp,
211                                       struct uni_pagedir *p)
212 {
213         int i, j, k, glyph;
214         u16 **p1, *p2;
215         u16 *q;
216
217         if (!p) return;
218         q = p->inverse_trans_unicode;
219         if (!q) {
220                 q = p->inverse_trans_unicode =
221                         kmalloc(MAX_GLYPH * sizeof(u16), GFP_KERNEL);
222                 if (!q)
223                         return;
224         }
225         memset(q, 0, MAX_GLYPH * sizeof(u16));
226
227         for (i = 0; i < 32; i++) {
228                 p1 = p->uni_pgdir[i];
229                 if (!p1)
230                         continue;
231                 for (j = 0; j < 32; j++) {
232                         p2 = p1[j];
233                         if (!p2)
234                                 continue;
235                         for (k = 0; k < 64; k++) {
236                                 glyph = p2[k];
237                                 if (glyph >= 0 && glyph < MAX_GLYPH
238                                                && q[glyph] < 32)
239                                         q[glyph] = (i << 11) + (j << 6) + k;
240                         }
241                 }
242         }
243 }
244
245 unsigned short *set_translate(int m, struct vc_data *vc)
246 {
247         inv_translate[vc->vc_num] = m;
248         return translations[m];
249 }
250
251 /*
252  * Inverse translation is impossible for several reasons:
253  * 1. The font<->character maps are not 1-1.
254  * 2. The text may have been written while a different translation map
255  *    was active.
256  * Still, it is now possible to a certain extent to cut and paste non-ASCII.
257  */
258 u16 inverse_translate(struct vc_data *conp, int glyph, int use_unicode)
259 {
260         struct uni_pagedir *p;
261         int m;
262         if (glyph < 0 || glyph >= MAX_GLYPH)
263                 return 0;
264         else {
265                 p = *conp->vc_uni_pagedir_loc;
266                 if (!p)
267                         return glyph;
268                 else if (use_unicode) {
269                         if (!p->inverse_trans_unicode)
270                                 return glyph;
271                         else
272                                 return p->inverse_trans_unicode[glyph];
273                         } else {
274                         m = inv_translate[conp->vc_num];
275                         if (!p->inverse_translations[m])
276                                 return glyph;
277                         else
278                                 return p->inverse_translations[m][glyph];
279                         }
280         }
281 }
282 EXPORT_SYMBOL_GPL(inverse_translate);
283
284 static void update_user_maps(void)
285 {
286         int i;
287         struct uni_pagedir *p, *q = NULL;
288         
289         for (i = 0; i < MAX_NR_CONSOLES; i++) {
290                 if (!vc_cons_allocated(i))
291                         continue;
292                 p = *vc_cons[i].d->vc_uni_pagedir_loc;
293                 if (p && p != q) {
294                         set_inverse_transl(vc_cons[i].d, p, USER_MAP);
295                         set_inverse_trans_unicode(vc_cons[i].d, p);
296                         q = p;
297                 }
298         }
299 }
300
301 /*
302  * Load customizable translation table
303  * arg points to a 256 byte translation table.
304  *
305  * The "old" variants are for translation directly to font (using the
306  * 0xf000-0xf0ff "transparent" Unicodes) whereas the "new" variants set
307  * Unicodes explicitly.
308  */
309 int con_set_trans_old(unsigned char __user * arg)
310 {
311         int i;
312         unsigned short *p = translations[USER_MAP];
313
314         if (!access_ok(VERIFY_READ, arg, E_TABSZ))
315                 return -EFAULT;
316
317         console_lock();
318         for (i=0; i<E_TABSZ ; i++) {
319                 unsigned char uc;
320                 __get_user(uc, arg+i);
321                 p[i] = UNI_DIRECT_BASE | uc;
322         }
323
324         update_user_maps();
325         console_unlock();
326         return 0;
327 }
328
329 int con_get_trans_old(unsigned char __user * arg)
330 {
331         int i, ch;
332         unsigned short *p = translations[USER_MAP];
333
334         if (!access_ok(VERIFY_WRITE, arg, E_TABSZ))
335                 return -EFAULT;
336
337         console_lock();
338         for (i=0; i<E_TABSZ ; i++)
339         {
340                 ch = conv_uni_to_pc(vc_cons[fg_console].d, p[i]);
341                 __put_user((ch & ~0xff) ? 0 : ch, arg+i);
342         }
343         console_unlock();
344         return 0;
345 }
346
347 int con_set_trans_new(ushort __user * arg)
348 {
349         int i;
350         unsigned short *p = translations[USER_MAP];
351
352         if (!access_ok(VERIFY_READ, arg, E_TABSZ*sizeof(unsigned short)))
353                 return -EFAULT;
354
355         console_lock();
356         for (i=0; i<E_TABSZ ; i++) {
357                 unsigned short us;
358                 __get_user(us, arg+i);
359                 p[i] = us;
360         }
361
362         update_user_maps();
363         console_unlock();
364         return 0;
365 }
366
367 int con_get_trans_new(ushort __user * arg)
368 {
369         int i;
370         unsigned short *p = translations[USER_MAP];
371
372         if (!access_ok(VERIFY_WRITE, arg, E_TABSZ*sizeof(unsigned short)))
373                 return -EFAULT;
374
375         console_lock();
376         for (i=0; i<E_TABSZ ; i++)
377           __put_user(p[i], arg+i);
378         console_unlock();
379         
380         return 0;
381 }
382
383 /*
384  * Unicode -> current font conversion 
385  *
386  * A font has at most 512 chars, usually 256.
387  * But one font position may represent several Unicode chars.
388  * A hashtable is somewhat of a pain to deal with, so use a
389  * "paged table" instead.  Simulation has shown the memory cost of
390  * this 3-level paged table scheme to be comparable to a hash table.
391  */
392
393 extern u8 dfont_unicount[];     /* Defined in console_defmap.c */
394 extern u16 dfont_unitable[];
395
396 static void con_release_unimap(struct uni_pagedir *p)
397 {
398         u16 **p1;
399         int i, j;
400
401         if (p == dflt) dflt = NULL;  
402         for (i = 0; i < 32; i++) {
403                 p1 = p->uni_pgdir[i];
404                 if (p1 != NULL) {
405                         for (j = 0; j < 32; j++)
406                                 kfree(p1[j]);
407                         kfree(p1);
408                 }
409                 p->uni_pgdir[i] = NULL;
410         }
411         for (i = 0; i < 4; i++) {
412                 kfree(p->inverse_translations[i]);
413                 p->inverse_translations[i] = NULL;
414         }
415         kfree(p->inverse_trans_unicode);
416         p->inverse_trans_unicode = NULL;
417 }
418
419 /* Caller must hold the console lock */
420 void con_free_unimap(struct vc_data *vc)
421 {
422         struct uni_pagedir *p;
423
424         p = *vc->vc_uni_pagedir_loc;
425         if (!p)
426                 return;
427         *vc->vc_uni_pagedir_loc = NULL;
428         if (--p->refcount)
429                 return;
430         con_release_unimap(p);
431         kfree(p);
432 }
433   
434 static int con_unify_unimap(struct vc_data *conp, struct uni_pagedir *p)
435 {
436         int i, j, k;
437         struct uni_pagedir *q;
438         
439         for (i = 0; i < MAX_NR_CONSOLES; i++) {
440                 if (!vc_cons_allocated(i))
441                         continue;
442                 q = *vc_cons[i].d->vc_uni_pagedir_loc;
443                 if (!q || q == p || q->sum != p->sum)
444                         continue;
445                 for (j = 0; j < 32; j++) {
446                         u16 **p1, **q1;
447                         p1 = p->uni_pgdir[j]; q1 = q->uni_pgdir[j];
448                         if (!p1 && !q1)
449                                 continue;
450                         if (!p1 || !q1)
451                                 break;
452                         for (k = 0; k < 32; k++) {
453                                 if (!p1[k] && !q1[k])
454                                         continue;
455                                 if (!p1[k] || !q1[k])
456                                         break;
457                                 if (memcmp(p1[k], q1[k], 64*sizeof(u16)))
458                                         break;
459                         }
460                         if (k < 32)
461                                 break;
462                 }
463                 if (j == 32) {
464                         q->refcount++;
465                         *conp->vc_uni_pagedir_loc = q;
466                         con_release_unimap(p);
467                         kfree(p);
468                         return 1;
469                 }
470         }
471         return 0;
472 }
473
474 static int
475 con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos)
476 {
477         int i, n;
478         u16 **p1, *p2;
479
480         p1 = p->uni_pgdir[n = unicode >> 11];
481         if (!p1) {
482                 p1 = p->uni_pgdir[n] = kmalloc(32*sizeof(u16 *), GFP_KERNEL);
483                 if (!p1) return -ENOMEM;
484                 for (i = 0; i < 32; i++)
485                         p1[i] = NULL;
486         }
487
488         p2 = p1[n = (unicode >> 6) & 0x1f];
489         if (!p2) {
490                 p2 = p1[n] = kmalloc(64*sizeof(u16), GFP_KERNEL);
491                 if (!p2) return -ENOMEM;
492                 memset(p2, 0xff, 64*sizeof(u16)); /* No glyphs for the characters (yet) */
493         }
494
495         p2[unicode & 0x3f] = fontpos;
496         
497         p->sum += (fontpos << 20) + unicode;
498
499         return 0;
500 }
501
502 /* ui is a leftover from using a hashtable, but might be used again
503    Caller must hold the lock */
504 static int con_do_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
505 {
506         struct uni_pagedir *p, *q;
507
508         p = *vc->vc_uni_pagedir_loc;
509         if (!p || --p->refcount) {
510                 q = kzalloc(sizeof(*p), GFP_KERNEL);
511                 if (!q) {
512                         if (p)
513                                 p->refcount++;
514                         return -ENOMEM;
515                 }
516                 q->refcount=1;
517                 *vc->vc_uni_pagedir_loc = q;
518         } else {
519                 if (p == dflt) dflt = NULL;
520                 p->refcount++;
521                 p->sum = 0;
522                 con_release_unimap(p);
523         }
524         return 0;
525 }
526
527 int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
528 {
529         int ret;
530         console_lock();
531         ret = con_do_clear_unimap(vc, ui);
532         console_unlock();
533         return ret;
534 }
535         
536 int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
537 {
538         int err = 0, err1, i;
539         struct uni_pagedir *p, *q;
540
541         if (!ct)
542                 return 0;
543
544         console_lock();
545
546         /* Save original vc_unipagdir_loc in case we allocate a new one */
547         p = *vc->vc_uni_pagedir_loc;
548
549         if (!p) {
550                 err = -EINVAL;
551
552                 goto out_unlock;
553         }
554         
555         if (p->refcount > 1) {
556                 int j, k;
557                 u16 **p1, *p2, l;
558                 
559                 err1 = con_do_clear_unimap(vc, NULL);
560                 if (err1) {
561                         console_unlock();
562                         return err1;
563                 }
564                 
565                 /*
566                  * Since refcount was > 1, con_clear_unimap() allocated a
567                  * a new uni_pagedir for this vc.  Re: p != q
568                  */
569                 q = *vc->vc_uni_pagedir_loc;
570
571                 /*
572                  * uni_pgdir is a 32*32*64 table with rows allocated
573                  * when its first entry is added.  The unicode value must
574                  * still be incremented for empty rows.  We are copying
575                  * entries from "p" (old) to "q" (new).
576                  */
577                 l = 0;          /* unicode value */
578                 for (i = 0; i < 32; i++) {
579                 p1 = p->uni_pgdir[i];
580                 if (p1)
581                         for (j = 0; j < 32; j++) {
582                         p2 = p1[j];
583                         if (p2) {
584                                 for (k = 0; k < 64; k++, l++)
585                                 if (p2[k] != 0xffff) {
586                                         /*
587                                          * Found one, copy entry for unicode
588                                          * l with fontpos value p2[k].
589                                          */
590                                         err1 = con_insert_unipair(q, l, p2[k]);
591                                         if (err1) {
592                                                 p->refcount++;
593                                                 *vc->vc_uni_pagedir_loc = p;
594                                                 con_release_unimap(q);
595                                                 kfree(q);
596                                                 console_unlock();
597                                                 return err1; 
598                                         }
599                                 }
600                         } else {
601                                 /* Account for row of 64 empty entries */
602                                 l += 64;
603                         }
604                 }
605                 else
606                         /* Account for empty table */
607                         l += 32 * 64;
608                 }
609
610                 /*
611                  * Finished copying font table, set vc_uni_pagedir to new table
612                  */
613                 p = q;
614         } else if (p == dflt) {
615                 dflt = NULL;
616         }
617
618         /*
619          * Insert user specified unicode pairs into new table.
620          */
621         while (ct--) {
622                 unsigned short unicode, fontpos;
623                 __get_user(unicode, &list->unicode);
624                 __get_user(fontpos, &list->fontpos);
625                 if ((err1 = con_insert_unipair(p, unicode,fontpos)) != 0)
626                         err = err1;
627                 list++;
628         }
629         
630         /*
631          * Merge with fontmaps of any other virtual consoles.
632          */
633         if (con_unify_unimap(vc, p)) {
634                 console_unlock();
635                 return err;
636         }
637
638         for (i = 0; i <= 3; i++)
639                 set_inverse_transl(vc, p, i); /* Update inverse translations */
640         set_inverse_trans_unicode(vc, p);
641
642 out_unlock:
643         console_unlock();
644         return err;
645 }
646
647 /**
648  *      con_set_default_unimap  -       set default unicode map
649  *      @vc: the console we are updating
650  *
651  *      Loads the unimap for the hardware font, as defined in uni_hash.tbl.
652  *      The representation used was the most compact I could come up
653  *      with.  This routine is executed at video setup, and when the
654  *      PIO_FONTRESET ioctl is called. 
655  *
656  *      The caller must hold the console lock
657  */
658 int con_set_default_unimap(struct vc_data *vc)
659 {
660         int i, j, err = 0, err1;
661         u16 *q;
662         struct uni_pagedir *p;
663
664         if (dflt) {
665                 p = *vc->vc_uni_pagedir_loc;
666                 if (p == dflt)
667                         return 0;
668
669                 dflt->refcount++;
670                 *vc->vc_uni_pagedir_loc = dflt;
671                 if (p && !--p->refcount) {
672                         con_release_unimap(p);
673                         kfree(p);
674                 }
675                 return 0;
676         }
677         
678         /* The default font is always 256 characters */
679
680         err = con_do_clear_unimap(vc, NULL);
681         if (err)
682                 return err;
683     
684         p = *vc->vc_uni_pagedir_loc;
685         q = dfont_unitable;
686         
687         for (i = 0; i < 256; i++)
688                 for (j = dfont_unicount[i]; j; j--) {
689                         err1 = con_insert_unipair(p, *(q++), i);
690                         if (err1)
691                                 err = err1;
692                 }
693                         
694         if (con_unify_unimap(vc, p)) {
695                 dflt = *vc->vc_uni_pagedir_loc;
696                 return err;
697         }
698
699         for (i = 0; i <= 3; i++)
700                 set_inverse_transl(vc, p, i);   /* Update all inverse translations */
701         set_inverse_trans_unicode(vc, p);
702         dflt = p;
703         return err;
704 }
705 EXPORT_SYMBOL(con_set_default_unimap);
706
707 /**
708  *      con_copy_unimap         -       copy unimap between two vts
709  *      @dst_vc: target
710  *      @src_vt: source
711  *
712  *      The caller must hold the console lock when invoking this method
713  */
714 int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc)
715 {
716         struct uni_pagedir *q;
717
718         if (!*src_vc->vc_uni_pagedir_loc)
719                 return -EINVAL;
720         if (*dst_vc->vc_uni_pagedir_loc == *src_vc->vc_uni_pagedir_loc)
721                 return 0;
722         con_free_unimap(dst_vc);
723         q = *src_vc->vc_uni_pagedir_loc;
724         q->refcount++;
725         *dst_vc->vc_uni_pagedir_loc = q;
726         return 0;
727 }
728 EXPORT_SYMBOL(con_copy_unimap);
729
730 /**
731  *      con_get_unimap          -       get the unicode map
732  *      @vc: the console to read from
733  *
734  *      Read the console unicode data for this console. Called from the ioctl
735  *      handlers.
736  */
737 int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct unipair __user *list)
738 {
739         int i, j, k, ect;
740         u16 **p1, *p2;
741         struct uni_pagedir *p;
742
743         console_lock();
744
745         ect = 0;
746         if (*vc->vc_uni_pagedir_loc) {
747                 p = *vc->vc_uni_pagedir_loc;
748                 for (i = 0; i < 32; i++) {
749                 p1 = p->uni_pgdir[i];
750                 if (p1)
751                         for (j = 0; j < 32; j++) {
752                         p2 = *(p1++);
753                         if (p2)
754                                 for (k = 0; k < 64; k++) {
755                                         if (*p2 < MAX_GLYPH && ect++ < ct) {
756                                                 __put_user((u_short)((i<<11)+(j<<6)+k),
757                                                            &list->unicode);
758                                                 __put_user((u_short) *p2, 
759                                                            &list->fontpos);
760                                                 list++;
761                                         }
762                                         p2++;
763                                 }
764                         }
765                 }
766         }
767         __put_user(ect, uct);
768         console_unlock();
769         return ((ect <= ct) ? 0 : -ENOMEM);
770 }
771
772 /*
773  * Always use USER_MAP. These functions are used by the keyboard,
774  * which shouldn't be affected by G0/G1 switching, etc.
775  * If the user map still contains default values, i.e. the
776  * direct-to-font mapping, then assume user is using Latin1.
777  *
778  * FIXME: at some point we need to decide if we want to lock the table
779  * update element itself via the keyboard_event_lock for consistency with the
780  * keyboard driver as well as the consoles
781  */
782 /* may be called during an interrupt */
783 u32 conv_8bit_to_uni(unsigned char c)
784 {
785         unsigned short uni = translations[USER_MAP][c];
786         return uni == (0xf000 | c) ? c : uni;
787 }
788
789 int conv_uni_to_8bit(u32 uni)
790 {
791         int c;
792         for (c = 0; c < 0x100; c++)
793                 if (translations[USER_MAP][c] == uni ||
794                    (translations[USER_MAP][c] == (c | 0xf000) && uni == c))
795                         return c;
796         return -1;
797 }
798
799 int
800 conv_uni_to_pc(struct vc_data *conp, long ucs) 
801 {
802         int h;
803         u16 **p1, *p2;
804         struct uni_pagedir *p;
805   
806         /* Only 16-bit codes supported at this time */
807         if (ucs > 0xffff)
808                 return -4;              /* Not found */
809         else if (ucs < 0x20)
810                 return -1;              /* Not a printable character */
811         else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f))
812                 return -2;                      /* Zero-width space */
813         /*
814          * UNI_DIRECT_BASE indicates the start of the region in the User Zone
815          * which always has a 1:1 mapping to the currently loaded font.  The
816          * UNI_DIRECT_MASK indicates the bit span of the region.
817          */
818         else if ((ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE)
819                 return ucs & UNI_DIRECT_MASK;
820   
821         if (!*conp->vc_uni_pagedir_loc)
822                 return -3;
823
824         p = *conp->vc_uni_pagedir_loc;
825         if ((p1 = p->uni_pgdir[ucs >> 11]) &&
826             (p2 = p1[(ucs >> 6) & 0x1f]) &&
827             (h = p2[ucs & 0x3f]) < MAX_GLYPH)
828                 return h;
829
830         return -4;              /* not found */
831 }
832
833 /*
834  * This is called at sys_setup time, after memory and the console are
835  * initialized.  It must be possible to call kmalloc(..., GFP_KERNEL)
836  * from this function, hence the call from sys_setup.
837  */
838 void __init 
839 console_map_init(void)
840 {
841         int i;
842         
843         for (i = 0; i < MAX_NR_CONSOLES; i++)
844                 if (vc_cons_allocated(i) && !*vc_cons[i].d->vc_uni_pagedir_loc)
845                         con_set_default_unimap(vc_cons[i].d);
846 }
847