linux/kernel/debug/kdb/kdb_keyboard.c
<<
>>
Prefs
   1/*
   2 * Kernel Debugger Architecture Dependent Console I/O handler
   3 *
   4 * This file is subject to the terms and conditions of the GNU General Public
   5 * License.
   6 *
   7 * Copyright (c) 1999-2006 Silicon Graphics, Inc.  All Rights Reserved.
   8 * Copyright (c) 2009 Wind River Systems, Inc.  All Rights Reserved.
   9 */
  10
  11#include <linux/kdb.h>
  12#include <linux/keyboard.h>
  13#include <linux/ctype.h>
  14#include <linux/module.h>
  15#include <linux/io.h>
  16
  17/* Keyboard Controller Registers on normal PCs. */
  18
  19#define KBD_STATUS_REG          0x64    /* Status register (R) */
  20#define KBD_DATA_REG            0x60    /* Keyboard data register (R/W) */
  21
  22/* Status Register Bits */
  23
  24#define KBD_STAT_OBF            0x01    /* Keyboard output buffer full */
  25#define KBD_STAT_MOUSE_OBF      0x20    /* Mouse output buffer full */
  26
  27static int kbd_exists;
  28static int kbd_last_ret;
  29
  30/*
  31 * Check if the keyboard controller has a keypress for us.
  32 * Some parts (Enter Release, LED change) are still blocking polled here,
  33 * but hopefully they are all short.
  34 */
  35int kdb_get_kbd_char(void)
  36{
  37        int scancode, scanstatus;
  38        static int shift_lock;  /* CAPS LOCK state (0-off, 1-on) */
  39        static int shift_key;   /* Shift next keypress */
  40        static int ctrl_key;
  41        u_short keychar;
  42
  43        if (KDB_FLAG(NO_I8042) || KDB_FLAG(NO_VT_CONSOLE) ||
  44            (inb(KBD_STATUS_REG) == 0xff && inb(KBD_DATA_REG) == 0xff)) {
  45                kbd_exists = 0;
  46                return -1;
  47        }
  48        kbd_exists = 1;
  49
  50        if ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
  51                return -1;
  52
  53        /*
  54         * Fetch the scancode
  55         */
  56        scancode = inb(KBD_DATA_REG);
  57        scanstatus = inb(KBD_STATUS_REG);
  58
  59        /*
  60         * Ignore mouse events.
  61         */
  62        if (scanstatus & KBD_STAT_MOUSE_OBF)
  63                return -1;
  64
  65        /*
  66         * Ignore release, trigger on make
  67         * (except for shift keys, where we want to
  68         *  keep the shift state so long as the key is
  69         *  held down).
  70         */
  71
  72        if (((scancode&0x7f) == 0x2a) || ((scancode&0x7f) == 0x36)) {
  73                /*
  74                 * Next key may use shift table
  75                 */
  76                if ((scancode & 0x80) == 0)
  77                        shift_key = 1;
  78                else
  79                        shift_key = 0;
  80                return -1;
  81        }
  82
  83        if ((scancode&0x7f) == 0x1d) {
  84                /*
  85                 * Left ctrl key
  86                 */
  87                if ((scancode & 0x80) == 0)
  88                        ctrl_key = 1;
  89                else
  90                        ctrl_key = 0;
  91                return -1;
  92        }
  93
  94        if ((scancode & 0x80) != 0) {
  95                if (scancode == 0x9c)
  96                        kbd_last_ret = 0;
  97                return -1;
  98        }
  99
 100        scancode &= 0x7f;
 101
 102        /*
 103         * Translate scancode
 104         */
 105
 106        if (scancode == 0x3a) {
 107                /*
 108                 * Toggle caps lock
 109                 */
 110                shift_lock ^= 1;
 111
 112#ifdef  KDB_BLINK_LED
 113                kdb_toggleled(0x4);
 114#endif
 115                return -1;
 116        }
 117
 118        if (scancode == 0x0e) {
 119                /*
 120                 * Backspace
 121                 */
 122                return 8;
 123        }
 124
 125        /* Special Key */
 126        switch (scancode) {
 127        case 0xF: /* Tab */
 128                return 9;
 129        case 0x53: /* Del */
 130                return 4;
 131        case 0x47: /* Home */
 132                return 1;
 133        case 0x4F: /* End */
 134                return 5;
 135        case 0x4B: /* Left */
 136                return 2;
 137        case 0x48: /* Up */
 138                return 16;
 139        case 0x50: /* Down */
 140                return 14;
 141        case 0x4D: /* Right */
 142                return 6;
 143        }
 144
 145        if (scancode == 0xe0)
 146                return -1;
 147
 148        /*
 149         * For Japanese 86/106 keyboards
 150         *      See comment in drivers/char/pc_keyb.c.
 151         *      - Masahiro Adegawa
 152         */
 153        if (scancode == 0x73)
 154                scancode = 0x59;
 155        else if (scancode == 0x7d)
 156                scancode = 0x7c;
 157
 158        if (!shift_lock && !shift_key && !ctrl_key) {
 159                keychar = plain_map[scancode];
 160        } else if ((shift_lock || shift_key) && key_maps[1]) {
 161                keychar = key_maps[1][scancode];
 162        } else if (ctrl_key && key_maps[4]) {
 163                keychar = key_maps[4][scancode];
 164        } else {
 165                keychar = 0x0020;
 166                kdb_printf("Unknown state/scancode (%d)\n", scancode);
 167        }
 168        keychar &= 0x0fff;
 169        if (keychar == '\t')
 170                keychar = ' ';
 171        switch (KTYP(keychar)) {
 172        case KT_LETTER:
 173        case KT_LATIN:
 174                if (isprint(keychar))
 175                        break;          /* printable characters */
 176                fallthrough;
 177        case KT_SPEC:
 178                if (keychar == K_ENTER)
 179                        break;
 180                fallthrough;
 181        default:
 182                return -1;      /* ignore unprintables */
 183        }
 184
 185        if (scancode == 0x1c) {
 186                kbd_last_ret = 1;
 187                return 13;
 188        }
 189
 190        return keychar & 0xff;
 191}
 192EXPORT_SYMBOL_GPL(kdb_get_kbd_char);
 193
 194/*
 195 * Best effort cleanup of ENTER break codes on leaving KDB. Called on
 196 * exiting KDB, when we know we processed an ENTER or KP ENTER scan
 197 * code.
 198 */
 199void kdb_kbd_cleanup_state(void)
 200{
 201        int scancode, scanstatus;
 202
 203        /*
 204         * Nothing to clean up, since either
 205         * ENTER was never pressed, or has already
 206         * gotten cleaned up.
 207         */
 208        if (!kbd_last_ret)
 209                return;
 210
 211        kbd_last_ret = 0;
 212        /*
 213         * Enter key. Need to absorb the break code here, lest it gets
 214         * leaked out if we exit KDB as the result of processing 'g'.
 215         *
 216         * This has several interesting implications:
 217         * + Need to handle KP ENTER, which has break code 0xe0 0x9c.
 218         * + Need to handle repeat ENTER and repeat KP ENTER. Repeats
 219         *   only get a break code at the end of the repeated
 220         *   sequence. This means we can't propagate the repeated key
 221         *   press, and must swallow it away.
 222         * + Need to handle possible PS/2 mouse input.
 223         * + Need to handle mashed keys.
 224         */
 225
 226        while (1) {
 227                while ((inb(KBD_STATUS_REG) & KBD_STAT_OBF) == 0)
 228                        cpu_relax();
 229
 230                /*
 231                 * Fetch the scancode.
 232                 */
 233                scancode = inb(KBD_DATA_REG);
 234                scanstatus = inb(KBD_STATUS_REG);
 235
 236                /*
 237                 * Skip mouse input.
 238                 */
 239                if (scanstatus & KBD_STAT_MOUSE_OBF)
 240                        continue;
 241
 242                /*
 243                 * If we see 0xe0, this is either a break code for KP
 244                 * ENTER, or a repeat make for KP ENTER. Either way,
 245                 * since the second byte is equivalent to an ENTER,
 246                 * skip the 0xe0 and try again.
 247                 *
 248                 * If we see 0x1c, this must be a repeat ENTER or KP
 249                 * ENTER (and we swallowed 0xe0 before). Try again.
 250                 *
 251                 * We can also see make and break codes for other keys
 252                 * mashed before or after pressing ENTER. Thus, if we
 253                 * see anything other than 0x9c, we have to try again.
 254                 *
 255                 * Note, if you held some key as ENTER was depressed,
 256                 * that break code would get leaked out.
 257                 */
 258                if (scancode != 0x9c)
 259                        continue;
 260
 261                return;
 262        }
 263}
 264