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 50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 70Sstevel@tonic-gate * with the License. 80Sstevel@tonic-gate * 90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 110Sstevel@tonic-gate * See the License for the specific language governing permissions 120Sstevel@tonic-gate * and limitations under the License. 130Sstevel@tonic-gate * 140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * CDDL HEADER END 210Sstevel@tonic-gate */ 220Sstevel@tonic-gate /* 23*822Ssethg * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 240Sstevel@tonic-gate * Use is subject to license terms. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 270Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 280Sstevel@tonic-gate 290Sstevel@tonic-gate #include <sys/types.h> 300Sstevel@tonic-gate #include <sys/stream.h> 310Sstevel@tonic-gate #include <sys/kbd.h> 320Sstevel@tonic-gate #include <sys/kbtrans.h> 330Sstevel@tonic-gate #include <sys/sunddi.h> 340Sstevel@tonic-gate #include <sys/consdev.h> 350Sstevel@tonic-gate #include <sys/promif.h> 360Sstevel@tonic-gate #include "kb8042.h" 370Sstevel@tonic-gate 380Sstevel@tonic-gate /* 390Sstevel@tonic-gate * Debugging for this module is enabled by the kb8042_debug flag 400Sstevel@tonic-gate * defined in kb8042.c. See that module for details. This flag is 410Sstevel@tonic-gate * hotkey enabled by F10 if the kb8042_enable_debug_hotkey flag is set. 420Sstevel@tonic-gate */ 430Sstevel@tonic-gate 440Sstevel@tonic-gate #if defined(DEBUG) || defined(lint) 450Sstevel@tonic-gate #define KD_DEBUG 460Sstevel@tonic-gate #endif 470Sstevel@tonic-gate 480Sstevel@tonic-gate /* 490Sstevel@tonic-gate * A note on the use of prom_printf here: Most of these routines can be 500Sstevel@tonic-gate * called from "polled mode", where we're servicing I/O requests from kmdb. 510Sstevel@tonic-gate * Normal system services are not available from polled mode; cmn_err will 520Sstevel@tonic-gate * not work. prom_printf is the only safe output mechanism. 530Sstevel@tonic-gate */ 540Sstevel@tonic-gate 550Sstevel@tonic-gate #if defined(KD_DEBUG) 560Sstevel@tonic-gate extern boolean_t kb8042_debug; 570Sstevel@tonic-gate #define DEBUG_KD(f) { if (kb8042_debug) prom_printf f; } 580Sstevel@tonic-gate #else 590Sstevel@tonic-gate #define DEBUG_KD(f) /* nothing */ 600Sstevel@tonic-gate #endif 610Sstevel@tonic-gate 620Sstevel@tonic-gate #define KEYBAD 0xff /* should generate an error */ 630Sstevel@tonic-gate #define KEYIGN 0xfe /* ignore this sequence */ 640Sstevel@tonic-gate 650Sstevel@tonic-gate #define KEY(code) (code) 660Sstevel@tonic-gate #define INVALID KEYBAD 670Sstevel@tonic-gate #define IGNORE KEYIGN 680Sstevel@tonic-gate 69*822Ssethg #define NELEM(a) (sizeof (a) / sizeof (a)[0]) 70*822Ssethg 710Sstevel@tonic-gate /* 720Sstevel@tonic-gate * These are the states of our parsing machine: 730Sstevel@tonic-gate */ 74*822Ssethg #define STATE_IDLE 0x00000001 /* Awaiting the start of a sequence */ 75*822Ssethg #define STATE_E0 0x00000002 /* Rec'd an E0 */ 76*822Ssethg #define STATE_E1 0x00000004 /* Rec'd an E1 (Pause key only) */ 77*822Ssethg #define STATE_E1_1D 0x00000008 /* Rec'd an E1 1D (Pause key only) */ 78*822Ssethg #define STATE_E1_14 0x00000010 /* Rec'd an E1 14 (Pause key only) */ 79*822Ssethg #define STATE_E1_14_77 0x00000020 80*822Ssethg #define STATE_E1_14_77_E1 0x00000040 81*822Ssethg #define STATE_E1_14_77_E1_F0 0x00000080 82*822Ssethg #define STATE_E1_14_77_E1_F0_14 0x00000100 83*822Ssethg #define STATE_E1_14_77_E1_F0_14_F0 0x00000200 840Sstevel@tonic-gate 85*822Ssethg static boolean_t KeyboardConvertScan_set1(struct kb8042 *, unsigned char, int *, 86*822Ssethg enum keystate *, boolean_t *); 87*822Ssethg static boolean_t KeyboardConvertScan_set2(struct kb8042 *, unsigned char, int *, 88*822Ssethg enum keystate *, boolean_t *); 890Sstevel@tonic-gate 90*822Ssethg static const unsigned char *keytab_base = NULL; 91*822Ssethg static int keytab_base_length = 0; 92*822Ssethg static const unsigned char *keytab_e0 = NULL; 93*822Ssethg static int keytab_e0_length = 0; 94*822Ssethg static boolean_t (*KeyboardConvertScan_fn)(struct kb8042 *, unsigned char, 95*822Ssethg int *, enum keystate *, boolean_t *) = NULL; 96*822Ssethg 97*822Ssethg static const unsigned char keytab_base_set1[] = { 980Sstevel@tonic-gate /* scan key number keycap */ 990Sstevel@tonic-gate /* 00 */ INVALID, 1000Sstevel@tonic-gate /* 01 */ KEY(110), /* Esc */ 1010Sstevel@tonic-gate /* 02 */ KEY(2), /* 1 */ 1020Sstevel@tonic-gate /* 03 */ KEY(3), /* 2 */ 1030Sstevel@tonic-gate /* 04 */ KEY(4), /* 3 */ 1040Sstevel@tonic-gate /* 05 */ KEY(5), /* 4 */ 1050Sstevel@tonic-gate /* 06 */ KEY(6), /* 5 */ 1060Sstevel@tonic-gate /* 07 */ KEY(7), /* 6 */ 1070Sstevel@tonic-gate /* 08 */ KEY(8), /* 7 */ 1080Sstevel@tonic-gate /* 09 */ KEY(9), /* 8 */ 1090Sstevel@tonic-gate /* 0a */ KEY(10), /* 9 */ 1100Sstevel@tonic-gate /* 0b */ KEY(11), /* 0 */ 1110Sstevel@tonic-gate /* 0c */ KEY(12), /* - */ 1120Sstevel@tonic-gate /* 0d */ KEY(13), /* = */ 1130Sstevel@tonic-gate /* 0e */ KEY(15), /* backspace */ 1140Sstevel@tonic-gate /* 0f */ KEY(16), /* tab */ 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate /* 10 */ KEY(17), /* Q */ 1170Sstevel@tonic-gate /* 11 */ KEY(18), /* W */ 1180Sstevel@tonic-gate /* 12 */ KEY(19), /* E */ 1190Sstevel@tonic-gate /* 13 */ KEY(20), /* R */ 1200Sstevel@tonic-gate /* 14 */ KEY(21), /* T */ 1210Sstevel@tonic-gate /* 15 */ KEY(22), /* Y */ 1220Sstevel@tonic-gate /* 16 */ KEY(23), /* U */ 1230Sstevel@tonic-gate /* 17 */ KEY(24), /* I */ 1240Sstevel@tonic-gate /* 18 */ KEY(25), /* O */ 1250Sstevel@tonic-gate /* 19 */ KEY(26), /* P */ 1260Sstevel@tonic-gate /* 1a */ KEY(27), /* [ */ 1270Sstevel@tonic-gate /* 1b */ KEY(28), /* ] */ 1280Sstevel@tonic-gate /* 1c */ KEY(43), /* Enter (main) */ 1290Sstevel@tonic-gate /* 1d */ KEY(58), /* L Ctrl */ 1300Sstevel@tonic-gate /* 1e */ KEY(31), /* A */ 1310Sstevel@tonic-gate /* 1f */ KEY(32), /* S */ 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate /* 20 */ KEY(33), /* D */ 1340Sstevel@tonic-gate /* 21 */ KEY(34), /* F */ 1350Sstevel@tonic-gate /* 22 */ KEY(35), /* G */ 1360Sstevel@tonic-gate /* 23 */ KEY(36), /* H */ 1370Sstevel@tonic-gate /* 24 */ KEY(37), /* J */ 1380Sstevel@tonic-gate /* 25 */ KEY(38), /* K */ 1390Sstevel@tonic-gate /* 26 */ KEY(39), /* L */ 1400Sstevel@tonic-gate /* 27 */ KEY(40), /* ; */ 1410Sstevel@tonic-gate /* 28 */ KEY(41), /* ' */ 1420Sstevel@tonic-gate /* 29 */ KEY(1), /* ` */ 1430Sstevel@tonic-gate /* 2a */ KEY(44), /* L Shift */ 1440Sstevel@tonic-gate /* 2b */ KEY(29), /* \ */ 1450Sstevel@tonic-gate /* 2c */ KEY(46), /* Z */ 1460Sstevel@tonic-gate /* 2d */ KEY(47), /* X */ 1470Sstevel@tonic-gate /* 2e */ KEY(48), /* C */ 1480Sstevel@tonic-gate /* 2f */ KEY(49), /* V */ 1490Sstevel@tonic-gate 1500Sstevel@tonic-gate /* 30 */ KEY(50), /* B */ 1510Sstevel@tonic-gate /* 31 */ KEY(51), /* N */ 1520Sstevel@tonic-gate /* 32 */ KEY(52), /* M */ 1530Sstevel@tonic-gate /* 33 */ KEY(53), /* , */ 1540Sstevel@tonic-gate /* 34 */ KEY(54), /* . */ 1550Sstevel@tonic-gate /* 35 */ KEY(55), /* / */ 1560Sstevel@tonic-gate /* 36 */ KEY(57), /* R Shift */ 1570Sstevel@tonic-gate /* 37 */ KEY(100), /* * (num) */ 1580Sstevel@tonic-gate /* 38 */ KEY(60), /* L Alt */ 1590Sstevel@tonic-gate /* 39 */ KEY(61), /* Space */ 1600Sstevel@tonic-gate /* 3a */ KEY(30), /* CapsLock */ 1610Sstevel@tonic-gate /* 3b */ KEY(112), /* F1 */ 1620Sstevel@tonic-gate /* 3c */ KEY(113), /* F2 */ 1630Sstevel@tonic-gate /* 3d */ KEY(114), /* F3 */ 1640Sstevel@tonic-gate /* 3e */ KEY(115), /* F4 */ 1650Sstevel@tonic-gate /* 3f */ KEY(116), /* F5 */ 1660Sstevel@tonic-gate 1670Sstevel@tonic-gate /* 40 */ KEY(117), /* F6 */ 1680Sstevel@tonic-gate /* 41 */ KEY(118), /* F7 */ 1690Sstevel@tonic-gate /* 42 */ KEY(119), /* F8 */ 1700Sstevel@tonic-gate /* 43 */ KEY(120), /* F9 */ 1710Sstevel@tonic-gate /* 44 */ KEY(121), /* F10 */ 1720Sstevel@tonic-gate /* 45 */ KEY(90), /* NumLock */ 1730Sstevel@tonic-gate /* 46 */ KEY(125), /* Scroll Lock */ 1740Sstevel@tonic-gate /* 47 */ KEY(91), /* 7 (num) */ 1750Sstevel@tonic-gate /* 48 */ KEY(96), /* 8 (num) */ 1760Sstevel@tonic-gate /* 49 */ KEY(101), /* 9 (num) */ 1770Sstevel@tonic-gate /* 4a */ KEY(105), /* - (num) */ 1780Sstevel@tonic-gate /* 4b */ KEY(92), /* 4 (num) */ 1790Sstevel@tonic-gate /* 4c */ KEY(97), /* 5 (num) */ 1800Sstevel@tonic-gate /* 4d */ KEY(102), /* 6 (num) */ 1810Sstevel@tonic-gate /* 4e */ KEY(106), /* + (num) */ 1820Sstevel@tonic-gate /* 4f */ KEY(93), /* 1 (num) */ 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate /* 50 */ KEY(98), /* 2 (num) */ 1850Sstevel@tonic-gate /* 51 */ KEY(103), /* 3 (num) */ 1860Sstevel@tonic-gate /* 52 */ KEY(99), /* 0 (num) */ 1870Sstevel@tonic-gate /* 53 */ KEY(104), /* . (num) */ 1880Sstevel@tonic-gate /* 54 */ KEY(124), /* PrintScreen (with Alt) */ 1890Sstevel@tonic-gate /* 55 */ INVALID, 1900Sstevel@tonic-gate /* 56 */ KEY(45), /* not labled (102-key only) */ 1910Sstevel@tonic-gate /* 57 */ KEY(122), /* F11 */ 1920Sstevel@tonic-gate /* 58 */ KEY(123), /* F12 */ 1930Sstevel@tonic-gate /* 59 */ INVALID, 1940Sstevel@tonic-gate /* 5a */ INVALID, 1950Sstevel@tonic-gate /* 5b */ INVALID, 1960Sstevel@tonic-gate /* 5c */ INVALID, 1970Sstevel@tonic-gate /* 5d */ INVALID, 1980Sstevel@tonic-gate /* 5e */ INVALID, 1990Sstevel@tonic-gate /* 5f */ INVALID, 2000Sstevel@tonic-gate 2010Sstevel@tonic-gate /* 60 */ INVALID, 2020Sstevel@tonic-gate /* 61 */ INVALID, 2030Sstevel@tonic-gate /* 62 */ INVALID, 2040Sstevel@tonic-gate /* 63 */ INVALID, 2050Sstevel@tonic-gate /* 64 */ INVALID, 2060Sstevel@tonic-gate /* 65 */ INVALID, 2070Sstevel@tonic-gate /* 66 */ INVALID, 2080Sstevel@tonic-gate /* 67 */ INVALID, 2090Sstevel@tonic-gate /* 68 */ INVALID, 2100Sstevel@tonic-gate /* 69 */ INVALID, 2110Sstevel@tonic-gate /* 6a */ INVALID, 2120Sstevel@tonic-gate /* 6b */ INVALID, 2130Sstevel@tonic-gate /* 6c */ INVALID, 2140Sstevel@tonic-gate /* 6d */ INVALID, 2150Sstevel@tonic-gate /* 6e */ INVALID, 2160Sstevel@tonic-gate /* 6f */ INVALID, 2170Sstevel@tonic-gate 2180Sstevel@tonic-gate /* 70 */ KEY(133), /* Japanese 106-key keyboard */ 2190Sstevel@tonic-gate /* 71 */ INVALID, 2200Sstevel@tonic-gate /* 72 */ INVALID, 2210Sstevel@tonic-gate /* 73 */ KEY(56), /* Japanese 106-key keyboard */ 2220Sstevel@tonic-gate /* 74 */ INVALID, 2230Sstevel@tonic-gate /* 75 */ INVALID, 2240Sstevel@tonic-gate /* 76 */ INVALID, 2250Sstevel@tonic-gate /* 77 */ INVALID, 2260Sstevel@tonic-gate /* 78 */ INVALID, 2270Sstevel@tonic-gate /* 79 */ KEY(132), /* Japanese 106-key keyboard */ 2280Sstevel@tonic-gate /* 7a */ INVALID, 2290Sstevel@tonic-gate /* 7b */ KEY(131), /* Japanese 106-key keyboard */ 2300Sstevel@tonic-gate /* 7c */ INVALID, 2310Sstevel@tonic-gate /* 7d */ KEY(14), /* Japanese 106-key keyboard */ 2320Sstevel@tonic-gate /* 7e */ INVALID, 2330Sstevel@tonic-gate /* 7f */ INVALID, 2340Sstevel@tonic-gate }; 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate /* 2370Sstevel@tonic-gate * Parse table after receiving an E0 prefix code. 2380Sstevel@tonic-gate * 2390Sstevel@tonic-gate * Generally speaking, keys that were added on the 101-key keyboard are 2400Sstevel@tonic-gate * represented as an E0 followed by the code for an 84-key key. Software 2410Sstevel@tonic-gate * ignorant of the 101-key keyboard ignores the E0 and so is handled 2420Sstevel@tonic-gate * compatibly. Many of these variants involve "fake" shift presses 2430Sstevel@tonic-gate * and releases for compatibility; these are also prefixed with E0. 2440Sstevel@tonic-gate * We ignore these fake shifts. 2450Sstevel@tonic-gate */ 246*822Ssethg static const unsigned char keytab_e0_set1[] = { 2470Sstevel@tonic-gate /* 00 */ INVALID, 2480Sstevel@tonic-gate /* 01 */ INVALID, 2490Sstevel@tonic-gate /* 02 */ INVALID, 2500Sstevel@tonic-gate /* 03 */ INVALID, 2510Sstevel@tonic-gate /* 04 */ INVALID, 2520Sstevel@tonic-gate /* 05 */ INVALID, 2530Sstevel@tonic-gate /* 06 */ INVALID, 2540Sstevel@tonic-gate /* 07 */ INVALID, 2550Sstevel@tonic-gate /* 08 */ INVALID, 2560Sstevel@tonic-gate /* 09 */ INVALID, 2570Sstevel@tonic-gate /* 0a */ INVALID, 2580Sstevel@tonic-gate /* 0b */ INVALID, 2590Sstevel@tonic-gate /* 0c */ INVALID, 2600Sstevel@tonic-gate /* 0d */ INVALID, 2610Sstevel@tonic-gate /* 0e */ INVALID, 2620Sstevel@tonic-gate /* 0f */ INVALID, 2630Sstevel@tonic-gate 2640Sstevel@tonic-gate /* 10 */ INVALID, 2650Sstevel@tonic-gate /* 11 */ INVALID, 2660Sstevel@tonic-gate /* 12 */ INVALID, 2670Sstevel@tonic-gate /* 13 */ INVALID, 2680Sstevel@tonic-gate /* 14 */ INVALID, 2690Sstevel@tonic-gate /* 15 */ INVALID, 2700Sstevel@tonic-gate /* 16 */ INVALID, 2710Sstevel@tonic-gate /* 17 */ INVALID, 2720Sstevel@tonic-gate /* 18 */ INVALID, 2730Sstevel@tonic-gate /* 19 */ INVALID, 2740Sstevel@tonic-gate /* 1a */ INVALID, 2750Sstevel@tonic-gate /* 1b */ INVALID, 2760Sstevel@tonic-gate /* 1c */ KEY(108), /* Enter (num) */ 2770Sstevel@tonic-gate /* 1d */ KEY(64), /* R Ctrl */ 2780Sstevel@tonic-gate /* 1e */ INVALID, 2790Sstevel@tonic-gate /* 1f */ INVALID, 2800Sstevel@tonic-gate 2810Sstevel@tonic-gate /* 20 */ INVALID, 2820Sstevel@tonic-gate /* 21 */ INVALID, 2830Sstevel@tonic-gate /* 22 */ INVALID, 2840Sstevel@tonic-gate /* 23 */ INVALID, 2850Sstevel@tonic-gate /* 24 */ INVALID, 2860Sstevel@tonic-gate /* 25 */ INVALID, 2870Sstevel@tonic-gate /* 26 */ INVALID, 2880Sstevel@tonic-gate /* 27 */ INVALID, 2890Sstevel@tonic-gate /* 28 */ INVALID, 2900Sstevel@tonic-gate /* 29 */ INVALID, 2910Sstevel@tonic-gate /* 2a */ INVALID, 2920Sstevel@tonic-gate /* 2b */ INVALID, 2930Sstevel@tonic-gate /* 2c */ INVALID, 2940Sstevel@tonic-gate /* 2d */ INVALID, 2950Sstevel@tonic-gate /* 2e */ INVALID, 2960Sstevel@tonic-gate /* 2f */ INVALID, 2970Sstevel@tonic-gate 2980Sstevel@tonic-gate /* 30 */ INVALID, 2990Sstevel@tonic-gate /* 31 */ INVALID, 3000Sstevel@tonic-gate /* 32 */ INVALID, 3010Sstevel@tonic-gate /* 33 */ INVALID, 3020Sstevel@tonic-gate /* 34 */ INVALID, 3030Sstevel@tonic-gate /* 35 */ KEY(95), /* / (num) */ 3040Sstevel@tonic-gate /* 36 */ INVALID, 3050Sstevel@tonic-gate /* 37 */ KEY(124), /* PrintScreen (no Alt) */ 3060Sstevel@tonic-gate /* 38 */ KEY(62), /* R Alt */ 3070Sstevel@tonic-gate /* 39 */ INVALID, 3080Sstevel@tonic-gate /* 3a */ INVALID, 3090Sstevel@tonic-gate /* 3b */ INVALID, 3100Sstevel@tonic-gate /* 3c */ INVALID, 3110Sstevel@tonic-gate /* 3d */ INVALID, 3120Sstevel@tonic-gate /* 3e */ INVALID, 3130Sstevel@tonic-gate /* 3f */ INVALID, 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate /* 40 */ INVALID, 3160Sstevel@tonic-gate /* 41 */ INVALID, 3170Sstevel@tonic-gate /* 42 */ INVALID, 3180Sstevel@tonic-gate /* 43 */ INVALID, 3190Sstevel@tonic-gate /* 44 */ INVALID, 3200Sstevel@tonic-gate /* 45 */ INVALID, 3210Sstevel@tonic-gate /* 46 */ KEY(126), /* Pause (with Cntl) */ 3220Sstevel@tonic-gate /* 47 */ KEY(80), /* Home (arrow) */ 3230Sstevel@tonic-gate /* 48 */ KEY(83), /* Up (arrow) */ 3240Sstevel@tonic-gate /* 49 */ KEY(85), /* PgUp (arrow) */ 3250Sstevel@tonic-gate /* 4a */ INVALID, 3260Sstevel@tonic-gate /* 4b */ KEY(79), /* Left (arrow) */ 3270Sstevel@tonic-gate /* 4c */ INVALID, 3280Sstevel@tonic-gate /* 4d */ KEY(89), /* Right (arrow) */ 3290Sstevel@tonic-gate /* 4e */ INVALID, 3300Sstevel@tonic-gate /* 4f */ KEY(81), /* End (arrow) */ 3310Sstevel@tonic-gate 3320Sstevel@tonic-gate /* 50 */ KEY(84), /* Down (arrow) */ 3330Sstevel@tonic-gate /* 51 */ KEY(86), /* PgDn (arrow) */ 3340Sstevel@tonic-gate /* 52 */ KEY(75), /* Insert (arrow) */ 3350Sstevel@tonic-gate /* 53 */ KEY(76), /* Delete (arrow) */ 3360Sstevel@tonic-gate /* 54 */ INVALID, 3370Sstevel@tonic-gate /* 55 */ INVALID, 3380Sstevel@tonic-gate /* 56 */ INVALID, 3390Sstevel@tonic-gate /* 57 */ INVALID, 3400Sstevel@tonic-gate /* 58 */ INVALID, 3410Sstevel@tonic-gate /* 59 */ INVALID, 3420Sstevel@tonic-gate /* 5a */ INVALID, 3430Sstevel@tonic-gate /* 5b */ KEY(59), /* L Window (104-key) */ 3440Sstevel@tonic-gate /* 5c */ KEY(63), /* R Window (104-key) */ 3450Sstevel@tonic-gate /* 5d */ KEY(65), /* Menu (104-key) */ 3460Sstevel@tonic-gate /* 5e */ INVALID, 3470Sstevel@tonic-gate /* 5f */ INVALID, 3480Sstevel@tonic-gate 3490Sstevel@tonic-gate /* 60 */ INVALID, 3500Sstevel@tonic-gate /* 61 */ INVALID, 3510Sstevel@tonic-gate /* 62 */ INVALID, 3520Sstevel@tonic-gate /* 63 */ INVALID, 3530Sstevel@tonic-gate /* 64 */ INVALID, 3540Sstevel@tonic-gate /* 65 */ INVALID, 3550Sstevel@tonic-gate /* 66 */ INVALID, 3560Sstevel@tonic-gate /* 67 */ INVALID, 3570Sstevel@tonic-gate /* 68 */ INVALID, 3580Sstevel@tonic-gate /* 69 */ INVALID, 3590Sstevel@tonic-gate /* 6a */ INVALID, 3600Sstevel@tonic-gate /* 6b */ INVALID, 3610Sstevel@tonic-gate /* 6c */ INVALID, 3620Sstevel@tonic-gate /* 6d */ INVALID, 3630Sstevel@tonic-gate /* 6e */ INVALID, 3640Sstevel@tonic-gate /* 6f */ INVALID, 3650Sstevel@tonic-gate 3660Sstevel@tonic-gate /* 70 */ INVALID, 3670Sstevel@tonic-gate /* 71 */ INVALID, 3680Sstevel@tonic-gate /* 72 */ INVALID, 3690Sstevel@tonic-gate /* 73 */ INVALID, 3700Sstevel@tonic-gate /* 74 */ INVALID, 3710Sstevel@tonic-gate /* 75 */ INVALID, 3720Sstevel@tonic-gate /* 76 */ INVALID, 3730Sstevel@tonic-gate /* 77 */ INVALID, 3740Sstevel@tonic-gate /* 78 */ INVALID, 3750Sstevel@tonic-gate /* 79 */ INVALID, 3760Sstevel@tonic-gate /* 7a */ INVALID, 3770Sstevel@tonic-gate /* 7b */ INVALID, 3780Sstevel@tonic-gate /* 7c */ INVALID, 3790Sstevel@tonic-gate /* 7d */ INVALID, 3800Sstevel@tonic-gate /* 7e */ INVALID, 3810Sstevel@tonic-gate }; 3820Sstevel@tonic-gate 3830Sstevel@tonic-gate 3840Sstevel@tonic-gate /* 3850Sstevel@tonic-gate * Parse table for the base keyboard state. The index is the start of 3860Sstevel@tonic-gate * a new sequence. 3870Sstevel@tonic-gate * 3880Sstevel@tonic-gate * Questionable or unusual cases: 389*822Ssethg * 02 On some SPARC keyboards, this is the scan code for the STOP 390*822Ssethg * key. The KEY() value was chosen so that it maps to a 391*822Ssethg * HOLE entry in the keytables in kb8042_keytables.c; therefore, 392*822Ssethg * the STOP key code is only translated properly when kb8042 393*822Ssethg * is "emulating" a USB keyboard (which it is by default-- 394*822Ssethg * see conskbd.c). 3950Sstevel@tonic-gate * 7f Old kd code says this is an 84-key SysReq. Manual says no. 3960Sstevel@tonic-gate * 87 Old kd code says 1 (num). Manual says no. 3970Sstevel@tonic-gate * 8c Old kd code says / (num). Manual says no. 3980Sstevel@tonic-gate * aa POST OK. Handled by code. 3990Sstevel@tonic-gate * e0 Extend prefix. Handled by code. (switches to E0 table) 4000Sstevel@tonic-gate * e1 Extend prefix. Handled by code. (Pause key only) 4010Sstevel@tonic-gate * f0 Break prefix. Handled by code. 4020Sstevel@tonic-gate * f1 Korean Hangul/Hanja key. Handled by code. 4030Sstevel@tonic-gate * f2 Korean Hangul key. Handled by code. 4040Sstevel@tonic-gate * ff Keyboard internal buffer overrun. Handled by code. 4050Sstevel@tonic-gate * 4060Sstevel@tonic-gate * Other values past the end of the table are treated as INVALID. 4070Sstevel@tonic-gate */ 4080Sstevel@tonic-gate 409*822Ssethg static const unsigned char keytab_base_set2[] = { 4100Sstevel@tonic-gate /* scan state keycap */ 4110Sstevel@tonic-gate /* 00 */ INVALID, 4120Sstevel@tonic-gate /* 01 */ KEY(120), /* F9 */ 413*822Ssethg #if defined(__sparc) 414*822Ssethg /* 02 */ KEY(K8042_STOP), /* STOP */ 415*822Ssethg #else 4160Sstevel@tonic-gate /* 02 */ INVALID, /* F7? Old code says so but manual doesn't */ 417*822Ssethg #endif 4180Sstevel@tonic-gate /* 03 */ KEY(116), /* F5 */ 4190Sstevel@tonic-gate /* 04 */ KEY(114), /* F3 */ 4200Sstevel@tonic-gate /* 05 */ KEY(112), /* F1 */ 4210Sstevel@tonic-gate /* 06 */ KEY(113), /* F2 */ 4220Sstevel@tonic-gate /* 07 */ KEY(123), /* F12 */ 4230Sstevel@tonic-gate /* 08 */ INVALID, 4240Sstevel@tonic-gate /* 09 */ KEY(121), /* F10 */ 4250Sstevel@tonic-gate /* 0a */ KEY(119), /* F8 */ 4260Sstevel@tonic-gate /* 0b */ KEY(117), /* F6 */ 4270Sstevel@tonic-gate /* 0c */ KEY(115), /* F4 */ 4280Sstevel@tonic-gate /* 0d */ KEY(16), /* tab */ 4290Sstevel@tonic-gate /* 0e */ KEY(1), /* ` */ 4300Sstevel@tonic-gate /* 0f */ INVALID, 4310Sstevel@tonic-gate /* 10 */ INVALID, 4320Sstevel@tonic-gate /* 11 */ KEY(60), /* L Alt */ 4330Sstevel@tonic-gate /* 12 */ KEY(44), /* L Shift */ 4340Sstevel@tonic-gate /* 13 */ KEY(133), /* Japanese 106-key */ 4350Sstevel@tonic-gate /* 14 */ KEY(58), /* L Ctrl */ 4360Sstevel@tonic-gate /* 15 */ KEY(17), /* Q */ 4370Sstevel@tonic-gate /* 16 */ KEY(2), /* 1 */ 4380Sstevel@tonic-gate /* 17 */ INVALID, 4390Sstevel@tonic-gate /* 18 */ INVALID, 4400Sstevel@tonic-gate /* 19 */ INVALID, 4410Sstevel@tonic-gate /* 1a */ KEY(46), /* Z */ 4420Sstevel@tonic-gate /* 1b */ KEY(32), /* S */ 4430Sstevel@tonic-gate /* 1c */ KEY(31), /* A */ 4440Sstevel@tonic-gate /* 1d */ KEY(18), /* W */ 4450Sstevel@tonic-gate /* 1e */ KEY(3), /* 2 */ 4460Sstevel@tonic-gate /* 1f */ INVALID, 4470Sstevel@tonic-gate /* 20 */ INVALID, 4480Sstevel@tonic-gate /* 21 */ KEY(48), /* C */ 4490Sstevel@tonic-gate /* 22 */ KEY(47), /* X */ 4500Sstevel@tonic-gate /* 23 */ KEY(33), /* D */ 4510Sstevel@tonic-gate /* 24 */ KEY(19), /* E */ 4520Sstevel@tonic-gate /* 25 */ KEY(5), /* 4 */ 4530Sstevel@tonic-gate /* 26 */ KEY(4), /* 3 */ 4540Sstevel@tonic-gate /* 27 */ INVALID, 4550Sstevel@tonic-gate /* 28 */ INVALID, 4560Sstevel@tonic-gate /* 29 */ KEY(61), /* Space */ 4570Sstevel@tonic-gate /* 2a */ KEY(49), /* V */ 4580Sstevel@tonic-gate /* 2b */ KEY(34), /* F */ 4590Sstevel@tonic-gate /* 2c */ KEY(21), /* T */ 4600Sstevel@tonic-gate /* 2d */ KEY(20), /* R */ 4610Sstevel@tonic-gate /* 2e */ KEY(6), /* 5 */ 4620Sstevel@tonic-gate /* 2f */ INVALID, 4630Sstevel@tonic-gate /* 30 */ INVALID, 4640Sstevel@tonic-gate /* 31 */ KEY(51), /* N */ 4650Sstevel@tonic-gate /* 32 */ KEY(50), /* B */ 4660Sstevel@tonic-gate /* 33 */ KEY(36), /* H */ 4670Sstevel@tonic-gate /* 34 */ KEY(35), /* G */ 4680Sstevel@tonic-gate /* 35 */ KEY(22), /* Y */ 4690Sstevel@tonic-gate /* 36 */ KEY(7), /* 6 */ 4700Sstevel@tonic-gate /* 37 */ INVALID, 4710Sstevel@tonic-gate /* 38 */ INVALID, 4720Sstevel@tonic-gate /* 39 */ INVALID, 4730Sstevel@tonic-gate /* 3a */ KEY(52), /* M */ 4740Sstevel@tonic-gate /* 3b */ KEY(37), /* J */ 4750Sstevel@tonic-gate /* 3c */ KEY(23), /* U */ 4760Sstevel@tonic-gate /* 3d */ KEY(8), /* 7 */ 4770Sstevel@tonic-gate /* 3e */ KEY(9), /* 8 */ 4780Sstevel@tonic-gate /* 3f */ INVALID, 4790Sstevel@tonic-gate /* 40 */ INVALID, 4800Sstevel@tonic-gate /* 41 */ KEY(53), /* , */ 4810Sstevel@tonic-gate /* 42 */ KEY(38), /* K */ 4820Sstevel@tonic-gate /* 43 */ KEY(24), /* I */ 4830Sstevel@tonic-gate /* 44 */ KEY(25), /* O */ 4840Sstevel@tonic-gate /* 45 */ KEY(11), /* 0 */ 4850Sstevel@tonic-gate /* 46 */ KEY(10), /* 9 */ 4860Sstevel@tonic-gate /* 47 */ INVALID, 4870Sstevel@tonic-gate /* 48 */ INVALID, 4880Sstevel@tonic-gate /* 49 */ KEY(54), /* . */ 4890Sstevel@tonic-gate /* 4a */ KEY(55), /* / */ 4900Sstevel@tonic-gate /* 4b */ KEY(39), /* L */ 4910Sstevel@tonic-gate /* 4c */ KEY(40), /* ; */ 4920Sstevel@tonic-gate /* 4d */ KEY(26), /* P */ 4930Sstevel@tonic-gate /* 4e */ KEY(12), /* - */ 4940Sstevel@tonic-gate /* 4f */ INVALID, 4950Sstevel@tonic-gate /* 50 */ INVALID, 4960Sstevel@tonic-gate /* 51 */ KEY(56), /* Japanese 106-key */ 4970Sstevel@tonic-gate /* 52 */ KEY(41), /* ' */ 4980Sstevel@tonic-gate /* 53 */ INVALID, 4990Sstevel@tonic-gate /* 54 */ KEY(27), /* [ */ 5000Sstevel@tonic-gate /* 55 */ KEY(13), /* = */ 5010Sstevel@tonic-gate /* 56 */ INVALID, 5020Sstevel@tonic-gate /* 57 */ INVALID, 5030Sstevel@tonic-gate /* 58 */ KEY(30), /* CapsLock */ 5040Sstevel@tonic-gate /* 59 */ KEY(57), /* R Shift */ 5050Sstevel@tonic-gate /* 5a */ KEY(43), /* Enter (main) */ 5060Sstevel@tonic-gate /* 5b */ KEY(28), /* ] */ 5070Sstevel@tonic-gate /* 5c */ INVALID, 5080Sstevel@tonic-gate /* 5d */ KEY(29), /* \, key 42 for 102-key */ 5090Sstevel@tonic-gate /* 5e */ INVALID, 5100Sstevel@tonic-gate /* 5f */ INVALID, 5110Sstevel@tonic-gate /* 60 */ INVALID, 5120Sstevel@tonic-gate /* 61 */ KEY(45), /* 102-key only, typically </> */ 5130Sstevel@tonic-gate /* 62 */ INVALID, 5140Sstevel@tonic-gate /* 63 */ INVALID, 5150Sstevel@tonic-gate /* 64 */ KEY(132), /* Japanese 106-key */ 5160Sstevel@tonic-gate /* 65 */ INVALID, 5170Sstevel@tonic-gate /* 66 */ KEY(15), /* backspace */ 5180Sstevel@tonic-gate /* 67 */ KEY(131), /* Japanese 106-key */ 5190Sstevel@tonic-gate /* 68 */ INVALID, 5200Sstevel@tonic-gate /* 69 */ KEY(93), /* 1 (num) */ 5210Sstevel@tonic-gate /* 6a */ KEY(14), /* Japanese 106-key */ 5220Sstevel@tonic-gate /* 6b */ KEY(92), /* 4 (num) */ 5230Sstevel@tonic-gate /* 6c */ KEY(91), /* 7 (num) */ 5240Sstevel@tonic-gate /* 6d */ INVALID, 5250Sstevel@tonic-gate /* 6e */ INVALID, 5260Sstevel@tonic-gate /* 6f */ INVALID, 5270Sstevel@tonic-gate /* 70 */ KEY(99), /* 0 (num) */ 5280Sstevel@tonic-gate /* 71 */ KEY(104), /* . (num) */ 5290Sstevel@tonic-gate /* 72 */ KEY(98), /* 2 (num) */ 5300Sstevel@tonic-gate /* 73 */ KEY(97), /* 5 (num) */ 5310Sstevel@tonic-gate /* 74 */ KEY(102), /* 6 (num) */ 5320Sstevel@tonic-gate /* 75 */ KEY(96), /* 8 (num) */ 5330Sstevel@tonic-gate /* 76 */ KEY(110), /* Esc */ 5340Sstevel@tonic-gate /* 77 */ KEY(90), /* NumLock */ 5350Sstevel@tonic-gate /* 78 */ KEY(122), /* F11 */ 5360Sstevel@tonic-gate /* 79 */ KEY(106), /* + (num) */ 5370Sstevel@tonic-gate /* 7a */ KEY(103), /* 3 (num) */ 5380Sstevel@tonic-gate /* 7b */ KEY(105), /* - (num) */ 5390Sstevel@tonic-gate /* 7c */ KEY(100), /* * (num) */ 5400Sstevel@tonic-gate /* 7d */ KEY(101), /* 9 (num) */ 5410Sstevel@tonic-gate /* 7e */ KEY(125), /* Scroll Lock */ 5420Sstevel@tonic-gate /* 7f */ INVALID, /* 84-key SysReq? Manual says no. */ 5430Sstevel@tonic-gate /* 80 */ INVALID, 5440Sstevel@tonic-gate /* 81 */ INVALID, 5450Sstevel@tonic-gate /* 82 */ INVALID, 5460Sstevel@tonic-gate /* 83 */ KEY(118), /* F7 */ 5470Sstevel@tonic-gate /* 84 */ KEY(124), /* PrintScreen (w/ Alt = SysRq) */ 5480Sstevel@tonic-gate }; 5490Sstevel@tonic-gate 5500Sstevel@tonic-gate /* 5510Sstevel@tonic-gate * Parse table after receiving an E0 prefix code. 5520Sstevel@tonic-gate * 5530Sstevel@tonic-gate * Generally speaking, keys that were added on the 101-key keyboard are 5540Sstevel@tonic-gate * represented as an E0 followed by the code for an 84-key key. Software 5550Sstevel@tonic-gate * ignorant of the 101-key keyboard ignores the E0 and so is handled 5560Sstevel@tonic-gate * compatibly. Many of these variants involve "fake" shift presses 5570Sstevel@tonic-gate * and releases for compatibility; these are also prefixed with E0. 5580Sstevel@tonic-gate * We ignore these fake shifts. 5590Sstevel@tonic-gate */ 560*822Ssethg static const unsigned char keytab_e0_set2[] = { 5610Sstevel@tonic-gate /* 00 */ INVALID, 5620Sstevel@tonic-gate /* 01 */ INVALID, 5630Sstevel@tonic-gate /* 02 */ INVALID, 5640Sstevel@tonic-gate /* 03 */ INVALID, 5650Sstevel@tonic-gate /* 04 */ INVALID, 5660Sstevel@tonic-gate /* 05 */ INVALID, 5670Sstevel@tonic-gate /* 06 */ INVALID, 5680Sstevel@tonic-gate /* 07 */ INVALID, 5690Sstevel@tonic-gate /* 08 */ INVALID, 5700Sstevel@tonic-gate /* 09 */ INVALID, 5710Sstevel@tonic-gate /* 0a */ INVALID, 5720Sstevel@tonic-gate /* 0b */ INVALID, 5730Sstevel@tonic-gate /* 0c */ INVALID, 5740Sstevel@tonic-gate /* 0d */ INVALID, 5750Sstevel@tonic-gate /* 0e */ INVALID, 5760Sstevel@tonic-gate /* 0f */ INVALID, 5770Sstevel@tonic-gate /* 10 */ INVALID, 5780Sstevel@tonic-gate /* 11 */ KEY(62), /* R Alt */ 5790Sstevel@tonic-gate /* 12 */ IGNORE, /* Fake L Shift */ 5800Sstevel@tonic-gate /* 13 */ INVALID, 5810Sstevel@tonic-gate /* 14 */ KEY(64), /* R Ctrl */ 5820Sstevel@tonic-gate /* 15 */ INVALID, 5830Sstevel@tonic-gate /* 16 */ INVALID, 5840Sstevel@tonic-gate /* 17 */ INVALID, 5850Sstevel@tonic-gate /* 18 */ INVALID, 5860Sstevel@tonic-gate /* 19 */ INVALID, 5870Sstevel@tonic-gate /* 1a */ INVALID, 5880Sstevel@tonic-gate /* 1b */ INVALID, 5890Sstevel@tonic-gate /* 1c */ INVALID, 5900Sstevel@tonic-gate /* 1d */ INVALID, 5910Sstevel@tonic-gate /* 1e */ INVALID, 5920Sstevel@tonic-gate /* 1f */ KEY(59), /* L Window (104-key) */ 5930Sstevel@tonic-gate /* 20 */ INVALID, 5940Sstevel@tonic-gate /* 21 */ INVALID, 5950Sstevel@tonic-gate /* 22 */ INVALID, 5960Sstevel@tonic-gate /* 23 */ INVALID, 5970Sstevel@tonic-gate /* 24 */ INVALID, 5980Sstevel@tonic-gate /* 25 */ INVALID, 5990Sstevel@tonic-gate /* 26 */ INVALID, 6000Sstevel@tonic-gate /* 27 */ KEY(63), /* R Window (104-key) */ 6010Sstevel@tonic-gate /* 28 */ INVALID, 6020Sstevel@tonic-gate /* 29 */ INVALID, 6030Sstevel@tonic-gate /* 2a */ INVALID, 6040Sstevel@tonic-gate /* 2b */ INVALID, 6050Sstevel@tonic-gate /* 2c */ INVALID, 6060Sstevel@tonic-gate /* 2d */ INVALID, 6070Sstevel@tonic-gate /* 2e */ INVALID, 6080Sstevel@tonic-gate /* 2f */ KEY(65), /* Menu (104-key) */ 6090Sstevel@tonic-gate /* 30 */ INVALID, 6100Sstevel@tonic-gate /* 31 */ INVALID, 6110Sstevel@tonic-gate /* 32 */ INVALID, 6120Sstevel@tonic-gate /* 33 */ INVALID, 6130Sstevel@tonic-gate /* 34 */ INVALID, 6140Sstevel@tonic-gate /* 35 */ INVALID, 6150Sstevel@tonic-gate /* 36 */ INVALID, 6160Sstevel@tonic-gate /* 37 */ INVALID, 6170Sstevel@tonic-gate /* 38 */ INVALID, 6180Sstevel@tonic-gate /* 39 */ INVALID, 6190Sstevel@tonic-gate /* 3a */ INVALID, 6200Sstevel@tonic-gate /* 3b */ INVALID, 6210Sstevel@tonic-gate /* 3c */ INVALID, 6220Sstevel@tonic-gate /* 3d */ INVALID, 6230Sstevel@tonic-gate /* 3e */ INVALID, 6240Sstevel@tonic-gate /* 3f */ INVALID, 6250Sstevel@tonic-gate /* 40 */ INVALID, 6260Sstevel@tonic-gate /* 41 */ INVALID, 6270Sstevel@tonic-gate /* 42 */ INVALID, 6280Sstevel@tonic-gate /* 43 */ INVALID, 6290Sstevel@tonic-gate /* 44 */ INVALID, 6300Sstevel@tonic-gate /* 45 */ INVALID, 6310Sstevel@tonic-gate /* 46 */ INVALID, 6320Sstevel@tonic-gate /* 47 */ INVALID, 6330Sstevel@tonic-gate /* 48 */ INVALID, 6340Sstevel@tonic-gate /* 49 */ INVALID, 6350Sstevel@tonic-gate /* 4a */ KEY(95), /* / (num) */ 6360Sstevel@tonic-gate /* 4b */ INVALID, 6370Sstevel@tonic-gate /* 4c */ INVALID, 6380Sstevel@tonic-gate /* 4d */ INVALID, 6390Sstevel@tonic-gate /* 4e */ INVALID, 6400Sstevel@tonic-gate /* 4f */ INVALID, 6410Sstevel@tonic-gate /* 50 */ INVALID, 6420Sstevel@tonic-gate /* 51 */ INVALID, 6430Sstevel@tonic-gate /* 52 */ INVALID, 6440Sstevel@tonic-gate /* 53 */ INVALID, 6450Sstevel@tonic-gate /* 54 */ INVALID, 6460Sstevel@tonic-gate /* 55 */ INVALID, 6470Sstevel@tonic-gate /* 56 */ INVALID, 6480Sstevel@tonic-gate /* 57 */ INVALID, 6490Sstevel@tonic-gate /* 58 */ INVALID, 6500Sstevel@tonic-gate /* 59 */ IGNORE, /* Fake R Shift */ 6510Sstevel@tonic-gate /* 5a */ KEY(108), /* Enter (num) */ 6520Sstevel@tonic-gate /* 5b */ INVALID, 6530Sstevel@tonic-gate /* 5c */ INVALID, 6540Sstevel@tonic-gate /* 5d */ INVALID, 6550Sstevel@tonic-gate /* 5e */ INVALID, 6560Sstevel@tonic-gate /* 5f */ INVALID, 6570Sstevel@tonic-gate /* 60 */ INVALID, 6580Sstevel@tonic-gate /* 61 */ INVALID, 6590Sstevel@tonic-gate /* 62 */ INVALID, 6600Sstevel@tonic-gate /* 63 */ INVALID, 6610Sstevel@tonic-gate /* 64 */ INVALID, 6620Sstevel@tonic-gate /* 65 */ INVALID, 6630Sstevel@tonic-gate /* 66 */ INVALID, 6640Sstevel@tonic-gate /* 67 */ INVALID, 6650Sstevel@tonic-gate /* 68 */ INVALID, 6660Sstevel@tonic-gate /* 69 */ KEY(81), /* End (arrow) */ 6670Sstevel@tonic-gate /* 6a */ INVALID, 6680Sstevel@tonic-gate /* 6b */ KEY(79), /* Left (arrow) */ 6690Sstevel@tonic-gate /* 6c */ KEY(80), /* Home (arrow) */ 6700Sstevel@tonic-gate /* 6d */ INVALID, 6710Sstevel@tonic-gate /* 6e */ INVALID, 6720Sstevel@tonic-gate /* 6f */ INVALID, 6730Sstevel@tonic-gate /* 70 */ KEY(75), /* Insert (arrow) */ 6740Sstevel@tonic-gate /* 71 */ KEY(76), /* Delete (arrow) */ 6750Sstevel@tonic-gate /* 72 */ KEY(84), /* Down (arrow) */ 6760Sstevel@tonic-gate /* 73 */ INVALID, 6770Sstevel@tonic-gate /* 74 */ KEY(89), /* Right (arrow) */ 6780Sstevel@tonic-gate /* 75 */ KEY(83), /* Up (arrow) */ 6790Sstevel@tonic-gate /* 76 */ INVALID, 6800Sstevel@tonic-gate /* 77 */ INVALID, 6810Sstevel@tonic-gate /* 78 */ INVALID, 6820Sstevel@tonic-gate /* 79 */ INVALID, 6830Sstevel@tonic-gate /* 7a */ KEY(86), /* PgDn (arrow) */ 6840Sstevel@tonic-gate /* 7b */ INVALID, 6850Sstevel@tonic-gate /* 7c */ KEY(124), /* PrintScreen (no Alt) */ 6860Sstevel@tonic-gate /* 7d */ KEY(85), /* PgUp (arrow) */ 6870Sstevel@tonic-gate /* 7e */ KEY(126), /* Pause (w/Ctrl = Break) */ 6880Sstevel@tonic-gate }; 6890Sstevel@tonic-gate 6900Sstevel@tonic-gate 6910Sstevel@tonic-gate /* 6920Sstevel@tonic-gate * Initialize the translation state machine. 6930Sstevel@tonic-gate */ 694*822Ssethg int 695*822Ssethg KeyboardConvertScan_init(struct kb8042 *kb8042, int scanset) 6960Sstevel@tonic-gate { 6970Sstevel@tonic-gate kb8042->parse_scan_state = STATE_IDLE; 698*822Ssethg kb8042->break_received = 0; 699*822Ssethg 700*822Ssethg if (scanset == 1) { 701*822Ssethg KeyboardConvertScan_fn = &KeyboardConvertScan_set1; 702*822Ssethg keytab_base = keytab_base_set1; 703*822Ssethg keytab_base_length = NELEM(keytab_base_set1); 704*822Ssethg keytab_e0 = keytab_e0_set1; 705*822Ssethg keytab_e0_length = NELEM(keytab_e0_set1); 706*822Ssethg } else if (scanset == 2) { 707*822Ssethg KeyboardConvertScan_fn = &KeyboardConvertScan_set2; 708*822Ssethg keytab_base = keytab_base_set2; 709*822Ssethg keytab_base_length = NELEM(keytab_base_set2); 710*822Ssethg keytab_e0 = keytab_e0_set2; 711*822Ssethg keytab_e0_length = NELEM(keytab_e0_set2); 712*822Ssethg } else { 713*822Ssethg return (DDI_FAILURE); 714*822Ssethg } 715*822Ssethg 716*822Ssethg return (DDI_SUCCESS); 717*822Ssethg } 718*822Ssethg 719*822Ssethg boolean_t 720*822Ssethg KeyboardConvertScan( 721*822Ssethg struct kb8042 *kb8042, 722*822Ssethg unsigned char scan, 723*822Ssethg int *keynum, 724*822Ssethg enum keystate *state, 725*822Ssethg boolean_t *synthetic_release_needed) 726*822Ssethg { 727*822Ssethg ASSERT(KeyboardConvertScan_fn != NULL); 728*822Ssethg 729*822Ssethg return ((*KeyboardConvertScan_fn)(kb8042, scan, keynum, state, 730*822Ssethg synthetic_release_needed)); 7310Sstevel@tonic-gate } 7320Sstevel@tonic-gate 7330Sstevel@tonic-gate /* 7340Sstevel@tonic-gate * KeyboardConvertScan(*kb8042, scan, *keynum, *state 7350Sstevel@tonic-gate * *synthetic_release_needed) 7360Sstevel@tonic-gate * 7370Sstevel@tonic-gate * State machine that takes scan codes from the keyboard and resolves 7380Sstevel@tonic-gate * them to key numbers using the above tables. Returns B_TRUE if this 7390Sstevel@tonic-gate * scan code completes a scan code sequence, in which case "keynum", 7400Sstevel@tonic-gate * "state", and "synthetic_release_needed" will be filled in correctly. 7410Sstevel@tonic-gate * 7420Sstevel@tonic-gate * "synthetic_release_needed" is a hack to handle the additional two 7430Sstevel@tonic-gate * keys on a Korean keyboard. They report press only, so we tell the 7440Sstevel@tonic-gate * upper layer to synthesize the release. 7450Sstevel@tonic-gate */ 7460Sstevel@tonic-gate boolean_t 747*822Ssethg KeyboardConvertScan_set1( 7480Sstevel@tonic-gate struct kb8042 *kb8042, 7490Sstevel@tonic-gate unsigned char scan, 7500Sstevel@tonic-gate int *keynum, 7510Sstevel@tonic-gate enum keystate *state, 7520Sstevel@tonic-gate boolean_t *synthetic_release_needed) 7530Sstevel@tonic-gate { 754*822Ssethg DEBUG_KD(("KeyboardConvertScan_set1: 0x%02x ", scan)); 7550Sstevel@tonic-gate 7560Sstevel@tonic-gate *synthetic_release_needed = B_FALSE; 7570Sstevel@tonic-gate *state = KEY_PRESSED; 7580Sstevel@tonic-gate 7590Sstevel@tonic-gate switch (scan) { 7600Sstevel@tonic-gate /* 7610Sstevel@tonic-gate * First, handle special cases. 7620Sstevel@tonic-gate * ACK has already been handled by our caller. 7630Sstevel@tonic-gate */ 7640Sstevel@tonic-gate case KB_ERROR: 7650Sstevel@tonic-gate /* 7660Sstevel@tonic-gate * Perhaps we should reset state here, 7670Sstevel@tonic-gate * since we no longer know what's going on. 7680Sstevel@tonic-gate */ 7690Sstevel@tonic-gate DEBUG_KD(("-> overrun\n")); 7700Sstevel@tonic-gate return (B_FALSE); 7710Sstevel@tonic-gate case KB_POST_FAIL: 7720Sstevel@tonic-gate /* 7730Sstevel@tonic-gate * Perhaps we should reset the LEDs now. 7740Sstevel@tonic-gate * If so, this check should probably be in the main line. 7750Sstevel@tonic-gate * Perhaps we should tell the higher layers that the 7760Sstevel@tonic-gate * keyboard has been reset. 7770Sstevel@tonic-gate */ 7780Sstevel@tonic-gate /* 7790Sstevel@tonic-gate * Reset to idle 7800Sstevel@tonic-gate */ 7810Sstevel@tonic-gate kb8042->parse_scan_state = STATE_IDLE; 7820Sstevel@tonic-gate DEBUG_KD(("-> POST %s\n", scan == KB_POST_OK ? "OK" : "FAIL")); 7830Sstevel@tonic-gate return (B_FALSE); 7840Sstevel@tonic-gate 7850Sstevel@tonic-gate case KXT_EXTEND: 7860Sstevel@tonic-gate case KXT_EXTEND2: 7870Sstevel@tonic-gate case KXT_HANGUL_HANJA: 7880Sstevel@tonic-gate case KXT_HANGUL: 7890Sstevel@tonic-gate /* 7900Sstevel@tonic-gate * Exclude these keys from the "default" test below. 7910Sstevel@tonic-gate */ 7920Sstevel@tonic-gate break; 7930Sstevel@tonic-gate 7940Sstevel@tonic-gate default: 7950Sstevel@tonic-gate /* 7960Sstevel@tonic-gate * See if it was a key release. 7970Sstevel@tonic-gate */ 7980Sstevel@tonic-gate if (scan > 0x80) { 7990Sstevel@tonic-gate *state = KEY_RELEASED; 8000Sstevel@tonic-gate scan -= 0x80; 8010Sstevel@tonic-gate } 8020Sstevel@tonic-gate break; 8030Sstevel@tonic-gate } 8040Sstevel@tonic-gate 805*822Ssethg if (kb8042->break_received) { 806*822Ssethg *state = KEY_RELEASED; 807*822Ssethg kb8042->break_received = 0; 808*822Ssethg } 809*822Ssethg 8100Sstevel@tonic-gate switch (kb8042->parse_scan_state) { 8110Sstevel@tonic-gate case STATE_IDLE: 8120Sstevel@tonic-gate switch (scan) { 8130Sstevel@tonic-gate case KXT_EXTEND: 8140Sstevel@tonic-gate kb8042->parse_scan_state = STATE_E0; 8150Sstevel@tonic-gate DEBUG_KD(("-> state E0\n")); 8160Sstevel@tonic-gate return (B_FALSE); 8170Sstevel@tonic-gate 8180Sstevel@tonic-gate case KXT_EXTEND2: 8190Sstevel@tonic-gate kb8042->parse_scan_state = STATE_E1; 8200Sstevel@tonic-gate DEBUG_KD(("-> state E1\n")); 8210Sstevel@tonic-gate return (B_FALSE); 8220Sstevel@tonic-gate 8230Sstevel@tonic-gate /* 8240Sstevel@tonic-gate * We could do the next two in the table, but it would 8250Sstevel@tonic-gate * require nearly doubling the size of the table. 8260Sstevel@tonic-gate * 8270Sstevel@tonic-gate * Also, for some stupid reason these two report presses 8280Sstevel@tonic-gate * only. We tell the upper layer to synthesize a release. 8290Sstevel@tonic-gate */ 8300Sstevel@tonic-gate case KXT_HANGUL_HANJA: 8310Sstevel@tonic-gate *keynum = KEY(150); 8320Sstevel@tonic-gate *synthetic_release_needed = B_TRUE; 8330Sstevel@tonic-gate break; 8340Sstevel@tonic-gate 8350Sstevel@tonic-gate case KXT_HANGUL: 8360Sstevel@tonic-gate *keynum = KEY(151); 8370Sstevel@tonic-gate *synthetic_release_needed = B_TRUE; 8380Sstevel@tonic-gate break; 8390Sstevel@tonic-gate 8400Sstevel@tonic-gate default: 8410Sstevel@tonic-gate /* 8420Sstevel@tonic-gate * Regular scan code 8430Sstevel@tonic-gate */ 844*822Ssethg if (scan < keytab_base_length) 8450Sstevel@tonic-gate *keynum = keytab_base[scan]; 8460Sstevel@tonic-gate else 8470Sstevel@tonic-gate *keynum = INVALID; 8480Sstevel@tonic-gate break; 8490Sstevel@tonic-gate } 8500Sstevel@tonic-gate break; 8510Sstevel@tonic-gate 8520Sstevel@tonic-gate case STATE_E0: /* Mostly 101-key additions */ 853*822Ssethg if (scan < keytab_e0_length) 8540Sstevel@tonic-gate *keynum = keytab_e0[scan]; 8550Sstevel@tonic-gate else 8560Sstevel@tonic-gate *keynum = INVALID; 8570Sstevel@tonic-gate break; 8580Sstevel@tonic-gate 8590Sstevel@tonic-gate case STATE_E1: /* Pause key only */ 8600Sstevel@tonic-gate switch (scan) { 8610Sstevel@tonic-gate case 0x1d: 8620Sstevel@tonic-gate kb8042->parse_scan_state = STATE_E1_1D; 8630Sstevel@tonic-gate DEBUG_KD(("-> state E1 1D\n")); 8640Sstevel@tonic-gate return (B_FALSE); 8650Sstevel@tonic-gate default: 8660Sstevel@tonic-gate *keynum = INVALID; 8670Sstevel@tonic-gate break; 8680Sstevel@tonic-gate } 8690Sstevel@tonic-gate break; 8700Sstevel@tonic-gate 8710Sstevel@tonic-gate case STATE_E1_1D: /* Pause key only */ 8720Sstevel@tonic-gate switch (scan) { 8730Sstevel@tonic-gate case 0x45: 8740Sstevel@tonic-gate *keynum = KEY(126); /* Pause */ 8750Sstevel@tonic-gate break; 8760Sstevel@tonic-gate default: 8770Sstevel@tonic-gate *keynum = INVALID; 8780Sstevel@tonic-gate break; 8790Sstevel@tonic-gate } 8800Sstevel@tonic-gate break; 8810Sstevel@tonic-gate } 8820Sstevel@tonic-gate 8830Sstevel@tonic-gate /* 8840Sstevel@tonic-gate * The results (*keynum, *state, and *synthetic_release_needed) 8850Sstevel@tonic-gate * have been filled in, but they are valid only if we return 8860Sstevel@tonic-gate * B_TRUE which is only done below. If we make it to here, we 8870Sstevel@tonic-gate * have completed a scan code sequence, so reset parse_scan_state. 8880Sstevel@tonic-gate */ 8890Sstevel@tonic-gate 8900Sstevel@tonic-gate kb8042->parse_scan_state = STATE_IDLE; 8910Sstevel@tonic-gate 8920Sstevel@tonic-gate switch (*keynum) { 8930Sstevel@tonic-gate case KEYIGN: /* not a key, nor an error */ 8940Sstevel@tonic-gate DEBUG_KD(("-> hole -> ignored\n")); 8950Sstevel@tonic-gate return (B_FALSE); /* also not a final keycode */ 8960Sstevel@tonic-gate 8970Sstevel@tonic-gate case KEYBAD: /* not part of a legit sequence? */ 8980Sstevel@tonic-gate DEBUG_KD(("-> bad -> ignored\n")); 8990Sstevel@tonic-gate return (B_FALSE); /* and return not a final keycode */ 9000Sstevel@tonic-gate 9010Sstevel@tonic-gate default: 9020Sstevel@tonic-gate /* 9030Sstevel@tonic-gate * If we're here, it's a valid keycode. We've already 9040Sstevel@tonic-gate * filled in the return values; return success. 9050Sstevel@tonic-gate */ 9060Sstevel@tonic-gate 9070Sstevel@tonic-gate DEBUG_KD(("-> %s keypos %d\n", 9080Sstevel@tonic-gate *state == KEY_RELEASED ? "released" : "pressed", 9090Sstevel@tonic-gate *keynum)); 9100Sstevel@tonic-gate 9110Sstevel@tonic-gate return (B_TRUE); /* resolved to a key */ 9120Sstevel@tonic-gate } 9130Sstevel@tonic-gate } 914*822Ssethg 915*822Ssethg /* 916*822Ssethg * KeyboardConvertScan(*kb8042, scan, *keynum, *state 917*822Ssethg * *synthetic_release_needed) 918*822Ssethg * 919*822Ssethg * State machine that takes scan codes from the keyboard and resolves 920*822Ssethg * them to key numbers using the above tables. Returns B_TRUE if this 921*822Ssethg * scan code completes a scan code sequence, in which case "keynum", 922*822Ssethg * "state", and "synthetic_release_needed" will be filled in correctly. 923*822Ssethg * 924*822Ssethg * "synthetic_release_needed" is a hack to handle the additional two 925*822Ssethg * keys on a Korean keyboard. They report press only, so we tell the 926*822Ssethg * upper layer to synthesize the release. 927*822Ssethg */ 928*822Ssethg boolean_t 929*822Ssethg KeyboardConvertScan_set2( 930*822Ssethg struct kb8042 *kb8042, 931*822Ssethg unsigned char scan, 932*822Ssethg int *keynum, 933*822Ssethg enum keystate *state, 934*822Ssethg boolean_t *synthetic_release_needed) 935*822Ssethg { 936*822Ssethg DEBUG_KD(("KeyboardConvertScan_set2: 0x%02x ", scan)); 937*822Ssethg 938*822Ssethg *synthetic_release_needed = B_FALSE; 939*822Ssethg *state = KEY_PRESSED; 940*822Ssethg 941*822Ssethg switch (scan) { 942*822Ssethg /* 943*822Ssethg * First, handle special cases. 944*822Ssethg * ACK has already been handled by our caller. 945*822Ssethg */ 946*822Ssethg 947*822Ssethg /* 948*822Ssethg * KAT_BREAK is 0xF0. It is the same as the break code for Japanese 949*822Ssethg * key 133. 950*822Ssethg * Therefore we don't treat it specially here. 951*822Ssethg */ 952*822Ssethg case KAT_BREAK: 953*822Ssethg /* Switch states so we can recognize the code that follows */ 954*822Ssethg kb8042->break_received = 1; 955*822Ssethg DEBUG_KD(("-> break prefix\n")); 956*822Ssethg return (B_FALSE); /* not a final keycode */ 957*822Ssethg 958*822Ssethg case KB_ERROR: 959*822Ssethg /* 960*822Ssethg * Perhaps we should reset state here, 961*822Ssethg * since we no longer know what's going on. 962*822Ssethg */ 963*822Ssethg DEBUG_KD(("-> overrun\n")); 964*822Ssethg return (B_FALSE); 965*822Ssethg 966*822Ssethg case KB_POST_OK: 967*822Ssethg case KB_POST_FAIL: 968*822Ssethg /* 969*822Ssethg * Perhaps we should reset the LEDs now. 970*822Ssethg * If so, this check should probably be in the main line. 971*822Ssethg * Perhaps we should tell the higher layers that the 972*822Ssethg * keyboard has been reset. 973*822Ssethg */ 974*822Ssethg /* 975*822Ssethg * Reset to idle 976*822Ssethg */ 977*822Ssethg kb8042->parse_scan_state = STATE_IDLE; 978*822Ssethg DEBUG_KD(("-> POST %s\n", scan == KB_POST_OK ? "OK" : "FAIL")); 979*822Ssethg return (B_FALSE); 980*822Ssethg } 981*822Ssethg 982*822Ssethg if (kb8042->break_received) { 983*822Ssethg *state = KEY_RELEASED; 984*822Ssethg kb8042->break_received = 0; 985*822Ssethg } 986*822Ssethg 987*822Ssethg switch (kb8042->parse_scan_state) { 988*822Ssethg case STATE_IDLE: 989*822Ssethg switch (scan) { 990*822Ssethg case KXT_EXTEND: 991*822Ssethg kb8042->parse_scan_state = STATE_E0; 992*822Ssethg DEBUG_KD(("-> state E0\n")); 993*822Ssethg return (B_FALSE); 994*822Ssethg 995*822Ssethg case KXT_EXTEND2: 996*822Ssethg kb8042->parse_scan_state = STATE_E1; 997*822Ssethg DEBUG_KD(("-> state E1\n")); 998*822Ssethg return (B_FALSE); 999*822Ssethg 1000*822Ssethg /* 1001*822Ssethg * We could do the next two in the table, but it would 1002*822Ssethg * require nearly doubling the size of the table. 1003*822Ssethg * 1004*822Ssethg * Also, for some stupid reason these two report presses 1005*822Ssethg * only. We tell the upper layer to synthesize a release. 1006*822Ssethg */ 1007*822Ssethg case KXT_HANGUL_HANJA: 1008*822Ssethg *keynum = KEY(150); 1009*822Ssethg *synthetic_release_needed = B_TRUE; 1010*822Ssethg break; 1011*822Ssethg 1012*822Ssethg case KXT_HANGUL: 1013*822Ssethg *keynum = KEY(151); 1014*822Ssethg *synthetic_release_needed = B_TRUE; 1015*822Ssethg break; 1016*822Ssethg 1017*822Ssethg default: 1018*822Ssethg /* 1019*822Ssethg * Regular scan code 1020*822Ssethg */ 1021*822Ssethg if (scan < keytab_base_length) 1022*822Ssethg *keynum = keytab_base[scan]; 1023*822Ssethg else 1024*822Ssethg *keynum = INVALID; 1025*822Ssethg break; 1026*822Ssethg } 1027*822Ssethg break; 1028*822Ssethg 1029*822Ssethg case STATE_E0: /* Mostly 101-key additions */ 1030*822Ssethg if (scan < keytab_e0_length) 1031*822Ssethg *keynum = keytab_e0[scan]; 1032*822Ssethg else 1033*822Ssethg *keynum = INVALID; 1034*822Ssethg break; 1035*822Ssethg 1036*822Ssethg case STATE_E1: /* Pause key only */ 1037*822Ssethg switch (scan) { 1038*822Ssethg case 0x14: 1039*822Ssethg kb8042->parse_scan_state = STATE_E1_14; 1040*822Ssethg DEBUG_KD(("-> state E1 14\n")); 1041*822Ssethg return (B_FALSE); 1042*822Ssethg default: 1043*822Ssethg *keynum = INVALID; 1044*822Ssethg break; 1045*822Ssethg } 1046*822Ssethg break; 1047*822Ssethg 1048*822Ssethg case STATE_E1_14: /* Pause key only */ 1049*822Ssethg if (scan == 0x77) { 1050*822Ssethg kb8042->parse_scan_state = STATE_E1_14_77; 1051*822Ssethg return (B_FALSE); 1052*822Ssethg } else { 1053*822Ssethg *keynum = INVALID; 1054*822Ssethg } 1055*822Ssethg break; 1056*822Ssethg 1057*822Ssethg case STATE_E1_14_77: 1058*822Ssethg if (scan == 0xE1) { 1059*822Ssethg kb8042->parse_scan_state = STATE_E1_14_77_E1; 1060*822Ssethg return (B_FALSE); 1061*822Ssethg } else { 1062*822Ssethg *keynum = INVALID; 1063*822Ssethg } 1064*822Ssethg break; 1065*822Ssethg 1066*822Ssethg case STATE_E1_14_77_E1: 1067*822Ssethg if (scan == 0xF0) { 1068*822Ssethg kb8042->parse_scan_state = STATE_E1_14_77_E1_F0; 1069*822Ssethg return (B_FALSE); 1070*822Ssethg } else { 1071*822Ssethg *keynum = INVALID; 1072*822Ssethg } 1073*822Ssethg break; 1074*822Ssethg 1075*822Ssethg case STATE_E1_14_77_E1_F0: 1076*822Ssethg if (scan == 0x14) { 1077*822Ssethg kb8042->parse_scan_state = STATE_E1_14_77_E1_F0_14; 1078*822Ssethg return (B_FALSE); 1079*822Ssethg } else { 1080*822Ssethg *keynum = INVALID; 1081*822Ssethg } 1082*822Ssethg break; 1083*822Ssethg 1084*822Ssethg case STATE_E1_14_77_E1_F0_14: 1085*822Ssethg if (scan == 0xF0) { 1086*822Ssethg kb8042->parse_scan_state = STATE_E1_14_77_E1_F0_14_F0; 1087*822Ssethg return (B_FALSE); 1088*822Ssethg } else { 1089*822Ssethg *keynum = INVALID; 1090*822Ssethg } 1091*822Ssethg break; 1092*822Ssethg 1093*822Ssethg case STATE_E1_14_77_E1_F0_14_F0: 1094*822Ssethg if (scan == 0x77) { 1095*822Ssethg *keynum = KEY(126); /* Pause */ 1096*822Ssethg } else { 1097*822Ssethg *keynum = INVALID; 1098*822Ssethg } 1099*822Ssethg break; 1100*822Ssethg } 1101*822Ssethg 1102*822Ssethg /* 1103*822Ssethg * The results (*keynum, *state, and *synthetic_release_needed) 1104*822Ssethg * have been filled in, but they are valid only if we return 1105*822Ssethg * B_TRUE which is only done below. If we make it to here, we 1106*822Ssethg * have completed a scan code sequence, so reset parse_scan_state. 1107*822Ssethg */ 1108*822Ssethg 1109*822Ssethg if (kb8042->break_received) { 1110*822Ssethg *state = KEY_RELEASED; 1111*822Ssethg kb8042->break_received = 0; 1112*822Ssethg } 1113*822Ssethg 1114*822Ssethg kb8042->parse_scan_state = STATE_IDLE; 1115*822Ssethg 1116*822Ssethg switch (*keynum) { 1117*822Ssethg case KEYIGN: /* not a key, nor an error */ 1118*822Ssethg DEBUG_KD(("-> hole -> ignored\n")); 1119*822Ssethg return (B_FALSE); /* also not a final keycode */ 1120*822Ssethg 1121*822Ssethg case KEYBAD: /* not part of a legit sequence? */ 1122*822Ssethg DEBUG_KD(("-> bad -> ignored\n")); 1123*822Ssethg return (B_FALSE); /* and return not a final keycode */ 1124*822Ssethg 1125*822Ssethg default: 1126*822Ssethg /* 1127*822Ssethg * If we're here, it's a valid keycode. We've already 1128*822Ssethg * filled in the return values; return success. 1129*822Ssethg */ 1130*822Ssethg 1131*822Ssethg DEBUG_KD(("-> %s keypos %d\n", 1132*822Ssethg *state == KEY_RELEASED ? "released" : "pressed", 1133*822Ssethg *keynum)); 1134*822Ssethg 1135*822Ssethg return (B_TRUE); /* resolved to a key */ 1136*822Ssethg } 1137*822Ssethg } 1138