17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51841b879SSeth Goldberg  * Common Development and Distribution License (the "License").
6*3791cf70SSeth Goldberg  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
221841b879SSeth Goldberg  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <sys/types.h>
277c478bd9Sstevel@tonic-gate #include <sys/stream.h>
287c478bd9Sstevel@tonic-gate #include <sys/kbd.h>
297c478bd9Sstevel@tonic-gate #include <sys/kbtrans.h>
307c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
317c478bd9Sstevel@tonic-gate #include <sys/consdev.h>
327c478bd9Sstevel@tonic-gate #include <sys/promif.h>
337c478bd9Sstevel@tonic-gate #include "kb8042.h"
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate /*
367c478bd9Sstevel@tonic-gate  * A note on the use of prom_printf here:  Most of these routines can be
377c478bd9Sstevel@tonic-gate  * called from "polled mode", where we're servicing I/O requests from kmdb.
387c478bd9Sstevel@tonic-gate  * Normal system services are not available from polled mode; cmn_err will
397c478bd9Sstevel@tonic-gate  * not work.  prom_printf is the only safe output mechanism.
407c478bd9Sstevel@tonic-gate  */
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate #define	KEYBAD		0xff		/* should generate an error */
437c478bd9Sstevel@tonic-gate #define	KEYIGN		0xfe		/* ignore this sequence */
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate #define	KEY(code)	(code)
467c478bd9Sstevel@tonic-gate #define	INVALID		KEYBAD
477c478bd9Sstevel@tonic-gate #define	IGNORE		KEYIGN
487c478bd9Sstevel@tonic-gate 
49fd9cb95cSsethg #define	NELEM(a)	(sizeof (a) / sizeof (a)[0])
50fd9cb95cSsethg 
517c478bd9Sstevel@tonic-gate /*
527c478bd9Sstevel@tonic-gate  * These are the states of our parsing machine:
537c478bd9Sstevel@tonic-gate  */
54fd9cb95cSsethg #define	STATE_IDLE	0x00000001 /* Awaiting the start of a sequence */
55fd9cb95cSsethg #define	STATE_E0	0x00000002 /* Rec'd an E0 */
56fd9cb95cSsethg #define	STATE_E1	0x00000004 /* Rec'd an E1 (Pause key only) */
57fd9cb95cSsethg #define	STATE_E1_1D	0x00000008 /* Rec'd an E1 1D (Pause key only) */
58fd9cb95cSsethg #define	STATE_E1_14	0x00000010 /* Rec'd an E1 14 (Pause key only) */
59fd9cb95cSsethg #define	STATE_E1_14_77			0x00000020
60fd9cb95cSsethg #define	STATE_E1_14_77_E1		0x00000040
61fd9cb95cSsethg #define	STATE_E1_14_77_E1_F0		0x00000080
62fd9cb95cSsethg #define	STATE_E1_14_77_E1_F0_14		0x00000100
63fd9cb95cSsethg #define	STATE_E1_14_77_E1_F0_14_F0	0x00000200
647c478bd9Sstevel@tonic-gate 
65fd9cb95cSsethg static boolean_t KeyboardConvertScan_set1(struct kb8042	*, unsigned char, int *,
66fd9cb95cSsethg     enum keystate *, boolean_t *);
67fd9cb95cSsethg static boolean_t KeyboardConvertScan_set2(struct kb8042	*, unsigned char, int *,
68fd9cb95cSsethg     enum keystate *, boolean_t *);
69fd9cb95cSsethg 
70fd9cb95cSsethg static const unsigned char *keytab_base = NULL;
71fd9cb95cSsethg static int keytab_base_length = 0;
72fd9cb95cSsethg static const unsigned char *keytab_e0 = NULL;
73fd9cb95cSsethg static int keytab_e0_length = 0;
74fd9cb95cSsethg static boolean_t (*KeyboardConvertScan_fn)(struct kb8042 *, unsigned char,
75fd9cb95cSsethg     int *, enum keystate *, boolean_t *) = NULL;
767c478bd9Sstevel@tonic-gate 
77fd9cb95cSsethg static const unsigned char	keytab_base_set1[] = {
787c478bd9Sstevel@tonic-gate /* scan		key number	keycap */
797c478bd9Sstevel@tonic-gate /* 00 */	INVALID,
807c478bd9Sstevel@tonic-gate /* 01 */	KEY(110),	/* Esc */
817c478bd9Sstevel@tonic-gate /* 02 */	KEY(2),		/* 1 */
827c478bd9Sstevel@tonic-gate /* 03 */	KEY(3),		/* 2 */
837c478bd9Sstevel@tonic-gate /* 04 */	KEY(4),		/* 3 */
847c478bd9Sstevel@tonic-gate /* 05 */	KEY(5),		/* 4 */
857c478bd9Sstevel@tonic-gate /* 06 */	KEY(6),		/* 5 */
867c478bd9Sstevel@tonic-gate /* 07 */	KEY(7),		/* 6 */
877c478bd9Sstevel@tonic-gate /* 08 */	KEY(8),		/* 7 */
887c478bd9Sstevel@tonic-gate /* 09 */	KEY(9),		/* 8 */
897c478bd9Sstevel@tonic-gate /* 0a */	KEY(10),	/* 9 */
907c478bd9Sstevel@tonic-gate /* 0b */	KEY(11),	/* 0 */
917c478bd9Sstevel@tonic-gate /* 0c */	KEY(12),	/* - */
927c478bd9Sstevel@tonic-gate /* 0d */	KEY(13),	/* = */
937c478bd9Sstevel@tonic-gate /* 0e */	KEY(15),	/* backspace */
947c478bd9Sstevel@tonic-gate /* 0f */	KEY(16),	/* tab */
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate /* 10 */	KEY(17),	/* Q */
977c478bd9Sstevel@tonic-gate /* 11 */	KEY(18),	/* W */
987c478bd9Sstevel@tonic-gate /* 12 */	KEY(19),	/* E */
997c478bd9Sstevel@tonic-gate /* 13 */	KEY(20),	/* R */
1007c478bd9Sstevel@tonic-gate /* 14 */	KEY(21),	/* T */
1017c478bd9Sstevel@tonic-gate /* 15 */	KEY(22),	/* Y */
1027c478bd9Sstevel@tonic-gate /* 16 */	KEY(23),	/* U */
1037c478bd9Sstevel@tonic-gate /* 17 */	KEY(24),	/* I */
1047c478bd9Sstevel@tonic-gate /* 18 */	KEY(25),	/* O */
1057c478bd9Sstevel@tonic-gate /* 19 */	KEY(26),	/* P */
1067c478bd9Sstevel@tonic-gate /* 1a */	KEY(27),	/* [ */
1077c478bd9Sstevel@tonic-gate /* 1b */	KEY(28),	/* ] */
1087c478bd9Sstevel@tonic-gate /* 1c */	KEY(43),	/* Enter (main) */
1097c478bd9Sstevel@tonic-gate /* 1d */	KEY(58),	/* L Ctrl */
1107c478bd9Sstevel@tonic-gate /* 1e */	KEY(31),	/* A */
1117c478bd9Sstevel@tonic-gate /* 1f */	KEY(32),	/* S */
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate /* 20 */	KEY(33),	/* D */
1147c478bd9Sstevel@tonic-gate /* 21 */	KEY(34),	/* F */
1157c478bd9Sstevel@tonic-gate /* 22 */	KEY(35),	/* G */
1167c478bd9Sstevel@tonic-gate /* 23 */	KEY(36),	/* H */
1177c478bd9Sstevel@tonic-gate /* 24 */	KEY(37),	/* J */
1187c478bd9Sstevel@tonic-gate /* 25 */	KEY(38),	/* K */
1197c478bd9Sstevel@tonic-gate /* 26 */	KEY(39),	/* L */
1207c478bd9Sstevel@tonic-gate /* 27 */	KEY(40),	/* ; */
1217c478bd9Sstevel@tonic-gate /* 28 */	KEY(41),	/* ' */
1227c478bd9Sstevel@tonic-gate /* 29 */	KEY(1),		/* ` */
1237c478bd9Sstevel@tonic-gate /* 2a */	KEY(44),	/* L Shift */
1247c478bd9Sstevel@tonic-gate /* 2b */	KEY(29),	/* \ */
1257c478bd9Sstevel@tonic-gate /* 2c */	KEY(46),	/* Z */
1267c478bd9Sstevel@tonic-gate /* 2d */	KEY(47),	/* X */
1277c478bd9Sstevel@tonic-gate /* 2e */	KEY(48),	/* C */
1287c478bd9Sstevel@tonic-gate /* 2f */	KEY(49),	/* V */
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate /* 30 */	KEY(50),	/* B */
1317c478bd9Sstevel@tonic-gate /* 31 */	KEY(51),	/* N */
1327c478bd9Sstevel@tonic-gate /* 32 */	KEY(52),	/* M */
1337c478bd9Sstevel@tonic-gate /* 33 */	KEY(53),	/* , */
1347c478bd9Sstevel@tonic-gate /* 34 */	KEY(54),	/* . */
1357c478bd9Sstevel@tonic-gate /* 35 */	KEY(55),	/* / */
1367c478bd9Sstevel@tonic-gate /* 36 */	KEY(57),	/* R Shift */
1377c478bd9Sstevel@tonic-gate /* 37 */	KEY(100),	/* * (num) */
1387c478bd9Sstevel@tonic-gate /* 38 */	KEY(60),	/* L Alt */
1397c478bd9Sstevel@tonic-gate /* 39 */	KEY(61),	/* Space */
1407c478bd9Sstevel@tonic-gate /* 3a */	KEY(30),	/* CapsLock */
1417c478bd9Sstevel@tonic-gate /* 3b */	KEY(112),	/* F1 */
1427c478bd9Sstevel@tonic-gate /* 3c */	KEY(113),	/* F2 */
1437c478bd9Sstevel@tonic-gate /* 3d */	KEY(114),	/* F3 */
1447c478bd9Sstevel@tonic-gate /* 3e */	KEY(115),	/* F4 */
1457c478bd9Sstevel@tonic-gate /* 3f */	KEY(116),	/* F5 */
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate /* 40 */	KEY(117),	/* F6 */
1487c478bd9Sstevel@tonic-gate /* 41 */	KEY(118),	/* F7 */
1497c478bd9Sstevel@tonic-gate /* 42 */	KEY(119),	/* F8 */
1507c478bd9Sstevel@tonic-gate /* 43 */	KEY(120),	/* F9 */
1517c478bd9Sstevel@tonic-gate /* 44 */	KEY(121),	/* F10 */
1527c478bd9Sstevel@tonic-gate /* 45 */	KEY(90),	/* NumLock */
1537c478bd9Sstevel@tonic-gate /* 46 */	KEY(125),	/* Scroll Lock */
1547c478bd9Sstevel@tonic-gate /* 47 */	KEY(91),	/* 7 (num) */
1557c478bd9Sstevel@tonic-gate /* 48 */	KEY(96),	/* 8 (num) */
1567c478bd9Sstevel@tonic-gate /* 49 */	KEY(101),	/* 9 (num) */
1577c478bd9Sstevel@tonic-gate /* 4a */	KEY(105),	/* - (num) */
1587c478bd9Sstevel@tonic-gate /* 4b */	KEY(92),	/* 4 (num) */
1597c478bd9Sstevel@tonic-gate /* 4c */	KEY(97),	/* 5 (num) */
1607c478bd9Sstevel@tonic-gate /* 4d */	KEY(102),	/* 6 (num) */
1617c478bd9Sstevel@tonic-gate /* 4e */	KEY(106),	/* + (num) */
1627c478bd9Sstevel@tonic-gate /* 4f */	KEY(93),	/* 1 (num) */
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate /* 50 */	KEY(98),	/* 2 (num) */
1657c478bd9Sstevel@tonic-gate /* 51 */	KEY(103),	/* 3 (num) */
1667c478bd9Sstevel@tonic-gate /* 52 */	KEY(99),	/* 0 (num) */
1677c478bd9Sstevel@tonic-gate /* 53 */	KEY(104),	/* . (num) */
1687c478bd9Sstevel@tonic-gate /* 54 */	KEY(124),	/* PrintScreen (with Alt) */
1697c478bd9Sstevel@tonic-gate /* 55 */	INVALID,
1707c478bd9Sstevel@tonic-gate /* 56 */	KEY(45),	/* not labled (102-key only) */
1717c478bd9Sstevel@tonic-gate /* 57 */	KEY(122),	/* F11 */
1727c478bd9Sstevel@tonic-gate /* 58 */	KEY(123),	/* F12 */
1737c478bd9Sstevel@tonic-gate /* 59 */	INVALID,
1747c478bd9Sstevel@tonic-gate /* 5a */	INVALID,
1757c478bd9Sstevel@tonic-gate /* 5b */	INVALID,
1767c478bd9Sstevel@tonic-gate /* 5c */	INVALID,
1777c478bd9Sstevel@tonic-gate /* 5d */	INVALID,
1787c478bd9Sstevel@tonic-gate /* 5e */	INVALID,
1797c478bd9Sstevel@tonic-gate /* 5f */	INVALID,
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate /* 60 */	INVALID,
1827c478bd9Sstevel@tonic-gate /* 61 */	INVALID,
1837c478bd9Sstevel@tonic-gate /* 62 */	INVALID,
1847c478bd9Sstevel@tonic-gate /* 63 */	INVALID,
1857c478bd9Sstevel@tonic-gate /* 64 */	INVALID,
1867c478bd9Sstevel@tonic-gate /* 65 */	INVALID,
1877c478bd9Sstevel@tonic-gate /* 66 */	INVALID,
1887c478bd9Sstevel@tonic-gate /* 67 */	INVALID,
1897c478bd9Sstevel@tonic-gate /* 68 */	INVALID,
1907c478bd9Sstevel@tonic-gate /* 69 */	INVALID,
1917c478bd9Sstevel@tonic-gate /* 6a */	INVALID,
1927c478bd9Sstevel@tonic-gate /* 6b */	INVALID,
1937c478bd9Sstevel@tonic-gate /* 6c */	INVALID,
1947c478bd9Sstevel@tonic-gate /* 6d */	INVALID,
1957c478bd9Sstevel@tonic-gate /* 6e */	INVALID,
1967c478bd9Sstevel@tonic-gate /* 6f */	INVALID,
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate /* 70 */	KEY(133),	/* Japanese 106-key keyboard */
1997c478bd9Sstevel@tonic-gate /* 71 */	INVALID,
2007c478bd9Sstevel@tonic-gate /* 72 */	INVALID,
2017c478bd9Sstevel@tonic-gate /* 73 */	KEY(56),	/* Japanese 106-key keyboard */
2027c478bd9Sstevel@tonic-gate /* 74 */	INVALID,
2037c478bd9Sstevel@tonic-gate /* 75 */	INVALID,
2047c478bd9Sstevel@tonic-gate /* 76 */	INVALID,
2057c478bd9Sstevel@tonic-gate /* 77 */	INVALID,
2067c478bd9Sstevel@tonic-gate /* 78 */	INVALID,
2077c478bd9Sstevel@tonic-gate /* 79 */	KEY(132),	/* Japanese 106-key keyboard */
2087c478bd9Sstevel@tonic-gate /* 7a */	INVALID,
2097c478bd9Sstevel@tonic-gate /* 7b */	KEY(131),	/* Japanese 106-key keyboard */
2107c478bd9Sstevel@tonic-gate /* 7c */	INVALID,
2117c478bd9Sstevel@tonic-gate /* 7d */	KEY(14),	/* Japanese 106-key keyboard */
2127c478bd9Sstevel@tonic-gate /* 7e */	INVALID,
2137c478bd9Sstevel@tonic-gate /* 7f */	INVALID,
2147c478bd9Sstevel@tonic-gate };
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate /*
2177c478bd9Sstevel@tonic-gate  * Parse table after receiving an E0 prefix code.
2187c478bd9Sstevel@tonic-gate  *
2197c478bd9Sstevel@tonic-gate  * Generally speaking, keys that were added on the 101-key keyboard are
2207c478bd9Sstevel@tonic-gate  * represented as an E0 followed by the code for an 84-key key.  Software
2217c478bd9Sstevel@tonic-gate  * ignorant of the 101-key keyboard ignores the E0 and so is handled
2227c478bd9Sstevel@tonic-gate  * compatibly.  Many of these variants involve "fake" shift presses
2237c478bd9Sstevel@tonic-gate  * and releases for compatibility; these are also prefixed with E0.
2247c478bd9Sstevel@tonic-gate  * We ignore these fake shifts.
2257c478bd9Sstevel@tonic-gate  */
226fd9cb95cSsethg static const unsigned char	keytab_e0_set1[] = {
2277c478bd9Sstevel@tonic-gate /* 00 */	INVALID,
2287c478bd9Sstevel@tonic-gate /* 01 */	INVALID,
2297c478bd9Sstevel@tonic-gate /* 02 */	INVALID,
2307c478bd9Sstevel@tonic-gate /* 03 */	INVALID,
2317c478bd9Sstevel@tonic-gate /* 04 */	INVALID,
2327c478bd9Sstevel@tonic-gate /* 05 */	INVALID,
2337c478bd9Sstevel@tonic-gate /* 06 */	INVALID,
2347c478bd9Sstevel@tonic-gate /* 07 */	INVALID,
2357c478bd9Sstevel@tonic-gate /* 08 */	INVALID,
2367c478bd9Sstevel@tonic-gate /* 09 */	INVALID,
2377c478bd9Sstevel@tonic-gate /* 0a */	INVALID,
2387c478bd9Sstevel@tonic-gate /* 0b */	INVALID,
2397c478bd9Sstevel@tonic-gate /* 0c */	INVALID,
2407c478bd9Sstevel@tonic-gate /* 0d */	INVALID,
2417c478bd9Sstevel@tonic-gate /* 0e */	INVALID,
2427c478bd9Sstevel@tonic-gate /* 0f */	INVALID,
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate /* 10 */	INVALID,
2457c478bd9Sstevel@tonic-gate /* 11 */	INVALID,
2467c478bd9Sstevel@tonic-gate /* 12 */	INVALID,
2477c478bd9Sstevel@tonic-gate /* 13 */	INVALID,
2487c478bd9Sstevel@tonic-gate /* 14 */	INVALID,
2497c478bd9Sstevel@tonic-gate /* 15 */	INVALID,
2507c478bd9Sstevel@tonic-gate /* 16 */	INVALID,
2517c478bd9Sstevel@tonic-gate /* 17 */	INVALID,
2527c478bd9Sstevel@tonic-gate /* 18 */	INVALID,
2537c478bd9Sstevel@tonic-gate /* 19 */	INVALID,
2547c478bd9Sstevel@tonic-gate /* 1a */	INVALID,
2557c478bd9Sstevel@tonic-gate /* 1b */	INVALID,
2567c478bd9Sstevel@tonic-gate /* 1c */	KEY(108),	/* Enter (num) */
2577c478bd9Sstevel@tonic-gate /* 1d */	KEY(64),	/* R Ctrl */
2587c478bd9Sstevel@tonic-gate /* 1e */	INVALID,
2597c478bd9Sstevel@tonic-gate /* 1f */	INVALID,
2607c478bd9Sstevel@tonic-gate 
2611841b879SSeth Goldberg /* 20 */	KEY(235),	/* Mute */
2627c478bd9Sstevel@tonic-gate /* 21 */	INVALID,
2637c478bd9Sstevel@tonic-gate /* 22 */	INVALID,
2647c478bd9Sstevel@tonic-gate /* 23 */	INVALID,
2657c478bd9Sstevel@tonic-gate /* 24 */	INVALID,
2667c478bd9Sstevel@tonic-gate /* 25 */	INVALID,
2677c478bd9Sstevel@tonic-gate /* 26 */	INVALID,
2687c478bd9Sstevel@tonic-gate /* 27 */	INVALID,
2697c478bd9Sstevel@tonic-gate /* 28 */	INVALID,
2707c478bd9Sstevel@tonic-gate /* 29 */	INVALID,
2717c478bd9Sstevel@tonic-gate /* 2a */	INVALID,
2727c478bd9Sstevel@tonic-gate /* 2b */	INVALID,
2737c478bd9Sstevel@tonic-gate /* 2c */	INVALID,
2747c478bd9Sstevel@tonic-gate /* 2d */	INVALID,
2751841b879SSeth Goldberg /* 2e */	KEY(234),	/* Volume Down */
2767c478bd9Sstevel@tonic-gate /* 2f */	INVALID,
2777c478bd9Sstevel@tonic-gate 
2781841b879SSeth Goldberg /* 30 */	KEY(233),	/* Volume Up */
2797c478bd9Sstevel@tonic-gate /* 31 */	INVALID,
2807c478bd9Sstevel@tonic-gate /* 32 */	INVALID,
2817c478bd9Sstevel@tonic-gate /* 33 */	INVALID,
2827c478bd9Sstevel@tonic-gate /* 34 */	INVALID,
2837c478bd9Sstevel@tonic-gate /* 35 */	KEY(95),	/* / (num) */
2847c478bd9Sstevel@tonic-gate /* 36 */	INVALID,
2857c478bd9Sstevel@tonic-gate /* 37 */	KEY(124),	/* PrintScreen (no Alt) */
2867c478bd9Sstevel@tonic-gate /* 38 */	KEY(62),	/* R Alt */
2877c478bd9Sstevel@tonic-gate /* 39 */	INVALID,
2887c478bd9Sstevel@tonic-gate /* 3a */	INVALID,
2897c478bd9Sstevel@tonic-gate /* 3b */	INVALID,
2907c478bd9Sstevel@tonic-gate /* 3c */	INVALID,
2917c478bd9Sstevel@tonic-gate /* 3d */	INVALID,
2927c478bd9Sstevel@tonic-gate /* 3e */	INVALID,
2937c478bd9Sstevel@tonic-gate /* 3f */	INVALID,
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate /* 40 */	INVALID,
2967c478bd9Sstevel@tonic-gate /* 41 */	INVALID,
2977c478bd9Sstevel@tonic-gate /* 42 */	INVALID,
2987c478bd9Sstevel@tonic-gate /* 43 */	INVALID,
2997c478bd9Sstevel@tonic-gate /* 44 */	INVALID,
3007c478bd9Sstevel@tonic-gate /* 45 */	INVALID,
3017c478bd9Sstevel@tonic-gate /* 46 */	KEY(126),	/* Pause (with Cntl) */
3027c478bd9Sstevel@tonic-gate /* 47 */	KEY(80),	/* Home (arrow) */
3037c478bd9Sstevel@tonic-gate /* 48 */	KEY(83),	/* Up (arrow) */
3047c478bd9Sstevel@tonic-gate /* 49 */	KEY(85),	/* PgUp (arrow) */
3057c478bd9Sstevel@tonic-gate /* 4a */	INVALID,
3067c478bd9Sstevel@tonic-gate /* 4b */	KEY(79),	/* Left (arrow) */
3077c478bd9Sstevel@tonic-gate /* 4c */	INVALID,
3087c478bd9Sstevel@tonic-gate /* 4d */	KEY(89),	/* Right (arrow) */
3097c478bd9Sstevel@tonic-gate /* 4e */	INVALID,
3107c478bd9Sstevel@tonic-gate /* 4f */	KEY(81),	/* End (arrow) */
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate /* 50 */	KEY(84),	/* Down (arrow) */
3137c478bd9Sstevel@tonic-gate /* 51 */	KEY(86),	/* PgDn (arrow) */
3147c478bd9Sstevel@tonic-gate /* 52 */	KEY(75),	/* Insert (arrow) */
3157c478bd9Sstevel@tonic-gate /* 53 */	KEY(76),	/* Delete (arrow) */
3167c478bd9Sstevel@tonic-gate /* 54 */	INVALID,
3177c478bd9Sstevel@tonic-gate /* 55 */	INVALID,
3187c478bd9Sstevel@tonic-gate /* 56 */	INVALID,
3197c478bd9Sstevel@tonic-gate /* 57 */	INVALID,
3207c478bd9Sstevel@tonic-gate /* 58 */	INVALID,
3217c478bd9Sstevel@tonic-gate /* 59 */	INVALID,
3227c478bd9Sstevel@tonic-gate /* 5a */	INVALID,
3237c478bd9Sstevel@tonic-gate /* 5b */	KEY(59),	/* L Window (104-key) */
3247c478bd9Sstevel@tonic-gate /* 5c */	KEY(63),	/* R Window (104-key) */
3257c478bd9Sstevel@tonic-gate /* 5d */	KEY(65),	/* Menu (104-key) */
3267c478bd9Sstevel@tonic-gate /* 5e */	INVALID,
3277c478bd9Sstevel@tonic-gate /* 5f */	INVALID,
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate /* 60 */	INVALID,
3307c478bd9Sstevel@tonic-gate /* 61 */	INVALID,
3317c478bd9Sstevel@tonic-gate /* 62 */	INVALID,
3327c478bd9Sstevel@tonic-gate /* 63 */	INVALID,
3337c478bd9Sstevel@tonic-gate /* 64 */	INVALID,
3347c478bd9Sstevel@tonic-gate /* 65 */	INVALID,
3357c478bd9Sstevel@tonic-gate /* 66 */	INVALID,
3367c478bd9Sstevel@tonic-gate /* 67 */	INVALID,
3377c478bd9Sstevel@tonic-gate /* 68 */	INVALID,
3387c478bd9Sstevel@tonic-gate /* 69 */	INVALID,
3397c478bd9Sstevel@tonic-gate /* 6a */	INVALID,
3407c478bd9Sstevel@tonic-gate /* 6b */	INVALID,
3417c478bd9Sstevel@tonic-gate /* 6c */	INVALID,
3427c478bd9Sstevel@tonic-gate /* 6d */	INVALID,
3437c478bd9Sstevel@tonic-gate /* 6e */	INVALID,
3447c478bd9Sstevel@tonic-gate /* 6f */	INVALID,
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate /* 70 */	INVALID,
3477c478bd9Sstevel@tonic-gate /* 71 */	INVALID,
3487c478bd9Sstevel@tonic-gate /* 72 */	INVALID,
3497c478bd9Sstevel@tonic-gate /* 73 */	INVALID,
3507c478bd9Sstevel@tonic-gate /* 74 */	INVALID,
3517c478bd9Sstevel@tonic-gate /* 75 */	INVALID,
3527c478bd9Sstevel@tonic-gate /* 76 */	INVALID,
3537c478bd9Sstevel@tonic-gate /* 77 */	INVALID,
3547c478bd9Sstevel@tonic-gate /* 78 */	INVALID,
3557c478bd9Sstevel@tonic-gate /* 79 */	INVALID,
3567c478bd9Sstevel@tonic-gate /* 7a */	INVALID,
3577c478bd9Sstevel@tonic-gate /* 7b */	INVALID,
3587c478bd9Sstevel@tonic-gate /* 7c */	INVALID,
3597c478bd9Sstevel@tonic-gate /* 7d */	INVALID,
3607c478bd9Sstevel@tonic-gate /* 7e */	INVALID,
3617c478bd9Sstevel@tonic-gate };
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate /*
3657c478bd9Sstevel@tonic-gate  *	Parse table for the base keyboard state.  The index is the start of
3667c478bd9Sstevel@tonic-gate  *	a new sequence.
3677c478bd9Sstevel@tonic-gate  *
3687c478bd9Sstevel@tonic-gate  * Questionable or unusual cases:
369fd9cb95cSsethg  * 02		On some SPARC keyboards, this is the scan code for the STOP
370fd9cb95cSsethg  *		key.  The KEY() value was chosen so that it maps to a
371fd9cb95cSsethg  *		HOLE entry in the keytables in kb8042_keytables.c; therefore,
372fd9cb95cSsethg  *		the STOP key code is only translated properly when kb8042
373fd9cb95cSsethg  *		is "emulating" a USB keyboard (which it is by default--
374fd9cb95cSsethg  *		see conskbd.c).
3757c478bd9Sstevel@tonic-gate  * 7f		Old kd code says this is an 84-key SysReq.  Manual says no.
3767c478bd9Sstevel@tonic-gate  * 87		Old kd code says 1 (num).  Manual says no.
3777c478bd9Sstevel@tonic-gate  * 8c		Old kd code says / (num).  Manual says no.
3787c478bd9Sstevel@tonic-gate  * aa		POST OK.  Handled by code.
3797c478bd9Sstevel@tonic-gate  * e0		Extend prefix.  Handled by code. (switches to E0 table)
3807c478bd9Sstevel@tonic-gate  * e1		Extend prefix.  Handled by code.  (Pause key only)
3817c478bd9Sstevel@tonic-gate  * f0		Break prefix.  Handled by code.
3827c478bd9Sstevel@tonic-gate  * f1		Korean Hangul/Hanja key.  Handled by code.
3837c478bd9Sstevel@tonic-gate  * f2		Korean Hangul key.  Handled by code.
3847c478bd9Sstevel@tonic-gate  * ff		Keyboard internal buffer overrun.  Handled by code.
3857c478bd9Sstevel@tonic-gate  *
3867c478bd9Sstevel@tonic-gate  * Other values past the end of the table are treated as INVALID.
3877c478bd9Sstevel@tonic-gate  */
3887c478bd9Sstevel@tonic-gate 
389fd9cb95cSsethg static const unsigned char	keytab_base_set2[] = {
3907c478bd9Sstevel@tonic-gate /* scan		state		keycap */
3917c478bd9Sstevel@tonic-gate /* 00 */	INVALID,
3927c478bd9Sstevel@tonic-gate /* 01 */	KEY(120),	/* F9 */
393fd9cb95cSsethg #if defined(__sparc)
394fd9cb95cSsethg /* 02 */	KEY(K8042_STOP), /* STOP */
395fd9cb95cSsethg #else
3967c478bd9Sstevel@tonic-gate /* 02 */	INVALID,	/* F7?  Old code says so but manual doesn't */
397fd9cb95cSsethg #endif
3987c478bd9Sstevel@tonic-gate /* 03 */	KEY(116),	/* F5 */
3997c478bd9Sstevel@tonic-gate /* 04 */	KEY(114),	/* F3 */
4007c478bd9Sstevel@tonic-gate /* 05 */	KEY(112),	/* F1 */
4017c478bd9Sstevel@tonic-gate /* 06 */	KEY(113),	/* F2 */
4027c478bd9Sstevel@tonic-gate /* 07 */	KEY(123),	/* F12 */
4037c478bd9Sstevel@tonic-gate /* 08 */	INVALID,
4047c478bd9Sstevel@tonic-gate /* 09 */	KEY(121),	/* F10 */
4057c478bd9Sstevel@tonic-gate /* 0a */	KEY(119),	/* F8 */
4067c478bd9Sstevel@tonic-gate /* 0b */	KEY(117),	/* F6 */
4077c478bd9Sstevel@tonic-gate /* 0c */	KEY(115),	/* F4 */
4087c478bd9Sstevel@tonic-gate /* 0d */	KEY(16),	/* tab */
4097c478bd9Sstevel@tonic-gate /* 0e */	KEY(1),		/* ` */
4107c478bd9Sstevel@tonic-gate /* 0f */	INVALID,
4117c478bd9Sstevel@tonic-gate /* 10 */	INVALID,
4127c478bd9Sstevel@tonic-gate /* 11 */	KEY(60),	/* L Alt */
4137c478bd9Sstevel@tonic-gate /* 12 */	KEY(44),	/* L Shift */
4147c478bd9Sstevel@tonic-gate /* 13 */	KEY(133),	/* Japanese 106-key */
4157c478bd9Sstevel@tonic-gate /* 14 */	KEY(58),	/* L Ctrl */
4167c478bd9Sstevel@tonic-gate /* 15 */	KEY(17),	/* Q */
4177c478bd9Sstevel@tonic-gate /* 16 */	KEY(2),		/* 1 */
4187c478bd9Sstevel@tonic-gate /* 17 */	INVALID,
4197c478bd9Sstevel@tonic-gate /* 18 */	INVALID,
4207c478bd9Sstevel@tonic-gate /* 19 */	INVALID,
4217c478bd9Sstevel@tonic-gate /* 1a */	KEY(46),	/* Z */
4227c478bd9Sstevel@tonic-gate /* 1b */	KEY(32),	/* S */
4237c478bd9Sstevel@tonic-gate /* 1c */	KEY(31),	/* A */
4247c478bd9Sstevel@tonic-gate /* 1d */	KEY(18),	/* W */
4257c478bd9Sstevel@tonic-gate /* 1e */	KEY(3),		/* 2 */
4267c478bd9Sstevel@tonic-gate /* 1f */	INVALID,
4277c478bd9Sstevel@tonic-gate /* 20 */	INVALID,
4287c478bd9Sstevel@tonic-gate /* 21 */	KEY(48),	/* C */
4297c478bd9Sstevel@tonic-gate /* 22 */	KEY(47),	/* X */
4307c478bd9Sstevel@tonic-gate /* 23 */	KEY(33),	/* D */
4317c478bd9Sstevel@tonic-gate /* 24 */	KEY(19),	/* E */
4327c478bd9Sstevel@tonic-gate /* 25 */	KEY(5),		/* 4 */
4337c478bd9Sstevel@tonic-gate /* 26 */	KEY(4),		/* 3 */
4347c478bd9Sstevel@tonic-gate /* 27 */	INVALID,
4357c478bd9Sstevel@tonic-gate /* 28 */	INVALID,
4367c478bd9Sstevel@tonic-gate /* 29 */	KEY(61),	/* Space */
4377c478bd9Sstevel@tonic-gate /* 2a */	KEY(49),	/* V */
4387c478bd9Sstevel@tonic-gate /* 2b */	KEY(34),	/* F */
4397c478bd9Sstevel@tonic-gate /* 2c */	KEY(21),	/* T */
4407c478bd9Sstevel@tonic-gate /* 2d */	KEY(20),	/* R */
4417c478bd9Sstevel@tonic-gate /* 2e */	KEY(6),		/* 5 */
4427c478bd9Sstevel@tonic-gate /* 2f */	INVALID,
4437c478bd9Sstevel@tonic-gate /* 30 */	INVALID,
4447c478bd9Sstevel@tonic-gate /* 31 */	KEY(51),	/* N */
4457c478bd9Sstevel@tonic-gate /* 32 */	KEY(50),	/* B */
4467c478bd9Sstevel@tonic-gate /* 33 */	KEY(36),	/* H */
4477c478bd9Sstevel@tonic-gate /* 34 */	KEY(35),	/* G */
4487c478bd9Sstevel@tonic-gate /* 35 */	KEY(22),	/* Y */
4497c478bd9Sstevel@tonic-gate /* 36 */	KEY(7),		/* 6 */
4507c478bd9Sstevel@tonic-gate /* 37 */	INVALID,
4517c478bd9Sstevel@tonic-gate /* 38 */	INVALID,
4527c478bd9Sstevel@tonic-gate /* 39 */	INVALID,
4537c478bd9Sstevel@tonic-gate /* 3a */	KEY(52),	/* M */
4547c478bd9Sstevel@tonic-gate /* 3b */	KEY(37),	/* J */
4557c478bd9Sstevel@tonic-gate /* 3c */	KEY(23),	/* U */
4567c478bd9Sstevel@tonic-gate /* 3d */	KEY(8),		/* 7 */
4577c478bd9Sstevel@tonic-gate /* 3e */	KEY(9),		/* 8 */
4587c478bd9Sstevel@tonic-gate /* 3f */	INVALID,
4597c478bd9Sstevel@tonic-gate /* 40 */	INVALID,
4607c478bd9Sstevel@tonic-gate /* 41 */	KEY(53),	/* , */
4617c478bd9Sstevel@tonic-gate /* 42 */	KEY(38),	/* K */
4627c478bd9Sstevel@tonic-gate /* 43 */	KEY(24),	/* I */
4637c478bd9Sstevel@tonic-gate /* 44 */	KEY(25),	/* O */
4647c478bd9Sstevel@tonic-gate /* 45 */	KEY(11),	/* 0 */
4657c478bd9Sstevel@tonic-gate /* 46 */	KEY(10),	/* 9 */
4667c478bd9Sstevel@tonic-gate /* 47 */	INVALID,
4677c478bd9Sstevel@tonic-gate /* 48 */	INVALID,
4687c478bd9Sstevel@tonic-gate /* 49 */	KEY(54),	/* . */
4697c478bd9Sstevel@tonic-gate /* 4a */	KEY(55),	/* / */
4707c478bd9Sstevel@tonic-gate /* 4b */	KEY(39),	/* L */
4717c478bd9Sstevel@tonic-gate /* 4c */	KEY(40),	/* ; */
4727c478bd9Sstevel@tonic-gate /* 4d */	KEY(26),	/* P */
4737c478bd9Sstevel@tonic-gate /* 4e */	KEY(12),	/* - */
4747c478bd9Sstevel@tonic-gate /* 4f */	INVALID,
4757c478bd9Sstevel@tonic-gate /* 50 */	INVALID,
4767c478bd9Sstevel@tonic-gate /* 51 */	KEY(56),	/* Japanese 106-key */
4777c478bd9Sstevel@tonic-gate /* 52 */	KEY(41),	/* ' */
4787c478bd9Sstevel@tonic-gate /* 53 */	INVALID,
4797c478bd9Sstevel@tonic-gate /* 54 */	KEY(27),	/* [ */
4807c478bd9Sstevel@tonic-gate /* 55 */	KEY(13),	/* = */
4817c478bd9Sstevel@tonic-gate /* 56 */	INVALID,
4827c478bd9Sstevel@tonic-gate /* 57 */	INVALID,
4837c478bd9Sstevel@tonic-gate /* 58 */	KEY(30),	/* CapsLock */
4847c478bd9Sstevel@tonic-gate /* 59 */	KEY(57),	/* R Shift */
4857c478bd9Sstevel@tonic-gate /* 5a */	KEY(43),	/* Enter (main) */
4867c478bd9Sstevel@tonic-gate /* 5b */	KEY(28),	/* ] */
4877c478bd9Sstevel@tonic-gate /* 5c */	INVALID,
4887c478bd9Sstevel@tonic-gate /* 5d */	KEY(29),	/* \, key 42 for 102-key */
4897c478bd9Sstevel@tonic-gate /* 5e */	INVALID,
4907c478bd9Sstevel@tonic-gate /* 5f */	INVALID,
4917c478bd9Sstevel@tonic-gate /* 60 */	INVALID,
4927c478bd9Sstevel@tonic-gate /* 61 */	KEY(45),	/* 102-key only, typically </> */
4937c478bd9Sstevel@tonic-gate /* 62 */	INVALID,
4947c478bd9Sstevel@tonic-gate /* 63 */	INVALID,
4957c478bd9Sstevel@tonic-gate /* 64 */	KEY(132),	/* Japanese 106-key */
4967c478bd9Sstevel@tonic-gate /* 65 */	INVALID,
4977c478bd9Sstevel@tonic-gate /* 66 */	KEY(15),	/* backspace */
4987c478bd9Sstevel@tonic-gate /* 67 */	KEY(131),	/* Japanese 106-key */
4997c478bd9Sstevel@tonic-gate /* 68 */	INVALID,
5007c478bd9Sstevel@tonic-gate /* 69 */	KEY(93),	/* 1 (num) */
5017c478bd9Sstevel@tonic-gate /* 6a */	KEY(14),	/* Japanese 106-key */
5027c478bd9Sstevel@tonic-gate /* 6b */	KEY(92),	/* 4 (num) */
5037c478bd9Sstevel@tonic-gate /* 6c */	KEY(91),	/* 7 (num) */
5047c478bd9Sstevel@tonic-gate /* 6d */	INVALID,
5057c478bd9Sstevel@tonic-gate /* 6e */	INVALID,
5067c478bd9Sstevel@tonic-gate /* 6f */	INVALID,
5077c478bd9Sstevel@tonic-gate /* 70 */	KEY(99),	/* 0 (num) */
5087c478bd9Sstevel@tonic-gate /* 71 */	KEY(104),	/* . (num) */
5097c478bd9Sstevel@tonic-gate /* 72 */	KEY(98),	/* 2 (num) */
5107c478bd9Sstevel@tonic-gate /* 73 */	KEY(97),	/* 5 (num) */
5117c478bd9Sstevel@tonic-gate /* 74 */	KEY(102),	/* 6 (num) */
5127c478bd9Sstevel@tonic-gate /* 75 */	KEY(96),	/* 8 (num) */
5137c478bd9Sstevel@tonic-gate /* 76 */	KEY(110),	/* Esc */
5147c478bd9Sstevel@tonic-gate /* 77 */	KEY(90),	/* NumLock */
5157c478bd9Sstevel@tonic-gate /* 78 */	KEY(122),	/* F11 */
5167c478bd9Sstevel@tonic-gate /* 79 */	KEY(106),	/* + (num) */
5177c478bd9Sstevel@tonic-gate /* 7a */	KEY(103),	/* 3 (num) */
5187c478bd9Sstevel@tonic-gate /* 7b */	KEY(105),	/* - (num) */
5197c478bd9Sstevel@tonic-gate /* 7c */	KEY(100),	/* * (num) */
5207c478bd9Sstevel@tonic-gate /* 7d */	KEY(101),	/* 9 (num) */
5217c478bd9Sstevel@tonic-gate /* 7e */	KEY(125),	/* Scroll Lock */
5227c478bd9Sstevel@tonic-gate /* 7f */	INVALID,	/* 84-key SysReq?  Manual says no. */
5237c478bd9Sstevel@tonic-gate /* 80 */	INVALID,
5247c478bd9Sstevel@tonic-gate /* 81 */	INVALID,
5257c478bd9Sstevel@tonic-gate /* 82 */	INVALID,
5267c478bd9Sstevel@tonic-gate /* 83 */	KEY(118),	/* F7 */
5277c478bd9Sstevel@tonic-gate /* 84 */	KEY(124),	/* PrintScreen (w/ Alt = SysRq) */
5287c478bd9Sstevel@tonic-gate };
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate /*
5317c478bd9Sstevel@tonic-gate  * Parse table after receiving an E0 prefix code.
5327c478bd9Sstevel@tonic-gate  *
5337c478bd9Sstevel@tonic-gate  * Generally speaking, keys that were added on the 101-key keyboard are
5347c478bd9Sstevel@tonic-gate  * represented as an E0 followed by the code for an 84-key key.  Software
5357c478bd9Sstevel@tonic-gate  * ignorant of the 101-key keyboard ignores the E0 and so is handled
5367c478bd9Sstevel@tonic-gate  * compatibly.  Many of these variants involve "fake" shift presses
5377c478bd9Sstevel@tonic-gate  * and releases for compatibility; these are also prefixed with E0.
5387c478bd9Sstevel@tonic-gate  * We ignore these fake shifts.
5397c478bd9Sstevel@tonic-gate  */
540fd9cb95cSsethg static const unsigned char	keytab_e0_set2[] = {
5417c478bd9Sstevel@tonic-gate /* 00 */	INVALID,
5427c478bd9Sstevel@tonic-gate /* 01 */	INVALID,
5437c478bd9Sstevel@tonic-gate /* 02 */	INVALID,
5447c478bd9Sstevel@tonic-gate /* 03 */	INVALID,
5457c478bd9Sstevel@tonic-gate /* 04 */	INVALID,
5467c478bd9Sstevel@tonic-gate /* 05 */	INVALID,
5477c478bd9Sstevel@tonic-gate /* 06 */	INVALID,
5487c478bd9Sstevel@tonic-gate /* 07 */	INVALID,
5497c478bd9Sstevel@tonic-gate /* 08 */	INVALID,
5507c478bd9Sstevel@tonic-gate /* 09 */	INVALID,
5517c478bd9Sstevel@tonic-gate /* 0a */	INVALID,
5527c478bd9Sstevel@tonic-gate /* 0b */	INVALID,
5537c478bd9Sstevel@tonic-gate /* 0c */	INVALID,
5547c478bd9Sstevel@tonic-gate /* 0d */	INVALID,
5557c478bd9Sstevel@tonic-gate /* 0e */	INVALID,
5567c478bd9Sstevel@tonic-gate /* 0f */	INVALID,
5577c478bd9Sstevel@tonic-gate /* 10 */	INVALID,
5587c478bd9Sstevel@tonic-gate /* 11 */	KEY(62),	/* R Alt */
5597c478bd9Sstevel@tonic-gate /* 12 */	IGNORE,		/* Fake L Shift */
5607c478bd9Sstevel@tonic-gate /* 13 */	INVALID,
5617c478bd9Sstevel@tonic-gate /* 14 */	KEY(64),	/* R Ctrl */
5627c478bd9Sstevel@tonic-gate /* 15 */	INVALID,
5637c478bd9Sstevel@tonic-gate /* 16 */	INVALID,
5647c478bd9Sstevel@tonic-gate /* 17 */	INVALID,
5657c478bd9Sstevel@tonic-gate /* 18 */	INVALID,
5667c478bd9Sstevel@tonic-gate /* 19 */	INVALID,
5677c478bd9Sstevel@tonic-gate /* 1a */	INVALID,
5687c478bd9Sstevel@tonic-gate /* 1b */	INVALID,
5697c478bd9Sstevel@tonic-gate /* 1c */	INVALID,
5707c478bd9Sstevel@tonic-gate /* 1d */	INVALID,
5717c478bd9Sstevel@tonic-gate /* 1e */	INVALID,
5727c478bd9Sstevel@tonic-gate /* 1f */	KEY(59),	/* L Window (104-key) */
5737c478bd9Sstevel@tonic-gate /* 20 */	INVALID,
5747c478bd9Sstevel@tonic-gate /* 21 */	INVALID,
5757c478bd9Sstevel@tonic-gate /* 22 */	INVALID,
5767c478bd9Sstevel@tonic-gate /* 23 */	INVALID,
5777c478bd9Sstevel@tonic-gate /* 24 */	INVALID,
5787c478bd9Sstevel@tonic-gate /* 25 */	INVALID,
5797c478bd9Sstevel@tonic-gate /* 26 */	INVALID,
5807c478bd9Sstevel@tonic-gate /* 27 */	KEY(63),	/* R Window (104-key) */
5817c478bd9Sstevel@tonic-gate /* 28 */	INVALID,
5827c478bd9Sstevel@tonic-gate /* 29 */	INVALID,
5837c478bd9Sstevel@tonic-gate /* 2a */	INVALID,
5847c478bd9Sstevel@tonic-gate /* 2b */	INVALID,
5857c478bd9Sstevel@tonic-gate /* 2c */	INVALID,
5867c478bd9Sstevel@tonic-gate /* 2d */	INVALID,
5877c478bd9Sstevel@tonic-gate /* 2e */	INVALID,
5887c478bd9Sstevel@tonic-gate /* 2f */	KEY(65),	/* Menu (104-key) */
5897c478bd9Sstevel@tonic-gate /* 30 */	INVALID,
5907c478bd9Sstevel@tonic-gate /* 31 */	INVALID,
5917c478bd9Sstevel@tonic-gate /* 32 */	INVALID,
5927c478bd9Sstevel@tonic-gate /* 33 */	INVALID,
5937c478bd9Sstevel@tonic-gate /* 34 */	INVALID,
5947c478bd9Sstevel@tonic-gate /* 35 */	INVALID,
5957c478bd9Sstevel@tonic-gate /* 36 */	INVALID,
5967c478bd9Sstevel@tonic-gate /* 37 */	INVALID,
5977c478bd9Sstevel@tonic-gate /* 38 */	INVALID,
5987c478bd9Sstevel@tonic-gate /* 39 */	INVALID,
5997c478bd9Sstevel@tonic-gate /* 3a */	INVALID,
6007c478bd9Sstevel@tonic-gate /* 3b */	INVALID,
6017c478bd9Sstevel@tonic-gate /* 3c */	INVALID,
6027c478bd9Sstevel@tonic-gate /* 3d */	INVALID,
6037c478bd9Sstevel@tonic-gate /* 3e */	INVALID,
6047c478bd9Sstevel@tonic-gate /* 3f */	INVALID,
6057c478bd9Sstevel@tonic-gate /* 40 */	INVALID,
6067c478bd9Sstevel@tonic-gate /* 41 */	INVALID,
6077c478bd9Sstevel@tonic-gate /* 42 */	INVALID,
6087c478bd9Sstevel@tonic-gate /* 43 */	INVALID,
6097c478bd9Sstevel@tonic-gate /* 44 */	INVALID,
6107c478bd9Sstevel@tonic-gate /* 45 */	INVALID,
6117c478bd9Sstevel@tonic-gate /* 46 */	INVALID,
6127c478bd9Sstevel@tonic-gate /* 47 */	INVALID,
6137c478bd9Sstevel@tonic-gate /* 48 */	INVALID,
6147c478bd9Sstevel@tonic-gate /* 49 */	INVALID,
6157c478bd9Sstevel@tonic-gate /* 4a */	KEY(95),	/* / (num) */
6167c478bd9Sstevel@tonic-gate /* 4b */	INVALID,
6177c478bd9Sstevel@tonic-gate /* 4c */	INVALID,
6187c478bd9Sstevel@tonic-gate /* 4d */	INVALID,
6197c478bd9Sstevel@tonic-gate /* 4e */	INVALID,
6207c478bd9Sstevel@tonic-gate /* 4f */	INVALID,
6217c478bd9Sstevel@tonic-gate /* 50 */	INVALID,
6227c478bd9Sstevel@tonic-gate /* 51 */	INVALID,
6237c478bd9Sstevel@tonic-gate /* 52 */	INVALID,
6247c478bd9Sstevel@tonic-gate /* 53 */	INVALID,
6257c478bd9Sstevel@tonic-gate /* 54 */	INVALID,
6267c478bd9Sstevel@tonic-gate /* 55 */	INVALID,
6277c478bd9Sstevel@tonic-gate /* 56 */	INVALID,
6287c478bd9Sstevel@tonic-gate /* 57 */	INVALID,
6297c478bd9Sstevel@tonic-gate /* 58 */	INVALID,
6307c478bd9Sstevel@tonic-gate /* 59 */	IGNORE,		/* Fake R Shift */
6317c478bd9Sstevel@tonic-gate /* 5a */	KEY(108),	/* Enter (num) */
6327c478bd9Sstevel@tonic-gate /* 5b */	INVALID,
6337c478bd9Sstevel@tonic-gate /* 5c */	INVALID,
6347c478bd9Sstevel@tonic-gate /* 5d */	INVALID,
6357c478bd9Sstevel@tonic-gate /* 5e */	INVALID,
6367c478bd9Sstevel@tonic-gate /* 5f */	INVALID,
6377c478bd9Sstevel@tonic-gate /* 60 */	INVALID,
6387c478bd9Sstevel@tonic-gate /* 61 */	INVALID,
6397c478bd9Sstevel@tonic-gate /* 62 */	INVALID,
6407c478bd9Sstevel@tonic-gate /* 63 */	INVALID,
6417c478bd9Sstevel@tonic-gate /* 64 */	INVALID,
6427c478bd9Sstevel@tonic-gate /* 65 */	INVALID,
6437c478bd9Sstevel@tonic-gate /* 66 */	INVALID,
6447c478bd9Sstevel@tonic-gate /* 67 */	INVALID,
6457c478bd9Sstevel@tonic-gate /* 68 */	INVALID,
6467c478bd9Sstevel@tonic-gate /* 69 */	KEY(81),	/* End (arrow) */
6477c478bd9Sstevel@tonic-gate /* 6a */	INVALID,
6487c478bd9Sstevel@tonic-gate /* 6b */	KEY(79),	/* Left (arrow) */
6497c478bd9Sstevel@tonic-gate /* 6c */	KEY(80),	/* Home (arrow) */
6507c478bd9Sstevel@tonic-gate /* 6d */	INVALID,
6517c478bd9Sstevel@tonic-gate /* 6e */	INVALID,
6527c478bd9Sstevel@tonic-gate /* 6f */	INVALID,
6537c478bd9Sstevel@tonic-gate /* 70 */	KEY(75),	/* Insert (arrow) */
6547c478bd9Sstevel@tonic-gate /* 71 */	KEY(76),	/* Delete (arrow) */
6557c478bd9Sstevel@tonic-gate /* 72 */	KEY(84),	/* Down (arrow) */
6567c478bd9Sstevel@tonic-gate /* 73 */	INVALID,
6577c478bd9Sstevel@tonic-gate /* 74 */	KEY(89),	/* Right (arrow) */
6587c478bd9Sstevel@tonic-gate /* 75 */	KEY(83),	/* Up (arrow) */
6597c478bd9Sstevel@tonic-gate /* 76 */	INVALID,
6607c478bd9Sstevel@tonic-gate /* 77 */	INVALID,
6617c478bd9Sstevel@tonic-gate /* 78 */	INVALID,
6627c478bd9Sstevel@tonic-gate /* 79 */	INVALID,
6637c478bd9Sstevel@tonic-gate /* 7a */	KEY(86),	/* PgDn (arrow) */
6647c478bd9Sstevel@tonic-gate /* 7b */	INVALID,
6657c478bd9Sstevel@tonic-gate /* 7c */	KEY(124),	/* PrintScreen (no Alt) */
6667c478bd9Sstevel@tonic-gate /* 7d */	KEY(85),	/* PgUp (arrow) */
6677c478bd9Sstevel@tonic-gate /* 7e */	KEY(126),	/* Pause (w/Ctrl = Break) */
6687c478bd9Sstevel@tonic-gate };
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate 
6717c478bd9Sstevel@tonic-gate /*
6727c478bd9Sstevel@tonic-gate  * Initialize the translation state machine.
6737c478bd9Sstevel@tonic-gate  */
674fd9cb95cSsethg int
KeyboardConvertScan_init(struct kb8042 * kb8042,int scanset)675fd9cb95cSsethg KeyboardConvertScan_init(struct kb8042 *kb8042, int scanset)
6767c478bd9Sstevel@tonic-gate {
6777c478bd9Sstevel@tonic-gate 	kb8042->parse_scan_state = STATE_IDLE;
678fd9cb95cSsethg 	kb8042->break_received = 0;
679fd9cb95cSsethg 
680fd9cb95cSsethg 	if (scanset == 1) {
681fd9cb95cSsethg 		KeyboardConvertScan_fn = &KeyboardConvertScan_set1;
682fd9cb95cSsethg 		keytab_base = keytab_base_set1;
683fd9cb95cSsethg 		keytab_base_length = NELEM(keytab_base_set1);
684fd9cb95cSsethg 		keytab_e0 = keytab_e0_set1;
685fd9cb95cSsethg 		keytab_e0_length = NELEM(keytab_e0_set1);
686fd9cb95cSsethg 	} else if (scanset == 2) {
687fd9cb95cSsethg 		KeyboardConvertScan_fn = &KeyboardConvertScan_set2;
688fd9cb95cSsethg 		keytab_base = keytab_base_set2;
689fd9cb95cSsethg 		keytab_base_length = NELEM(keytab_base_set2);
690fd9cb95cSsethg 		keytab_e0 = keytab_e0_set2;
691fd9cb95cSsethg 		keytab_e0_length = NELEM(keytab_e0_set2);
692fd9cb95cSsethg 	} else {
693fd9cb95cSsethg 		return (DDI_FAILURE);
694fd9cb95cSsethg 	}
695fd9cb95cSsethg 
696fd9cb95cSsethg 	return (DDI_SUCCESS);
697fd9cb95cSsethg }
698fd9cb95cSsethg 
6991841b879SSeth Goldberg /*
7001841b879SSeth Goldberg  *	KeyboardConvertScan(*kb8042, scan, *keynum, *state
7011841b879SSeth Goldberg  *		*synthetic_release_needed)
7021841b879SSeth Goldberg  *
7031841b879SSeth Goldberg  *	State machine that takes scan codes from the keyboard and resolves
7041841b879SSeth Goldberg  *	them to key numbers using the above tables.  Returns B_TRUE if this
7051841b879SSeth Goldberg  *	scan code completes a scan code sequence, in which case "keynum",
7061841b879SSeth Goldberg  *	"state", and "synthetic_release_needed" will be filled in correctly.
7071841b879SSeth Goldberg  *
7081841b879SSeth Goldberg  *	"synthetic_release_needed" is a hack to handle the additional two
7091841b879SSeth Goldberg  *	keys on a Korean keyboard.  They report press only, so we tell the
7101841b879SSeth Goldberg  *	upper layer to synthesize the release.
7111841b879SSeth Goldberg  */
712fd9cb95cSsethg boolean_t
KeyboardConvertScan(struct kb8042 * kb8042,unsigned char scan,int * keynum,enum keystate * state,boolean_t * synthetic_release_needed)713fd9cb95cSsethg KeyboardConvertScan(
714fd9cb95cSsethg     struct kb8042	*kb8042,
715fd9cb95cSsethg     unsigned char	scan,
716fd9cb95cSsethg     int			*keynum,
717fd9cb95cSsethg     enum keystate	*state,
718fd9cb95cSsethg     boolean_t		*synthetic_release_needed)
719fd9cb95cSsethg {
720fd9cb95cSsethg 	ASSERT(KeyboardConvertScan_fn != NULL);
721fd9cb95cSsethg 
722fd9cb95cSsethg 	return ((*KeyboardConvertScan_fn)(kb8042, scan, keynum, state,
723fd9cb95cSsethg 	    synthetic_release_needed));
7247c478bd9Sstevel@tonic-gate }
7257c478bd9Sstevel@tonic-gate 
7267c478bd9Sstevel@tonic-gate boolean_t
KeyboardConvertScan_set1(struct kb8042 * kb8042,unsigned char scan,int * keynum,enum keystate * state,boolean_t * synthetic_release_needed)727fd9cb95cSsethg KeyboardConvertScan_set1(
7287c478bd9Sstevel@tonic-gate     struct kb8042	*kb8042,
7297c478bd9Sstevel@tonic-gate     unsigned char	scan,
7307c478bd9Sstevel@tonic-gate     int			*keynum,
7317c478bd9Sstevel@tonic-gate     enum keystate	*state,
7327c478bd9Sstevel@tonic-gate     boolean_t		*synthetic_release_needed)
7337c478bd9Sstevel@tonic-gate {
7347c478bd9Sstevel@tonic-gate 	*synthetic_release_needed = B_FALSE;
7357c478bd9Sstevel@tonic-gate 	*state = KEY_PRESSED;
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate 	switch (scan) {
7387c478bd9Sstevel@tonic-gate 	/*
7397c478bd9Sstevel@tonic-gate 	 * First, handle special cases.
7407c478bd9Sstevel@tonic-gate 	 * ACK has already been handled by our caller.
7417c478bd9Sstevel@tonic-gate 	 */
7427c478bd9Sstevel@tonic-gate 	case KB_ERROR:
7437c478bd9Sstevel@tonic-gate 		/*
7447c478bd9Sstevel@tonic-gate 		 * Perhaps we should reset state here,
7457c478bd9Sstevel@tonic-gate 		 * since we no longer know what's going on.
7467c478bd9Sstevel@tonic-gate 		 */
7477c478bd9Sstevel@tonic-gate 		return (B_FALSE);
7487c478bd9Sstevel@tonic-gate 	case KB_POST_FAIL:
7497c478bd9Sstevel@tonic-gate 		/*
7507c478bd9Sstevel@tonic-gate 		 * Perhaps we should reset the LEDs now.
7517c478bd9Sstevel@tonic-gate 		 * If so, this check should probably be in the main line.
7527c478bd9Sstevel@tonic-gate 		 * Perhaps we should tell the higher layers that the
7537c478bd9Sstevel@tonic-gate 		 * keyboard has been reset.
7547c478bd9Sstevel@tonic-gate 		 */
7557c478bd9Sstevel@tonic-gate 		/*
7567c478bd9Sstevel@tonic-gate 		 * Reset to idle
7577c478bd9Sstevel@tonic-gate 		 */
7587c478bd9Sstevel@tonic-gate 		kb8042->parse_scan_state = STATE_IDLE;
7597c478bd9Sstevel@tonic-gate 		return (B_FALSE);
7607c478bd9Sstevel@tonic-gate 
7617c478bd9Sstevel@tonic-gate 	case KXT_EXTEND:
7627c478bd9Sstevel@tonic-gate 	case KXT_EXTEND2:
7637c478bd9Sstevel@tonic-gate 	case KXT_HANGUL_HANJA:
7647c478bd9Sstevel@tonic-gate 	case KXT_HANGUL:
7657c478bd9Sstevel@tonic-gate 		/*
7667c478bd9Sstevel@tonic-gate 		 * Exclude these keys from the "default" test below.
7677c478bd9Sstevel@tonic-gate 		 */
7687c478bd9Sstevel@tonic-gate 		break;
7697c478bd9Sstevel@tonic-gate 
7707c478bd9Sstevel@tonic-gate 	default:
7717c478bd9Sstevel@tonic-gate 		/*
7727c478bd9Sstevel@tonic-gate 		 * See if it was a key release.
7737c478bd9Sstevel@tonic-gate 		 */
7747c478bd9Sstevel@tonic-gate 		if (scan > 0x80) {
7757c478bd9Sstevel@tonic-gate 			*state = KEY_RELEASED;
7767c478bd9Sstevel@tonic-gate 			scan -= 0x80;
7777c478bd9Sstevel@tonic-gate 		}
7787c478bd9Sstevel@tonic-gate 		break;
7797c478bd9Sstevel@tonic-gate 	}
7807c478bd9Sstevel@tonic-gate 
781fd9cb95cSsethg 	if (kb8042->break_received) {
782fd9cb95cSsethg 		*state = KEY_RELEASED;
783fd9cb95cSsethg 		kb8042->break_received = 0;
784fd9cb95cSsethg 	}
785fd9cb95cSsethg 
7867c478bd9Sstevel@tonic-gate 	switch (kb8042->parse_scan_state) {
7877c478bd9Sstevel@tonic-gate 	case STATE_IDLE:
7887c478bd9Sstevel@tonic-gate 		switch (scan) {
7897c478bd9Sstevel@tonic-gate 		case KXT_EXTEND:
7907c478bd9Sstevel@tonic-gate 			kb8042->parse_scan_state = STATE_E0;
7917c478bd9Sstevel@tonic-gate 			return (B_FALSE);
7927c478bd9Sstevel@tonic-gate 
7937c478bd9Sstevel@tonic-gate 		case KXT_EXTEND2:
7947c478bd9Sstevel@tonic-gate 			kb8042->parse_scan_state = STATE_E1;
7957c478bd9Sstevel@tonic-gate 			return (B_FALSE);
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate 		/*
7987c478bd9Sstevel@tonic-gate 		 * We could do the next two in the table, but it would
7997c478bd9Sstevel@tonic-gate 		 * require nearly doubling the size of the table.
8007c478bd9Sstevel@tonic-gate 		 *
8017c478bd9Sstevel@tonic-gate 		 * Also, for some stupid reason these two report presses
8027c478bd9Sstevel@tonic-gate 		 * only.  We tell the upper layer to synthesize a release.
8037c478bd9Sstevel@tonic-gate 		 */
8047c478bd9Sstevel@tonic-gate 		case KXT_HANGUL_HANJA:
8057c478bd9Sstevel@tonic-gate 			*keynum = KEY(150);
8067c478bd9Sstevel@tonic-gate 			*synthetic_release_needed = B_TRUE;
8077c478bd9Sstevel@tonic-gate 			break;
8087c478bd9Sstevel@tonic-gate 
8097c478bd9Sstevel@tonic-gate 		case KXT_HANGUL:
8107c478bd9Sstevel@tonic-gate 			*keynum = KEY(151);
8117c478bd9Sstevel@tonic-gate 			*synthetic_release_needed = B_TRUE;
8127c478bd9Sstevel@tonic-gate 			break;
8137c478bd9Sstevel@tonic-gate 
8147c478bd9Sstevel@tonic-gate 		default:
8157c478bd9Sstevel@tonic-gate 			/*
8167c478bd9Sstevel@tonic-gate 			 * Regular scan code
8177c478bd9Sstevel@tonic-gate 			 */
818fd9cb95cSsethg 			if (scan < keytab_base_length)
8197c478bd9Sstevel@tonic-gate 				*keynum = keytab_base[scan];
8207c478bd9Sstevel@tonic-gate 			else
8217c478bd9Sstevel@tonic-gate 				*keynum = INVALID;
8227c478bd9Sstevel@tonic-gate 			break;
8237c478bd9Sstevel@tonic-gate 		}
8247c478bd9Sstevel@tonic-gate 		break;
8257c478bd9Sstevel@tonic-gate 
8267c478bd9Sstevel@tonic-gate 	case STATE_E0:		/* Mostly 101-key additions */
827fd9cb95cSsethg 		if (scan < keytab_e0_length)
8287c478bd9Sstevel@tonic-gate 			*keynum = keytab_e0[scan];
8297c478bd9Sstevel@tonic-gate 		else
8307c478bd9Sstevel@tonic-gate 			*keynum = INVALID;
8317c478bd9Sstevel@tonic-gate 		break;
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate 	case STATE_E1:		/* Pause key only */
8347c478bd9Sstevel@tonic-gate 		switch (scan) {
8357c478bd9Sstevel@tonic-gate 		case 0x1d:
8367c478bd9Sstevel@tonic-gate 			kb8042->parse_scan_state = STATE_E1_1D;
8377c478bd9Sstevel@tonic-gate 			return (B_FALSE);
8387c478bd9Sstevel@tonic-gate 		default:
8397c478bd9Sstevel@tonic-gate 			*keynum = INVALID;
8407c478bd9Sstevel@tonic-gate 			break;
8417c478bd9Sstevel@tonic-gate 		}
8427c478bd9Sstevel@tonic-gate 		break;
8437c478bd9Sstevel@tonic-gate 
8447c478bd9Sstevel@tonic-gate 	case STATE_E1_1D:	/* Pause key only */
8457c478bd9Sstevel@tonic-gate 		switch (scan) {
8467c478bd9Sstevel@tonic-gate 		case 0x45:
8477c478bd9Sstevel@tonic-gate 			*keynum = KEY(126);	/* Pause */
8487c478bd9Sstevel@tonic-gate 			break;
8497c478bd9Sstevel@tonic-gate 		default:
8507c478bd9Sstevel@tonic-gate 			*keynum = INVALID;
8517c478bd9Sstevel@tonic-gate 			break;
8527c478bd9Sstevel@tonic-gate 		}
8537c478bd9Sstevel@tonic-gate 		break;
854fd9cb95cSsethg 	}
855fd9cb95cSsethg 
856fd9cb95cSsethg 	/*
857fd9cb95cSsethg 	 * The results (*keynum, *state, and *synthetic_release_needed)
858fd9cb95cSsethg 	 * have been filled in, but they are valid only if we return
859fd9cb95cSsethg 	 * B_TRUE which is only done below.  If we make it to here, we
860fd9cb95cSsethg 	 * have completed a scan code sequence, so reset parse_scan_state.
861fd9cb95cSsethg 	 */
862fd9cb95cSsethg 
863fd9cb95cSsethg 	kb8042->parse_scan_state = STATE_IDLE;
864fd9cb95cSsethg 
865fd9cb95cSsethg 	switch (*keynum) {
866fd9cb95cSsethg 	case KEYIGN:				/* not a key, nor an error */
867fd9cb95cSsethg 		return (B_FALSE);		/* also not a final keycode */
868fd9cb95cSsethg 
869fd9cb95cSsethg 	case KEYBAD:		/* not part of a legit sequence? */
870fd9cb95cSsethg 		return (B_FALSE);	/* and return not a final keycode */
871fd9cb95cSsethg 
872fd9cb95cSsethg 	default:
873fd9cb95cSsethg 		/*
874fd9cb95cSsethg 		 * If we're here, it's a valid keycode.  We've already
875fd9cb95cSsethg 		 * filled in the return values; return success.
876fd9cb95cSsethg 		 */
877fd9cb95cSsethg 		return (B_TRUE);		/* resolved to a key */
878fd9cb95cSsethg 	}
879fd9cb95cSsethg }
880fd9cb95cSsethg 
881fd9cb95cSsethg /*
882fd9cb95cSsethg  *	KeyboardConvertScan(*kb8042, scan, *keynum, *state
883fd9cb95cSsethg  *		*synthetic_release_needed)
884fd9cb95cSsethg  *
885fd9cb95cSsethg  *	State machine that takes scan codes from the keyboard and resolves
886fd9cb95cSsethg  *	them to key numbers using the above tables.  Returns B_TRUE if this
887fd9cb95cSsethg  *	scan code completes a scan code sequence, in which case "keynum",
888fd9cb95cSsethg  *	"state", and "synthetic_release_needed" will be filled in correctly.
889fd9cb95cSsethg  *
890fd9cb95cSsethg  *	"synthetic_release_needed" is a hack to handle the additional two
891fd9cb95cSsethg  *	keys on a Korean keyboard.  They report press only, so we tell the
892fd9cb95cSsethg  *	upper layer to synthesize the release.
893fd9cb95cSsethg  */
894fd9cb95cSsethg boolean_t
KeyboardConvertScan_set2(struct kb8042 * kb8042,unsigned char scan,int * keynum,enum keystate * state,boolean_t * synthetic_release_needed)895fd9cb95cSsethg KeyboardConvertScan_set2(
896fd9cb95cSsethg     struct kb8042	*kb8042,
897fd9cb95cSsethg     unsigned char	scan,
898fd9cb95cSsethg     int			*keynum,
899fd9cb95cSsethg     enum keystate	*state,
900fd9cb95cSsethg     boolean_t		*synthetic_release_needed)
901fd9cb95cSsethg {
902fd9cb95cSsethg 	*synthetic_release_needed = B_FALSE;
903fd9cb95cSsethg 	*state = KEY_PRESSED;
904fd9cb95cSsethg 
905fd9cb95cSsethg 	switch (scan) {
906fd9cb95cSsethg 	/*
907fd9cb95cSsethg 	 * First, handle special cases.
908fd9cb95cSsethg 	 * ACK has already been handled by our caller.
909fd9cb95cSsethg 	 */
910fd9cb95cSsethg 
911fd9cb95cSsethg 	/*
912fd9cb95cSsethg 	 * KAT_BREAK is 0xF0. It is the same as the break code for Japanese
913fd9cb95cSsethg 	 * key 133.
914fd9cb95cSsethg 	 * Therefore we don't treat it specially here.
915fd9cb95cSsethg 	 */
916fd9cb95cSsethg 	case KAT_BREAK:
917fd9cb95cSsethg 		/* Switch states so we can recognize the code that follows */
918fd9cb95cSsethg 		kb8042->break_received = 1;
919fd9cb95cSsethg 		return (B_FALSE);	/* not a final keycode */
920fd9cb95cSsethg 
921fd9cb95cSsethg 	case KB_ERROR:
922fd9cb95cSsethg 		/*
923fd9cb95cSsethg 		 * Perhaps we should reset state here,
924fd9cb95cSsethg 		 * since we no longer know what's going on.
925fd9cb95cSsethg 		 */
926fd9cb95cSsethg 		return (B_FALSE);
927fd9cb95cSsethg 
928fd9cb95cSsethg 	case KB_POST_OK:
929fd9cb95cSsethg 	case KB_POST_FAIL:
930fd9cb95cSsethg 		/*
931fd9cb95cSsethg 		 * Perhaps we should reset the LEDs now.
932fd9cb95cSsethg 		 * If so, this check should probably be in the main line.
933fd9cb95cSsethg 		 * Perhaps we should tell the higher layers that the
934fd9cb95cSsethg 		 * keyboard has been reset.
935fd9cb95cSsethg 		 */
936fd9cb95cSsethg 		/*
937fd9cb95cSsethg 		 * Reset to idle
938fd9cb95cSsethg 		 */
939fd9cb95cSsethg 		kb8042->parse_scan_state = STATE_IDLE;
940fd9cb95cSsethg 		return (B_FALSE);
941fd9cb95cSsethg 	}
942fd9cb95cSsethg 
943fd9cb95cSsethg 	if (kb8042->break_received) {
944fd9cb95cSsethg 		*state = KEY_RELEASED;
945fd9cb95cSsethg 		kb8042->break_received = 0;
946fd9cb95cSsethg 	}
947fd9cb95cSsethg 
948fd9cb95cSsethg 	switch (kb8042->parse_scan_state) {
949fd9cb95cSsethg 	case STATE_IDLE:
9507c478bd9Sstevel@tonic-gate 		switch (scan) {
951fd9cb95cSsethg 		case KXT_EXTEND:
952fd9cb95cSsethg 			kb8042->parse_scan_state = STATE_E0;
953fd9cb95cSsethg 			return (B_FALSE);
954fd9cb95cSsethg 
955fd9cb95cSsethg 		case KXT_EXTEND2:
956fd9cb95cSsethg 			kb8042->parse_scan_state = STATE_E1;
957fd9cb95cSsethg 			return (B_FALSE);
958fd9cb95cSsethg 
959fd9cb95cSsethg 		/*
960fd9cb95cSsethg 		 * We could do the next two in the table, but it would
961fd9cb95cSsethg 		 * require nearly doubling the size of the table.
962fd9cb95cSsethg 		 *
963fd9cb95cSsethg 		 * Also, for some stupid reason these two report presses
964fd9cb95cSsethg 		 * only.  We tell the upper layer to synthesize a release.
965fd9cb95cSsethg 		 */
966fd9cb95cSsethg 		case KXT_HANGUL_HANJA:
967fd9cb95cSsethg 			*keynum = KEY(150);
968fd9cb95cSsethg 			*synthetic_release_needed = B_TRUE;
969fd9cb95cSsethg 			break;
970fd9cb95cSsethg 
971fd9cb95cSsethg 		case KXT_HANGUL:
972fd9cb95cSsethg 			*keynum = KEY(151);
973fd9cb95cSsethg 			*synthetic_release_needed = B_TRUE;
974fd9cb95cSsethg 			break;
975fd9cb95cSsethg 
976fd9cb95cSsethg 		default:
977fd9cb95cSsethg 			/*
978fd9cb95cSsethg 			 * Regular scan code
979fd9cb95cSsethg 			 */
980fd9cb95cSsethg 			if (scan < keytab_base_length)
981fd9cb95cSsethg 				*keynum = keytab_base[scan];
982fd9cb95cSsethg 			else
983fd9cb95cSsethg 				*keynum = INVALID;
9847c478bd9Sstevel@tonic-gate 			break;
985fd9cb95cSsethg 		}
986fd9cb95cSsethg 		break;
987fd9cb95cSsethg 
988fd9cb95cSsethg 	case STATE_E0:		/* Mostly 101-key additions */
989fd9cb95cSsethg 		if (scan < keytab_e0_length)
990fd9cb95cSsethg 			*keynum = keytab_e0[scan];
991fd9cb95cSsethg 		else
992fd9cb95cSsethg 			*keynum = INVALID;
993fd9cb95cSsethg 		break;
994fd9cb95cSsethg 
995fd9cb95cSsethg 	case STATE_E1:		/* Pause key only */
996fd9cb95cSsethg 		switch (scan) {
997fd9cb95cSsethg 		case 0x14:
998fd9cb95cSsethg 			kb8042->parse_scan_state = STATE_E1_14;
999fd9cb95cSsethg 			return (B_FALSE);
10007c478bd9Sstevel@tonic-gate 		default:
10017c478bd9Sstevel@tonic-gate 			*keynum = INVALID;
10027c478bd9Sstevel@tonic-gate 			break;
10037c478bd9Sstevel@tonic-gate 		}
10047c478bd9Sstevel@tonic-gate 		break;
1005fd9cb95cSsethg 
1006fd9cb95cSsethg 	case STATE_E1_14:	/* Pause key only */
1007fd9cb95cSsethg 		if (scan == 0x77) {
1008fd9cb95cSsethg 			kb8042->parse_scan_state = STATE_E1_14_77;
1009fd9cb95cSsethg 			return (B_FALSE);
1010fd9cb95cSsethg 		} else {
1011fd9cb95cSsethg 			*keynum = INVALID;
1012fd9cb95cSsethg 		}
1013fd9cb95cSsethg 		break;
1014fd9cb95cSsethg 
1015fd9cb95cSsethg 	case STATE_E1_14_77:
1016fd9cb95cSsethg 		if (scan == 0xE1) {
1017fd9cb95cSsethg 			kb8042->parse_scan_state = STATE_E1_14_77_E1;
1018fd9cb95cSsethg 			return (B_FALSE);
1019fd9cb95cSsethg 		} else {
1020fd9cb95cSsethg 			*keynum = INVALID;
1021fd9cb95cSsethg 		}
1022fd9cb95cSsethg 		break;
1023fd9cb95cSsethg 
1024fd9cb95cSsethg 	case STATE_E1_14_77_E1:
1025fd9cb95cSsethg 		if (scan == 0xF0) {
1026fd9cb95cSsethg 			kb8042->parse_scan_state = STATE_E1_14_77_E1_F0;
1027fd9cb95cSsethg 			return (B_FALSE);
1028fd9cb95cSsethg 		} else {
1029fd9cb95cSsethg 			*keynum = INVALID;
1030fd9cb95cSsethg 		}
1031fd9cb95cSsethg 		break;
1032fd9cb95cSsethg 
1033fd9cb95cSsethg 	case STATE_E1_14_77_E1_F0:
1034fd9cb95cSsethg 		if (scan == 0x14) {
1035fd9cb95cSsethg 			kb8042->parse_scan_state = STATE_E1_14_77_E1_F0_14;
1036fd9cb95cSsethg 			return (B_FALSE);
1037fd9cb95cSsethg 		} else {
1038fd9cb95cSsethg 			*keynum = INVALID;
1039fd9cb95cSsethg 		}
1040fd9cb95cSsethg 		break;
1041fd9cb95cSsethg 
1042fd9cb95cSsethg 	case STATE_E1_14_77_E1_F0_14:
1043fd9cb95cSsethg 		if (scan == 0xF0) {
1044fd9cb95cSsethg 			kb8042->parse_scan_state = STATE_E1_14_77_E1_F0_14_F0;
1045fd9cb95cSsethg 			return (B_FALSE);
1046fd9cb95cSsethg 		} else {
1047fd9cb95cSsethg 			*keynum = INVALID;
1048fd9cb95cSsethg 		}
1049fd9cb95cSsethg 		break;
1050fd9cb95cSsethg 
1051fd9cb95cSsethg 	case STATE_E1_14_77_E1_F0_14_F0:
1052fd9cb95cSsethg 		if (scan == 0x77) {
1053fd9cb95cSsethg 			*keynum = KEY(126);	/* Pause */
1054fd9cb95cSsethg 		} else {
1055fd9cb95cSsethg 			*keynum = INVALID;
1056fd9cb95cSsethg 		}
1057fd9cb95cSsethg 		break;
10587c478bd9Sstevel@tonic-gate 	}
10597c478bd9Sstevel@tonic-gate 
10607c478bd9Sstevel@tonic-gate 	/*
10617c478bd9Sstevel@tonic-gate 	 * The results (*keynum, *state, and *synthetic_release_needed)
10627c478bd9Sstevel@tonic-gate 	 * have been filled in, but they are valid only if we return
10637c478bd9Sstevel@tonic-gate 	 * B_TRUE which is only done below.  If we make it to here, we
10647c478bd9Sstevel@tonic-gate 	 * have completed a scan code sequence, so reset parse_scan_state.
10657c478bd9Sstevel@tonic-gate 	 */
10667c478bd9Sstevel@tonic-gate 
1067fd9cb95cSsethg 	if (kb8042->break_received) {
1068fd9cb95cSsethg 		*state = KEY_RELEASED;
1069fd9cb95cSsethg 		kb8042->break_received = 0;
1070fd9cb95cSsethg 	}
1071fd9cb95cSsethg 
10727c478bd9Sstevel@tonic-gate 	kb8042->parse_scan_state = STATE_IDLE;
10737c478bd9Sstevel@tonic-gate 
10747c478bd9Sstevel@tonic-gate 	switch (*keynum) {
10757c478bd9Sstevel@tonic-gate 	case KEYIGN:				/* not a key, nor an error */
10767c478bd9Sstevel@tonic-gate 		return (B_FALSE);		/* also not a final keycode */
10777c478bd9Sstevel@tonic-gate 
10787c478bd9Sstevel@tonic-gate 	case KEYBAD:		/* not part of a legit sequence? */
10797c478bd9Sstevel@tonic-gate 		return (B_FALSE);	/* and return not a final keycode */
10807c478bd9Sstevel@tonic-gate 
10817c478bd9Sstevel@tonic-gate 	default:
10827c478bd9Sstevel@tonic-gate 		/*
10837c478bd9Sstevel@tonic-gate 		 * If we're here, it's a valid keycode.  We've already
10847c478bd9Sstevel@tonic-gate 		 * filled in the return values; return success.
10857c478bd9Sstevel@tonic-gate 		 */
10867c478bd9Sstevel@tonic-gate 		return (B_TRUE);		/* resolved to a key */
10877c478bd9Sstevel@tonic-gate 	}
10887c478bd9Sstevel@tonic-gate }
1089