pinctrl: at91: enhance (debugfs) at91_gpio_dbg_show
[cascardo/linux.git] / 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->refcount > 1) {
544                 int j, k;
545                 u16 **p1, *p2, l;
546                 
547                 err1 = con_do_clear_unimap(vc, NULL);
548                 if (err1) {
549                         console_unlock();
550                         return err1;
551                 }
552                 
553                 /*
554                  * Since refcount was > 1, con_clear_unimap() allocated a
555                  * a new uni_pagedir for this vc.  Re: p != q
556                  */
557                 q = *vc->vc_uni_pagedir_loc;
558
559                 /*
560                  * uni_pgdir is a 32*32*64 table with rows allocated
561                  * when its first entry is added.  The unicode value must
562                  * still be incremented for empty rows.  We are copying
563                  * entries from "p" (old) to "q" (new).
564                  */
565                 l = 0;          /* unicode value */
566                 for (i = 0; i < 32; i++)
567                 if ((p1 = p->uni_pgdir[i]))
568                         for (j = 0; j < 32; j++)
569                         if ((p2 = p1[j])) {
570                                 for (k = 0; k < 64; k++, l++)
571                                 if (p2[k] != 0xffff) {
572                                         /*
573                                          * Found one, copy entry for unicode
574                                          * l with fontpos value p2[k].
575                                          */
576                                         err1 = con_insert_unipair(q, l, p2[k]);
577                                         if (err1) {
578                                                 p->refcount++;
579                                                 *vc->vc_uni_pagedir_loc = p;
580                                                 con_release_unimap(q);
581                                                 kfree(q);
582                                                 console_unlock();
583                                                 return err1; 
584                                         }
585                                 }
586                         } else {
587                                 /* Account for row of 64 empty entries */
588                                 l += 64;
589                         }
590                 else
591                         /* Account for empty table */
592                         l += 32 * 64;
593
594                 /*
595                  * Finished copying font table, set vc_uni_pagedir to new table
596                  */
597                 p = q;
598         } else if (p == dflt) {
599                 dflt = NULL;
600         }
601
602         /*
603          * Insert user specified unicode pairs into new table.
604          */
605         while (ct--) {
606                 unsigned short unicode, fontpos;
607                 __get_user(unicode, &list->unicode);
608                 __get_user(fontpos, &list->fontpos);
609                 if ((err1 = con_insert_unipair(p, unicode,fontpos)) != 0)
610                         err = err1;
611                 list++;
612         }
613         
614         /*
615          * Merge with fontmaps of any other virtual consoles.
616          */
617         if (con_unify_unimap(vc, p)) {
618                 console_unlock();
619                 return err;
620         }
621
622         for (i = 0; i <= 3; i++)
623                 set_inverse_transl(vc, p, i); /* Update inverse translations */
624         set_inverse_trans_unicode(vc, p);
625
626         console_unlock();
627         return err;
628 }
629
630 /**
631  *      con_set_default_unimap  -       set default unicode map
632  *      @vc: the console we are updating
633  *
634  *      Loads the unimap for the hardware font, as defined in uni_hash.tbl.
635  *      The representation used was the most compact I could come up
636  *      with.  This routine is executed at video setup, and when the
637  *      PIO_FONTRESET ioctl is called. 
638  *
639  *      The caller must hold the console lock
640  */
641 int con_set_default_unimap(struct vc_data *vc)
642 {
643         int i, j, err = 0, err1;
644         u16 *q;
645         struct uni_pagedir *p;
646
647         if (dflt) {
648                 p = *vc->vc_uni_pagedir_loc;
649                 if (p == dflt)
650                         return 0;
651
652                 dflt->refcount++;
653                 *vc->vc_uni_pagedir_loc = dflt;
654                 if (p && !--p->refcount) {
655                         con_release_unimap(p);
656                         kfree(p);
657                 }
658                 return 0;
659         }
660         
661         /* The default font is always 256 characters */
662
663         err = con_do_clear_unimap(vc, NULL);
664         if (err)
665                 return err;
666     
667         p = *vc->vc_uni_pagedir_loc;
668         q = dfont_unitable;
669         
670         for (i = 0; i < 256; i++)
671                 for (j = dfont_unicount[i]; j; j--) {
672                         err1 = con_insert_unipair(p, *(q++), i);
673                         if (err1)
674                                 err = err1;
675                 }
676                         
677         if (con_unify_unimap(vc, p)) {
678                 dflt = *vc->vc_uni_pagedir_loc;
679                 return err;
680         }
681
682         for (i = 0; i <= 3; i++)
683                 set_inverse_transl(vc, p, i);   /* Update all inverse translations */
684         set_inverse_trans_unicode(vc, p);
685         dflt = p;
686         return err;
687 }
688 EXPORT_SYMBOL(con_set_default_unimap);
689
690 /**
691  *      con_copy_unimap         -       copy unimap between two vts
692  *      @dst_vc: target
693  *      @src_vt: source
694  *
695  *      The caller must hold the console lock when invoking this method
696  */
697 int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc)
698 {
699         struct uni_pagedir *q;
700
701         if (!*src_vc->vc_uni_pagedir_loc)
702                 return -EINVAL;
703         if (*dst_vc->vc_uni_pagedir_loc == *src_vc->vc_uni_pagedir_loc)
704                 return 0;
705         con_free_unimap(dst_vc);
706         q = *src_vc->vc_uni_pagedir_loc;
707         q->refcount++;
708         *dst_vc->vc_uni_pagedir_loc = q;
709         return 0;
710 }
711 EXPORT_SYMBOL(con_copy_unimap);
712
713 /**
714  *      con_get_unimap          -       get the unicode map
715  *      @vc: the console to read from
716  *
717  *      Read the console unicode data for this console. Called from the ioctl
718  *      handlers.
719  */
720 int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct unipair __user *list)
721 {
722         int i, j, k, ect;
723         u16 **p1, *p2;
724         struct uni_pagedir *p;
725
726         console_lock();
727
728         ect = 0;
729         if (*vc->vc_uni_pagedir_loc) {
730                 p = *vc->vc_uni_pagedir_loc;
731                 for (i = 0; i < 32; i++)
732                 if ((p1 = p->uni_pgdir[i]))
733                         for (j = 0; j < 32; j++)
734                         if ((p2 = *(p1++)))
735                                 for (k = 0; k < 64; k++) {
736                                         if (*p2 < MAX_GLYPH && ect++ < ct) {
737                                                 __put_user((u_short)((i<<11)+(j<<6)+k),
738                                                            &list->unicode);
739                                                 __put_user((u_short) *p2, 
740                                                            &list->fontpos);
741                                                 list++;
742                                         }
743                                         p2++;
744                                 }
745         }
746         __put_user(ect, uct);
747         console_unlock();
748         return ((ect <= ct) ? 0 : -ENOMEM);
749 }
750
751 /*
752  * Always use USER_MAP. These functions are used by the keyboard,
753  * which shouldn't be affected by G0/G1 switching, etc.
754  * If the user map still contains default values, i.e. the
755  * direct-to-font mapping, then assume user is using Latin1.
756  *
757  * FIXME: at some point we need to decide if we want to lock the table
758  * update element itself via the keyboard_event_lock for consistency with the
759  * keyboard driver as well as the consoles
760  */
761 /* may be called during an interrupt */
762 u32 conv_8bit_to_uni(unsigned char c)
763 {
764         unsigned short uni = translations[USER_MAP][c];
765         return uni == (0xf000 | c) ? c : uni;
766 }
767
768 int conv_uni_to_8bit(u32 uni)
769 {
770         int c;
771         for (c = 0; c < 0x100; c++)
772                 if (translations[USER_MAP][c] == uni ||
773                    (translations[USER_MAP][c] == (c | 0xf000) && uni == c))
774                         return c;
775         return -1;
776 }
777
778 int
779 conv_uni_to_pc(struct vc_data *conp, long ucs) 
780 {
781         int h;
782         u16 **p1, *p2;
783         struct uni_pagedir *p;
784   
785         /* Only 16-bit codes supported at this time */
786         if (ucs > 0xffff)
787                 return -4;              /* Not found */
788         else if (ucs < 0x20)
789                 return -1;              /* Not a printable character */
790         else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f))
791                 return -2;                      /* Zero-width space */
792         /*
793          * UNI_DIRECT_BASE indicates the start of the region in the User Zone
794          * which always has a 1:1 mapping to the currently loaded font.  The
795          * UNI_DIRECT_MASK indicates the bit span of the region.
796          */
797         else if ((ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE)
798                 return ucs & UNI_DIRECT_MASK;
799   
800         if (!*conp->vc_uni_pagedir_loc)
801                 return -3;
802
803         p = *conp->vc_uni_pagedir_loc;
804         if ((p1 = p->uni_pgdir[ucs >> 11]) &&
805             (p2 = p1[(ucs >> 6) & 0x1f]) &&
806             (h = p2[ucs & 0x3f]) < MAX_GLYPH)
807                 return h;
808
809         return -4;              /* not found */
810 }
811
812 /*
813  * This is called at sys_setup time, after memory and the console are
814  * initialized.  It must be possible to call kmalloc(..., GFP_KERNEL)
815  * from this function, hence the call from sys_setup.
816  */
817 void __init 
818 console_map_init(void)
819 {
820         int i;
821         
822         for (i = 0; i < MAX_NR_CONSOLES; i++)
823                 if (vc_cons_allocated(i) && !*vc_cons[i].d->vc_uni_pagedir_loc)
824                         con_set_default_unimap(vc_cons[i].d);
825 }
826