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 5*9026SSeth.Goldberg@Sun.COM * Common Development and Distribution License (the "License"). 60Sstevel@tonic-gate * 70Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 80Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 90Sstevel@tonic-gate * See the License for the specific language governing permissions 100Sstevel@tonic-gate * and limitations under the License. 110Sstevel@tonic-gate * 120Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 130Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 140Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 150Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 160Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 170Sstevel@tonic-gate * 180Sstevel@tonic-gate * CDDL HEADER END 190Sstevel@tonic-gate */ 200Sstevel@tonic-gate /* 21*9026SSeth.Goldberg@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 220Sstevel@tonic-gate * Use is subject to license terms. 230Sstevel@tonic-gate */ 240Sstevel@tonic-gate 250Sstevel@tonic-gate #include <sys/types.h> 260Sstevel@tonic-gate #include <sys/stream.h> 270Sstevel@tonic-gate #include <sys/kbd.h> 280Sstevel@tonic-gate #include <sys/kbtrans.h> 290Sstevel@tonic-gate #include <sys/sunddi.h> 300Sstevel@tonic-gate #include <sys/consdev.h> 310Sstevel@tonic-gate #include <sys/promif.h> 320Sstevel@tonic-gate #include "kb8042.h" 330Sstevel@tonic-gate 340Sstevel@tonic-gate /* 350Sstevel@tonic-gate * Debugging for this module is enabled by the kb8042_debug flag 360Sstevel@tonic-gate * defined in kb8042.c. See that module for details. This flag is 370Sstevel@tonic-gate * hotkey enabled by F10 if the kb8042_enable_debug_hotkey flag is set. 380Sstevel@tonic-gate */ 390Sstevel@tonic-gate 400Sstevel@tonic-gate #if defined(DEBUG) || defined(lint) 410Sstevel@tonic-gate #define KD_DEBUG 420Sstevel@tonic-gate #endif 430Sstevel@tonic-gate 440Sstevel@tonic-gate /* 450Sstevel@tonic-gate * A note on the use of prom_printf here: Most of these routines can be 460Sstevel@tonic-gate * called from "polled mode", where we're servicing I/O requests from kmdb. 470Sstevel@tonic-gate * Normal system services are not available from polled mode; cmn_err will 480Sstevel@tonic-gate * not work. prom_printf is the only safe output mechanism. 490Sstevel@tonic-gate */ 500Sstevel@tonic-gate 510Sstevel@tonic-gate #if defined(KD_DEBUG) 520Sstevel@tonic-gate extern boolean_t kb8042_debug; 530Sstevel@tonic-gate #define DEBUG_KD(f) { if (kb8042_debug) prom_printf f; } 540Sstevel@tonic-gate #else 550Sstevel@tonic-gate #define DEBUG_KD(f) /* nothing */ 560Sstevel@tonic-gate #endif 570Sstevel@tonic-gate 580Sstevel@tonic-gate #define KEYBAD 0xff /* should generate an error */ 590Sstevel@tonic-gate #define KEYIGN 0xfe /* ignore this sequence */ 600Sstevel@tonic-gate 610Sstevel@tonic-gate #define KEY(code) (code) 620Sstevel@tonic-gate #define INVALID KEYBAD 630Sstevel@tonic-gate #define IGNORE KEYIGN 640Sstevel@tonic-gate 65822Ssethg #define NELEM(a) (sizeof (a) / sizeof (a)[0]) 66822Ssethg 670Sstevel@tonic-gate /* 680Sstevel@tonic-gate * These are the states of our parsing machine: 690Sstevel@tonic-gate */ 70822Ssethg #define STATE_IDLE 0x00000001 /* Awaiting the start of a sequence */ 71822Ssethg #define STATE_E0 0x00000002 /* Rec'd an E0 */ 72822Ssethg #define STATE_E1 0x00000004 /* Rec'd an E1 (Pause key only) */ 73822Ssethg #define STATE_E1_1D 0x00000008 /* Rec'd an E1 1D (Pause key only) */ 74822Ssethg #define STATE_E1_14 0x00000010 /* Rec'd an E1 14 (Pause key only) */ 75822Ssethg #define STATE_E1_14_77 0x00000020 76822Ssethg #define STATE_E1_14_77_E1 0x00000040 77822Ssethg #define STATE_E1_14_77_E1_F0 0x00000080 78822Ssethg #define STATE_E1_14_77_E1_F0_14 0x00000100 79822Ssethg #define STATE_E1_14_77_E1_F0_14_F0 0x00000200 800Sstevel@tonic-gate 81822Ssethg static boolean_t KeyboardConvertScan_set1(struct kb8042 *, unsigned char, int *, 82822Ssethg enum keystate *, boolean_t *); 83822Ssethg static boolean_t KeyboardConvertScan_set2(struct kb8042 *, unsigned char, int *, 84822Ssethg enum keystate *, boolean_t *); 850Sstevel@tonic-gate 86822Ssethg static const unsigned char *keytab_base = NULL; 87822Ssethg static int keytab_base_length = 0; 88822Ssethg static const unsigned char *keytab_e0 = NULL; 89822Ssethg static int keytab_e0_length = 0; 90822Ssethg static boolean_t (*KeyboardConvertScan_fn)(struct kb8042 *, unsigned char, 91822Ssethg int *, enum keystate *, boolean_t *) = NULL; 92822Ssethg 93822Ssethg static const unsigned char keytab_base_set1[] = { 940Sstevel@tonic-gate /* scan key number keycap */ 950Sstevel@tonic-gate /* 00 */ INVALID, 960Sstevel@tonic-gate /* 01 */ KEY(110), /* Esc */ 970Sstevel@tonic-gate /* 02 */ KEY(2), /* 1 */ 980Sstevel@tonic-gate /* 03 */ KEY(3), /* 2 */ 990Sstevel@tonic-gate /* 04 */ KEY(4), /* 3 */ 1000Sstevel@tonic-gate /* 05 */ KEY(5), /* 4 */ 1010Sstevel@tonic-gate /* 06 */ KEY(6), /* 5 */ 1020Sstevel@tonic-gate /* 07 */ KEY(7), /* 6 */ 1030Sstevel@tonic-gate /* 08 */ KEY(8), /* 7 */ 1040Sstevel@tonic-gate /* 09 */ KEY(9), /* 8 */ 1050Sstevel@tonic-gate /* 0a */ KEY(10), /* 9 */ 1060Sstevel@tonic-gate /* 0b */ KEY(11), /* 0 */ 1070Sstevel@tonic-gate /* 0c */ KEY(12), /* - */ 1080Sstevel@tonic-gate /* 0d */ KEY(13), /* = */ 1090Sstevel@tonic-gate /* 0e */ KEY(15), /* backspace */ 1100Sstevel@tonic-gate /* 0f */ KEY(16), /* tab */ 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate /* 10 */ KEY(17), /* Q */ 1130Sstevel@tonic-gate /* 11 */ KEY(18), /* W */ 1140Sstevel@tonic-gate /* 12 */ KEY(19), /* E */ 1150Sstevel@tonic-gate /* 13 */ KEY(20), /* R */ 1160Sstevel@tonic-gate /* 14 */ KEY(21), /* T */ 1170Sstevel@tonic-gate /* 15 */ KEY(22), /* Y */ 1180Sstevel@tonic-gate /* 16 */ KEY(23), /* U */ 1190Sstevel@tonic-gate /* 17 */ KEY(24), /* I */ 1200Sstevel@tonic-gate /* 18 */ KEY(25), /* O */ 1210Sstevel@tonic-gate /* 19 */ KEY(26), /* P */ 1220Sstevel@tonic-gate /* 1a */ KEY(27), /* [ */ 1230Sstevel@tonic-gate /* 1b */ KEY(28), /* ] */ 1240Sstevel@tonic-gate /* 1c */ KEY(43), /* Enter (main) */ 1250Sstevel@tonic-gate /* 1d */ KEY(58), /* L Ctrl */ 1260Sstevel@tonic-gate /* 1e */ KEY(31), /* A */ 1270Sstevel@tonic-gate /* 1f */ KEY(32), /* S */ 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate /* 20 */ KEY(33), /* D */ 1300Sstevel@tonic-gate /* 21 */ KEY(34), /* F */ 1310Sstevel@tonic-gate /* 22 */ KEY(35), /* G */ 1320Sstevel@tonic-gate /* 23 */ KEY(36), /* H */ 1330Sstevel@tonic-gate /* 24 */ KEY(37), /* J */ 1340Sstevel@tonic-gate /* 25 */ KEY(38), /* K */ 1350Sstevel@tonic-gate /* 26 */ KEY(39), /* L */ 1360Sstevel@tonic-gate /* 27 */ KEY(40), /* ; */ 1370Sstevel@tonic-gate /* 28 */ KEY(41), /* ' */ 1380Sstevel@tonic-gate /* 29 */ KEY(1), /* ` */ 1390Sstevel@tonic-gate /* 2a */ KEY(44), /* L Shift */ 1400Sstevel@tonic-gate /* 2b */ KEY(29), /* \ */ 1410Sstevel@tonic-gate /* 2c */ KEY(46), /* Z */ 1420Sstevel@tonic-gate /* 2d */ KEY(47), /* X */ 1430Sstevel@tonic-gate /* 2e */ KEY(48), /* C */ 1440Sstevel@tonic-gate /* 2f */ KEY(49), /* V */ 1450Sstevel@tonic-gate 1460Sstevel@tonic-gate /* 30 */ KEY(50), /* B */ 1470Sstevel@tonic-gate /* 31 */ KEY(51), /* N */ 1480Sstevel@tonic-gate /* 32 */ KEY(52), /* M */ 1490Sstevel@tonic-gate /* 33 */ KEY(53), /* , */ 1500Sstevel@tonic-gate /* 34 */ KEY(54), /* . */ 1510Sstevel@tonic-gate /* 35 */ KEY(55), /* / */ 1520Sstevel@tonic-gate /* 36 */ KEY(57), /* R Shift */ 1530Sstevel@tonic-gate /* 37 */ KEY(100), /* * (num) */ 1540Sstevel@tonic-gate /* 38 */ KEY(60), /* L Alt */ 1550Sstevel@tonic-gate /* 39 */ KEY(61), /* Space */ 1560Sstevel@tonic-gate /* 3a */ KEY(30), /* CapsLock */ 1570Sstevel@tonic-gate /* 3b */ KEY(112), /* F1 */ 1580Sstevel@tonic-gate /* 3c */ KEY(113), /* F2 */ 1590Sstevel@tonic-gate /* 3d */ KEY(114), /* F3 */ 1600Sstevel@tonic-gate /* 3e */ KEY(115), /* F4 */ 1610Sstevel@tonic-gate /* 3f */ KEY(116), /* F5 */ 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate /* 40 */ KEY(117), /* F6 */ 1640Sstevel@tonic-gate /* 41 */ KEY(118), /* F7 */ 1650Sstevel@tonic-gate /* 42 */ KEY(119), /* F8 */ 1660Sstevel@tonic-gate /* 43 */ KEY(120), /* F9 */ 1670Sstevel@tonic-gate /* 44 */ KEY(121), /* F10 */ 1680Sstevel@tonic-gate /* 45 */ KEY(90), /* NumLock */ 1690Sstevel@tonic-gate /* 46 */ KEY(125), /* Scroll Lock */ 1700Sstevel@tonic-gate /* 47 */ KEY(91), /* 7 (num) */ 1710Sstevel@tonic-gate /* 48 */ KEY(96), /* 8 (num) */ 1720Sstevel@tonic-gate /* 49 */ KEY(101), /* 9 (num) */ 1730Sstevel@tonic-gate /* 4a */ KEY(105), /* - (num) */ 1740Sstevel@tonic-gate /* 4b */ KEY(92), /* 4 (num) */ 1750Sstevel@tonic-gate /* 4c */ KEY(97), /* 5 (num) */ 1760Sstevel@tonic-gate /* 4d */ KEY(102), /* 6 (num) */ 1770Sstevel@tonic-gate /* 4e */ KEY(106), /* + (num) */ 1780Sstevel@tonic-gate /* 4f */ KEY(93), /* 1 (num) */ 1790Sstevel@tonic-gate 1800Sstevel@tonic-gate /* 50 */ KEY(98), /* 2 (num) */ 1810Sstevel@tonic-gate /* 51 */ KEY(103), /* 3 (num) */ 1820Sstevel@tonic-gate /* 52 */ KEY(99), /* 0 (num) */ 1830Sstevel@tonic-gate /* 53 */ KEY(104), /* . (num) */ 1840Sstevel@tonic-gate /* 54 */ KEY(124), /* PrintScreen (with Alt) */ 1850Sstevel@tonic-gate /* 55 */ INVALID, 1860Sstevel@tonic-gate /* 56 */ KEY(45), /* not labled (102-key only) */ 1870Sstevel@tonic-gate /* 57 */ KEY(122), /* F11 */ 1880Sstevel@tonic-gate /* 58 */ KEY(123), /* F12 */ 1890Sstevel@tonic-gate /* 59 */ INVALID, 1900Sstevel@tonic-gate /* 5a */ INVALID, 1910Sstevel@tonic-gate /* 5b */ INVALID, 1920Sstevel@tonic-gate /* 5c */ INVALID, 1930Sstevel@tonic-gate /* 5d */ INVALID, 1940Sstevel@tonic-gate /* 5e */ INVALID, 1950Sstevel@tonic-gate /* 5f */ INVALID, 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate /* 60 */ INVALID, 1980Sstevel@tonic-gate /* 61 */ INVALID, 1990Sstevel@tonic-gate /* 62 */ INVALID, 2000Sstevel@tonic-gate /* 63 */ INVALID, 2010Sstevel@tonic-gate /* 64 */ INVALID, 2020Sstevel@tonic-gate /* 65 */ INVALID, 2030Sstevel@tonic-gate /* 66 */ INVALID, 2040Sstevel@tonic-gate /* 67 */ INVALID, 2050Sstevel@tonic-gate /* 68 */ INVALID, 2060Sstevel@tonic-gate /* 69 */ INVALID, 2070Sstevel@tonic-gate /* 6a */ INVALID, 2080Sstevel@tonic-gate /* 6b */ INVALID, 2090Sstevel@tonic-gate /* 6c */ INVALID, 2100Sstevel@tonic-gate /* 6d */ INVALID, 2110Sstevel@tonic-gate /* 6e */ INVALID, 2120Sstevel@tonic-gate /* 6f */ INVALID, 2130Sstevel@tonic-gate 2140Sstevel@tonic-gate /* 70 */ KEY(133), /* Japanese 106-key keyboard */ 2150Sstevel@tonic-gate /* 71 */ INVALID, 2160Sstevel@tonic-gate /* 72 */ INVALID, 2170Sstevel@tonic-gate /* 73 */ KEY(56), /* Japanese 106-key keyboard */ 2180Sstevel@tonic-gate /* 74 */ INVALID, 2190Sstevel@tonic-gate /* 75 */ INVALID, 2200Sstevel@tonic-gate /* 76 */ INVALID, 2210Sstevel@tonic-gate /* 77 */ INVALID, 2220Sstevel@tonic-gate /* 78 */ INVALID, 2230Sstevel@tonic-gate /* 79 */ KEY(132), /* Japanese 106-key keyboard */ 2240Sstevel@tonic-gate /* 7a */ INVALID, 2250Sstevel@tonic-gate /* 7b */ KEY(131), /* Japanese 106-key keyboard */ 2260Sstevel@tonic-gate /* 7c */ INVALID, 2270Sstevel@tonic-gate /* 7d */ KEY(14), /* Japanese 106-key keyboard */ 2280Sstevel@tonic-gate /* 7e */ INVALID, 2290Sstevel@tonic-gate /* 7f */ INVALID, 2300Sstevel@tonic-gate }; 2310Sstevel@tonic-gate 2320Sstevel@tonic-gate /* 2330Sstevel@tonic-gate * Parse table after receiving an E0 prefix code. 2340Sstevel@tonic-gate * 2350Sstevel@tonic-gate * Generally speaking, keys that were added on the 101-key keyboard are 2360Sstevel@tonic-gate * represented as an E0 followed by the code for an 84-key key. Software 2370Sstevel@tonic-gate * ignorant of the 101-key keyboard ignores the E0 and so is handled 2380Sstevel@tonic-gate * compatibly. Many of these variants involve "fake" shift presses 2390Sstevel@tonic-gate * and releases for compatibility; these are also prefixed with E0. 2400Sstevel@tonic-gate * We ignore these fake shifts. 2410Sstevel@tonic-gate */ 242822Ssethg static const unsigned char keytab_e0_set1[] = { 2430Sstevel@tonic-gate /* 00 */ INVALID, 2440Sstevel@tonic-gate /* 01 */ INVALID, 2450Sstevel@tonic-gate /* 02 */ INVALID, 2460Sstevel@tonic-gate /* 03 */ INVALID, 2470Sstevel@tonic-gate /* 04 */ INVALID, 2480Sstevel@tonic-gate /* 05 */ INVALID, 2490Sstevel@tonic-gate /* 06 */ INVALID, 2500Sstevel@tonic-gate /* 07 */ INVALID, 2510Sstevel@tonic-gate /* 08 */ INVALID, 2520Sstevel@tonic-gate /* 09 */ INVALID, 2530Sstevel@tonic-gate /* 0a */ INVALID, 2540Sstevel@tonic-gate /* 0b */ INVALID, 2550Sstevel@tonic-gate /* 0c */ INVALID, 2560Sstevel@tonic-gate /* 0d */ INVALID, 2570Sstevel@tonic-gate /* 0e */ INVALID, 2580Sstevel@tonic-gate /* 0f */ INVALID, 2590Sstevel@tonic-gate 2600Sstevel@tonic-gate /* 10 */ INVALID, 2610Sstevel@tonic-gate /* 11 */ INVALID, 2620Sstevel@tonic-gate /* 12 */ INVALID, 2630Sstevel@tonic-gate /* 13 */ INVALID, 2640Sstevel@tonic-gate /* 14 */ INVALID, 2650Sstevel@tonic-gate /* 15 */ INVALID, 2660Sstevel@tonic-gate /* 16 */ INVALID, 2670Sstevel@tonic-gate /* 17 */ INVALID, 2680Sstevel@tonic-gate /* 18 */ INVALID, 2690Sstevel@tonic-gate /* 19 */ INVALID, 2700Sstevel@tonic-gate /* 1a */ INVALID, 2710Sstevel@tonic-gate /* 1b */ INVALID, 2720Sstevel@tonic-gate /* 1c */ KEY(108), /* Enter (num) */ 2730Sstevel@tonic-gate /* 1d */ KEY(64), /* R Ctrl */ 2740Sstevel@tonic-gate /* 1e */ INVALID, 2750Sstevel@tonic-gate /* 1f */ INVALID, 2760Sstevel@tonic-gate 277*9026SSeth.Goldberg@Sun.COM /* 20 */ KEY(235), /* Mute */ 2780Sstevel@tonic-gate /* 21 */ INVALID, 2790Sstevel@tonic-gate /* 22 */ INVALID, 2800Sstevel@tonic-gate /* 23 */ INVALID, 2810Sstevel@tonic-gate /* 24 */ INVALID, 2820Sstevel@tonic-gate /* 25 */ INVALID, 2830Sstevel@tonic-gate /* 26 */ INVALID, 2840Sstevel@tonic-gate /* 27 */ INVALID, 2850Sstevel@tonic-gate /* 28 */ INVALID, 2860Sstevel@tonic-gate /* 29 */ INVALID, 2870Sstevel@tonic-gate /* 2a */ INVALID, 2880Sstevel@tonic-gate /* 2b */ INVALID, 2890Sstevel@tonic-gate /* 2c */ INVALID, 2900Sstevel@tonic-gate /* 2d */ INVALID, 291*9026SSeth.Goldberg@Sun.COM /* 2e */ KEY(234), /* Volume Down */ 2920Sstevel@tonic-gate /* 2f */ INVALID, 2930Sstevel@tonic-gate 294*9026SSeth.Goldberg@Sun.COM /* 30 */ KEY(233), /* Volume Up */ 2950Sstevel@tonic-gate /* 31 */ INVALID, 2960Sstevel@tonic-gate /* 32 */ INVALID, 2970Sstevel@tonic-gate /* 33 */ INVALID, 2980Sstevel@tonic-gate /* 34 */ INVALID, 2990Sstevel@tonic-gate /* 35 */ KEY(95), /* / (num) */ 3000Sstevel@tonic-gate /* 36 */ INVALID, 3010Sstevel@tonic-gate /* 37 */ KEY(124), /* PrintScreen (no Alt) */ 3020Sstevel@tonic-gate /* 38 */ KEY(62), /* R Alt */ 3030Sstevel@tonic-gate /* 39 */ INVALID, 3040Sstevel@tonic-gate /* 3a */ INVALID, 3050Sstevel@tonic-gate /* 3b */ INVALID, 3060Sstevel@tonic-gate /* 3c */ INVALID, 3070Sstevel@tonic-gate /* 3d */ INVALID, 3080Sstevel@tonic-gate /* 3e */ INVALID, 3090Sstevel@tonic-gate /* 3f */ INVALID, 3100Sstevel@tonic-gate 3110Sstevel@tonic-gate /* 40 */ INVALID, 3120Sstevel@tonic-gate /* 41 */ INVALID, 3130Sstevel@tonic-gate /* 42 */ INVALID, 3140Sstevel@tonic-gate /* 43 */ INVALID, 3150Sstevel@tonic-gate /* 44 */ INVALID, 3160Sstevel@tonic-gate /* 45 */ INVALID, 3170Sstevel@tonic-gate /* 46 */ KEY(126), /* Pause (with Cntl) */ 3180Sstevel@tonic-gate /* 47 */ KEY(80), /* Home (arrow) */ 3190Sstevel@tonic-gate /* 48 */ KEY(83), /* Up (arrow) */ 3200Sstevel@tonic-gate /* 49 */ KEY(85), /* PgUp (arrow) */ 3210Sstevel@tonic-gate /* 4a */ INVALID, 3220Sstevel@tonic-gate /* 4b */ KEY(79), /* Left (arrow) */ 3230Sstevel@tonic-gate /* 4c */ INVALID, 3240Sstevel@tonic-gate /* 4d */ KEY(89), /* Right (arrow) */ 3250Sstevel@tonic-gate /* 4e */ INVALID, 3260Sstevel@tonic-gate /* 4f */ KEY(81), /* End (arrow) */ 3270Sstevel@tonic-gate 3280Sstevel@tonic-gate /* 50 */ KEY(84), /* Down (arrow) */ 3290Sstevel@tonic-gate /* 51 */ KEY(86), /* PgDn (arrow) */ 3300Sstevel@tonic-gate /* 52 */ KEY(75), /* Insert (arrow) */ 3310Sstevel@tonic-gate /* 53 */ KEY(76), /* Delete (arrow) */ 3320Sstevel@tonic-gate /* 54 */ INVALID, 3330Sstevel@tonic-gate /* 55 */ INVALID, 3340Sstevel@tonic-gate /* 56 */ INVALID, 3350Sstevel@tonic-gate /* 57 */ INVALID, 3360Sstevel@tonic-gate /* 58 */ INVALID, 3370Sstevel@tonic-gate /* 59 */ INVALID, 3380Sstevel@tonic-gate /* 5a */ INVALID, 3390Sstevel@tonic-gate /* 5b */ KEY(59), /* L Window (104-key) */ 3400Sstevel@tonic-gate /* 5c */ KEY(63), /* R Window (104-key) */ 3410Sstevel@tonic-gate /* 5d */ KEY(65), /* Menu (104-key) */ 3420Sstevel@tonic-gate /* 5e */ INVALID, 3430Sstevel@tonic-gate /* 5f */ INVALID, 3440Sstevel@tonic-gate 3450Sstevel@tonic-gate /* 60 */ INVALID, 3460Sstevel@tonic-gate /* 61 */ INVALID, 3470Sstevel@tonic-gate /* 62 */ INVALID, 3480Sstevel@tonic-gate /* 63 */ INVALID, 3490Sstevel@tonic-gate /* 64 */ INVALID, 3500Sstevel@tonic-gate /* 65 */ INVALID, 3510Sstevel@tonic-gate /* 66 */ INVALID, 3520Sstevel@tonic-gate /* 67 */ INVALID, 3530Sstevel@tonic-gate /* 68 */ INVALID, 3540Sstevel@tonic-gate /* 69 */ INVALID, 3550Sstevel@tonic-gate /* 6a */ INVALID, 3560Sstevel@tonic-gate /* 6b */ INVALID, 3570Sstevel@tonic-gate /* 6c */ INVALID, 3580Sstevel@tonic-gate /* 6d */ INVALID, 3590Sstevel@tonic-gate /* 6e */ INVALID, 3600Sstevel@tonic-gate /* 6f */ INVALID, 3610Sstevel@tonic-gate 3620Sstevel@tonic-gate /* 70 */ INVALID, 3630Sstevel@tonic-gate /* 71 */ INVALID, 3640Sstevel@tonic-gate /* 72 */ INVALID, 3650Sstevel@tonic-gate /* 73 */ INVALID, 3660Sstevel@tonic-gate /* 74 */ INVALID, 3670Sstevel@tonic-gate /* 75 */ INVALID, 3680Sstevel@tonic-gate /* 76 */ INVALID, 3690Sstevel@tonic-gate /* 77 */ INVALID, 3700Sstevel@tonic-gate /* 78 */ INVALID, 3710Sstevel@tonic-gate /* 79 */ INVALID, 3720Sstevel@tonic-gate /* 7a */ INVALID, 3730Sstevel@tonic-gate /* 7b */ INVALID, 3740Sstevel@tonic-gate /* 7c */ INVALID, 3750Sstevel@tonic-gate /* 7d */ INVALID, 3760Sstevel@tonic-gate /* 7e */ INVALID, 3770Sstevel@tonic-gate }; 3780Sstevel@tonic-gate 3790Sstevel@tonic-gate 3800Sstevel@tonic-gate /* 3810Sstevel@tonic-gate * Parse table for the base keyboard state. The index is the start of 3820Sstevel@tonic-gate * a new sequence. 3830Sstevel@tonic-gate * 3840Sstevel@tonic-gate * Questionable or unusual cases: 385822Ssethg * 02 On some SPARC keyboards, this is the scan code for the STOP 386822Ssethg * key. The KEY() value was chosen so that it maps to a 387822Ssethg * HOLE entry in the keytables in kb8042_keytables.c; therefore, 388822Ssethg * the STOP key code is only translated properly when kb8042 389822Ssethg * is "emulating" a USB keyboard (which it is by default-- 390822Ssethg * see conskbd.c). 3910Sstevel@tonic-gate * 7f Old kd code says this is an 84-key SysReq. Manual says no. 3920Sstevel@tonic-gate * 87 Old kd code says 1 (num). Manual says no. 3930Sstevel@tonic-gate * 8c Old kd code says / (num). Manual says no. 3940Sstevel@tonic-gate * aa POST OK. Handled by code. 3950Sstevel@tonic-gate * e0 Extend prefix. Handled by code. (switches to E0 table) 3960Sstevel@tonic-gate * e1 Extend prefix. Handled by code. (Pause key only) 3970Sstevel@tonic-gate * f0 Break prefix. Handled by code. 3980Sstevel@tonic-gate * f1 Korean Hangul/Hanja key. Handled by code. 3990Sstevel@tonic-gate * f2 Korean Hangul key. Handled by code. 4000Sstevel@tonic-gate * ff Keyboard internal buffer overrun. Handled by code. 4010Sstevel@tonic-gate * 4020Sstevel@tonic-gate * Other values past the end of the table are treated as INVALID. 4030Sstevel@tonic-gate */ 4040Sstevel@tonic-gate 405822Ssethg static const unsigned char keytab_base_set2[] = { 4060Sstevel@tonic-gate /* scan state keycap */ 4070Sstevel@tonic-gate /* 00 */ INVALID, 4080Sstevel@tonic-gate /* 01 */ KEY(120), /* F9 */ 409822Ssethg #if defined(__sparc) 410822Ssethg /* 02 */ KEY(K8042_STOP), /* STOP */ 411822Ssethg #else 4120Sstevel@tonic-gate /* 02 */ INVALID, /* F7? Old code says so but manual doesn't */ 413822Ssethg #endif 4140Sstevel@tonic-gate /* 03 */ KEY(116), /* F5 */ 4150Sstevel@tonic-gate /* 04 */ KEY(114), /* F3 */ 4160Sstevel@tonic-gate /* 05 */ KEY(112), /* F1 */ 4170Sstevel@tonic-gate /* 06 */ KEY(113), /* F2 */ 4180Sstevel@tonic-gate /* 07 */ KEY(123), /* F12 */ 4190Sstevel@tonic-gate /* 08 */ INVALID, 4200Sstevel@tonic-gate /* 09 */ KEY(121), /* F10 */ 4210Sstevel@tonic-gate /* 0a */ KEY(119), /* F8 */ 4220Sstevel@tonic-gate /* 0b */ KEY(117), /* F6 */ 4230Sstevel@tonic-gate /* 0c */ KEY(115), /* F4 */ 4240Sstevel@tonic-gate /* 0d */ KEY(16), /* tab */ 4250Sstevel@tonic-gate /* 0e */ KEY(1), /* ` */ 4260Sstevel@tonic-gate /* 0f */ INVALID, 4270Sstevel@tonic-gate /* 10 */ INVALID, 4280Sstevel@tonic-gate /* 11 */ KEY(60), /* L Alt */ 4290Sstevel@tonic-gate /* 12 */ KEY(44), /* L Shift */ 4300Sstevel@tonic-gate /* 13 */ KEY(133), /* Japanese 106-key */ 4310Sstevel@tonic-gate /* 14 */ KEY(58), /* L Ctrl */ 4320Sstevel@tonic-gate /* 15 */ KEY(17), /* Q */ 4330Sstevel@tonic-gate /* 16 */ KEY(2), /* 1 */ 4340Sstevel@tonic-gate /* 17 */ INVALID, 4350Sstevel@tonic-gate /* 18 */ INVALID, 4360Sstevel@tonic-gate /* 19 */ INVALID, 4370Sstevel@tonic-gate /* 1a */ KEY(46), /* Z */ 4380Sstevel@tonic-gate /* 1b */ KEY(32), /* S */ 4390Sstevel@tonic-gate /* 1c */ KEY(31), /* A */ 4400Sstevel@tonic-gate /* 1d */ KEY(18), /* W */ 4410Sstevel@tonic-gate /* 1e */ KEY(3), /* 2 */ 4420Sstevel@tonic-gate /* 1f */ INVALID, 4430Sstevel@tonic-gate /* 20 */ INVALID, 4440Sstevel@tonic-gate /* 21 */ KEY(48), /* C */ 4450Sstevel@tonic-gate /* 22 */ KEY(47), /* X */ 4460Sstevel@tonic-gate /* 23 */ KEY(33), /* D */ 4470Sstevel@tonic-gate /* 24 */ KEY(19), /* E */ 4480Sstevel@tonic-gate /* 25 */ KEY(5), /* 4 */ 4490Sstevel@tonic-gate /* 26 */ KEY(4), /* 3 */ 4500Sstevel@tonic-gate /* 27 */ INVALID, 4510Sstevel@tonic-gate /* 28 */ INVALID, 4520Sstevel@tonic-gate /* 29 */ KEY(61), /* Space */ 4530Sstevel@tonic-gate /* 2a */ KEY(49), /* V */ 4540Sstevel@tonic-gate /* 2b */ KEY(34), /* F */ 4550Sstevel@tonic-gate /* 2c */ KEY(21), /* T */ 4560Sstevel@tonic-gate /* 2d */ KEY(20), /* R */ 4570Sstevel@tonic-gate /* 2e */ KEY(6), /* 5 */ 4580Sstevel@tonic-gate /* 2f */ INVALID, 4590Sstevel@tonic-gate /* 30 */ INVALID, 4600Sstevel@tonic-gate /* 31 */ KEY(51), /* N */ 4610Sstevel@tonic-gate /* 32 */ KEY(50), /* B */ 4620Sstevel@tonic-gate /* 33 */ KEY(36), /* H */ 4630Sstevel@tonic-gate /* 34 */ KEY(35), /* G */ 4640Sstevel@tonic-gate /* 35 */ KEY(22), /* Y */ 4650Sstevel@tonic-gate /* 36 */ KEY(7), /* 6 */ 4660Sstevel@tonic-gate /* 37 */ INVALID, 4670Sstevel@tonic-gate /* 38 */ INVALID, 4680Sstevel@tonic-gate /* 39 */ INVALID, 4690Sstevel@tonic-gate /* 3a */ KEY(52), /* M */ 4700Sstevel@tonic-gate /* 3b */ KEY(37), /* J */ 4710Sstevel@tonic-gate /* 3c */ KEY(23), /* U */ 4720Sstevel@tonic-gate /* 3d */ KEY(8), /* 7 */ 4730Sstevel@tonic-gate /* 3e */ KEY(9), /* 8 */ 4740Sstevel@tonic-gate /* 3f */ INVALID, 4750Sstevel@tonic-gate /* 40 */ INVALID, 4760Sstevel@tonic-gate /* 41 */ KEY(53), /* , */ 4770Sstevel@tonic-gate /* 42 */ KEY(38), /* K */ 4780Sstevel@tonic-gate /* 43 */ KEY(24), /* I */ 4790Sstevel@tonic-gate /* 44 */ KEY(25), /* O */ 4800Sstevel@tonic-gate /* 45 */ KEY(11), /* 0 */ 4810Sstevel@tonic-gate /* 46 */ KEY(10), /* 9 */ 4820Sstevel@tonic-gate /* 47 */ INVALID, 4830Sstevel@tonic-gate /* 48 */ INVALID, 4840Sstevel@tonic-gate /* 49 */ KEY(54), /* . */ 4850Sstevel@tonic-gate /* 4a */ KEY(55), /* / */ 4860Sstevel@tonic-gate /* 4b */ KEY(39), /* L */ 4870Sstevel@tonic-gate /* 4c */ KEY(40), /* ; */ 4880Sstevel@tonic-gate /* 4d */ KEY(26), /* P */ 4890Sstevel@tonic-gate /* 4e */ KEY(12), /* - */ 4900Sstevel@tonic-gate /* 4f */ INVALID, 4910Sstevel@tonic-gate /* 50 */ INVALID, 4920Sstevel@tonic-gate /* 51 */ KEY(56), /* Japanese 106-key */ 4930Sstevel@tonic-gate /* 52 */ KEY(41), /* ' */ 4940Sstevel@tonic-gate /* 53 */ INVALID, 4950Sstevel@tonic-gate /* 54 */ KEY(27), /* [ */ 4960Sstevel@tonic-gate /* 55 */ KEY(13), /* = */ 4970Sstevel@tonic-gate /* 56 */ INVALID, 4980Sstevel@tonic-gate /* 57 */ INVALID, 4990Sstevel@tonic-gate /* 58 */ KEY(30), /* CapsLock */ 5000Sstevel@tonic-gate /* 59 */ KEY(57), /* R Shift */ 5010Sstevel@tonic-gate /* 5a */ KEY(43), /* Enter (main) */ 5020Sstevel@tonic-gate /* 5b */ KEY(28), /* ] */ 5030Sstevel@tonic-gate /* 5c */ INVALID, 5040Sstevel@tonic-gate /* 5d */ KEY(29), /* \, key 42 for 102-key */ 5050Sstevel@tonic-gate /* 5e */ INVALID, 5060Sstevel@tonic-gate /* 5f */ INVALID, 5070Sstevel@tonic-gate /* 60 */ INVALID, 5080Sstevel@tonic-gate /* 61 */ KEY(45), /* 102-key only, typically </> */ 5090Sstevel@tonic-gate /* 62 */ INVALID, 5100Sstevel@tonic-gate /* 63 */ INVALID, 5110Sstevel@tonic-gate /* 64 */ KEY(132), /* Japanese 106-key */ 5120Sstevel@tonic-gate /* 65 */ INVALID, 5130Sstevel@tonic-gate /* 66 */ KEY(15), /* backspace */ 5140Sstevel@tonic-gate /* 67 */ KEY(131), /* Japanese 106-key */ 5150Sstevel@tonic-gate /* 68 */ INVALID, 5160Sstevel@tonic-gate /* 69 */ KEY(93), /* 1 (num) */ 5170Sstevel@tonic-gate /* 6a */ KEY(14), /* Japanese 106-key */ 5180Sstevel@tonic-gate /* 6b */ KEY(92), /* 4 (num) */ 5190Sstevel@tonic-gate /* 6c */ KEY(91), /* 7 (num) */ 5200Sstevel@tonic-gate /* 6d */ INVALID, 5210Sstevel@tonic-gate /* 6e */ INVALID, 5220Sstevel@tonic-gate /* 6f */ INVALID, 5230Sstevel@tonic-gate /* 70 */ KEY(99), /* 0 (num) */ 5240Sstevel@tonic-gate /* 71 */ KEY(104), /* . (num) */ 5250Sstevel@tonic-gate /* 72 */ KEY(98), /* 2 (num) */ 5260Sstevel@tonic-gate /* 73 */ KEY(97), /* 5 (num) */ 5270Sstevel@tonic-gate /* 74 */ KEY(102), /* 6 (num) */ 5280Sstevel@tonic-gate /* 75 */ KEY(96), /* 8 (num) */ 5290Sstevel@tonic-gate /* 76 */ KEY(110), /* Esc */ 5300Sstevel@tonic-gate /* 77 */ KEY(90), /* NumLock */ 5310Sstevel@tonic-gate /* 78 */ KEY(122), /* F11 */ 5320Sstevel@tonic-gate /* 79 */ KEY(106), /* + (num) */ 5330Sstevel@tonic-gate /* 7a */ KEY(103), /* 3 (num) */ 5340Sstevel@tonic-gate /* 7b */ KEY(105), /* - (num) */ 5350Sstevel@tonic-gate /* 7c */ KEY(100), /* * (num) */ 5360Sstevel@tonic-gate /* 7d */ KEY(101), /* 9 (num) */ 5370Sstevel@tonic-gate /* 7e */ KEY(125), /* Scroll Lock */ 5380Sstevel@tonic-gate /* 7f */ INVALID, /* 84-key SysReq? Manual says no. */ 5390Sstevel@tonic-gate /* 80 */ INVALID, 5400Sstevel@tonic-gate /* 81 */ INVALID, 5410Sstevel@tonic-gate /* 82 */ INVALID, 5420Sstevel@tonic-gate /* 83 */ KEY(118), /* F7 */ 5430Sstevel@tonic-gate /* 84 */ KEY(124), /* PrintScreen (w/ Alt = SysRq) */ 5440Sstevel@tonic-gate }; 5450Sstevel@tonic-gate 5460Sstevel@tonic-gate /* 5470Sstevel@tonic-gate * Parse table after receiving an E0 prefix code. 5480Sstevel@tonic-gate * 5490Sstevel@tonic-gate * Generally speaking, keys that were added on the 101-key keyboard are 5500Sstevel@tonic-gate * represented as an E0 followed by the code for an 84-key key. Software 5510Sstevel@tonic-gate * ignorant of the 101-key keyboard ignores the E0 and so is handled 5520Sstevel@tonic-gate * compatibly. Many of these variants involve "fake" shift presses 5530Sstevel@tonic-gate * and releases for compatibility; these are also prefixed with E0. 5540Sstevel@tonic-gate * We ignore these fake shifts. 5550Sstevel@tonic-gate */ 556822Ssethg static const unsigned char keytab_e0_set2[] = { 5570Sstevel@tonic-gate /* 00 */ INVALID, 5580Sstevel@tonic-gate /* 01 */ INVALID, 5590Sstevel@tonic-gate /* 02 */ INVALID, 5600Sstevel@tonic-gate /* 03 */ INVALID, 5610Sstevel@tonic-gate /* 04 */ INVALID, 5620Sstevel@tonic-gate /* 05 */ INVALID, 5630Sstevel@tonic-gate /* 06 */ INVALID, 5640Sstevel@tonic-gate /* 07 */ INVALID, 5650Sstevel@tonic-gate /* 08 */ INVALID, 5660Sstevel@tonic-gate /* 09 */ INVALID, 5670Sstevel@tonic-gate /* 0a */ INVALID, 5680Sstevel@tonic-gate /* 0b */ INVALID, 5690Sstevel@tonic-gate /* 0c */ INVALID, 5700Sstevel@tonic-gate /* 0d */ INVALID, 5710Sstevel@tonic-gate /* 0e */ INVALID, 5720Sstevel@tonic-gate /* 0f */ INVALID, 5730Sstevel@tonic-gate /* 10 */ INVALID, 5740Sstevel@tonic-gate /* 11 */ KEY(62), /* R Alt */ 5750Sstevel@tonic-gate /* 12 */ IGNORE, /* Fake L Shift */ 5760Sstevel@tonic-gate /* 13 */ INVALID, 5770Sstevel@tonic-gate /* 14 */ KEY(64), /* R Ctrl */ 5780Sstevel@tonic-gate /* 15 */ INVALID, 5790Sstevel@tonic-gate /* 16 */ INVALID, 5800Sstevel@tonic-gate /* 17 */ INVALID, 5810Sstevel@tonic-gate /* 18 */ INVALID, 5820Sstevel@tonic-gate /* 19 */ INVALID, 5830Sstevel@tonic-gate /* 1a */ INVALID, 5840Sstevel@tonic-gate /* 1b */ INVALID, 5850Sstevel@tonic-gate /* 1c */ INVALID, 5860Sstevel@tonic-gate /* 1d */ INVALID, 5870Sstevel@tonic-gate /* 1e */ INVALID, 5880Sstevel@tonic-gate /* 1f */ KEY(59), /* L Window (104-key) */ 5890Sstevel@tonic-gate /* 20 */ INVALID, 5900Sstevel@tonic-gate /* 21 */ INVALID, 5910Sstevel@tonic-gate /* 22 */ INVALID, 5920Sstevel@tonic-gate /* 23 */ INVALID, 5930Sstevel@tonic-gate /* 24 */ INVALID, 5940Sstevel@tonic-gate /* 25 */ INVALID, 5950Sstevel@tonic-gate /* 26 */ INVALID, 5960Sstevel@tonic-gate /* 27 */ KEY(63), /* R Window (104-key) */ 5970Sstevel@tonic-gate /* 28 */ INVALID, 5980Sstevel@tonic-gate /* 29 */ INVALID, 5990Sstevel@tonic-gate /* 2a */ INVALID, 6000Sstevel@tonic-gate /* 2b */ INVALID, 6010Sstevel@tonic-gate /* 2c */ INVALID, 6020Sstevel@tonic-gate /* 2d */ INVALID, 6030Sstevel@tonic-gate /* 2e */ INVALID, 6040Sstevel@tonic-gate /* 2f */ KEY(65), /* Menu (104-key) */ 6050Sstevel@tonic-gate /* 30 */ INVALID, 6060Sstevel@tonic-gate /* 31 */ INVALID, 6070Sstevel@tonic-gate /* 32 */ INVALID, 6080Sstevel@tonic-gate /* 33 */ INVALID, 6090Sstevel@tonic-gate /* 34 */ INVALID, 6100Sstevel@tonic-gate /* 35 */ INVALID, 6110Sstevel@tonic-gate /* 36 */ INVALID, 6120Sstevel@tonic-gate /* 37 */ INVALID, 6130Sstevel@tonic-gate /* 38 */ INVALID, 6140Sstevel@tonic-gate /* 39 */ INVALID, 6150Sstevel@tonic-gate /* 3a */ INVALID, 6160Sstevel@tonic-gate /* 3b */ INVALID, 6170Sstevel@tonic-gate /* 3c */ INVALID, 6180Sstevel@tonic-gate /* 3d */ INVALID, 6190Sstevel@tonic-gate /* 3e */ INVALID, 6200Sstevel@tonic-gate /* 3f */ INVALID, 6210Sstevel@tonic-gate /* 40 */ INVALID, 6220Sstevel@tonic-gate /* 41 */ INVALID, 6230Sstevel@tonic-gate /* 42 */ INVALID, 6240Sstevel@tonic-gate /* 43 */ INVALID, 6250Sstevel@tonic-gate /* 44 */ INVALID, 6260Sstevel@tonic-gate /* 45 */ INVALID, 6270Sstevel@tonic-gate /* 46 */ INVALID, 6280Sstevel@tonic-gate /* 47 */ INVALID, 6290Sstevel@tonic-gate /* 48 */ INVALID, 6300Sstevel@tonic-gate /* 49 */ INVALID, 6310Sstevel@tonic-gate /* 4a */ KEY(95), /* / (num) */ 6320Sstevel@tonic-gate /* 4b */ INVALID, 6330Sstevel@tonic-gate /* 4c */ INVALID, 6340Sstevel@tonic-gate /* 4d */ INVALID, 6350Sstevel@tonic-gate /* 4e */ INVALID, 6360Sstevel@tonic-gate /* 4f */ INVALID, 6370Sstevel@tonic-gate /* 50 */ INVALID, 6380Sstevel@tonic-gate /* 51 */ INVALID, 6390Sstevel@tonic-gate /* 52 */ INVALID, 6400Sstevel@tonic-gate /* 53 */ INVALID, 6410Sstevel@tonic-gate /* 54 */ INVALID, 6420Sstevel@tonic-gate /* 55 */ INVALID, 6430Sstevel@tonic-gate /* 56 */ INVALID, 6440Sstevel@tonic-gate /* 57 */ INVALID, 6450Sstevel@tonic-gate /* 58 */ INVALID, 6460Sstevel@tonic-gate /* 59 */ IGNORE, /* Fake R Shift */ 6470Sstevel@tonic-gate /* 5a */ KEY(108), /* Enter (num) */ 6480Sstevel@tonic-gate /* 5b */ INVALID, 6490Sstevel@tonic-gate /* 5c */ INVALID, 6500Sstevel@tonic-gate /* 5d */ INVALID, 6510Sstevel@tonic-gate /* 5e */ INVALID, 6520Sstevel@tonic-gate /* 5f */ INVALID, 6530Sstevel@tonic-gate /* 60 */ INVALID, 6540Sstevel@tonic-gate /* 61 */ INVALID, 6550Sstevel@tonic-gate /* 62 */ INVALID, 6560Sstevel@tonic-gate /* 63 */ INVALID, 6570Sstevel@tonic-gate /* 64 */ INVALID, 6580Sstevel@tonic-gate /* 65 */ INVALID, 6590Sstevel@tonic-gate /* 66 */ INVALID, 6600Sstevel@tonic-gate /* 67 */ INVALID, 6610Sstevel@tonic-gate /* 68 */ INVALID, 6620Sstevel@tonic-gate /* 69 */ KEY(81), /* End (arrow) */ 6630Sstevel@tonic-gate /* 6a */ INVALID, 6640Sstevel@tonic-gate /* 6b */ KEY(79), /* Left (arrow) */ 6650Sstevel@tonic-gate /* 6c */ KEY(80), /* Home (arrow) */ 6660Sstevel@tonic-gate /* 6d */ INVALID, 6670Sstevel@tonic-gate /* 6e */ INVALID, 6680Sstevel@tonic-gate /* 6f */ INVALID, 6690Sstevel@tonic-gate /* 70 */ KEY(75), /* Insert (arrow) */ 6700Sstevel@tonic-gate /* 71 */ KEY(76), /* Delete (arrow) */ 6710Sstevel@tonic-gate /* 72 */ KEY(84), /* Down (arrow) */ 6720Sstevel@tonic-gate /* 73 */ INVALID, 6730Sstevel@tonic-gate /* 74 */ KEY(89), /* Right (arrow) */ 6740Sstevel@tonic-gate /* 75 */ KEY(83), /* Up (arrow) */ 6750Sstevel@tonic-gate /* 76 */ INVALID, 6760Sstevel@tonic-gate /* 77 */ INVALID, 6770Sstevel@tonic-gate /* 78 */ INVALID, 6780Sstevel@tonic-gate /* 79 */ INVALID, 6790Sstevel@tonic-gate /* 7a */ KEY(86), /* PgDn (arrow) */ 6800Sstevel@tonic-gate /* 7b */ INVALID, 6810Sstevel@tonic-gate /* 7c */ KEY(124), /* PrintScreen (no Alt) */ 6820Sstevel@tonic-gate /* 7d */ KEY(85), /* PgUp (arrow) */ 6830Sstevel@tonic-gate /* 7e */ KEY(126), /* Pause (w/Ctrl = Break) */ 6840Sstevel@tonic-gate }; 6850Sstevel@tonic-gate 6860Sstevel@tonic-gate 6870Sstevel@tonic-gate /* 6880Sstevel@tonic-gate * Initialize the translation state machine. 6890Sstevel@tonic-gate */ 690822Ssethg int 691822Ssethg KeyboardConvertScan_init(struct kb8042 *kb8042, int scanset) 6920Sstevel@tonic-gate { 6930Sstevel@tonic-gate kb8042->parse_scan_state = STATE_IDLE; 694822Ssethg kb8042->break_received = 0; 695822Ssethg 696822Ssethg if (scanset == 1) { 697822Ssethg KeyboardConvertScan_fn = &KeyboardConvertScan_set1; 698822Ssethg keytab_base = keytab_base_set1; 699822Ssethg keytab_base_length = NELEM(keytab_base_set1); 700822Ssethg keytab_e0 = keytab_e0_set1; 701822Ssethg keytab_e0_length = NELEM(keytab_e0_set1); 702822Ssethg } else if (scanset == 2) { 703822Ssethg KeyboardConvertScan_fn = &KeyboardConvertScan_set2; 704822Ssethg keytab_base = keytab_base_set2; 705822Ssethg keytab_base_length = NELEM(keytab_base_set2); 706822Ssethg keytab_e0 = keytab_e0_set2; 707822Ssethg keytab_e0_length = NELEM(keytab_e0_set2); 708822Ssethg } else { 709822Ssethg return (DDI_FAILURE); 710822Ssethg } 711822Ssethg 712822Ssethg return (DDI_SUCCESS); 713822Ssethg } 714822Ssethg 715*9026SSeth.Goldberg@Sun.COM /* 716*9026SSeth.Goldberg@Sun.COM * KeyboardConvertScan(*kb8042, scan, *keynum, *state 717*9026SSeth.Goldberg@Sun.COM * *synthetic_release_needed) 718*9026SSeth.Goldberg@Sun.COM * 719*9026SSeth.Goldberg@Sun.COM * State machine that takes scan codes from the keyboard and resolves 720*9026SSeth.Goldberg@Sun.COM * them to key numbers using the above tables. Returns B_TRUE if this 721*9026SSeth.Goldberg@Sun.COM * scan code completes a scan code sequence, in which case "keynum", 722*9026SSeth.Goldberg@Sun.COM * "state", and "synthetic_release_needed" will be filled in correctly. 723*9026SSeth.Goldberg@Sun.COM * 724*9026SSeth.Goldberg@Sun.COM * "synthetic_release_needed" is a hack to handle the additional two 725*9026SSeth.Goldberg@Sun.COM * keys on a Korean keyboard. They report press only, so we tell the 726*9026SSeth.Goldberg@Sun.COM * upper layer to synthesize the release. 727*9026SSeth.Goldberg@Sun.COM */ 728822Ssethg boolean_t 729822Ssethg KeyboardConvertScan( 730822Ssethg struct kb8042 *kb8042, 731822Ssethg unsigned char scan, 732822Ssethg int *keynum, 733822Ssethg enum keystate *state, 734822Ssethg boolean_t *synthetic_release_needed) 735822Ssethg { 736822Ssethg ASSERT(KeyboardConvertScan_fn != NULL); 737822Ssethg 738822Ssethg return ((*KeyboardConvertScan_fn)(kb8042, scan, keynum, state, 739822Ssethg synthetic_release_needed)); 7400Sstevel@tonic-gate } 7410Sstevel@tonic-gate 7420Sstevel@tonic-gate boolean_t 743822Ssethg KeyboardConvertScan_set1( 7440Sstevel@tonic-gate struct kb8042 *kb8042, 7450Sstevel@tonic-gate unsigned char scan, 7460Sstevel@tonic-gate int *keynum, 7470Sstevel@tonic-gate enum keystate *state, 7480Sstevel@tonic-gate boolean_t *synthetic_release_needed) 7490Sstevel@tonic-gate { 750822Ssethg DEBUG_KD(("KeyboardConvertScan_set1: 0x%02x ", scan)); 7510Sstevel@tonic-gate 7520Sstevel@tonic-gate *synthetic_release_needed = B_FALSE; 7530Sstevel@tonic-gate *state = KEY_PRESSED; 7540Sstevel@tonic-gate 7550Sstevel@tonic-gate switch (scan) { 7560Sstevel@tonic-gate /* 7570Sstevel@tonic-gate * First, handle special cases. 7580Sstevel@tonic-gate * ACK has already been handled by our caller. 7590Sstevel@tonic-gate */ 7600Sstevel@tonic-gate case KB_ERROR: 7610Sstevel@tonic-gate /* 7620Sstevel@tonic-gate * Perhaps we should reset state here, 7630Sstevel@tonic-gate * since we no longer know what's going on. 7640Sstevel@tonic-gate */ 7650Sstevel@tonic-gate DEBUG_KD(("-> overrun\n")); 7660Sstevel@tonic-gate return (B_FALSE); 7670Sstevel@tonic-gate case KB_POST_FAIL: 7680Sstevel@tonic-gate /* 7690Sstevel@tonic-gate * Perhaps we should reset the LEDs now. 7700Sstevel@tonic-gate * If so, this check should probably be in the main line. 7710Sstevel@tonic-gate * Perhaps we should tell the higher layers that the 7720Sstevel@tonic-gate * keyboard has been reset. 7730Sstevel@tonic-gate */ 7740Sstevel@tonic-gate /* 7750Sstevel@tonic-gate * Reset to idle 7760Sstevel@tonic-gate */ 7770Sstevel@tonic-gate kb8042->parse_scan_state = STATE_IDLE; 7780Sstevel@tonic-gate DEBUG_KD(("-> POST %s\n", scan == KB_POST_OK ? "OK" : "FAIL")); 7790Sstevel@tonic-gate return (B_FALSE); 7800Sstevel@tonic-gate 7810Sstevel@tonic-gate case KXT_EXTEND: 7820Sstevel@tonic-gate case KXT_EXTEND2: 7830Sstevel@tonic-gate case KXT_HANGUL_HANJA: 7840Sstevel@tonic-gate case KXT_HANGUL: 7850Sstevel@tonic-gate /* 7860Sstevel@tonic-gate * Exclude these keys from the "default" test below. 7870Sstevel@tonic-gate */ 7880Sstevel@tonic-gate break; 7890Sstevel@tonic-gate 7900Sstevel@tonic-gate default: 7910Sstevel@tonic-gate /* 7920Sstevel@tonic-gate * See if it was a key release. 7930Sstevel@tonic-gate */ 7940Sstevel@tonic-gate if (scan > 0x80) { 7950Sstevel@tonic-gate *state = KEY_RELEASED; 7960Sstevel@tonic-gate scan -= 0x80; 7970Sstevel@tonic-gate } 7980Sstevel@tonic-gate break; 7990Sstevel@tonic-gate } 8000Sstevel@tonic-gate 801822Ssethg if (kb8042->break_received) { 802822Ssethg *state = KEY_RELEASED; 803822Ssethg kb8042->break_received = 0; 804822Ssethg } 805822Ssethg 8060Sstevel@tonic-gate switch (kb8042->parse_scan_state) { 8070Sstevel@tonic-gate case STATE_IDLE: 8080Sstevel@tonic-gate switch (scan) { 8090Sstevel@tonic-gate case KXT_EXTEND: 8100Sstevel@tonic-gate kb8042->parse_scan_state = STATE_E0; 8110Sstevel@tonic-gate DEBUG_KD(("-> state E0\n")); 8120Sstevel@tonic-gate return (B_FALSE); 8130Sstevel@tonic-gate 8140Sstevel@tonic-gate case KXT_EXTEND2: 8150Sstevel@tonic-gate kb8042->parse_scan_state = STATE_E1; 8160Sstevel@tonic-gate DEBUG_KD(("-> state E1\n")); 8170Sstevel@tonic-gate return (B_FALSE); 8180Sstevel@tonic-gate 8190Sstevel@tonic-gate /* 8200Sstevel@tonic-gate * We could do the next two in the table, but it would 8210Sstevel@tonic-gate * require nearly doubling the size of the table. 8220Sstevel@tonic-gate * 8230Sstevel@tonic-gate * Also, for some stupid reason these two report presses 8240Sstevel@tonic-gate * only. We tell the upper layer to synthesize a release. 8250Sstevel@tonic-gate */ 8260Sstevel@tonic-gate case KXT_HANGUL_HANJA: 8270Sstevel@tonic-gate *keynum = KEY(150); 8280Sstevel@tonic-gate *synthetic_release_needed = B_TRUE; 8290Sstevel@tonic-gate break; 8300Sstevel@tonic-gate 8310Sstevel@tonic-gate case KXT_HANGUL: 8320Sstevel@tonic-gate *keynum = KEY(151); 8330Sstevel@tonic-gate *synthetic_release_needed = B_TRUE; 8340Sstevel@tonic-gate break; 8350Sstevel@tonic-gate 8360Sstevel@tonic-gate default: 8370Sstevel@tonic-gate /* 8380Sstevel@tonic-gate * Regular scan code 8390Sstevel@tonic-gate */ 840822Ssethg if (scan < keytab_base_length) 8410Sstevel@tonic-gate *keynum = keytab_base[scan]; 8420Sstevel@tonic-gate else 8430Sstevel@tonic-gate *keynum = INVALID; 8440Sstevel@tonic-gate break; 8450Sstevel@tonic-gate } 8460Sstevel@tonic-gate break; 8470Sstevel@tonic-gate 8480Sstevel@tonic-gate case STATE_E0: /* Mostly 101-key additions */ 849822Ssethg if (scan < keytab_e0_length) 8500Sstevel@tonic-gate *keynum = keytab_e0[scan]; 8510Sstevel@tonic-gate else 8520Sstevel@tonic-gate *keynum = INVALID; 8530Sstevel@tonic-gate break; 8540Sstevel@tonic-gate 8550Sstevel@tonic-gate case STATE_E1: /* Pause key only */ 8560Sstevel@tonic-gate switch (scan) { 8570Sstevel@tonic-gate case 0x1d: 8580Sstevel@tonic-gate kb8042->parse_scan_state = STATE_E1_1D; 8590Sstevel@tonic-gate DEBUG_KD(("-> state E1 1D\n")); 8600Sstevel@tonic-gate return (B_FALSE); 8610Sstevel@tonic-gate default: 8620Sstevel@tonic-gate *keynum = INVALID; 8630Sstevel@tonic-gate break; 8640Sstevel@tonic-gate } 8650Sstevel@tonic-gate break; 8660Sstevel@tonic-gate 8670Sstevel@tonic-gate case STATE_E1_1D: /* Pause key only */ 8680Sstevel@tonic-gate switch (scan) { 8690Sstevel@tonic-gate case 0x45: 8700Sstevel@tonic-gate *keynum = KEY(126); /* Pause */ 8710Sstevel@tonic-gate break; 8720Sstevel@tonic-gate default: 8730Sstevel@tonic-gate *keynum = INVALID; 8740Sstevel@tonic-gate break; 8750Sstevel@tonic-gate } 8760Sstevel@tonic-gate break; 8770Sstevel@tonic-gate } 8780Sstevel@tonic-gate 8790Sstevel@tonic-gate /* 8800Sstevel@tonic-gate * The results (*keynum, *state, and *synthetic_release_needed) 8810Sstevel@tonic-gate * have been filled in, but they are valid only if we return 8820Sstevel@tonic-gate * B_TRUE which is only done below. If we make it to here, we 8830Sstevel@tonic-gate * have completed a scan code sequence, so reset parse_scan_state. 8840Sstevel@tonic-gate */ 8850Sstevel@tonic-gate 8860Sstevel@tonic-gate kb8042->parse_scan_state = STATE_IDLE; 8870Sstevel@tonic-gate 8880Sstevel@tonic-gate switch (*keynum) { 8890Sstevel@tonic-gate case KEYIGN: /* not a key, nor an error */ 8900Sstevel@tonic-gate DEBUG_KD(("-> hole -> ignored\n")); 8910Sstevel@tonic-gate return (B_FALSE); /* also not a final keycode */ 8920Sstevel@tonic-gate 8930Sstevel@tonic-gate case KEYBAD: /* not part of a legit sequence? */ 8940Sstevel@tonic-gate DEBUG_KD(("-> bad -> ignored\n")); 8950Sstevel@tonic-gate return (B_FALSE); /* and return not a final keycode */ 8960Sstevel@tonic-gate 8970Sstevel@tonic-gate default: 8980Sstevel@tonic-gate /* 8990Sstevel@tonic-gate * If we're here, it's a valid keycode. We've already 9000Sstevel@tonic-gate * filled in the return values; return success. 9010Sstevel@tonic-gate */ 9020Sstevel@tonic-gate 9030Sstevel@tonic-gate DEBUG_KD(("-> %s keypos %d\n", 904*9026SSeth.Goldberg@Sun.COM *state == KEY_RELEASED ? "released" : "pressed", 905*9026SSeth.Goldberg@Sun.COM *keynum)); 9060Sstevel@tonic-gate 9070Sstevel@tonic-gate return (B_TRUE); /* resolved to a key */ 9080Sstevel@tonic-gate } 9090Sstevel@tonic-gate } 910822Ssethg 911822Ssethg /* 912822Ssethg * KeyboardConvertScan(*kb8042, scan, *keynum, *state 913822Ssethg * *synthetic_release_needed) 914822Ssethg * 915822Ssethg * State machine that takes scan codes from the keyboard and resolves 916822Ssethg * them to key numbers using the above tables. Returns B_TRUE if this 917822Ssethg * scan code completes a scan code sequence, in which case "keynum", 918822Ssethg * "state", and "synthetic_release_needed" will be filled in correctly. 919822Ssethg * 920822Ssethg * "synthetic_release_needed" is a hack to handle the additional two 921822Ssethg * keys on a Korean keyboard. They report press only, so we tell the 922822Ssethg * upper layer to synthesize the release. 923822Ssethg */ 924822Ssethg boolean_t 925822Ssethg KeyboardConvertScan_set2( 926822Ssethg struct kb8042 *kb8042, 927822Ssethg unsigned char scan, 928822Ssethg int *keynum, 929822Ssethg enum keystate *state, 930822Ssethg boolean_t *synthetic_release_needed) 931822Ssethg { 932822Ssethg DEBUG_KD(("KeyboardConvertScan_set2: 0x%02x ", scan)); 933822Ssethg 934822Ssethg *synthetic_release_needed = B_FALSE; 935822Ssethg *state = KEY_PRESSED; 936822Ssethg 937822Ssethg switch (scan) { 938822Ssethg /* 939822Ssethg * First, handle special cases. 940822Ssethg * ACK has already been handled by our caller. 941822Ssethg */ 942822Ssethg 943822Ssethg /* 944822Ssethg * KAT_BREAK is 0xF0. It is the same as the break code for Japanese 945822Ssethg * key 133. 946822Ssethg * Therefore we don't treat it specially here. 947822Ssethg */ 948822Ssethg case KAT_BREAK: 949822Ssethg /* Switch states so we can recognize the code that follows */ 950822Ssethg kb8042->break_received = 1; 951822Ssethg DEBUG_KD(("-> break prefix\n")); 952822Ssethg return (B_FALSE); /* not a final keycode */ 953822Ssethg 954822Ssethg case KB_ERROR: 955822Ssethg /* 956822Ssethg * Perhaps we should reset state here, 957822Ssethg * since we no longer know what's going on. 958822Ssethg */ 959822Ssethg DEBUG_KD(("-> overrun\n")); 960822Ssethg return (B_FALSE); 961822Ssethg 962822Ssethg case KB_POST_OK: 963822Ssethg case KB_POST_FAIL: 964822Ssethg /* 965822Ssethg * Perhaps we should reset the LEDs now. 966822Ssethg * If so, this check should probably be in the main line. 967822Ssethg * Perhaps we should tell the higher layers that the 968822Ssethg * keyboard has been reset. 969822Ssethg */ 970822Ssethg /* 971822Ssethg * Reset to idle 972822Ssethg */ 973822Ssethg kb8042->parse_scan_state = STATE_IDLE; 974822Ssethg DEBUG_KD(("-> POST %s\n", scan == KB_POST_OK ? "OK" : "FAIL")); 975822Ssethg return (B_FALSE); 976822Ssethg } 977822Ssethg 978822Ssethg if (kb8042->break_received) { 979822Ssethg *state = KEY_RELEASED; 980822Ssethg kb8042->break_received = 0; 981822Ssethg } 982822Ssethg 983822Ssethg switch (kb8042->parse_scan_state) { 984822Ssethg case STATE_IDLE: 985822Ssethg switch (scan) { 986822Ssethg case KXT_EXTEND: 987822Ssethg kb8042->parse_scan_state = STATE_E0; 988822Ssethg DEBUG_KD(("-> state E0\n")); 989822Ssethg return (B_FALSE); 990822Ssethg 991822Ssethg case KXT_EXTEND2: 992822Ssethg kb8042->parse_scan_state = STATE_E1; 993822Ssethg DEBUG_KD(("-> state E1\n")); 994822Ssethg return (B_FALSE); 995822Ssethg 996822Ssethg /* 997822Ssethg * We could do the next two in the table, but it would 998822Ssethg * require nearly doubling the size of the table. 999822Ssethg * 1000822Ssethg * Also, for some stupid reason these two report presses 1001822Ssethg * only. We tell the upper layer to synthesize a release. 1002822Ssethg */ 1003822Ssethg case KXT_HANGUL_HANJA: 1004822Ssethg *keynum = KEY(150); 1005822Ssethg *synthetic_release_needed = B_TRUE; 1006822Ssethg break; 1007822Ssethg 1008822Ssethg case KXT_HANGUL: 1009822Ssethg *keynum = KEY(151); 1010822Ssethg *synthetic_release_needed = B_TRUE; 1011822Ssethg break; 1012822Ssethg 1013822Ssethg default: 1014822Ssethg /* 1015822Ssethg * Regular scan code 1016822Ssethg */ 1017822Ssethg if (scan < keytab_base_length) 1018822Ssethg *keynum = keytab_base[scan]; 1019822Ssethg else 1020822Ssethg *keynum = INVALID; 1021822Ssethg break; 1022822Ssethg } 1023822Ssethg break; 1024822Ssethg 1025822Ssethg case STATE_E0: /* Mostly 101-key additions */ 1026822Ssethg if (scan < keytab_e0_length) 1027822Ssethg *keynum = keytab_e0[scan]; 1028822Ssethg else 1029822Ssethg *keynum = INVALID; 1030822Ssethg break; 1031822Ssethg 1032822Ssethg case STATE_E1: /* Pause key only */ 1033822Ssethg switch (scan) { 1034822Ssethg case 0x14: 1035822Ssethg kb8042->parse_scan_state = STATE_E1_14; 1036822Ssethg DEBUG_KD(("-> state E1 14\n")); 1037822Ssethg return (B_FALSE); 1038822Ssethg default: 1039822Ssethg *keynum = INVALID; 1040822Ssethg break; 1041822Ssethg } 1042822Ssethg break; 1043822Ssethg 1044822Ssethg case STATE_E1_14: /* Pause key only */ 1045822Ssethg if (scan == 0x77) { 1046822Ssethg kb8042->parse_scan_state = STATE_E1_14_77; 1047822Ssethg return (B_FALSE); 1048822Ssethg } else { 1049822Ssethg *keynum = INVALID; 1050822Ssethg } 1051822Ssethg break; 1052822Ssethg 1053822Ssethg case STATE_E1_14_77: 1054822Ssethg if (scan == 0xE1) { 1055822Ssethg kb8042->parse_scan_state = STATE_E1_14_77_E1; 1056822Ssethg return (B_FALSE); 1057822Ssethg } else { 1058822Ssethg *keynum = INVALID; 1059822Ssethg } 1060822Ssethg break; 1061822Ssethg 1062822Ssethg case STATE_E1_14_77_E1: 1063822Ssethg if (scan == 0xF0) { 1064822Ssethg kb8042->parse_scan_state = STATE_E1_14_77_E1_F0; 1065822Ssethg return (B_FALSE); 1066822Ssethg } else { 1067822Ssethg *keynum = INVALID; 1068822Ssethg } 1069822Ssethg break; 1070822Ssethg 1071822Ssethg case STATE_E1_14_77_E1_F0: 1072822Ssethg if (scan == 0x14) { 1073822Ssethg kb8042->parse_scan_state = STATE_E1_14_77_E1_F0_14; 1074822Ssethg return (B_FALSE); 1075822Ssethg } else { 1076822Ssethg *keynum = INVALID; 1077822Ssethg } 1078822Ssethg break; 1079822Ssethg 1080822Ssethg case STATE_E1_14_77_E1_F0_14: 1081822Ssethg if (scan == 0xF0) { 1082822Ssethg kb8042->parse_scan_state = STATE_E1_14_77_E1_F0_14_F0; 1083822Ssethg return (B_FALSE); 1084822Ssethg } else { 1085822Ssethg *keynum = INVALID; 1086822Ssethg } 1087822Ssethg break; 1088822Ssethg 1089822Ssethg case STATE_E1_14_77_E1_F0_14_F0: 1090822Ssethg if (scan == 0x77) { 1091822Ssethg *keynum = KEY(126); /* Pause */ 1092822Ssethg } else { 1093822Ssethg *keynum = INVALID; 1094822Ssethg } 1095822Ssethg break; 1096822Ssethg } 1097822Ssethg 1098822Ssethg /* 1099822Ssethg * The results (*keynum, *state, and *synthetic_release_needed) 1100822Ssethg * have been filled in, but they are valid only if we return 1101822Ssethg * B_TRUE which is only done below. If we make it to here, we 1102822Ssethg * have completed a scan code sequence, so reset parse_scan_state. 1103822Ssethg */ 1104822Ssethg 1105822Ssethg if (kb8042->break_received) { 1106822Ssethg *state = KEY_RELEASED; 1107822Ssethg kb8042->break_received = 0; 1108822Ssethg } 1109822Ssethg 1110822Ssethg kb8042->parse_scan_state = STATE_IDLE; 1111822Ssethg 1112822Ssethg switch (*keynum) { 1113822Ssethg case KEYIGN: /* not a key, nor an error */ 1114822Ssethg DEBUG_KD(("-> hole -> ignored\n")); 1115822Ssethg return (B_FALSE); /* also not a final keycode */ 1116822Ssethg 1117822Ssethg case KEYBAD: /* not part of a legit sequence? */ 1118822Ssethg DEBUG_KD(("-> bad -> ignored\n")); 1119822Ssethg return (B_FALSE); /* and return not a final keycode */ 1120822Ssethg 1121822Ssethg default: 1122822Ssethg /* 1123822Ssethg * If we're here, it's a valid keycode. We've already 1124822Ssethg * filled in the return values; return success. 1125822Ssethg */ 1126822Ssethg 1127822Ssethg DEBUG_KD(("-> %s keypos %d\n", 1128*9026SSeth.Goldberg@Sun.COM *state == KEY_RELEASED ? "released" : "pressed", 1129*9026SSeth.Goldberg@Sun.COM *keynum)); 1130822Ssethg 1131822Ssethg return (B_TRUE); /* resolved to a key */ 1132822Ssethg } 1133822Ssethg } 1134