blob: 43e356a4a23873d1e8a7a88db9c6f069f4f1f970 [file] [log] [blame]
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -07001/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
Seth Goldberg1841b872009-03-12 20:08:47 -07005 * Common Development and Distribution License (the "License").
Seth Goldberg3791cf72009-03-12 22:21:27 -07006 * You may not use this file except in compliance with the License.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -07007 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
Seth Goldberg1841b872009-03-12 20:08:47 -070022 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070023 * Use is subject to license terms.
24 */
25
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070026#include <sys/types.h>
27#include <sys/stream.h>
28#include <sys/kbd.h>
29#include <sys/kbtrans.h>
30#include <sys/sunddi.h>
31#include <sys/consdev.h>
32#include <sys/promif.h>
33#include "kb8042.h"
34
35/*
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070036 * A note on the use of prom_printf here: Most of these routines can be
37 * called from "polled mode", where we're servicing I/O requests from kmdb.
38 * Normal system services are not available from polled mode; cmn_err will
39 * not work. prom_printf is the only safe output mechanism.
40 */
41
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070042#define KEYBAD 0xff /* should generate an error */
43#define KEYIGN 0xfe /* ignore this sequence */
44
45#define KEY(code) (code)
46#define INVALID KEYBAD
47#define IGNORE KEYIGN
48
sethgfd9cb952005-11-01 22:55:18 -080049#define NELEM(a) (sizeof (a) / sizeof (a)[0])
50
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070051/*
52 * These are the states of our parsing machine:
53 */
sethgfd9cb952005-11-01 22:55:18 -080054#define STATE_IDLE 0x00000001 /* Awaiting the start of a sequence */
55#define STATE_E0 0x00000002 /* Rec'd an E0 */
56#define STATE_E1 0x00000004 /* Rec'd an E1 (Pause key only) */
57#define STATE_E1_1D 0x00000008 /* Rec'd an E1 1D (Pause key only) */
58#define STATE_E1_14 0x00000010 /* Rec'd an E1 14 (Pause key only) */
59#define STATE_E1_14_77 0x00000020
60#define STATE_E1_14_77_E1 0x00000040
61#define STATE_E1_14_77_E1_F0 0x00000080
62#define STATE_E1_14_77_E1_F0_14 0x00000100
63#define STATE_E1_14_77_E1_F0_14_F0 0x00000200
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070064
sethgfd9cb952005-11-01 22:55:18 -080065static boolean_t KeyboardConvertScan_set1(struct kb8042 *, unsigned char, int *,
66 enum keystate *, boolean_t *);
67static boolean_t KeyboardConvertScan_set2(struct kb8042 *, unsigned char, int *,
68 enum keystate *, boolean_t *);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070069
sethgfd9cb952005-11-01 22:55:18 -080070static const unsigned char *keytab_base = NULL;
71static int keytab_base_length = 0;
72static const unsigned char *keytab_e0 = NULL;
73static int keytab_e0_length = 0;
74static boolean_t (*KeyboardConvertScan_fn)(struct kb8042 *, unsigned char,
75 int *, enum keystate *, boolean_t *) = NULL;
76
77static const unsigned char keytab_base_set1[] = {
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -070078/* scan key number keycap */
79/* 00 */ INVALID,
80/* 01 */ KEY(110), /* Esc */
81/* 02 */ KEY(2), /* 1 */
82/* 03 */ KEY(3), /* 2 */
83/* 04 */ KEY(4), /* 3 */
84/* 05 */ KEY(5), /* 4 */
85/* 06 */ KEY(6), /* 5 */
86/* 07 */ KEY(7), /* 6 */
87/* 08 */ KEY(8), /* 7 */
88/* 09 */ KEY(9), /* 8 */
89/* 0a */ KEY(10), /* 9 */
90/* 0b */ KEY(11), /* 0 */
91/* 0c */ KEY(12), /* - */
92/* 0d */ KEY(13), /* = */
93/* 0e */ KEY(15), /* backspace */
94/* 0f */ KEY(16), /* tab */
95
96/* 10 */ KEY(17), /* Q */
97/* 11 */ KEY(18), /* W */
98/* 12 */ KEY(19), /* E */
99/* 13 */ KEY(20), /* R */
100/* 14 */ KEY(21), /* T */
101/* 15 */ KEY(22), /* Y */
102/* 16 */ KEY(23), /* U */
103/* 17 */ KEY(24), /* I */
104/* 18 */ KEY(25), /* O */
105/* 19 */ KEY(26), /* P */
106/* 1a */ KEY(27), /* [ */
107/* 1b */ KEY(28), /* ] */
108/* 1c */ KEY(43), /* Enter (main) */
109/* 1d */ KEY(58), /* L Ctrl */
110/* 1e */ KEY(31), /* A */
111/* 1f */ KEY(32), /* S */
112
113/* 20 */ KEY(33), /* D */
114/* 21 */ KEY(34), /* F */
115/* 22 */ KEY(35), /* G */
116/* 23 */ KEY(36), /* H */
117/* 24 */ KEY(37), /* J */
118/* 25 */ KEY(38), /* K */
119/* 26 */ KEY(39), /* L */
120/* 27 */ KEY(40), /* ; */
121/* 28 */ KEY(41), /* ' */
122/* 29 */ KEY(1), /* ` */
123/* 2a */ KEY(44), /* L Shift */
124/* 2b */ KEY(29), /* \ */
125/* 2c */ KEY(46), /* Z */
126/* 2d */ KEY(47), /* X */
127/* 2e */ KEY(48), /* C */
128/* 2f */ KEY(49), /* V */
129
130/* 30 */ KEY(50), /* B */
131/* 31 */ KEY(51), /* N */
132/* 32 */ KEY(52), /* M */
133/* 33 */ KEY(53), /* , */
134/* 34 */ KEY(54), /* . */
135/* 35 */ KEY(55), /* / */
136/* 36 */ KEY(57), /* R Shift */
137/* 37 */ KEY(100), /* * (num) */
138/* 38 */ KEY(60), /* L Alt */
139/* 39 */ KEY(61), /* Space */
140/* 3a */ KEY(30), /* CapsLock */
141/* 3b */ KEY(112), /* F1 */
142/* 3c */ KEY(113), /* F2 */
143/* 3d */ KEY(114), /* F3 */
144/* 3e */ KEY(115), /* F4 */
145/* 3f */ KEY(116), /* F5 */
146
147/* 40 */ KEY(117), /* F6 */
148/* 41 */ KEY(118), /* F7 */
149/* 42 */ KEY(119), /* F8 */
150/* 43 */ KEY(120), /* F9 */
151/* 44 */ KEY(121), /* F10 */
152/* 45 */ KEY(90), /* NumLock */
153/* 46 */ KEY(125), /* Scroll Lock */
154/* 47 */ KEY(91), /* 7 (num) */
155/* 48 */ KEY(96), /* 8 (num) */
156/* 49 */ KEY(101), /* 9 (num) */
157/* 4a */ KEY(105), /* - (num) */
158/* 4b */ KEY(92), /* 4 (num) */
159/* 4c */ KEY(97), /* 5 (num) */
160/* 4d */ KEY(102), /* 6 (num) */
161/* 4e */ KEY(106), /* + (num) */
162/* 4f */ KEY(93), /* 1 (num) */
163
164/* 50 */ KEY(98), /* 2 (num) */
165/* 51 */ KEY(103), /* 3 (num) */
166/* 52 */ KEY(99), /* 0 (num) */
167/* 53 */ KEY(104), /* . (num) */
168/* 54 */ KEY(124), /* PrintScreen (with Alt) */
169/* 55 */ INVALID,
170/* 56 */ KEY(45), /* not labled (102-key only) */
171/* 57 */ KEY(122), /* F11 */
172/* 58 */ KEY(123), /* F12 */
173/* 59 */ INVALID,
174/* 5a */ INVALID,
175/* 5b */ INVALID,
176/* 5c */ INVALID,
177/* 5d */ INVALID,
178/* 5e */ INVALID,
179/* 5f */ INVALID,
180
181/* 60 */ INVALID,
182/* 61 */ INVALID,
183/* 62 */ INVALID,
184/* 63 */ INVALID,
185/* 64 */ INVALID,
186/* 65 */ INVALID,
187/* 66 */ INVALID,
188/* 67 */ INVALID,
189/* 68 */ INVALID,
190/* 69 */ INVALID,
191/* 6a */ INVALID,
192/* 6b */ INVALID,
193/* 6c */ INVALID,
194/* 6d */ INVALID,
195/* 6e */ INVALID,
196/* 6f */ INVALID,
197
198/* 70 */ KEY(133), /* Japanese 106-key keyboard */
199/* 71 */ INVALID,
200/* 72 */ INVALID,
201/* 73 */ KEY(56), /* Japanese 106-key keyboard */
202/* 74 */ INVALID,
203/* 75 */ INVALID,
204/* 76 */ INVALID,
205/* 77 */ INVALID,
206/* 78 */ INVALID,
207/* 79 */ KEY(132), /* Japanese 106-key keyboard */
208/* 7a */ INVALID,
209/* 7b */ KEY(131), /* Japanese 106-key keyboard */
210/* 7c */ INVALID,
211/* 7d */ KEY(14), /* Japanese 106-key keyboard */
212/* 7e */ INVALID,
213/* 7f */ INVALID,
214};
215
216/*
217 * Parse table after receiving an E0 prefix code.
218 *
219 * Generally speaking, keys that were added on the 101-key keyboard are
220 * represented as an E0 followed by the code for an 84-key key. Software
221 * ignorant of the 101-key keyboard ignores the E0 and so is handled
222 * compatibly. Many of these variants involve "fake" shift presses
223 * and releases for compatibility; these are also prefixed with E0.
224 * We ignore these fake shifts.
225 */
sethgfd9cb952005-11-01 22:55:18 -0800226static const unsigned char keytab_e0_set1[] = {
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700227/* 00 */ INVALID,
228/* 01 */ INVALID,
229/* 02 */ INVALID,
230/* 03 */ INVALID,
231/* 04 */ INVALID,
232/* 05 */ INVALID,
233/* 06 */ INVALID,
234/* 07 */ INVALID,
235/* 08 */ INVALID,
236/* 09 */ INVALID,
237/* 0a */ INVALID,
238/* 0b */ INVALID,
239/* 0c */ INVALID,
240/* 0d */ INVALID,
241/* 0e */ INVALID,
242/* 0f */ INVALID,
243
244/* 10 */ INVALID,
245/* 11 */ INVALID,
246/* 12 */ INVALID,
247/* 13 */ INVALID,
248/* 14 */ INVALID,
249/* 15 */ INVALID,
250/* 16 */ INVALID,
251/* 17 */ INVALID,
252/* 18 */ INVALID,
253/* 19 */ INVALID,
254/* 1a */ INVALID,
255/* 1b */ INVALID,
256/* 1c */ KEY(108), /* Enter (num) */
257/* 1d */ KEY(64), /* R Ctrl */
258/* 1e */ INVALID,
259/* 1f */ INVALID,
260
Seth Goldberg1841b872009-03-12 20:08:47 -0700261/* 20 */ KEY(235), /* Mute */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700262/* 21 */ INVALID,
263/* 22 */ INVALID,
264/* 23 */ INVALID,
265/* 24 */ INVALID,
266/* 25 */ INVALID,
267/* 26 */ INVALID,
268/* 27 */ INVALID,
269/* 28 */ INVALID,
270/* 29 */ INVALID,
271/* 2a */ INVALID,
272/* 2b */ INVALID,
273/* 2c */ INVALID,
274/* 2d */ INVALID,
Seth Goldberg1841b872009-03-12 20:08:47 -0700275/* 2e */ KEY(234), /* Volume Down */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700276/* 2f */ INVALID,
277
Seth Goldberg1841b872009-03-12 20:08:47 -0700278/* 30 */ KEY(233), /* Volume Up */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700279/* 31 */ INVALID,
280/* 32 */ INVALID,
281/* 33 */ INVALID,
282/* 34 */ INVALID,
283/* 35 */ KEY(95), /* / (num) */
284/* 36 */ INVALID,
285/* 37 */ KEY(124), /* PrintScreen (no Alt) */
286/* 38 */ KEY(62), /* R Alt */
287/* 39 */ INVALID,
288/* 3a */ INVALID,
289/* 3b */ INVALID,
290/* 3c */ INVALID,
291/* 3d */ INVALID,
292/* 3e */ INVALID,
293/* 3f */ INVALID,
294
295/* 40 */ INVALID,
296/* 41 */ INVALID,
297/* 42 */ INVALID,
298/* 43 */ INVALID,
299/* 44 */ INVALID,
300/* 45 */ INVALID,
301/* 46 */ KEY(126), /* Pause (with Cntl) */
302/* 47 */ KEY(80), /* Home (arrow) */
303/* 48 */ KEY(83), /* Up (arrow) */
304/* 49 */ KEY(85), /* PgUp (arrow) */
305/* 4a */ INVALID,
306/* 4b */ KEY(79), /* Left (arrow) */
307/* 4c */ INVALID,
308/* 4d */ KEY(89), /* Right (arrow) */
309/* 4e */ INVALID,
310/* 4f */ KEY(81), /* End (arrow) */
311
312/* 50 */ KEY(84), /* Down (arrow) */
313/* 51 */ KEY(86), /* PgDn (arrow) */
314/* 52 */ KEY(75), /* Insert (arrow) */
315/* 53 */ KEY(76), /* Delete (arrow) */
316/* 54 */ INVALID,
317/* 55 */ INVALID,
318/* 56 */ INVALID,
319/* 57 */ INVALID,
320/* 58 */ INVALID,
321/* 59 */ INVALID,
322/* 5a */ INVALID,
323/* 5b */ KEY(59), /* L Window (104-key) */
324/* 5c */ KEY(63), /* R Window (104-key) */
325/* 5d */ KEY(65), /* Menu (104-key) */
326/* 5e */ INVALID,
327/* 5f */ INVALID,
328
329/* 60 */ INVALID,
330/* 61 */ INVALID,
331/* 62 */ INVALID,
332/* 63 */ INVALID,
333/* 64 */ INVALID,
334/* 65 */ INVALID,
335/* 66 */ INVALID,
336/* 67 */ INVALID,
337/* 68 */ INVALID,
338/* 69 */ INVALID,
339/* 6a */ INVALID,
340/* 6b */ INVALID,
341/* 6c */ INVALID,
342/* 6d */ INVALID,
343/* 6e */ INVALID,
344/* 6f */ INVALID,
345
346/* 70 */ INVALID,
347/* 71 */ INVALID,
348/* 72 */ INVALID,
349/* 73 */ INVALID,
350/* 74 */ INVALID,
351/* 75 */ INVALID,
352/* 76 */ INVALID,
353/* 77 */ INVALID,
354/* 78 */ INVALID,
355/* 79 */ INVALID,
356/* 7a */ INVALID,
357/* 7b */ INVALID,
358/* 7c */ INVALID,
359/* 7d */ INVALID,
360/* 7e */ INVALID,
361};
362
363
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700364/*
365 * Parse table for the base keyboard state. The index is the start of
366 * a new sequence.
367 *
368 * Questionable or unusual cases:
sethgfd9cb952005-11-01 22:55:18 -0800369 * 02 On some SPARC keyboards, this is the scan code for the STOP
370 * key. The KEY() value was chosen so that it maps to a
371 * HOLE entry in the keytables in kb8042_keytables.c; therefore,
372 * the STOP key code is only translated properly when kb8042
373 * is "emulating" a USB keyboard (which it is by default--
374 * see conskbd.c).
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700375 * 7f Old kd code says this is an 84-key SysReq. Manual says no.
376 * 87 Old kd code says 1 (num). Manual says no.
377 * 8c Old kd code says / (num). Manual says no.
378 * aa POST OK. Handled by code.
379 * e0 Extend prefix. Handled by code. (switches to E0 table)
380 * e1 Extend prefix. Handled by code. (Pause key only)
381 * f0 Break prefix. Handled by code.
382 * f1 Korean Hangul/Hanja key. Handled by code.
383 * f2 Korean Hangul key. Handled by code.
384 * ff Keyboard internal buffer overrun. Handled by code.
385 *
386 * Other values past the end of the table are treated as INVALID.
387 */
388
sethgfd9cb952005-11-01 22:55:18 -0800389static const unsigned char keytab_base_set2[] = {
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700390/* scan state keycap */
391/* 00 */ INVALID,
392/* 01 */ KEY(120), /* F9 */
sethgfd9cb952005-11-01 22:55:18 -0800393#if defined(__sparc)
394/* 02 */ KEY(K8042_STOP), /* STOP */
395#else
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700396/* 02 */ INVALID, /* F7? Old code says so but manual doesn't */
sethgfd9cb952005-11-01 22:55:18 -0800397#endif
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700398/* 03 */ KEY(116), /* F5 */
399/* 04 */ KEY(114), /* F3 */
400/* 05 */ KEY(112), /* F1 */
401/* 06 */ KEY(113), /* F2 */
402/* 07 */ KEY(123), /* F12 */
403/* 08 */ INVALID,
404/* 09 */ KEY(121), /* F10 */
405/* 0a */ KEY(119), /* F8 */
406/* 0b */ KEY(117), /* F6 */
407/* 0c */ KEY(115), /* F4 */
408/* 0d */ KEY(16), /* tab */
409/* 0e */ KEY(1), /* ` */
410/* 0f */ INVALID,
411/* 10 */ INVALID,
412/* 11 */ KEY(60), /* L Alt */
413/* 12 */ KEY(44), /* L Shift */
414/* 13 */ KEY(133), /* Japanese 106-key */
415/* 14 */ KEY(58), /* L Ctrl */
416/* 15 */ KEY(17), /* Q */
417/* 16 */ KEY(2), /* 1 */
418/* 17 */ INVALID,
419/* 18 */ INVALID,
420/* 19 */ INVALID,
421/* 1a */ KEY(46), /* Z */
422/* 1b */ KEY(32), /* S */
423/* 1c */ KEY(31), /* A */
424/* 1d */ KEY(18), /* W */
425/* 1e */ KEY(3), /* 2 */
426/* 1f */ INVALID,
427/* 20 */ INVALID,
428/* 21 */ KEY(48), /* C */
429/* 22 */ KEY(47), /* X */
430/* 23 */ KEY(33), /* D */
431/* 24 */ KEY(19), /* E */
432/* 25 */ KEY(5), /* 4 */
433/* 26 */ KEY(4), /* 3 */
434/* 27 */ INVALID,
435/* 28 */ INVALID,
436/* 29 */ KEY(61), /* Space */
437/* 2a */ KEY(49), /* V */
438/* 2b */ KEY(34), /* F */
439/* 2c */ KEY(21), /* T */
440/* 2d */ KEY(20), /* R */
441/* 2e */ KEY(6), /* 5 */
442/* 2f */ INVALID,
443/* 30 */ INVALID,
444/* 31 */ KEY(51), /* N */
445/* 32 */ KEY(50), /* B */
446/* 33 */ KEY(36), /* H */
447/* 34 */ KEY(35), /* G */
448/* 35 */ KEY(22), /* Y */
449/* 36 */ KEY(7), /* 6 */
450/* 37 */ INVALID,
451/* 38 */ INVALID,
452/* 39 */ INVALID,
453/* 3a */ KEY(52), /* M */
454/* 3b */ KEY(37), /* J */
455/* 3c */ KEY(23), /* U */
456/* 3d */ KEY(8), /* 7 */
457/* 3e */ KEY(9), /* 8 */
458/* 3f */ INVALID,
459/* 40 */ INVALID,
460/* 41 */ KEY(53), /* , */
461/* 42 */ KEY(38), /* K */
462/* 43 */ KEY(24), /* I */
463/* 44 */ KEY(25), /* O */
464/* 45 */ KEY(11), /* 0 */
465/* 46 */ KEY(10), /* 9 */
466/* 47 */ INVALID,
467/* 48 */ INVALID,
468/* 49 */ KEY(54), /* . */
469/* 4a */ KEY(55), /* / */
470/* 4b */ KEY(39), /* L */
471/* 4c */ KEY(40), /* ; */
472/* 4d */ KEY(26), /* P */
473/* 4e */ KEY(12), /* - */
474/* 4f */ INVALID,
475/* 50 */ INVALID,
476/* 51 */ KEY(56), /* Japanese 106-key */
477/* 52 */ KEY(41), /* ' */
478/* 53 */ INVALID,
479/* 54 */ KEY(27), /* [ */
480/* 55 */ KEY(13), /* = */
481/* 56 */ INVALID,
482/* 57 */ INVALID,
483/* 58 */ KEY(30), /* CapsLock */
484/* 59 */ KEY(57), /* R Shift */
485/* 5a */ KEY(43), /* Enter (main) */
486/* 5b */ KEY(28), /* ] */
487/* 5c */ INVALID,
488/* 5d */ KEY(29), /* \, key 42 for 102-key */
489/* 5e */ INVALID,
490/* 5f */ INVALID,
491/* 60 */ INVALID,
492/* 61 */ KEY(45), /* 102-key only, typically </> */
493/* 62 */ INVALID,
494/* 63 */ INVALID,
495/* 64 */ KEY(132), /* Japanese 106-key */
496/* 65 */ INVALID,
497/* 66 */ KEY(15), /* backspace */
498/* 67 */ KEY(131), /* Japanese 106-key */
499/* 68 */ INVALID,
500/* 69 */ KEY(93), /* 1 (num) */
501/* 6a */ KEY(14), /* Japanese 106-key */
502/* 6b */ KEY(92), /* 4 (num) */
503/* 6c */ KEY(91), /* 7 (num) */
504/* 6d */ INVALID,
505/* 6e */ INVALID,
506/* 6f */ INVALID,
507/* 70 */ KEY(99), /* 0 (num) */
508/* 71 */ KEY(104), /* . (num) */
509/* 72 */ KEY(98), /* 2 (num) */
510/* 73 */ KEY(97), /* 5 (num) */
511/* 74 */ KEY(102), /* 6 (num) */
512/* 75 */ KEY(96), /* 8 (num) */
513/* 76 */ KEY(110), /* Esc */
514/* 77 */ KEY(90), /* NumLock */
515/* 78 */ KEY(122), /* F11 */
516/* 79 */ KEY(106), /* + (num) */
517/* 7a */ KEY(103), /* 3 (num) */
518/* 7b */ KEY(105), /* - (num) */
519/* 7c */ KEY(100), /* * (num) */
520/* 7d */ KEY(101), /* 9 (num) */
521/* 7e */ KEY(125), /* Scroll Lock */
522/* 7f */ INVALID, /* 84-key SysReq? Manual says no. */
523/* 80 */ INVALID,
524/* 81 */ INVALID,
525/* 82 */ INVALID,
526/* 83 */ KEY(118), /* F7 */
527/* 84 */ KEY(124), /* PrintScreen (w/ Alt = SysRq) */
528};
529
530/*
531 * Parse table after receiving an E0 prefix code.
532 *
533 * Generally speaking, keys that were added on the 101-key keyboard are
534 * represented as an E0 followed by the code for an 84-key key. Software
535 * ignorant of the 101-key keyboard ignores the E0 and so is handled
536 * compatibly. Many of these variants involve "fake" shift presses
537 * and releases for compatibility; these are also prefixed with E0.
538 * We ignore these fake shifts.
539 */
sethgfd9cb952005-11-01 22:55:18 -0800540static const unsigned char keytab_e0_set2[] = {
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700541/* 00 */ INVALID,
542/* 01 */ INVALID,
543/* 02 */ INVALID,
544/* 03 */ INVALID,
545/* 04 */ INVALID,
546/* 05 */ INVALID,
547/* 06 */ INVALID,
548/* 07 */ INVALID,
549/* 08 */ INVALID,
550/* 09 */ INVALID,
551/* 0a */ INVALID,
552/* 0b */ INVALID,
553/* 0c */ INVALID,
554/* 0d */ INVALID,
555/* 0e */ INVALID,
556/* 0f */ INVALID,
557/* 10 */ INVALID,
558/* 11 */ KEY(62), /* R Alt */
559/* 12 */ IGNORE, /* Fake L Shift */
560/* 13 */ INVALID,
561/* 14 */ KEY(64), /* R Ctrl */
562/* 15 */ INVALID,
563/* 16 */ INVALID,
564/* 17 */ INVALID,
565/* 18 */ INVALID,
566/* 19 */ INVALID,
567/* 1a */ INVALID,
568/* 1b */ INVALID,
569/* 1c */ INVALID,
570/* 1d */ INVALID,
571/* 1e */ INVALID,
572/* 1f */ KEY(59), /* L Window (104-key) */
573/* 20 */ INVALID,
574/* 21 */ INVALID,
575/* 22 */ INVALID,
576/* 23 */ INVALID,
577/* 24 */ INVALID,
578/* 25 */ INVALID,
579/* 26 */ INVALID,
580/* 27 */ KEY(63), /* R Window (104-key) */
581/* 28 */ INVALID,
582/* 29 */ INVALID,
583/* 2a */ INVALID,
584/* 2b */ INVALID,
585/* 2c */ INVALID,
586/* 2d */ INVALID,
587/* 2e */ INVALID,
588/* 2f */ KEY(65), /* Menu (104-key) */
589/* 30 */ INVALID,
590/* 31 */ INVALID,
591/* 32 */ INVALID,
592/* 33 */ INVALID,
593/* 34 */ INVALID,
594/* 35 */ INVALID,
595/* 36 */ INVALID,
596/* 37 */ INVALID,
597/* 38 */ INVALID,
598/* 39 */ INVALID,
599/* 3a */ INVALID,
600/* 3b */ INVALID,
601/* 3c */ INVALID,
602/* 3d */ INVALID,
603/* 3e */ INVALID,
604/* 3f */ INVALID,
605/* 40 */ INVALID,
606/* 41 */ INVALID,
607/* 42 */ INVALID,
608/* 43 */ INVALID,
609/* 44 */ INVALID,
610/* 45 */ INVALID,
611/* 46 */ INVALID,
612/* 47 */ INVALID,
613/* 48 */ INVALID,
614/* 49 */ INVALID,
615/* 4a */ KEY(95), /* / (num) */
616/* 4b */ INVALID,
617/* 4c */ INVALID,
618/* 4d */ INVALID,
619/* 4e */ INVALID,
620/* 4f */ INVALID,
621/* 50 */ INVALID,
622/* 51 */ INVALID,
623/* 52 */ INVALID,
624/* 53 */ INVALID,
625/* 54 */ INVALID,
626/* 55 */ INVALID,
627/* 56 */ INVALID,
628/* 57 */ INVALID,
629/* 58 */ INVALID,
630/* 59 */ IGNORE, /* Fake R Shift */
631/* 5a */ KEY(108), /* Enter (num) */
632/* 5b */ INVALID,
633/* 5c */ INVALID,
634/* 5d */ INVALID,
635/* 5e */ INVALID,
636/* 5f */ INVALID,
637/* 60 */ INVALID,
638/* 61 */ INVALID,
639/* 62 */ INVALID,
640/* 63 */ INVALID,
641/* 64 */ INVALID,
642/* 65 */ INVALID,
643/* 66 */ INVALID,
644/* 67 */ INVALID,
645/* 68 */ INVALID,
646/* 69 */ KEY(81), /* End (arrow) */
647/* 6a */ INVALID,
648/* 6b */ KEY(79), /* Left (arrow) */
649/* 6c */ KEY(80), /* Home (arrow) */
650/* 6d */ INVALID,
651/* 6e */ INVALID,
652/* 6f */ INVALID,
653/* 70 */ KEY(75), /* Insert (arrow) */
654/* 71 */ KEY(76), /* Delete (arrow) */
655/* 72 */ KEY(84), /* Down (arrow) */
656/* 73 */ INVALID,
657/* 74 */ KEY(89), /* Right (arrow) */
658/* 75 */ KEY(83), /* Up (arrow) */
659/* 76 */ INVALID,
660/* 77 */ INVALID,
661/* 78 */ INVALID,
662/* 79 */ INVALID,
663/* 7a */ KEY(86), /* PgDn (arrow) */
664/* 7b */ INVALID,
665/* 7c */ KEY(124), /* PrintScreen (no Alt) */
666/* 7d */ KEY(85), /* PgUp (arrow) */
667/* 7e */ KEY(126), /* Pause (w/Ctrl = Break) */
668};
669
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700670
671/*
672 * Initialize the translation state machine.
673 */
sethgfd9cb952005-11-01 22:55:18 -0800674int
675KeyboardConvertScan_init(struct kb8042 *kb8042, int scanset)
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700676{
677 kb8042->parse_scan_state = STATE_IDLE;
sethgfd9cb952005-11-01 22:55:18 -0800678 kb8042->break_received = 0;
679
680 if (scanset == 1) {
681 KeyboardConvertScan_fn = &KeyboardConvertScan_set1;
682 keytab_base = keytab_base_set1;
683 keytab_base_length = NELEM(keytab_base_set1);
684 keytab_e0 = keytab_e0_set1;
685 keytab_e0_length = NELEM(keytab_e0_set1);
686 } else if (scanset == 2) {
687 KeyboardConvertScan_fn = &KeyboardConvertScan_set2;
688 keytab_base = keytab_base_set2;
689 keytab_base_length = NELEM(keytab_base_set2);
690 keytab_e0 = keytab_e0_set2;
691 keytab_e0_length = NELEM(keytab_e0_set2);
692 } else {
693 return (DDI_FAILURE);
694 }
695
696 return (DDI_SUCCESS);
697}
698
Seth Goldberg1841b872009-03-12 20:08:47 -0700699/*
700 * KeyboardConvertScan(*kb8042, scan, *keynum, *state
701 * *synthetic_release_needed)
702 *
703 * State machine that takes scan codes from the keyboard and resolves
704 * them to key numbers using the above tables. Returns B_TRUE if this
705 * scan code completes a scan code sequence, in which case "keynum",
706 * "state", and "synthetic_release_needed" will be filled in correctly.
707 *
708 * "synthetic_release_needed" is a hack to handle the additional two
709 * keys on a Korean keyboard. They report press only, so we tell the
710 * upper layer to synthesize the release.
711 */
sethgfd9cb952005-11-01 22:55:18 -0800712boolean_t
713KeyboardConvertScan(
714 struct kb8042 *kb8042,
715 unsigned char scan,
716 int *keynum,
717 enum keystate *state,
718 boolean_t *synthetic_release_needed)
719{
720 ASSERT(KeyboardConvertScan_fn != NULL);
721
722 return ((*KeyboardConvertScan_fn)(kb8042, scan, keynum, state,
723 synthetic_release_needed));
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700724}
725
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700726boolean_t
sethgfd9cb952005-11-01 22:55:18 -0800727KeyboardConvertScan_set1(
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700728 struct kb8042 *kb8042,
729 unsigned char scan,
730 int *keynum,
731 enum keystate *state,
732 boolean_t *synthetic_release_needed)
733{
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700734 *synthetic_release_needed = B_FALSE;
735 *state = KEY_PRESSED;
736
737 switch (scan) {
738 /*
739 * First, handle special cases.
740 * ACK has already been handled by our caller.
741 */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700742 case KB_ERROR:
743 /*
744 * Perhaps we should reset state here,
745 * since we no longer know what's going on.
746 */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700747 return (B_FALSE);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700748 case KB_POST_FAIL:
749 /*
750 * Perhaps we should reset the LEDs now.
751 * If so, this check should probably be in the main line.
752 * Perhaps we should tell the higher layers that the
753 * keyboard has been reset.
754 */
755 /*
756 * Reset to idle
757 */
758 kb8042->parse_scan_state = STATE_IDLE;
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700759 return (B_FALSE);
760
761 case KXT_EXTEND:
762 case KXT_EXTEND2:
763 case KXT_HANGUL_HANJA:
764 case KXT_HANGUL:
765 /*
766 * Exclude these keys from the "default" test below.
767 */
768 break;
769
770 default:
771 /*
772 * See if it was a key release.
773 */
774 if (scan > 0x80) {
775 *state = KEY_RELEASED;
776 scan -= 0x80;
777 }
778 break;
779 }
780
sethgfd9cb952005-11-01 22:55:18 -0800781 if (kb8042->break_received) {
782 *state = KEY_RELEASED;
783 kb8042->break_received = 0;
784 }
785
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700786 switch (kb8042->parse_scan_state) {
787 case STATE_IDLE:
788 switch (scan) {
789 case KXT_EXTEND:
790 kb8042->parse_scan_state = STATE_E0;
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700791 return (B_FALSE);
792
793 case KXT_EXTEND2:
794 kb8042->parse_scan_state = STATE_E1;
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700795 return (B_FALSE);
796
797 /*
798 * We could do the next two in the table, but it would
799 * require nearly doubling the size of the table.
800 *
801 * Also, for some stupid reason these two report presses
802 * only. We tell the upper layer to synthesize a release.
803 */
804 case KXT_HANGUL_HANJA:
805 *keynum = KEY(150);
806 *synthetic_release_needed = B_TRUE;
807 break;
808
809 case KXT_HANGUL:
810 *keynum = KEY(151);
811 *synthetic_release_needed = B_TRUE;
812 break;
813
814 default:
815 /*
816 * Regular scan code
817 */
sethgfd9cb952005-11-01 22:55:18 -0800818 if (scan < keytab_base_length)
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700819 *keynum = keytab_base[scan];
820 else
821 *keynum = INVALID;
822 break;
823 }
824 break;
825
826 case STATE_E0: /* Mostly 101-key additions */
sethgfd9cb952005-11-01 22:55:18 -0800827 if (scan < keytab_e0_length)
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700828 *keynum = keytab_e0[scan];
829 else
830 *keynum = INVALID;
831 break;
832
833 case STATE_E1: /* Pause key only */
834 switch (scan) {
835 case 0x1d:
836 kb8042->parse_scan_state = STATE_E1_1D;
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700837 return (B_FALSE);
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700838 default:
839 *keynum = INVALID;
840 break;
841 }
842 break;
843
844 case STATE_E1_1D: /* Pause key only */
845 switch (scan) {
846 case 0x45:
847 *keynum = KEY(126); /* Pause */
848 break;
849 default:
850 *keynum = INVALID;
851 break;
852 }
853 break;
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700854 }
855
856 /*
857 * The results (*keynum, *state, and *synthetic_release_needed)
858 * have been filled in, but they are valid only if we return
859 * B_TRUE which is only done below. If we make it to here, we
860 * have completed a scan code sequence, so reset parse_scan_state.
861 */
862
863 kb8042->parse_scan_state = STATE_IDLE;
864
865 switch (*keynum) {
866 case KEYIGN: /* not a key, nor an error */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700867 return (B_FALSE); /* also not a final keycode */
868
869 case KEYBAD: /* not part of a legit sequence? */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700870 return (B_FALSE); /* and return not a final keycode */
871
872 default:
873 /*
874 * If we're here, it's a valid keycode. We've already
875 * filled in the return values; return success.
876 */
stevel@tonic-gate7c478bd2005-06-14 00:00:00 -0700877 return (B_TRUE); /* resolved to a key */
878 }
879}
sethgfd9cb952005-11-01 22:55:18 -0800880
881/*
882 * KeyboardConvertScan(*kb8042, scan, *keynum, *state
883 * *synthetic_release_needed)
884 *
885 * State machine that takes scan codes from the keyboard and resolves
886 * them to key numbers using the above tables. Returns B_TRUE if this
887 * scan code completes a scan code sequence, in which case "keynum",
888 * "state", and "synthetic_release_needed" will be filled in correctly.
889 *
890 * "synthetic_release_needed" is a hack to handle the additional two
891 * keys on a Korean keyboard. They report press only, so we tell the
892 * upper layer to synthesize the release.
893 */
894boolean_t
895KeyboardConvertScan_set2(
896 struct kb8042 *kb8042,
897 unsigned char scan,
898 int *keynum,
899 enum keystate *state,
900 boolean_t *synthetic_release_needed)
901{
sethgfd9cb952005-11-01 22:55:18 -0800902 *synthetic_release_needed = B_FALSE;
903 *state = KEY_PRESSED;
904
905 switch (scan) {
906 /*
907 * First, handle special cases.
908 * ACK has already been handled by our caller.
909 */
910
911 /*
912 * KAT_BREAK is 0xF0. It is the same as the break code for Japanese
913 * key 133.
914 * Therefore we don't treat it specially here.
915 */
916 case KAT_BREAK:
917 /* Switch states so we can recognize the code that follows */
918 kb8042->break_received = 1;
sethgfd9cb952005-11-01 22:55:18 -0800919 return (B_FALSE); /* not a final keycode */
920
921 case KB_ERROR:
922 /*
923 * Perhaps we should reset state here,
924 * since we no longer know what's going on.
925 */
sethgfd9cb952005-11-01 22:55:18 -0800926 return (B_FALSE);
927
928 case KB_POST_OK:
929 case KB_POST_FAIL:
930 /*
931 * Perhaps we should reset the LEDs now.
932 * If so, this check should probably be in the main line.
933 * Perhaps we should tell the higher layers that the
934 * keyboard has been reset.
935 */
936 /*
937 * Reset to idle
938 */
939 kb8042->parse_scan_state = STATE_IDLE;
sethgfd9cb952005-11-01 22:55:18 -0800940 return (B_FALSE);
941 }
942
943 if (kb8042->break_received) {
944 *state = KEY_RELEASED;
945 kb8042->break_received = 0;
946 }
947
948 switch (kb8042->parse_scan_state) {
949 case STATE_IDLE:
950 switch (scan) {
951 case KXT_EXTEND:
952 kb8042->parse_scan_state = STATE_E0;
sethgfd9cb952005-11-01 22:55:18 -0800953 return (B_FALSE);
954
955 case KXT_EXTEND2:
956 kb8042->parse_scan_state = STATE_E1;
sethgfd9cb952005-11-01 22:55:18 -0800957 return (B_FALSE);
958
959 /*
960 * We could do the next two in the table, but it would
961 * require nearly doubling the size of the table.
962 *
963 * Also, for some stupid reason these two report presses
964 * only. We tell the upper layer to synthesize a release.
965 */
966 case KXT_HANGUL_HANJA:
967 *keynum = KEY(150);
968 *synthetic_release_needed = B_TRUE;
969 break;
970
971 case KXT_HANGUL:
972 *keynum = KEY(151);
973 *synthetic_release_needed = B_TRUE;
974 break;
975
976 default:
977 /*
978 * Regular scan code
979 */
980 if (scan < keytab_base_length)
981 *keynum = keytab_base[scan];
982 else
983 *keynum = INVALID;
984 break;
985 }
986 break;
987
988 case STATE_E0: /* Mostly 101-key additions */
989 if (scan < keytab_e0_length)
990 *keynum = keytab_e0[scan];
991 else
992 *keynum = INVALID;
993 break;
994
995 case STATE_E1: /* Pause key only */
996 switch (scan) {
997 case 0x14:
998 kb8042->parse_scan_state = STATE_E1_14;
sethgfd9cb952005-11-01 22:55:18 -0800999 return (B_FALSE);
1000 default:
1001 *keynum = INVALID;
1002 break;
1003 }
1004 break;
1005
1006 case STATE_E1_14: /* Pause key only */
1007 if (scan == 0x77) {
1008 kb8042->parse_scan_state = STATE_E1_14_77;
1009 return (B_FALSE);
1010 } else {
1011 *keynum = INVALID;
1012 }
1013 break;
1014
1015 case STATE_E1_14_77:
1016 if (scan == 0xE1) {
1017 kb8042->parse_scan_state = STATE_E1_14_77_E1;
1018 return (B_FALSE);
1019 } else {
1020 *keynum = INVALID;
1021 }
1022 break;
1023
1024 case STATE_E1_14_77_E1:
1025 if (scan == 0xF0) {
1026 kb8042->parse_scan_state = STATE_E1_14_77_E1_F0;
1027 return (B_FALSE);
1028 } else {
1029 *keynum = INVALID;
1030 }
1031 break;
1032
1033 case STATE_E1_14_77_E1_F0:
1034 if (scan == 0x14) {
1035 kb8042->parse_scan_state = STATE_E1_14_77_E1_F0_14;
1036 return (B_FALSE);
1037 } else {
1038 *keynum = INVALID;
1039 }
1040 break;
1041
1042 case STATE_E1_14_77_E1_F0_14:
1043 if (scan == 0xF0) {
1044 kb8042->parse_scan_state = STATE_E1_14_77_E1_F0_14_F0;
1045 return (B_FALSE);
1046 } else {
1047 *keynum = INVALID;
1048 }
1049 break;
1050
1051 case STATE_E1_14_77_E1_F0_14_F0:
1052 if (scan == 0x77) {
1053 *keynum = KEY(126); /* Pause */
1054 } else {
1055 *keynum = INVALID;
1056 }
1057 break;
1058 }
1059
1060 /*
1061 * The results (*keynum, *state, and *synthetic_release_needed)
1062 * have been filled in, but they are valid only if we return
1063 * B_TRUE which is only done below. If we make it to here, we
1064 * have completed a scan code sequence, so reset parse_scan_state.
1065 */
1066
1067 if (kb8042->break_received) {
1068 *state = KEY_RELEASED;
1069 kb8042->break_received = 0;
1070 }
1071
1072 kb8042->parse_scan_state = STATE_IDLE;
1073
1074 switch (*keynum) {
1075 case KEYIGN: /* not a key, nor an error */
sethgfd9cb952005-11-01 22:55:18 -08001076 return (B_FALSE); /* also not a final keycode */
1077
1078 case KEYBAD: /* not part of a legit sequence? */
sethgfd9cb952005-11-01 22:55:18 -08001079 return (B_FALSE); /* and return not a final keycode */
1080
1081 default:
1082 /*
1083 * If we're here, it's a valid keycode. We've already
1084 * filled in the return values; return success.
1085 */
sethgfd9cb952005-11-01 22:55:18 -08001086 return (B_TRUE); /* resolved to a key */
1087 }
1088}