Add the rt linux 4.1.3-rt3 as base
[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 if (!(p = *conp->vc_uni_pagedir_loc))
265                 return glyph;
266         else if (use_unicode) {
267                 if (!p->inverse_trans_unicode)
268                         return glyph;
269                 else
270                         return p->inverse_trans_unicode[glyph];
271         } else {
272                 m = inv_translate[conp->vc_num];
273                 if (!p->inverse_translations[m])
274                         return glyph;
275                 else
276                         return p->inverse_translations[m][glyph];
277         }
278 }
279 EXPORT_SYMBOL_GPL(inverse_translate);
280
281 static void update_user_maps(void)
282 {
283         int i;
284         struct uni_pagedir *p, *q = NULL;
285         
286         for (i = 0; i < MAX_NR_CONSOLES; i++) {
287                 if (!vc_cons_allocated(i))
288                         continue;
289                 p = *vc_cons[i].d->vc_uni_pagedir_loc;
290                 if (p && p != q) {
291                         set_inverse_transl(vc_cons[i].d, p, USER_MAP);
292                         set_inverse_trans_unicode(vc_cons[i].d, p);
293                         q = p;
294                 }
295         }
296 }
297
298 /*
299  * Load customizable translation table
300  * arg points to a 256 byte translation table.
301  *
302  * The "old" variants are for translation directly to font (using the
303  * 0xf000-0xf0ff "transparent" Unicodes) whereas the "new" variants set
304  * Unicodes explicitly.
305  */
306 int con_set_trans_old(unsigned char __user * arg)
307 {
308         int i;
309         unsigned short *p = translations[USER_MAP];
310
311         if (!access_ok(VERIFY_READ, arg, E_TABSZ))
312                 return -EFAULT;
313
314         console_lock();
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         console_unlock();
323         return 0;
324 }
325
326 int con_get_trans_old(unsigned char __user * arg)
327 {
328         int i, ch;
329         unsigned short *p = translations[USER_MAP];
330
331         if (!access_ok(VERIFY_WRITE, arg, E_TABSZ))
332                 return -EFAULT;
333
334         console_lock();
335         for (i=0; i<E_TABSZ ; i++)
336         {
337                 ch = conv_uni_to_pc(vc_cons[fg_console].d, p[i]);
338                 __put_user((ch & ~0xff) ? 0 : ch, arg+i);
339         }
340         console_unlock();
341         return 0;
342 }
343
344 int con_set_trans_new(ushort __user * arg)
345 {
346         int i;
347         unsigned short *p = translations[USER_MAP];
348
349         if (!access_ok(VERIFY_READ, arg, E_TABSZ*sizeof(unsigned short)))
350                 return -EFAULT;
351
352         console_lock();
353         for (i=0; i<E_TABSZ ; i++) {
354                 unsigned short us;
355                 __get_user(us, arg+i);
356                 p[i] = us;
357         }
358
359         update_user_maps();
360         console_unlock();
361         return 0;
362 }
363
364 int con_get_trans_new(ushort __user * arg)
365 {
366         int i;
367         unsigned short *p = translations[USER_MAP];
368
369         if (!access_ok(VERIFY_WRITE, arg, E_TABSZ*sizeof(unsigned short)))
370                 return -EFAULT;
371
372         console_lock();
373         for (i=0; i<E_TABSZ ; i++)
374           __put_user(p[i], arg+i);
375         console_unlock();
376         
377         return 0;
378 }
379
380 /*
381  * Unicode -> current font conversion 
382  *
383  * A font has at most 512 chars, usually 256.
384  * But one font position may represent several Unicode chars.
385  * A hashtable is somewhat of a pain to deal with, so use a
386  * "paged table" instead.  Simulation has shown the memory cost of
387  * this 3-level paged table scheme to be comparable to a hash table.
388  */
389
390 extern u8 dfont_unicount[];     /* Defined in console_defmap.c */
391 extern u16 dfont_unitable[];
392
393 static void con_release_unimap(struct uni_pagedir *p)
394 {
395         u16 **p1;
396         int i, j;
397
398         if (p == dflt) dflt = NULL;  
399         for (i = 0; i < 32; i++) {
400                 if ((p1 = p->uni_pgdir[i]) != NULL) {
401                         for (j = 0; j < 32; j++)
402                                 kfree(p1[j]);
403                         kfree(p1);
404                 }
405                 p->uni_pgdir[i] = NULL;
406         }
407         for (i = 0; i < 4; i++) {
408                 kfree(p->inverse_translations[i]);
409                 p->inverse_translations[i] = NULL;
410         }
411         kfree(p->inverse_trans_unicode);
412         p->inverse_trans_unicode = NULL;
413 }
414
415 /* Caller must hold the console lock */
416 void con_free_unimap(struct vc_data *vc)
417 {
418         struct uni_pagedir *p;
419
420         p = *vc->vc_uni_pagedir_loc;
421         if (!p)
422                 return;
423         *vc->vc_uni_pagedir_loc = NULL;
424         if (--p->refcount)
425                 return;
426         con_release_unimap(p);
427         kfree(p);
428 }
429   
430 static int con_unify_unimap(struct vc_data *conp, struct uni_pagedir *p)
431 {
432         int i, j, k;
433         struct uni_pagedir *q;
434         
435         for (i = 0; i < MAX_NR_CONSOLES; i++) {
436                 if (!vc_cons_allocated(i))
437                         continue;
438                 q = *vc_cons[i].d->vc_uni_pagedir_loc;
439                 if (!q || q == p || q->sum != p->sum)
440                         continue;
441                 for (j = 0; j < 32; j++) {
442                         u16 **p1, **q1;
443                         p1 = p->uni_pgdir[j]; q1 = q->uni_pgdir[j];
444                         if (!p1 && !q1)
445                                 continue;
446                         if (!p1 || !q1)
447                                 break;
448                         for (k = 0; k < 32; k++) {
449                                 if (!p1[k] && !q1[k])
450                                         continue;
451                                 if (!p1[k] || !q1[k])
452                                         break;
453                                 if (memcmp(p1[k], q1[k], 64*sizeof(u16)))
454                                         break;
455                         }
456                         if (k < 32)
457                                 break;
458                 }
459                 if (j == 32) {
460                         q->refcount++;
461                         *conp->vc_uni_pagedir_loc = q;
462                         con_release_unimap(p);
463                         kfree(p);
464                         return 1;
465                 }
466         }
467         return 0;
468 }
469
470 static int
471 con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos)
472 {
473         int i, n;
474         u16 **p1, *p2;
475
476         if (!(p1 = p->uni_pgdir[n = unicode >> 11])) {
477                 p1 = p->uni_pgdir[n] = kmalloc(32*sizeof(u16 *), GFP_KERNEL);
478                 if (!p1) return -ENOMEM;
479                 for (i = 0; i < 32; i++)
480                         p1[i] = NULL;
481         }
482
483         if (!(p2 = p1[n = (unicode >> 6) & 0x1f])) {
484                 p2 = p1[n] = kmalloc(64*sizeof(u16), GFP_KERNEL);
485                 if (!p2) return -ENOMEM;
486                 memset(p2, 0xff, 64*sizeof(u16)); /* No glyphs for the characters (yet) */
487         }
488
489         p2[unicode & 0x3f] = fontpos;
490         
491         p->sum += (fontpos << 20) + unicode;
492
493         return 0;
494 }
495
496 /* ui is a leftover from using a hashtable, but might be used again
497    Caller must hold the lock */
498 static int con_do_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
499 {
500         struct uni_pagedir *p, *q;
501
502         p = *vc->vc_uni_pagedir_loc;
503         if (!p || --p->refcount) {
504                 q = kzalloc(sizeof(*p), GFP_KERNEL);
505                 if (!q) {
506                         if (p)
507                                 p->refcount++;
508                         return -ENOMEM;
509                 }
510                 q->refcount=1;
511                 *vc->vc_uni_pagedir_loc = q;
512         } else {
513                 if (p == dflt) dflt = NULL;
514                 p->refcount++;
515                 p->sum = 0;
516                 con_release_unimap(p);
517         }
518         return 0;
519 }
520
521 int con_clear_unimap(struct vc_data *vc, struct unimapinit *ui)
522 {
523         int ret;
524         console_lock();
525         ret = con_do_clear_unimap(vc, ui);
526         console_unlock();
527         return ret;
528 }
529         
530 int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
531 {
532         int err = 0, err1, i;
533         struct uni_pagedir *p, *q;
534
535         if (!ct)
536                 return 0;
537
538         console_lock();
539
540         /* Save original vc_unipagdir_loc in case we allocate a new one */
541         p = *vc->vc_uni_pagedir_loc;
542
543         if (!p) {
544                 err = -EINVAL;
545
546                 goto out_unlock;
547         }
548         
549         if (p->refcount > 1) {
550                 int j, k;
551                 u16 **p1, *p2, l;
552                 
553                 err1 = con_do_clear_unimap(vc, NULL);
554                 if (err1) {
555                         console_unlock();
556                         return err1;
557                 }
558                 
559                 /*
560                  * Since refcount was > 1, con_clear_unimap() allocated a
561                  * a new uni_pagedir for this vc.  Re: p != q
562                  */
563                 q = *vc->vc_uni_pagedir_loc;
564
565                 /*
566                  * uni_pgdir is a 32*32*64 table with rows allocated
567                  * when its first entry is added.  The unicode value must
568                  * still be incremented for empty rows.  We are copying
569                  * entries from "p" (old) to "q" (new).
570                  */
571                 l = 0;          /* unicode value */
572                 for (i = 0; i < 32; i++)
573                 if ((p1 = p->uni_pgdir[i]))
574                         for (j = 0; j < 32; j++)
575                         if ((p2 = p1[j])) {
576                                 for (k = 0; k < 64; k++, l++)
577                                 if (p2[k] != 0xffff) {
578                                         /*
579                                          * Found one, copy entry for unicode
580                                          * l with fontpos value p2[k].
581                                          */
582                                         err1 = con_insert_unipair(q, l, p2[k]);
583                                         if (err1) {
584                                                 p->refcount++;
585                                                 *vc->vc_uni_pagedir_loc = p;
586                                                 con_release_unimap(q);
587                                                 kfree(q);
588                                                 console_unlock();
589                                                 return err1; 
590                                         }
591                                 }
592                         } else {
593                                 /* Account for row of 64 empty entries */
594                                 l += 64;
595                         }
596                 else
597                         /* Account for empty table */
598                         l += 32 * 64;
599
600                 /*
601                  * Finished copying font table, set vc_uni_pagedir to new table
602                  */
603                 p = q;
604         } else if (p == dflt) {
605                 dflt = NULL;
606         }
607
608         /*
609          * Insert user specified unicode pairs into new table.
610          */
611         while (ct--) {
612                 unsigned short unicode, fontpos;
613                 __get_user(unicode, &list->unicode);
614                 __get_user(fontpos, &list->fontpos);
615                 if ((err1 = con_insert_unipair(p, unicode,fontpos)) != 0)
616                         err = err1;
617                 list++;
618         }
619         
620         /*
621          * Merge with fontmaps of any other virtual consoles.
622          */
623         if (con_unify_unimap(vc, p)) {
624                 console_unlock();
625                 return err;
626         }
627
628         for (i = 0; i <= 3; i++)
629                 set_inverse_transl(vc, p, i); /* Update inverse translations */
630         set_inverse_trans_unicode(vc, p);
631
632 out_unlock:
633         console_unlock();
634         return err;
635 }
636
637 /**
638  *      con_set_default_unimap  -       set default unicode map
639  *      @vc: the console we are updating
640  *
641  *      Loads the unimap for the hardware font, as defined in uni_hash.tbl.
642  *      The representation used was the most compact I could come up
643  *      with.  This routine is executed at video setup, and when the
644  *      PIO_FONTRESET ioctl is called. 
645  *
646  *      The caller must hold the console lock
647  */
648 int con_set_default_unimap(struct vc_data *vc)
649 {
650         int i, j, err = 0, err1;
651         u16 *q;
652         struct uni_pagedir *p;
653
654         if (dflt) {
655                 p = *vc->vc_uni_pagedir_loc;
656                 if (p == dflt)
657                         return 0;
658
659                 dflt->refcount++;
660                 *vc->vc_uni_pagedir_loc = dflt;
661                 if (p && !--p->refcount) {
662                         con_release_unimap(p);
663                         kfree(p);
664                 }
665                 return 0;
666         }
667         
668         /* The default font is always 256 characters */
669
670         err = con_do_clear_unimap(vc, NULL);
671         if (err)
672                 return err;
673     
674         p = *vc->vc_uni_pagedir_loc;
675         q = dfont_unitable;
676         
677         for (i = 0; i < 256; i++)
678                 for (j = dfont_unicount[i]; j; j--) {
679                         err1 = con_insert_unipair(p, *(q++), i);
680                         if (err1)
681                                 err = err1;
682                 }
683                         
684         if (con_unify_unimap(vc, p)) {
685                 dflt = *vc->vc_uni_pagedir_loc;
686                 return err;
687         }
688
689         for (i = 0; i <= 3; i++)
690                 set_inverse_transl(vc, p, i);   /* Update all inverse translations */
691         set_inverse_trans_unicode(vc, p);
692         dflt = p;
693         return err;
694 }
695 EXPORT_SYMBOL(con_set_default_unimap);
696
697 /**
698  *      con_copy_unimap         -       copy unimap between two vts
699  *      @dst_vc: target
700  *      @src_vt: source
701  *
702  *      The caller must hold the console lock when invoking this method
703  */
704 int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc)
705 {
706         struct uni_pagedir *q;
707
708         if (!*src_vc->vc_uni_pagedir_loc)
709                 return -EINVAL;
710         if (*dst_vc->vc_uni_pagedir_loc == *src_vc->vc_uni_pagedir_loc)
711                 return 0;
712         con_free_unimap(dst_vc);
713         q = *src_vc->vc_uni_pagedir_loc;
714         q->refcount++;
715         *dst_vc->vc_uni_pagedir_loc = q;
716         return 0;
717 }
718 EXPORT_SYMBOL(con_copy_unimap);
719
720 /**
721  *      con_get_unimap          -       get the unicode map
722  *      @vc: the console to read from
723  *
724  *      Read the console unicode data for this console. Called from the ioctl
725  *      handlers.
726  */
727 int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct unipair __user *list)
728 {
729         int i, j, k, ect;
730         u16 **p1, *p2;
731         struct uni_pagedir *p;
732
733         console_lock();
734
735         ect = 0;
736         if (*vc->vc_uni_pagedir_loc) {
737                 p = *vc->vc_uni_pagedir_loc;
738                 for (i = 0; i < 32; i++)
739                 if ((p1 = p->uni_pgdir[i]))
740                         for (j = 0; j < 32; j++)
741                         if ((p2 = *(p1++)))
742                                 for (k = 0; k < 64; k++) {
743                                         if (*p2 < MAX_GLYPH && ect++ < ct) {
744                                                 __put_user((u_short)((i<<11)+(j<<6)+k),
745                                                            &list->unicode);
746                                                 __put_user((u_short) *p2, 
747                                                            &list->fontpos);
748                                                 list++;
749                                         }
750                                         p2++;
751                                 }
752         }
753         __put_user(ect, uct);
754         console_unlock();
755         return ((ect <= ct) ? 0 : -ENOMEM);
756 }
757
758 /*
759  * Always use USER_MAP. These functions are used by the keyboard,
760  * which shouldn't be affected by G0/G1 switching, etc.
761  * If the user map still contains default values, i.e. the
762  * direct-to-font mapping, then assume user is using Latin1.
763  *
764  * FIXME: at some point we need to decide if we want to lock the table
765  * update element itself via the keyboard_event_lock for consistency with the
766  * keyboard driver as well as the consoles
767  */
768 /* may be called during an interrupt */
769 u32 conv_8bit_to_uni(unsigned char c)
770 {
771         unsigned short uni = translations[USER_MAP][c];
772         return uni == (0xf000 | c) ? c : uni;
773 }
774
775 int conv_uni_to_8bit(u32 uni)
776 {
777         int c;
778         for (c = 0; c < 0x100; c++)
779                 if (translations[USER_MAP][c] == uni ||
780                    (translations[USER_MAP][c] == (c | 0xf000) && uni == c))
781                         return c;
782         return -1;
783 }
784
785 int
786 conv_uni_to_pc(struct vc_data *conp, long ucs) 
787 {
788         int h;
789         u16 **p1, *p2;
790         struct uni_pagedir *p;
791   
792         /* Only 16-bit codes supported at this time */
793         if (ucs > 0xffff)
794                 return -4;              /* Not found */
795         else if (ucs < 0x20)
796                 return -1;              /* Not a printable character */
797         else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f))
798                 return -2;                      /* Zero-width space */
799         /*
800          * UNI_DIRECT_BASE indicates the start of the region in the User Zone
801          * which always has a 1:1 mapping to the currently loaded font.  The
802          * UNI_DIRECT_MASK indicates the bit span of the region.
803          */
804         else if ((ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE)
805                 return ucs & UNI_DIRECT_MASK;
806   
807         if (!*conp->vc_uni_pagedir_loc)
808                 return -3;
809
810         p = *conp->vc_uni_pagedir_loc;
811         if ((p1 = p->uni_pgdir[ucs >> 11]) &&
812             (p2 = p1[(ucs >> 6) & 0x1f]) &&
813             (h = p2[ucs & 0x3f]) < MAX_GLYPH)
814                 return h;
815
816         return -4;              /* not found */
817 }
818
819 /*
820  * This is called at sys_setup time, after memory and the console are
821  * initialized.  It must be possible to call kmalloc(..., GFP_KERNEL)
822  * from this function, hence the call from sys_setup.
823  */
824 void __init 
825 console_map_init(void)
826 {
827         int i;
828         
829         for (i = 0; i < MAX_NR_CONSOLES; i++)
830                 if (vc_cons_allocated(i) && !*vc_cons[i].d->vc_uni_pagedir_loc)
831                         con_set_default_unimap(vc_cons[i].d);
832 }
833