xref: /onnv-gate/usr/src/uts/common/io/kb8042/at_keyprocess.c (revision 10087:45644b99daec)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
59026SSeth.Goldberg@Sun.COM  * Common Development and Distribution License (the "License").
6*9027SSeth.Goldberg@Sun.COM  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
229026SSeth.Goldberg@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #include <sys/types.h>
270Sstevel@tonic-gate #include <sys/stream.h>
280Sstevel@tonic-gate #include <sys/kbd.h>
290Sstevel@tonic-gate #include <sys/kbtrans.h>
300Sstevel@tonic-gate #include <sys/sunddi.h>
310Sstevel@tonic-gate #include <sys/consdev.h>
320Sstevel@tonic-gate #include <sys/promif.h>
330Sstevel@tonic-gate #include "kb8042.h"
340Sstevel@tonic-gate 
350Sstevel@tonic-gate /*
360Sstevel@tonic-gate  * A note on the use of prom_printf here:  Most of these routines can be
370Sstevel@tonic-gate  * called from "polled mode", where we're servicing I/O requests from kmdb.
380Sstevel@tonic-gate  * Normal system services are not available from polled mode; cmn_err will
390Sstevel@tonic-gate  * not work.  prom_printf is the only safe output mechanism.
400Sstevel@tonic-gate  */
410Sstevel@tonic-gate 
420Sstevel@tonic-gate #define	KEYBAD		0xff		/* should generate an error */
430Sstevel@tonic-gate #define	KEYIGN		0xfe		/* ignore this sequence */
440Sstevel@tonic-gate 
450Sstevel@tonic-gate #define	KEY(code)	(code)
460Sstevel@tonic-gate #define	INVALID		KEYBAD
470Sstevel@tonic-gate #define	IGNORE		KEYIGN
480Sstevel@tonic-gate 
49822Ssethg #define	NELEM(a)	(sizeof (a) / sizeof (a)[0])
50822Ssethg 
510Sstevel@tonic-gate /*
520Sstevel@tonic-gate  * These are the states of our parsing machine:
530Sstevel@tonic-gate  */
54822Ssethg #define	STATE_IDLE	0x00000001 /* Awaiting the start of a sequence */
55822Ssethg #define	STATE_E0	0x00000002 /* Rec'd an E0 */
56822Ssethg #define	STATE_E1	0x00000004 /* Rec'd an E1 (Pause key only) */
57822Ssethg #define	STATE_E1_1D	0x00000008 /* Rec'd an E1 1D (Pause key only) */
58822Ssethg #define	STATE_E1_14	0x00000010 /* Rec'd an E1 14 (Pause key only) */
59822Ssethg #define	STATE_E1_14_77			0x00000020
60822Ssethg #define	STATE_E1_14_77_E1		0x00000040
61822Ssethg #define	STATE_E1_14_77_E1_F0		0x00000080
62822Ssethg #define	STATE_E1_14_77_E1_F0_14		0x00000100
63822Ssethg #define	STATE_E1_14_77_E1_F0_14_F0	0x00000200
640Sstevel@tonic-gate 
65822Ssethg static boolean_t KeyboardConvertScan_set1(struct kb8042	*, unsigned char, int *,
66822Ssethg     enum keystate *, boolean_t *);
67822Ssethg static boolean_t KeyboardConvertScan_set2(struct kb8042	*, unsigned char, int *,
68822Ssethg     enum keystate *, boolean_t *);
690Sstevel@tonic-gate 
70822Ssethg static const unsigned char *keytab_base = NULL;
71822Ssethg static int keytab_base_length = 0;
72822Ssethg static const unsigned char *keytab_e0 = NULL;
73822Ssethg static int keytab_e0_length = 0;
74822Ssethg static boolean_t (*KeyboardConvertScan_fn)(struct kb8042 *, unsigned char,
75822Ssethg     int *, enum keystate *, boolean_t *) = NULL;
76822Ssethg 
77822Ssethg static const unsigned char	keytab_base_set1[] = {
780Sstevel@tonic-gate /* scan		key number	keycap */
790Sstevel@tonic-gate /* 00 */	INVALID,
800Sstevel@tonic-gate /* 01 */	KEY(110),	/* Esc */
810Sstevel@tonic-gate /* 02 */	KEY(2),		/* 1 */
820Sstevel@tonic-gate /* 03 */	KEY(3),		/* 2 */
830Sstevel@tonic-gate /* 04 */	KEY(4),		/* 3 */
840Sstevel@tonic-gate /* 05 */	KEY(5),		/* 4 */
850Sstevel@tonic-gate /* 06 */	KEY(6),		/* 5 */
860Sstevel@tonic-gate /* 07 */	KEY(7),		/* 6 */
870Sstevel@tonic-gate /* 08 */	KEY(8),		/* 7 */
880Sstevel@tonic-gate /* 09 */	KEY(9),		/* 8 */
890Sstevel@tonic-gate /* 0a */	KEY(10),	/* 9 */
900Sstevel@tonic-gate /* 0b */	KEY(11),	/* 0 */
910Sstevel@tonic-gate /* 0c */	KEY(12),	/* - */
920Sstevel@tonic-gate /* 0d */	KEY(13),	/* = */
930Sstevel@tonic-gate /* 0e */	KEY(15),	/* backspace */
940Sstevel@tonic-gate /* 0f */	KEY(16),	/* tab */
950Sstevel@tonic-gate 
960Sstevel@tonic-gate /* 10 */	KEY(17),	/* Q */
970Sstevel@tonic-gate /* 11 */	KEY(18),	/* W */
980Sstevel@tonic-gate /* 12 */	KEY(19),	/* E */
990Sstevel@tonic-gate /* 13 */	KEY(20),	/* R */
1000Sstevel@tonic-gate /* 14 */	KEY(21),	/* T */
1010Sstevel@tonic-gate /* 15 */	KEY(22),	/* Y */
1020Sstevel@tonic-gate /* 16 */	KEY(23),	/* U */
1030Sstevel@tonic-gate /* 17 */	KEY(24),	/* I */
1040Sstevel@tonic-gate /* 18 */	KEY(25),	/* O */
1050Sstevel@tonic-gate /* 19 */	KEY(26),	/* P */
1060Sstevel@tonic-gate /* 1a */	KEY(27),	/* [ */
1070Sstevel@tonic-gate /* 1b */	KEY(28),	/* ] */
1080Sstevel@tonic-gate /* 1c */	KEY(43),	/* Enter (main) */
1090Sstevel@tonic-gate /* 1d */	KEY(58),	/* L Ctrl */
1100Sstevel@tonic-gate /* 1e */	KEY(31),	/* A */
1110Sstevel@tonic-gate /* 1f */	KEY(32),	/* S */
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate /* 20 */	KEY(33),	/* D */
1140Sstevel@tonic-gate /* 21 */	KEY(34),	/* F */
1150Sstevel@tonic-gate /* 22 */	KEY(35),	/* G */
1160Sstevel@tonic-gate /* 23 */	KEY(36),	/* H */
1170Sstevel@tonic-gate /* 24 */	KEY(37),	/* J */
1180Sstevel@tonic-gate /* 25 */	KEY(38),	/* K */
1190Sstevel@tonic-gate /* 26 */	KEY(39),	/* L */
1200Sstevel@tonic-gate /* 27 */	KEY(40),	/* ; */
1210Sstevel@tonic-gate /* 28 */	KEY(41),	/* ' */
1220Sstevel@tonic-gate /* 29 */	KEY(1),		/* ` */
1230Sstevel@tonic-gate /* 2a */	KEY(44),	/* L Shift */
1240Sstevel@tonic-gate /* 2b */	KEY(29),	/* \ */
1250Sstevel@tonic-gate /* 2c */	KEY(46),	/* Z */
1260Sstevel@tonic-gate /* 2d */	KEY(47),	/* X */
1270Sstevel@tonic-gate /* 2e */	KEY(48),	/* C */
1280Sstevel@tonic-gate /* 2f */	KEY(49),	/* V */
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate /* 30 */	KEY(50),	/* B */
1310Sstevel@tonic-gate /* 31 */	KEY(51),	/* N */
1320Sstevel@tonic-gate /* 32 */	KEY(52),	/* M */
1330Sstevel@tonic-gate /* 33 */	KEY(53),	/* , */
1340Sstevel@tonic-gate /* 34 */	KEY(54),	/* . */
1350Sstevel@tonic-gate /* 35 */	KEY(55),	/* / */
1360Sstevel@tonic-gate /* 36 */	KEY(57),	/* R Shift */
1370Sstevel@tonic-gate /* 37 */	KEY(100),	/* * (num) */
1380Sstevel@tonic-gate /* 38 */	KEY(60),	/* L Alt */
1390Sstevel@tonic-gate /* 39 */	KEY(61),	/* Space */
1400Sstevel@tonic-gate /* 3a */	KEY(30),	/* CapsLock */
1410Sstevel@tonic-gate /* 3b */	KEY(112),	/* F1 */
1420Sstevel@tonic-gate /* 3c */	KEY(113),	/* F2 */
1430Sstevel@tonic-gate /* 3d */	KEY(114),	/* F3 */
1440Sstevel@tonic-gate /* 3e */	KEY(115),	/* F4 */
1450Sstevel@tonic-gate /* 3f */	KEY(116),	/* F5 */
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate /* 40 */	KEY(117),	/* F6 */
1480Sstevel@tonic-gate /* 41 */	KEY(118),	/* F7 */
1490Sstevel@tonic-gate /* 42 */	KEY(119),	/* F8 */
1500Sstevel@tonic-gate /* 43 */	KEY(120),	/* F9 */
1510Sstevel@tonic-gate /* 44 */	KEY(121),	/* F10 */
1520Sstevel@tonic-gate /* 45 */	KEY(90),	/* NumLock */
1530Sstevel@tonic-gate /* 46 */	KEY(125),	/* Scroll Lock */
1540Sstevel@tonic-gate /* 47 */	KEY(91),	/* 7 (num) */
1550Sstevel@tonic-gate /* 48 */	KEY(96),	/* 8 (num) */
1560Sstevel@tonic-gate /* 49 */	KEY(101),	/* 9 (num) */
1570Sstevel@tonic-gate /* 4a */	KEY(105),	/* - (num) */
1580Sstevel@tonic-gate /* 4b */	KEY(92),	/* 4 (num) */
1590Sstevel@tonic-gate /* 4c */	KEY(97),	/* 5 (num) */
1600Sstevel@tonic-gate /* 4d */	KEY(102),	/* 6 (num) */
1610Sstevel@tonic-gate /* 4e */	KEY(106),	/* + (num) */
1620Sstevel@tonic-gate /* 4f */	KEY(93),	/* 1 (num) */
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate /* 50 */	KEY(98),	/* 2 (num) */
1650Sstevel@tonic-gate /* 51 */	KEY(103),	/* 3 (num) */
1660Sstevel@tonic-gate /* 52 */	KEY(99),	/* 0 (num) */
1670Sstevel@tonic-gate /* 53 */	KEY(104),	/* . (num) */
1680Sstevel@tonic-gate /* 54 */	KEY(124),	/* PrintScreen (with Alt) */
1690Sstevel@tonic-gate /* 55 */	INVALID,
1700Sstevel@tonic-gate /* 56 */	KEY(45),	/* not labled (102-key only) */
1710Sstevel@tonic-gate /* 57 */	KEY(122),	/* F11 */
1720Sstevel@tonic-gate /* 58 */	KEY(123),	/* F12 */
1730Sstevel@tonic-gate /* 59 */	INVALID,
1740Sstevel@tonic-gate /* 5a */	INVALID,
1750Sstevel@tonic-gate /* 5b */	INVALID,
1760Sstevel@tonic-gate /* 5c */	INVALID,
1770Sstevel@tonic-gate /* 5d */	INVALID,
1780Sstevel@tonic-gate /* 5e */	INVALID,
1790Sstevel@tonic-gate /* 5f */	INVALID,
1800Sstevel@tonic-gate 
1810Sstevel@tonic-gate /* 60 */	INVALID,
1820Sstevel@tonic-gate /* 61 */	INVALID,
1830Sstevel@tonic-gate /* 62 */	INVALID,
1840Sstevel@tonic-gate /* 63 */	INVALID,
1850Sstevel@tonic-gate /* 64 */	INVALID,
1860Sstevel@tonic-gate /* 65 */	INVALID,
1870Sstevel@tonic-gate /* 66 */	INVALID,
1880Sstevel@tonic-gate /* 67 */	INVALID,
1890Sstevel@tonic-gate /* 68 */	INVALID,
1900Sstevel@tonic-gate /* 69 */	INVALID,
1910Sstevel@tonic-gate /* 6a */	INVALID,
1920Sstevel@tonic-gate /* 6b */	INVALID,
1930Sstevel@tonic-gate /* 6c */	INVALID,
1940Sstevel@tonic-gate /* 6d */	INVALID,
1950Sstevel@tonic-gate /* 6e */	INVALID,
1960Sstevel@tonic-gate /* 6f */	INVALID,
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate /* 70 */	KEY(133),	/* Japanese 106-key keyboard */
1990Sstevel@tonic-gate /* 71 */	INVALID,
2000Sstevel@tonic-gate /* 72 */	INVALID,
2010Sstevel@tonic-gate /* 73 */	KEY(56),	/* Japanese 106-key keyboard */
2020Sstevel@tonic-gate /* 74 */	INVALID,
2030Sstevel@tonic-gate /* 75 */	INVALID,
2040Sstevel@tonic-gate /* 76 */	INVALID,
2050Sstevel@tonic-gate /* 77 */	INVALID,
2060Sstevel@tonic-gate /* 78 */	INVALID,
2070Sstevel@tonic-gate /* 79 */	KEY(132),	/* Japanese 106-key keyboard */
2080Sstevel@tonic-gate /* 7a */	INVALID,
2090Sstevel@tonic-gate /* 7b */	KEY(131),	/* Japanese 106-key keyboard */
2100Sstevel@tonic-gate /* 7c */	INVALID,
2110Sstevel@tonic-gate /* 7d */	KEY(14),	/* Japanese 106-key keyboard */
2120Sstevel@tonic-gate /* 7e */	INVALID,
2130Sstevel@tonic-gate /* 7f */	INVALID,
2140Sstevel@tonic-gate };
2150Sstevel@tonic-gate 
2160Sstevel@tonic-gate /*
2170Sstevel@tonic-gate  * Parse table after receiving an E0 prefix code.
2180Sstevel@tonic-gate  *
2190Sstevel@tonic-gate  * Generally speaking, keys that were added on the 101-key keyboard are
2200Sstevel@tonic-gate  * represented as an E0 followed by the code for an 84-key key.  Software
2210Sstevel@tonic-gate  * ignorant of the 101-key keyboard ignores the E0 and so is handled
2220Sstevel@tonic-gate  * compatibly.  Many of these variants involve "fake" shift presses
2230Sstevel@tonic-gate  * and releases for compatibility; these are also prefixed with E0.
2240Sstevel@tonic-gate  * We ignore these fake shifts.
2250Sstevel@tonic-gate  */
226822Ssethg static const unsigned char	keytab_e0_set1[] = {
2270Sstevel@tonic-gate /* 00 */	INVALID,
2280Sstevel@tonic-gate /* 01 */	INVALID,
2290Sstevel@tonic-gate /* 02 */	INVALID,
2300Sstevel@tonic-gate /* 03 */	INVALID,
2310Sstevel@tonic-gate /* 04 */	INVALID,
2320Sstevel@tonic-gate /* 05 */	INVALID,
2330Sstevel@tonic-gate /* 06 */	INVALID,
2340Sstevel@tonic-gate /* 07 */	INVALID,
2350Sstevel@tonic-gate /* 08 */	INVALID,
2360Sstevel@tonic-gate /* 09 */	INVALID,
2370Sstevel@tonic-gate /* 0a */	INVALID,
2380Sstevel@tonic-gate /* 0b */	INVALID,
2390Sstevel@tonic-gate /* 0c */	INVALID,
2400Sstevel@tonic-gate /* 0d */	INVALID,
2410Sstevel@tonic-gate /* 0e */	INVALID,
2420Sstevel@tonic-gate /* 0f */	INVALID,
2430Sstevel@tonic-gate 
2440Sstevel@tonic-gate /* 10 */	INVALID,
2450Sstevel@tonic-gate /* 11 */	INVALID,
2460Sstevel@tonic-gate /* 12 */	INVALID,
2470Sstevel@tonic-gate /* 13 */	INVALID,
2480Sstevel@tonic-gate /* 14 */	INVALID,
2490Sstevel@tonic-gate /* 15 */	INVALID,
2500Sstevel@tonic-gate /* 16 */	INVALID,
2510Sstevel@tonic-gate /* 17 */	INVALID,
2520Sstevel@tonic-gate /* 18 */	INVALID,
2530Sstevel@tonic-gate /* 19 */	INVALID,
2540Sstevel@tonic-gate /* 1a */	INVALID,
2550Sstevel@tonic-gate /* 1b */	INVALID,
2560Sstevel@tonic-gate /* 1c */	KEY(108),	/* Enter (num) */
2570Sstevel@tonic-gate /* 1d */	KEY(64),	/* R Ctrl */
2580Sstevel@tonic-gate /* 1e */	INVALID,
2590Sstevel@tonic-gate /* 1f */	INVALID,
2600Sstevel@tonic-gate 
2619026SSeth.Goldberg@Sun.COM /* 20 */	KEY(235),	/* Mute */
2620Sstevel@tonic-gate /* 21 */	INVALID,
2630Sstevel@tonic-gate /* 22 */	INVALID,
2640Sstevel@tonic-gate /* 23 */	INVALID,
2650Sstevel@tonic-gate /* 24 */	INVALID,
2660Sstevel@tonic-gate /* 25 */	INVALID,
2670Sstevel@tonic-gate /* 26 */	INVALID,
2680Sstevel@tonic-gate /* 27 */	INVALID,
2690Sstevel@tonic-gate /* 28 */	INVALID,
2700Sstevel@tonic-gate /* 29 */	INVALID,
2710Sstevel@tonic-gate /* 2a */	INVALID,
2720Sstevel@tonic-gate /* 2b */	INVALID,
2730Sstevel@tonic-gate /* 2c */	INVALID,
2740Sstevel@tonic-gate /* 2d */	INVALID,
2759026SSeth.Goldberg@Sun.COM /* 2e */	KEY(234),	/* Volume Down */
2760Sstevel@tonic-gate /* 2f */	INVALID,
2770Sstevel@tonic-gate 
2789026SSeth.Goldberg@Sun.COM /* 30 */	KEY(233),	/* Volume Up */
2790Sstevel@tonic-gate /* 31 */	INVALID,
2800Sstevel@tonic-gate /* 32 */	INVALID,
2810Sstevel@tonic-gate /* 33 */	INVALID,
2820Sstevel@tonic-gate /* 34 */	INVALID,
2830Sstevel@tonic-gate /* 35 */	KEY(95),	/* / (num) */
2840Sstevel@tonic-gate /* 36 */	INVALID,
2850Sstevel@tonic-gate /* 37 */	KEY(124),	/* PrintScreen (no Alt) */
2860Sstevel@tonic-gate /* 38 */	KEY(62),	/* R Alt */
2870Sstevel@tonic-gate /* 39 */	INVALID,
2880Sstevel@tonic-gate /* 3a */	INVALID,
2890Sstevel@tonic-gate /* 3b */	INVALID,
2900Sstevel@tonic-gate /* 3c */	INVALID,
2910Sstevel@tonic-gate /* 3d */	INVALID,
2920Sstevel@tonic-gate /* 3e */	INVALID,
2930Sstevel@tonic-gate /* 3f */	INVALID,
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate /* 40 */	INVALID,
2960Sstevel@tonic-gate /* 41 */	INVALID,
2970Sstevel@tonic-gate /* 42 */	INVALID,
2980Sstevel@tonic-gate /* 43 */	INVALID,
2990Sstevel@tonic-gate /* 44 */	INVALID,
3000Sstevel@tonic-gate /* 45 */	INVALID,
3010Sstevel@tonic-gate /* 46 */	KEY(126),	/* Pause (with Cntl) */
3020Sstevel@tonic-gate /* 47 */	KEY(80),	/* Home (arrow) */
3030Sstevel@tonic-gate /* 48 */	KEY(83),	/* Up (arrow) */
3040Sstevel@tonic-gate /* 49 */	KEY(85),	/* PgUp (arrow) */
3050Sstevel@tonic-gate /* 4a */	INVALID,
3060Sstevel@tonic-gate /* 4b */	KEY(79),	/* Left (arrow) */
3070Sstevel@tonic-gate /* 4c */	INVALID,
3080Sstevel@tonic-gate /* 4d */	KEY(89),	/* Right (arrow) */
3090Sstevel@tonic-gate /* 4e */	INVALID,
3100Sstevel@tonic-gate /* 4f */	KEY(81),	/* End (arrow) */
3110Sstevel@tonic-gate 
3120Sstevel@tonic-gate /* 50 */	KEY(84),	/* Down (arrow) */
3130Sstevel@tonic-gate /* 51 */	KEY(86),	/* PgDn (arrow) */
3140Sstevel@tonic-gate /* 52 */	KEY(75),	/* Insert (arrow) */
3150Sstevel@tonic-gate /* 53 */	KEY(76),	/* Delete (arrow) */
3160Sstevel@tonic-gate /* 54 */	INVALID,
3170Sstevel@tonic-gate /* 55 */	INVALID,
3180Sstevel@tonic-gate /* 56 */	INVALID,
3190Sstevel@tonic-gate /* 57 */	INVALID,
3200Sstevel@tonic-gate /* 58 */	INVALID,
3210Sstevel@tonic-gate /* 59 */	INVALID,
3220Sstevel@tonic-gate /* 5a */	INVALID,
3230Sstevel@tonic-gate /* 5b */	KEY(59),	/* L Window (104-key) */
3240Sstevel@tonic-gate /* 5c */	KEY(63),	/* R Window (104-key) */
3250Sstevel@tonic-gate /* 5d */	KEY(65),	/* Menu (104-key) */
3260Sstevel@tonic-gate /* 5e */	INVALID,
3270Sstevel@tonic-gate /* 5f */	INVALID,
3280Sstevel@tonic-gate 
3290Sstevel@tonic-gate /* 60 */	INVALID,
3300Sstevel@tonic-gate /* 61 */	INVALID,
3310Sstevel@tonic-gate /* 62 */	INVALID,
3320Sstevel@tonic-gate /* 63 */	INVALID,
3330Sstevel@tonic-gate /* 64 */	INVALID,
3340Sstevel@tonic-gate /* 65 */	INVALID,
3350Sstevel@tonic-gate /* 66 */	INVALID,
3360Sstevel@tonic-gate /* 67 */	INVALID,
3370Sstevel@tonic-gate /* 68 */	INVALID,
3380Sstevel@tonic-gate /* 69 */	INVALID,
3390Sstevel@tonic-gate /* 6a */	INVALID,
3400Sstevel@tonic-gate /* 6b */	INVALID,
3410Sstevel@tonic-gate /* 6c */	INVALID,
3420Sstevel@tonic-gate /* 6d */	INVALID,
3430Sstevel@tonic-gate /* 6e */	INVALID,
3440Sstevel@tonic-gate /* 6f */	INVALID,
3450Sstevel@tonic-gate 
3460Sstevel@tonic-gate /* 70 */	INVALID,
3470Sstevel@tonic-gate /* 71 */	INVALID,
3480Sstevel@tonic-gate /* 72 */	INVALID,
3490Sstevel@tonic-gate /* 73 */	INVALID,
3500Sstevel@tonic-gate /* 74 */	INVALID,
3510Sstevel@tonic-gate /* 75 */	INVALID,
3520Sstevel@tonic-gate /* 76 */	INVALID,
3530Sstevel@tonic-gate /* 77 */	INVALID,
3540Sstevel@tonic-gate /* 78 */	INVALID,
3550Sstevel@tonic-gate /* 79 */	INVALID,
3560Sstevel@tonic-gate /* 7a */	INVALID,
3570Sstevel@tonic-gate /* 7b */	INVALID,
3580Sstevel@tonic-gate /* 7c */	INVALID,
3590Sstevel@tonic-gate /* 7d */	INVALID,
3600Sstevel@tonic-gate /* 7e */	INVALID,
3610Sstevel@tonic-gate };
3620Sstevel@tonic-gate 
3630Sstevel@tonic-gate 
3640Sstevel@tonic-gate /*
3650Sstevel@tonic-gate  *	Parse table for the base keyboard state.  The index is the start of
3660Sstevel@tonic-gate  *	a new sequence.
3670Sstevel@tonic-gate  *
3680Sstevel@tonic-gate  * Questionable or unusual cases:
369822Ssethg  * 02		On some SPARC keyboards, this is the scan code for the STOP
370822Ssethg  *		key.  The KEY() value was chosen so that it maps to a
371822Ssethg  *		HOLE entry in the keytables in kb8042_keytables.c; therefore,
372822Ssethg  *		the STOP key code is only translated properly when kb8042
373822Ssethg  *		is "emulating" a USB keyboard (which it is by default--
374822Ssethg  *		see conskbd.c).
3750Sstevel@tonic-gate  * 7f		Old kd code says this is an 84-key SysReq.  Manual says no.
3760Sstevel@tonic-gate  * 87		Old kd code says 1 (num).  Manual says no.
3770Sstevel@tonic-gate  * 8c		Old kd code says / (num).  Manual says no.
3780Sstevel@tonic-gate  * aa		POST OK.  Handled by code.
3790Sstevel@tonic-gate  * e0		Extend prefix.  Handled by code. (switches to E0 table)
3800Sstevel@tonic-gate  * e1		Extend prefix.  Handled by code.  (Pause key only)
3810Sstevel@tonic-gate  * f0		Break prefix.  Handled by code.
3820Sstevel@tonic-gate  * f1		Korean Hangul/Hanja key.  Handled by code.
3830Sstevel@tonic-gate  * f2		Korean Hangul key.  Handled by code.
3840Sstevel@tonic-gate  * ff		Keyboard internal buffer overrun.  Handled by code.
3850Sstevel@tonic-gate  *
3860Sstevel@tonic-gate  * Other values past the end of the table are treated as INVALID.
3870Sstevel@tonic-gate  */
3880Sstevel@tonic-gate 
389822Ssethg static const unsigned char	keytab_base_set2[] = {
3900Sstevel@tonic-gate /* scan		state		keycap */
3910Sstevel@tonic-gate /* 00 */	INVALID,
3920Sstevel@tonic-gate /* 01 */	KEY(120),	/* F9 */
393822Ssethg #if defined(__sparc)
394822Ssethg /* 02 */	KEY(K8042_STOP), /* STOP */
395822Ssethg #else
3960Sstevel@tonic-gate /* 02 */	INVALID,	/* F7?  Old code says so but manual doesn't */
397822Ssethg #endif
3980Sstevel@tonic-gate /* 03 */	KEY(116),	/* F5 */
3990Sstevel@tonic-gate /* 04 */	KEY(114),	/* F3 */
4000Sstevel@tonic-gate /* 05 */	KEY(112),	/* F1 */
4010Sstevel@tonic-gate /* 06 */	KEY(113),	/* F2 */
4020Sstevel@tonic-gate /* 07 */	KEY(123),	/* F12 */
4030Sstevel@tonic-gate /* 08 */	INVALID,
4040Sstevel@tonic-gate /* 09 */	KEY(121),	/* F10 */
4050Sstevel@tonic-gate /* 0a */	KEY(119),	/* F8 */
4060Sstevel@tonic-gate /* 0b */	KEY(117),	/* F6 */
4070Sstevel@tonic-gate /* 0c */	KEY(115),	/* F4 */
4080Sstevel@tonic-gate /* 0d */	KEY(16),	/* tab */
4090Sstevel@tonic-gate /* 0e */	KEY(1),		/* ` */
4100Sstevel@tonic-gate /* 0f */	INVALID,
4110Sstevel@tonic-gate /* 10 */	INVALID,
4120Sstevel@tonic-gate /* 11 */	KEY(60),	/* L Alt */
4130Sstevel@tonic-gate /* 12 */	KEY(44),	/* L Shift */
4140Sstevel@tonic-gate /* 13 */	KEY(133),	/* Japanese 106-key */
4150Sstevel@tonic-gate /* 14 */	KEY(58),	/* L Ctrl */
4160Sstevel@tonic-gate /* 15 */	KEY(17),	/* Q */
4170Sstevel@tonic-gate /* 16 */	KEY(2),		/* 1 */
4180Sstevel@tonic-gate /* 17 */	INVALID,
4190Sstevel@tonic-gate /* 18 */	INVALID,
4200Sstevel@tonic-gate /* 19 */	INVALID,
4210Sstevel@tonic-gate /* 1a */	KEY(46),	/* Z */
4220Sstevel@tonic-gate /* 1b */	KEY(32),	/* S */
4230Sstevel@tonic-gate /* 1c */	KEY(31),	/* A */
4240Sstevel@tonic-gate /* 1d */	KEY(18),	/* W */
4250Sstevel@tonic-gate /* 1e */	KEY(3),		/* 2 */
4260Sstevel@tonic-gate /* 1f */	INVALID,
4270Sstevel@tonic-gate /* 20 */	INVALID,
4280Sstevel@tonic-gate /* 21 */	KEY(48),	/* C */
4290Sstevel@tonic-gate /* 22 */	KEY(47),	/* X */
4300Sstevel@tonic-gate /* 23 */	KEY(33),	/* D */
4310Sstevel@tonic-gate /* 24 */	KEY(19),	/* E */
4320Sstevel@tonic-gate /* 25 */	KEY(5),		/* 4 */
4330Sstevel@tonic-gate /* 26 */	KEY(4),		/* 3 */
4340Sstevel@tonic-gate /* 27 */	INVALID,
4350Sstevel@tonic-gate /* 28 */	INVALID,
4360Sstevel@tonic-gate /* 29 */	KEY(61),	/* Space */
4370Sstevel@tonic-gate /* 2a */	KEY(49),	/* V */
4380Sstevel@tonic-gate /* 2b */	KEY(34),	/* F */
4390Sstevel@tonic-gate /* 2c */	KEY(21),	/* T */
4400Sstevel@tonic-gate /* 2d */	KEY(20),	/* R */
4410Sstevel@tonic-gate /* 2e */	KEY(6),		/* 5 */
4420Sstevel@tonic-gate /* 2f */	INVALID,
4430Sstevel@tonic-gate /* 30 */	INVALID,
4440Sstevel@tonic-gate /* 31 */	KEY(51),	/* N */
4450Sstevel@tonic-gate /* 32 */	KEY(50),	/* B */
4460Sstevel@tonic-gate /* 33 */	KEY(36),	/* H */
4470Sstevel@tonic-gate /* 34 */	KEY(35),	/* G */
4480Sstevel@tonic-gate /* 35 */	KEY(22),	/* Y */
4490Sstevel@tonic-gate /* 36 */	KEY(7),		/* 6 */
4500Sstevel@tonic-gate /* 37 */	INVALID,
4510Sstevel@tonic-gate /* 38 */	INVALID,
4520Sstevel@tonic-gate /* 39 */	INVALID,
4530Sstevel@tonic-gate /* 3a */	KEY(52),	/* M */
4540Sstevel@tonic-gate /* 3b */	KEY(37),	/* J */
4550Sstevel@tonic-gate /* 3c */	KEY(23),	/* U */
4560Sstevel@tonic-gate /* 3d */	KEY(8),		/* 7 */
4570Sstevel@tonic-gate /* 3e */	KEY(9),		/* 8 */
4580Sstevel@tonic-gate /* 3f */	INVALID,
4590Sstevel@tonic-gate /* 40 */	INVALID,
4600Sstevel@tonic-gate /* 41 */	KEY(53),	/* , */
4610Sstevel@tonic-gate /* 42 */	KEY(38),	/* K */
4620Sstevel@tonic-gate /* 43 */	KEY(24),	/* I */
4630Sstevel@tonic-gate /* 44 */	KEY(25),	/* O */
4640Sstevel@tonic-gate /* 45 */	KEY(11),	/* 0 */
4650Sstevel@tonic-gate /* 46 */	KEY(10),	/* 9 */
4660Sstevel@tonic-gate /* 47 */	INVALID,
4670Sstevel@tonic-gate /* 48 */	INVALID,
4680Sstevel@tonic-gate /* 49 */	KEY(54),	/* . */
4690Sstevel@tonic-gate /* 4a */	KEY(55),	/* / */
4700Sstevel@tonic-gate /* 4b */	KEY(39),	/* L */
4710Sstevel@tonic-gate /* 4c */	KEY(40),	/* ; */
4720Sstevel@tonic-gate /* 4d */	KEY(26),	/* P */
4730Sstevel@tonic-gate /* 4e */	KEY(12),	/* - */
4740Sstevel@tonic-gate /* 4f */	INVALID,
4750Sstevel@tonic-gate /* 50 */	INVALID,
4760Sstevel@tonic-gate /* 51 */	KEY(56),	/* Japanese 106-key */
4770Sstevel@tonic-gate /* 52 */	KEY(41),	/* ' */
4780Sstevel@tonic-gate /* 53 */	INVALID,
4790Sstevel@tonic-gate /* 54 */	KEY(27),	/* [ */
4800Sstevel@tonic-gate /* 55 */	KEY(13),	/* = */
4810Sstevel@tonic-gate /* 56 */	INVALID,
4820Sstevel@tonic-gate /* 57 */	INVALID,
4830Sstevel@tonic-gate /* 58 */	KEY(30),	/* CapsLock */
4840Sstevel@tonic-gate /* 59 */	KEY(57),	/* R Shift */
4850Sstevel@tonic-gate /* 5a */	KEY(43),	/* Enter (main) */
4860Sstevel@tonic-gate /* 5b */	KEY(28),	/* ] */
4870Sstevel@tonic-gate /* 5c */	INVALID,
4880Sstevel@tonic-gate /* 5d */	KEY(29),	/* \, key 42 for 102-key */
4890Sstevel@tonic-gate /* 5e */	INVALID,
4900Sstevel@tonic-gate /* 5f */	INVALID,
4910Sstevel@tonic-gate /* 60 */	INVALID,
4920Sstevel@tonic-gate /* 61 */	KEY(45),	/* 102-key only, typically </> */
4930Sstevel@tonic-gate /* 62 */	INVALID,
4940Sstevel@tonic-gate /* 63 */	INVALID,
4950Sstevel@tonic-gate /* 64 */	KEY(132),	/* Japanese 106-key */
4960Sstevel@tonic-gate /* 65 */	INVALID,
4970Sstevel@tonic-gate /* 66 */	KEY(15),	/* backspace */
4980Sstevel@tonic-gate /* 67 */	KEY(131),	/* Japanese 106-key */
4990Sstevel@tonic-gate /* 68 */	INVALID,
5000Sstevel@tonic-gate /* 69 */	KEY(93),	/* 1 (num) */
5010Sstevel@tonic-gate /* 6a */	KEY(14),	/* Japanese 106-key */
5020Sstevel@tonic-gate /* 6b */	KEY(92),	/* 4 (num) */
5030Sstevel@tonic-gate /* 6c */	KEY(91),	/* 7 (num) */
5040Sstevel@tonic-gate /* 6d */	INVALID,
5050Sstevel@tonic-gate /* 6e */	INVALID,
5060Sstevel@tonic-gate /* 6f */	INVALID,
5070Sstevel@tonic-gate /* 70 */	KEY(99),	/* 0 (num) */
5080Sstevel@tonic-gate /* 71 */	KEY(104),	/* . (num) */
5090Sstevel@tonic-gate /* 72 */	KEY(98),	/* 2 (num) */
5100Sstevel@tonic-gate /* 73 */	KEY(97),	/* 5 (num) */
5110Sstevel@tonic-gate /* 74 */	KEY(102),	/* 6 (num) */
5120Sstevel@tonic-gate /* 75 */	KEY(96),	/* 8 (num) */
5130Sstevel@tonic-gate /* 76 */	KEY(110),	/* Esc */
5140Sstevel@tonic-gate /* 77 */	KEY(90),	/* NumLock */
5150Sstevel@tonic-gate /* 78 */	KEY(122),	/* F11 */
5160Sstevel@tonic-gate /* 79 */	KEY(106),	/* + (num) */
5170Sstevel@tonic-gate /* 7a */	KEY(103),	/* 3 (num) */
5180Sstevel@tonic-gate /* 7b */	KEY(105),	/* - (num) */
5190Sstevel@tonic-gate /* 7c */	KEY(100),	/* * (num) */
5200Sstevel@tonic-gate /* 7d */	KEY(101),	/* 9 (num) */
5210Sstevel@tonic-gate /* 7e */	KEY(125),	/* Scroll Lock */
5220Sstevel@tonic-gate /* 7f */	INVALID,	/* 84-key SysReq?  Manual says no. */
5230Sstevel@tonic-gate /* 80 */	INVALID,
5240Sstevel@tonic-gate /* 81 */	INVALID,
5250Sstevel@tonic-gate /* 82 */	INVALID,
5260Sstevel@tonic-gate /* 83 */	KEY(118),	/* F7 */
5270Sstevel@tonic-gate /* 84 */	KEY(124),	/* PrintScreen (w/ Alt = SysRq) */
5280Sstevel@tonic-gate };
5290Sstevel@tonic-gate 
5300Sstevel@tonic-gate /*
5310Sstevel@tonic-gate  * Parse table after receiving an E0 prefix code.
5320Sstevel@tonic-gate  *
5330Sstevel@tonic-gate  * Generally speaking, keys that were added on the 101-key keyboard are
5340Sstevel@tonic-gate  * represented as an E0 followed by the code for an 84-key key.  Software
5350Sstevel@tonic-gate  * ignorant of the 101-key keyboard ignores the E0 and so is handled
5360Sstevel@tonic-gate  * compatibly.  Many of these variants involve "fake" shift presses
5370Sstevel@tonic-gate  * and releases for compatibility; these are also prefixed with E0.
5380Sstevel@tonic-gate  * We ignore these fake shifts.
5390Sstevel@tonic-gate  */
540822Ssethg static const unsigned char	keytab_e0_set2[] = {
5410Sstevel@tonic-gate /* 00 */	INVALID,
5420Sstevel@tonic-gate /* 01 */	INVALID,
5430Sstevel@tonic-gate /* 02 */	INVALID,
5440Sstevel@tonic-gate /* 03 */	INVALID,
5450Sstevel@tonic-gate /* 04 */	INVALID,
5460Sstevel@tonic-gate /* 05 */	INVALID,
5470Sstevel@tonic-gate /* 06 */	INVALID,
5480Sstevel@tonic-gate /* 07 */	INVALID,
5490Sstevel@tonic-gate /* 08 */	INVALID,
5500Sstevel@tonic-gate /* 09 */	INVALID,
5510Sstevel@tonic-gate /* 0a */	INVALID,
5520Sstevel@tonic-gate /* 0b */	INVALID,
5530Sstevel@tonic-gate /* 0c */	INVALID,
5540Sstevel@tonic-gate /* 0d */	INVALID,
5550Sstevel@tonic-gate /* 0e */	INVALID,
5560Sstevel@tonic-gate /* 0f */	INVALID,
5570Sstevel@tonic-gate /* 10 */	INVALID,
5580Sstevel@tonic-gate /* 11 */	KEY(62),	/* R Alt */
5590Sstevel@tonic-gate /* 12 */	IGNORE,		/* Fake L Shift */
5600Sstevel@tonic-gate /* 13 */	INVALID,
5610Sstevel@tonic-gate /* 14 */	KEY(64),	/* R Ctrl */
5620Sstevel@tonic-gate /* 15 */	INVALID,
5630Sstevel@tonic-gate /* 16 */	INVALID,
5640Sstevel@tonic-gate /* 17 */	INVALID,
5650Sstevel@tonic-gate /* 18 */	INVALID,
5660Sstevel@tonic-gate /* 19 */	INVALID,
5670Sstevel@tonic-gate /* 1a */	INVALID,
5680Sstevel@tonic-gate /* 1b */	INVALID,
5690Sstevel@tonic-gate /* 1c */	INVALID,
5700Sstevel@tonic-gate /* 1d */	INVALID,
5710Sstevel@tonic-gate /* 1e */	INVALID,
5720Sstevel@tonic-gate /* 1f */	KEY(59),	/* L Window (104-key) */
5730Sstevel@tonic-gate /* 20 */	INVALID,
5740Sstevel@tonic-gate /* 21 */	INVALID,
5750Sstevel@tonic-gate /* 22 */	INVALID,
5760Sstevel@tonic-gate /* 23 */	INVALID,
5770Sstevel@tonic-gate /* 24 */	INVALID,
5780Sstevel@tonic-gate /* 25 */	INVALID,
5790Sstevel@tonic-gate /* 26 */	INVALID,
5800Sstevel@tonic-gate /* 27 */	KEY(63),	/* R Window (104-key) */
5810Sstevel@tonic-gate /* 28 */	INVALID,
5820Sstevel@tonic-gate /* 29 */	INVALID,
5830Sstevel@tonic-gate /* 2a */	INVALID,
5840Sstevel@tonic-gate /* 2b */	INVALID,
5850Sstevel@tonic-gate /* 2c */	INVALID,
5860Sstevel@tonic-gate /* 2d */	INVALID,
5870Sstevel@tonic-gate /* 2e */	INVALID,
5880Sstevel@tonic-gate /* 2f */	KEY(65),	/* Menu (104-key) */
5890Sstevel@tonic-gate /* 30 */	INVALID,
5900Sstevel@tonic-gate /* 31 */	INVALID,
5910Sstevel@tonic-gate /* 32 */	INVALID,
5920Sstevel@tonic-gate /* 33 */	INVALID,
5930Sstevel@tonic-gate /* 34 */	INVALID,
5940Sstevel@tonic-gate /* 35 */	INVALID,
5950Sstevel@tonic-gate /* 36 */	INVALID,
5960Sstevel@tonic-gate /* 37 */	INVALID,
5970Sstevel@tonic-gate /* 38 */	INVALID,
5980Sstevel@tonic-gate /* 39 */	INVALID,
5990Sstevel@tonic-gate /* 3a */	INVALID,
6000Sstevel@tonic-gate /* 3b */	INVALID,
6010Sstevel@tonic-gate /* 3c */	INVALID,
6020Sstevel@tonic-gate /* 3d */	INVALID,
6030Sstevel@tonic-gate /* 3e */	INVALID,
6040Sstevel@tonic-gate /* 3f */	INVALID,
6050Sstevel@tonic-gate /* 40 */	INVALID,
6060Sstevel@tonic-gate /* 41 */	INVALID,
6070Sstevel@tonic-gate /* 42 */	INVALID,
6080Sstevel@tonic-gate /* 43 */	INVALID,
6090Sstevel@tonic-gate /* 44 */	INVALID,
6100Sstevel@tonic-gate /* 45 */	INVALID,
6110Sstevel@tonic-gate /* 46 */	INVALID,
6120Sstevel@tonic-gate /* 47 */	INVALID,
6130Sstevel@tonic-gate /* 48 */	INVALID,
6140Sstevel@tonic-gate /* 49 */	INVALID,
6150Sstevel@tonic-gate /* 4a */	KEY(95),	/* / (num) */
6160Sstevel@tonic-gate /* 4b */	INVALID,
6170Sstevel@tonic-gate /* 4c */	INVALID,
6180Sstevel@tonic-gate /* 4d */	INVALID,
6190Sstevel@tonic-gate /* 4e */	INVALID,
6200Sstevel@tonic-gate /* 4f */	INVALID,
6210Sstevel@tonic-gate /* 50 */	INVALID,
6220Sstevel@tonic-gate /* 51 */	INVALID,
6230Sstevel@tonic-gate /* 52 */	INVALID,
6240Sstevel@tonic-gate /* 53 */	INVALID,
6250Sstevel@tonic-gate /* 54 */	INVALID,
6260Sstevel@tonic-gate /* 55 */	INVALID,
6270Sstevel@tonic-gate /* 56 */	INVALID,
6280Sstevel@tonic-gate /* 57 */	INVALID,
6290Sstevel@tonic-gate /* 58 */	INVALID,
6300Sstevel@tonic-gate /* 59 */	IGNORE,		/* Fake R Shift */
6310Sstevel@tonic-gate /* 5a */	KEY(108),	/* Enter (num) */
6320Sstevel@tonic-gate /* 5b */	INVALID,
6330Sstevel@tonic-gate /* 5c */	INVALID,
6340Sstevel@tonic-gate /* 5d */	INVALID,
6350Sstevel@tonic-gate /* 5e */	INVALID,
6360Sstevel@tonic-gate /* 5f */	INVALID,
6370Sstevel@tonic-gate /* 60 */	INVALID,
6380Sstevel@tonic-gate /* 61 */	INVALID,
6390Sstevel@tonic-gate /* 62 */	INVALID,
6400Sstevel@tonic-gate /* 63 */	INVALID,
6410Sstevel@tonic-gate /* 64 */	INVALID,
6420Sstevel@tonic-gate /* 65 */	INVALID,
6430Sstevel@tonic-gate /* 66 */	INVALID,
6440Sstevel@tonic-gate /* 67 */	INVALID,
6450Sstevel@tonic-gate /* 68 */	INVALID,
6460Sstevel@tonic-gate /* 69 */	KEY(81),	/* End (arrow) */
6470Sstevel@tonic-gate /* 6a */	INVALID,
6480Sstevel@tonic-gate /* 6b */	KEY(79),	/* Left (arrow) */
6490Sstevel@tonic-gate /* 6c */	KEY(80),	/* Home (arrow) */
6500Sstevel@tonic-gate /* 6d */	INVALID,
6510Sstevel@tonic-gate /* 6e */	INVALID,
6520Sstevel@tonic-gate /* 6f */	INVALID,
6530Sstevel@tonic-gate /* 70 */	KEY(75),	/* Insert (arrow) */
6540Sstevel@tonic-gate /* 71 */	KEY(76),	/* Delete (arrow) */
6550Sstevel@tonic-gate /* 72 */	KEY(84),	/* Down (arrow) */
6560Sstevel@tonic-gate /* 73 */	INVALID,
6570Sstevel@tonic-gate /* 74 */	KEY(89),	/* Right (arrow) */
6580Sstevel@tonic-gate /* 75 */	KEY(83),	/* Up (arrow) */
6590Sstevel@tonic-gate /* 76 */	INVALID,
6600Sstevel@tonic-gate /* 77 */	INVALID,
6610Sstevel@tonic-gate /* 78 */	INVALID,
6620Sstevel@tonic-gate /* 79 */	INVALID,
6630Sstevel@tonic-gate /* 7a */	KEY(86),	/* PgDn (arrow) */
6640Sstevel@tonic-gate /* 7b */	INVALID,
6650Sstevel@tonic-gate /* 7c */	KEY(124),	/* PrintScreen (no Alt) */
6660Sstevel@tonic-gate /* 7d */	KEY(85),	/* PgUp (arrow) */
6670Sstevel@tonic-gate /* 7e */	KEY(126),	/* Pause (w/Ctrl = Break) */
6680Sstevel@tonic-gate };
6690Sstevel@tonic-gate 
6700Sstevel@tonic-gate 
6710Sstevel@tonic-gate /*
6720Sstevel@tonic-gate  * Initialize the translation state machine.
6730Sstevel@tonic-gate  */
674822Ssethg int
KeyboardConvertScan_init(struct kb8042 * kb8042,int scanset)675822Ssethg KeyboardConvertScan_init(struct kb8042 *kb8042, int scanset)
6760Sstevel@tonic-gate {
6770Sstevel@tonic-gate 	kb8042->parse_scan_state = STATE_IDLE;
678822Ssethg 	kb8042->break_received = 0;
679822Ssethg 
680822Ssethg 	if (scanset == 1) {
681822Ssethg 		KeyboardConvertScan_fn = &KeyboardConvertScan_set1;
682822Ssethg 		keytab_base = keytab_base_set1;
683822Ssethg 		keytab_base_length = NELEM(keytab_base_set1);
684822Ssethg 		keytab_e0 = keytab_e0_set1;
685822Ssethg 		keytab_e0_length = NELEM(keytab_e0_set1);
686822Ssethg 	} else if (scanset == 2) {
687822Ssethg 		KeyboardConvertScan_fn = &KeyboardConvertScan_set2;
688822Ssethg 		keytab_base = keytab_base_set2;
689822Ssethg 		keytab_base_length = NELEM(keytab_base_set2);
690822Ssethg 		keytab_e0 = keytab_e0_set2;
691822Ssethg 		keytab_e0_length = NELEM(keytab_e0_set2);
692822Ssethg 	} else {
693822Ssethg 		return (DDI_FAILURE);
694822Ssethg 	}
695822Ssethg 
696822Ssethg 	return (DDI_SUCCESS);
697822Ssethg }
698822Ssethg 
6999026SSeth.Goldberg@Sun.COM /*
7009026SSeth.Goldberg@Sun.COM  *	KeyboardConvertScan(*kb8042, scan, *keynum, *state
7019026SSeth.Goldberg@Sun.COM  *		*synthetic_release_needed)
7029026SSeth.Goldberg@Sun.COM  *
7039026SSeth.Goldberg@Sun.COM  *	State machine that takes scan codes from the keyboard and resolves
7049026SSeth.Goldberg@Sun.COM  *	them to key numbers using the above tables.  Returns B_TRUE if this
7059026SSeth.Goldberg@Sun.COM  *	scan code completes a scan code sequence, in which case "keynum",
7069026SSeth.Goldberg@Sun.COM  *	"state", and "synthetic_release_needed" will be filled in correctly.
7079026SSeth.Goldberg@Sun.COM  *
7089026SSeth.Goldberg@Sun.COM  *	"synthetic_release_needed" is a hack to handle the additional two
7099026SSeth.Goldberg@Sun.COM  *	keys on a Korean keyboard.  They report press only, so we tell the
7109026SSeth.Goldberg@Sun.COM  *	upper layer to synthesize the release.
7119026SSeth.Goldberg@Sun.COM  */
712822Ssethg boolean_t
KeyboardConvertScan(struct kb8042 * kb8042,unsigned char scan,int * keynum,enum keystate * state,boolean_t * synthetic_release_needed)713822Ssethg KeyboardConvertScan(
714822Ssethg     struct kb8042	*kb8042,
715822Ssethg     unsigned char	scan,
716822Ssethg     int			*keynum,
717822Ssethg     enum keystate	*state,
718822Ssethg     boolean_t		*synthetic_release_needed)
719822Ssethg {
720822Ssethg 	ASSERT(KeyboardConvertScan_fn != NULL);
721822Ssethg 
722822Ssethg 	return ((*KeyboardConvertScan_fn)(kb8042, scan, keynum, state,
723822Ssethg 	    synthetic_release_needed));
7240Sstevel@tonic-gate }
7250Sstevel@tonic-gate 
7260Sstevel@tonic-gate boolean_t
KeyboardConvertScan_set1(struct kb8042 * kb8042,unsigned char scan,int * keynum,enum keystate * state,boolean_t * synthetic_release_needed)727822Ssethg KeyboardConvertScan_set1(
7280Sstevel@tonic-gate     struct kb8042	*kb8042,
7290Sstevel@tonic-gate     unsigned char	scan,
7300Sstevel@tonic-gate     int			*keynum,
7310Sstevel@tonic-gate     enum keystate	*state,
7320Sstevel@tonic-gate     boolean_t		*synthetic_release_needed)
7330Sstevel@tonic-gate {
7340Sstevel@tonic-gate 	*synthetic_release_needed = B_FALSE;
7350Sstevel@tonic-gate 	*state = KEY_PRESSED;
7360Sstevel@tonic-gate 
7370Sstevel@tonic-gate 	switch (scan) {
7380Sstevel@tonic-gate 	/*
7390Sstevel@tonic-gate 	 * First, handle special cases.
7400Sstevel@tonic-gate 	 * ACK has already been handled by our caller.
7410Sstevel@tonic-gate 	 */
7420Sstevel@tonic-gate 	case KB_ERROR:
7430Sstevel@tonic-gate 		/*
7440Sstevel@tonic-gate 		 * Perhaps we should reset state here,
7450Sstevel@tonic-gate 		 * since we no longer know what's going on.
7460Sstevel@tonic-gate 		 */
7470Sstevel@tonic-gate 		return (B_FALSE);
7480Sstevel@tonic-gate 	case KB_POST_FAIL:
7490Sstevel@tonic-gate 		/*
7500Sstevel@tonic-gate 		 * Perhaps we should reset the LEDs now.
7510Sstevel@tonic-gate 		 * If so, this check should probably be in the main line.
7520Sstevel@tonic-gate 		 * Perhaps we should tell the higher layers that the
7530Sstevel@tonic-gate 		 * keyboard has been reset.
7540Sstevel@tonic-gate 		 */
7550Sstevel@tonic-gate 		/*
7560Sstevel@tonic-gate 		 * Reset to idle
7570Sstevel@tonic-gate 		 */
7580Sstevel@tonic-gate 		kb8042->parse_scan_state = STATE_IDLE;
7590Sstevel@tonic-gate 		return (B_FALSE);
7600Sstevel@tonic-gate 
7610Sstevel@tonic-gate 	case KXT_EXTEND:
7620Sstevel@tonic-gate 	case KXT_EXTEND2:
7630Sstevel@tonic-gate 	case KXT_HANGUL_HANJA:
7640Sstevel@tonic-gate 	case KXT_HANGUL:
7650Sstevel@tonic-gate 		/*
7660Sstevel@tonic-gate 		 * Exclude these keys from the "default" test below.
7670Sstevel@tonic-gate 		 */
7680Sstevel@tonic-gate 		break;
7690Sstevel@tonic-gate 
7700Sstevel@tonic-gate 	default:
7710Sstevel@tonic-gate 		/*
7720Sstevel@tonic-gate 		 * See if it was a key release.
7730Sstevel@tonic-gate 		 */
7740Sstevel@tonic-gate 		if (scan > 0x80) {
7750Sstevel@tonic-gate 			*state = KEY_RELEASED;
7760Sstevel@tonic-gate 			scan -= 0x80;
7770Sstevel@tonic-gate 		}
7780Sstevel@tonic-gate 		break;
7790Sstevel@tonic-gate 	}
7800Sstevel@tonic-gate 
781822Ssethg 	if (kb8042->break_received) {
782822Ssethg 		*state = KEY_RELEASED;
783822Ssethg 		kb8042->break_received = 0;
784822Ssethg 	}
785822Ssethg 
7860Sstevel@tonic-gate 	switch (kb8042->parse_scan_state) {
7870Sstevel@tonic-gate 	case STATE_IDLE:
7880Sstevel@tonic-gate 		switch (scan) {
7890Sstevel@tonic-gate 		case KXT_EXTEND:
7900Sstevel@tonic-gate 			kb8042->parse_scan_state = STATE_E0;
7910Sstevel@tonic-gate 			return (B_FALSE);
7920Sstevel@tonic-gate 
7930Sstevel@tonic-gate 		case KXT_EXTEND2:
7940Sstevel@tonic-gate 			kb8042->parse_scan_state = STATE_E1;
7950Sstevel@tonic-gate 			return (B_FALSE);
7960Sstevel@tonic-gate 
7970Sstevel@tonic-gate 		/*
7980Sstevel@tonic-gate 		 * We could do the next two in the table, but it would
7990Sstevel@tonic-gate 		 * require nearly doubling the size of the table.
8000Sstevel@tonic-gate 		 *
8010Sstevel@tonic-gate 		 * Also, for some stupid reason these two report presses
8020Sstevel@tonic-gate 		 * only.  We tell the upper layer to synthesize a release.
8030Sstevel@tonic-gate 		 */
8040Sstevel@tonic-gate 		case KXT_HANGUL_HANJA:
8050Sstevel@tonic-gate 			*keynum = KEY(150);
8060Sstevel@tonic-gate 			*synthetic_release_needed = B_TRUE;
8070Sstevel@tonic-gate 			break;
8080Sstevel@tonic-gate 
8090Sstevel@tonic-gate 		case KXT_HANGUL:
8100Sstevel@tonic-gate 			*keynum = KEY(151);
8110Sstevel@tonic-gate 			*synthetic_release_needed = B_TRUE;
8120Sstevel@tonic-gate 			break;
8130Sstevel@tonic-gate 
8140Sstevel@tonic-gate 		default:
8150Sstevel@tonic-gate 			/*
8160Sstevel@tonic-gate 			 * Regular scan code
8170Sstevel@tonic-gate 			 */
818822Ssethg 			if (scan < keytab_base_length)
8190Sstevel@tonic-gate 				*keynum = keytab_base[scan];
8200Sstevel@tonic-gate 			else
8210Sstevel@tonic-gate 				*keynum = INVALID;
8220Sstevel@tonic-gate 			break;
8230Sstevel@tonic-gate 		}
8240Sstevel@tonic-gate 		break;
8250Sstevel@tonic-gate 
8260Sstevel@tonic-gate 	case STATE_E0:		/* Mostly 101-key additions */
827822Ssethg 		if (scan < keytab_e0_length)
8280Sstevel@tonic-gate 			*keynum = keytab_e0[scan];
8290Sstevel@tonic-gate 		else
8300Sstevel@tonic-gate 			*keynum = INVALID;
8310Sstevel@tonic-gate 		break;
8320Sstevel@tonic-gate 
8330Sstevel@tonic-gate 	case STATE_E1:		/* Pause key only */
8340Sstevel@tonic-gate 		switch (scan) {
8350Sstevel@tonic-gate 		case 0x1d:
8360Sstevel@tonic-gate 			kb8042->parse_scan_state = STATE_E1_1D;
8370Sstevel@tonic-gate 			return (B_FALSE);
8380Sstevel@tonic-gate 		default:
8390Sstevel@tonic-gate 			*keynum = INVALID;
8400Sstevel@tonic-gate 			break;
8410Sstevel@tonic-gate 		}
8420Sstevel@tonic-gate 		break;
8430Sstevel@tonic-gate 
8440Sstevel@tonic-gate 	case STATE_E1_1D:	/* Pause key only */
8450Sstevel@tonic-gate 		switch (scan) {
8460Sstevel@tonic-gate 		case 0x45:
8470Sstevel@tonic-gate 			*keynum = KEY(126);	/* Pause */
8480Sstevel@tonic-gate 			break;
8490Sstevel@tonic-gate 		default:
8500Sstevel@tonic-gate 			*keynum = INVALID;
8510Sstevel@tonic-gate 			break;
8520Sstevel@tonic-gate 		}
8530Sstevel@tonic-gate 		break;
8540Sstevel@tonic-gate 	}
8550Sstevel@tonic-gate 
8560Sstevel@tonic-gate 	/*
8570Sstevel@tonic-gate 	 * The results (*keynum, *state, and *synthetic_release_needed)
8580Sstevel@tonic-gate 	 * have been filled in, but they are valid only if we return
8590Sstevel@tonic-gate 	 * B_TRUE which is only done below.  If we make it to here, we
8600Sstevel@tonic-gate 	 * have completed a scan code sequence, so reset parse_scan_state.
8610Sstevel@tonic-gate 	 */
8620Sstevel@tonic-gate 
8630Sstevel@tonic-gate 	kb8042->parse_scan_state = STATE_IDLE;
8640Sstevel@tonic-gate 
8650Sstevel@tonic-gate 	switch (*keynum) {
8660Sstevel@tonic-gate 	case KEYIGN:				/* not a key, nor an error */
8670Sstevel@tonic-gate 		return (B_FALSE);		/* also not a final keycode */
8680Sstevel@tonic-gate 
8690Sstevel@tonic-gate 	case KEYBAD:		/* not part of a legit sequence? */
8700Sstevel@tonic-gate 		return (B_FALSE);	/* and return not a final keycode */
8710Sstevel@tonic-gate 
8720Sstevel@tonic-gate 	default:
8730Sstevel@tonic-gate 		/*
8740Sstevel@tonic-gate 		 * If we're here, it's a valid keycode.  We've already
8750Sstevel@tonic-gate 		 * filled in the return values; return success.
8760Sstevel@tonic-gate 		 */
8770Sstevel@tonic-gate 		return (B_TRUE);		/* resolved to a key */
8780Sstevel@tonic-gate 	}
8790Sstevel@tonic-gate }
880822Ssethg 
881822Ssethg /*
882822Ssethg  *	KeyboardConvertScan(*kb8042, scan, *keynum, *state
883822Ssethg  *		*synthetic_release_needed)
884822Ssethg  *
885822Ssethg  *	State machine that takes scan codes from the keyboard and resolves
886822Ssethg  *	them to key numbers using the above tables.  Returns B_TRUE if this
887822Ssethg  *	scan code completes a scan code sequence, in which case "keynum",
888822Ssethg  *	"state", and "synthetic_release_needed" will be filled in correctly.
889822Ssethg  *
890822Ssethg  *	"synthetic_release_needed" is a hack to handle the additional two
891822Ssethg  *	keys on a Korean keyboard.  They report press only, so we tell the
892822Ssethg  *	upper layer to synthesize the release.
893822Ssethg  */
894822Ssethg boolean_t
KeyboardConvertScan_set2(struct kb8042 * kb8042,unsigned char scan,int * keynum,enum keystate * state,boolean_t * synthetic_release_needed)895822Ssethg KeyboardConvertScan_set2(
896822Ssethg     struct kb8042	*kb8042,
897822Ssethg     unsigned char	scan,
898822Ssethg     int			*keynum,
899822Ssethg     enum keystate	*state,
900822Ssethg     boolean_t		*synthetic_release_needed)
901822Ssethg {
902822Ssethg 	*synthetic_release_needed = B_FALSE;
903822Ssethg 	*state = KEY_PRESSED;
904822Ssethg 
905822Ssethg 	switch (scan) {
906822Ssethg 	/*
907822Ssethg 	 * First, handle special cases.
908822Ssethg 	 * ACK has already been handled by our caller.
909822Ssethg 	 */
910822Ssethg 
911822Ssethg 	/*
912822Ssethg 	 * KAT_BREAK is 0xF0. It is the same as the break code for Japanese
913822Ssethg 	 * key 133.
914822Ssethg 	 * Therefore we don't treat it specially here.
915822Ssethg 	 */
916822Ssethg 	case KAT_BREAK:
917822Ssethg 		/* Switch states so we can recognize the code that follows */
918822Ssethg 		kb8042->break_received = 1;
919822Ssethg 		return (B_FALSE);	/* not a final keycode */
920822Ssethg 
921822Ssethg 	case KB_ERROR:
922822Ssethg 		/*
923822Ssethg 		 * Perhaps we should reset state here,
924822Ssethg 		 * since we no longer know what's going on.
925822Ssethg 		 */
926822Ssethg 		return (B_FALSE);
927822Ssethg 
928822Ssethg 	case KB_POST_OK:
929822Ssethg 	case KB_POST_FAIL:
930822Ssethg 		/*
931822Ssethg 		 * Perhaps we should reset the LEDs now.
932822Ssethg 		 * If so, this check should probably be in the main line.
933822Ssethg 		 * Perhaps we should tell the higher layers that the
934822Ssethg 		 * keyboard has been reset.
935822Ssethg 		 */
936822Ssethg 		/*
937822Ssethg 		 * Reset to idle
938822Ssethg 		 */
939822Ssethg 		kb8042->parse_scan_state = STATE_IDLE;
940822Ssethg 		return (B_FALSE);
941822Ssethg 	}
942822Ssethg 
943822Ssethg 	if (kb8042->break_received) {
944822Ssethg 		*state = KEY_RELEASED;
945822Ssethg 		kb8042->break_received = 0;
946822Ssethg 	}
947822Ssethg 
948822Ssethg 	switch (kb8042->parse_scan_state) {
949822Ssethg 	case STATE_IDLE:
950822Ssethg 		switch (scan) {
951822Ssethg 		case KXT_EXTEND:
952822Ssethg 			kb8042->parse_scan_state = STATE_E0;
953822Ssethg 			return (B_FALSE);
954822Ssethg 
955822Ssethg 		case KXT_EXTEND2:
956822Ssethg 			kb8042->parse_scan_state = STATE_E1;
957822Ssethg 			return (B_FALSE);
958822Ssethg 
959822Ssethg 		/*
960822Ssethg 		 * We could do the next two in the table, but it would
961822Ssethg 		 * require nearly doubling the size of the table.
962822Ssethg 		 *
963822Ssethg 		 * Also, for some stupid reason these two report presses
964822Ssethg 		 * only.  We tell the upper layer to synthesize a release.
965822Ssethg 		 */
966822Ssethg 		case KXT_HANGUL_HANJA:
967822Ssethg 			*keynum = KEY(150);
968822Ssethg 			*synthetic_release_needed = B_TRUE;
969822Ssethg 			break;
970822Ssethg 
971822Ssethg 		case KXT_HANGUL:
972822Ssethg 			*keynum = KEY(151);
973822Ssethg 			*synthetic_release_needed = B_TRUE;
974822Ssethg 			break;
975822Ssethg 
976822Ssethg 		default:
977822Ssethg 			/*
978822Ssethg 			 * Regular scan code
979822Ssethg 			 */
980822Ssethg 			if (scan < keytab_base_length)
981822Ssethg 				*keynum = keytab_base[scan];
982822Ssethg 			else
983822Ssethg 				*keynum = INVALID;
984822Ssethg 			break;
985822Ssethg 		}
986822Ssethg 		break;
987822Ssethg 
988822Ssethg 	case STATE_E0:		/* Mostly 101-key additions */
989822Ssethg 		if (scan < keytab_e0_length)
990822Ssethg 			*keynum = keytab_e0[scan];
991822Ssethg 		else
992822Ssethg 			*keynum = INVALID;
993822Ssethg 		break;
994822Ssethg 
995822Ssethg 	case STATE_E1:		/* Pause key only */
996822Ssethg 		switch (scan) {
997822Ssethg 		case 0x14:
998822Ssethg 			kb8042->parse_scan_state = STATE_E1_14;
999822Ssethg 			return (B_FALSE);
1000822Ssethg 		default:
1001822Ssethg 			*keynum = INVALID;
1002822Ssethg 			break;
1003822Ssethg 		}
1004822Ssethg 		break;
1005822Ssethg 
1006822Ssethg 	case STATE_E1_14:	/* Pause key only */
1007822Ssethg 		if (scan == 0x77) {
1008822Ssethg 			kb8042->parse_scan_state = STATE_E1_14_77;
1009822Ssethg 			return (B_FALSE);
1010822Ssethg 		} else {
1011822Ssethg 			*keynum = INVALID;
1012822Ssethg 		}
1013822Ssethg 		break;
1014822Ssethg 
1015822Ssethg 	case STATE_E1_14_77:
1016822Ssethg 		if (scan == 0xE1) {
1017822Ssethg 			kb8042->parse_scan_state = STATE_E1_14_77_E1;
1018822Ssethg 			return (B_FALSE);
1019822Ssethg 		} else {
1020822Ssethg 			*keynum = INVALID;
1021822Ssethg 		}
1022822Ssethg 		break;
1023822Ssethg 
1024822Ssethg 	case STATE_E1_14_77_E1:
1025822Ssethg 		if (scan == 0xF0) {
1026822Ssethg 			kb8042->parse_scan_state = STATE_E1_14_77_E1_F0;
1027822Ssethg 			return (B_FALSE);
1028822Ssethg 		} else {
1029822Ssethg 			*keynum = INVALID;
1030822Ssethg 		}
1031822Ssethg 		break;
1032822Ssethg 
1033822Ssethg 	case STATE_E1_14_77_E1_F0:
1034822Ssethg 		if (scan == 0x14) {
1035822Ssethg 			kb8042->parse_scan_state = STATE_E1_14_77_E1_F0_14;
1036822Ssethg 			return (B_FALSE);
1037822Ssethg 		} else {
1038822Ssethg 			*keynum = INVALID;
1039822Ssethg 		}
1040822Ssethg 		break;
1041822Ssethg 
1042822Ssethg 	case STATE_E1_14_77_E1_F0_14:
1043822Ssethg 		if (scan == 0xF0) {
1044822Ssethg 			kb8042->parse_scan_state = STATE_E1_14_77_E1_F0_14_F0;
1045822Ssethg 			return (B_FALSE);
1046822Ssethg 		} else {
1047822Ssethg 			*keynum = INVALID;
1048822Ssethg 		}
1049822Ssethg 		break;
1050822Ssethg 
1051822Ssethg 	case STATE_E1_14_77_E1_F0_14_F0:
1052822Ssethg 		if (scan == 0x77) {
1053822Ssethg 			*keynum = KEY(126);	/* Pause */
1054822Ssethg 		} else {
1055822Ssethg 			*keynum = INVALID;
1056822Ssethg 		}
1057822Ssethg 		break;
1058822Ssethg 	}
1059822Ssethg 
1060822Ssethg 	/*
1061822Ssethg 	 * The results (*keynum, *state, and *synthetic_release_needed)
1062822Ssethg 	 * have been filled in, but they are valid only if we return
1063822Ssethg 	 * B_TRUE which is only done below.  If we make it to here, we
1064822Ssethg 	 * have completed a scan code sequence, so reset parse_scan_state.
1065822Ssethg 	 */
1066822Ssethg 
1067822Ssethg 	if (kb8042->break_received) {
1068822Ssethg 		*state = KEY_RELEASED;
1069822Ssethg 		kb8042->break_received = 0;
1070822Ssethg 	}
1071822Ssethg 
1072822Ssethg 	kb8042->parse_scan_state = STATE_IDLE;
1073822Ssethg 
1074822Ssethg 	switch (*keynum) {
1075822Ssethg 	case KEYIGN:				/* not a key, nor an error */
1076822Ssethg 		return (B_FALSE);		/* also not a final keycode */
1077822Ssethg 
1078822Ssethg 	case KEYBAD:		/* not part of a legit sequence? */
1079822Ssethg 		return (B_FALSE);	/* and return not a final keycode */
1080822Ssethg 
1081822Ssethg 	default:
1082822Ssethg 		/*
1083822Ssethg 		 * If we're here, it's a valid keycode.  We've already
1084822Ssethg 		 * filled in the return values; return success.
1085822Ssethg 		 */
1086822Ssethg 		return (B_TRUE);		/* resolved to a key */
1087822Ssethg 	}
1088822Ssethg }
1089