CTC++ Coverage Report - Execution Profile    #372/1532

Files Summary | Functions Summary | Execution Profile | Index | No Index
First | Previous | Next | Last


File: drivers/char/keyboard.c
Instrumentation mode: function-decision-multicondition
TER: 37 % (197/531)

Start/ End/    
True False - Line Source

  1 /*
  2  * linux/drivers/char/keyboard.c
  3  *
  4  * Written for linux by Johan Myreen as a translation from
  5  * the assembly version by Linus (with diacriticals added)
  6  *
  7  * Some additional features added by Christoph Niemann (ChN), March 1993
  8  *
  9  * Loadable keymaps by Risto Kankkunen, May 1993
  10  *
  11  * Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
  12  * Added decr/incr_console, dynamic keymaps, Unicode support,
  13  * dynamic function/string keys, led setting,  Sept 1994
  14  * `Sticky' modifier keys, 951006.
  15  *
  16  * 11-11-96: SAK should now work in the raw mode (Martin Mares)
  17  *
  18  * Modified to provide 'generic' keyboard support by Hamish Macdonald
  19  * Merge with the m68k keyboard driver and split-off of the PC low-level
  20  * parts by Geert Uytterhoeven, May 1997
  21  *
  22  * 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
  23  * 30-07-98: Dead keys redone, aeb@cwi.nl.
  24  * 21-08-02: Converted to input API, major cleanup. (Vojtech Pavlik)
  25  */
  26 
  27 #include <linux/config.h>
  28 #include <linux/module.h>
  29 #include <linux/sched.h>
  30 #include <linux/tty.h>
  31 #include <linux/tty_flip.h>
  32 #include <linux/mm.h>
  33 #include <linux/string.h>
  34 #include <linux/init.h>
  35 #include <linux/slab.h>
  36 
  37 #include <linux/kbd_kern.h>
  38 #include <linux/kbd_diacr.h>
  39 #include <linux/vt_kern.h>
  40 #include <linux/sysrq.h>
  41 #include <linux/input.h>
  42 
  43 static void kbd_disconnect(struct input_handle *handle);
  44 extern void ctrl_alt_del(void);
  45 
  46 /*
  47  * Exported functions/variables
  48  */
  49 
  50 #define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
  51 
  52 /*
  53  * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on.
  54  * This seems a good reason to start with NumLock off. On HIL keyboards
  55  * of PARISC machines however there is no NumLock key and everyone expects the keypad
  56  * to be used for numbers.
  57  */
  58 
  59 #if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
  60 #define KBD_DEFLEDS (1 << VC_NUMLOCK)
  61 #else
  62 #define KBD_DEFLEDS 0
  63 #endif
  64 
  65 #define KBD_DEFLOCK 0
  66 
  67 void compute_shiftstate(void);
  68 
  69 /*
  70  * Handler Tables.
  71  */
  72 
  73 #define K_HANDLERS\
  74    k_self,      k_fn,      k_spec,      k_pad,\
  75    k_dead,      k_cons,      k_cur,      k_shift,\
  76    k_meta,      k_ascii,   k_lock,      k_lowercase,\
  77    k_slock,   k_dead2,   k_ignore,   k_ignore
  78 
  79 typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
  80              char up_flag, struct pt_regs *regs);
  81 static k_handler_fn K_HANDLERS;
  82 static k_handler_fn *k_handler[16] = { K_HANDLERS };
  83 
  84 #define FN_HANDLERS\
  85    fn_null,   fn_enter,   fn_show_ptregs,   fn_show_mem,\
  86    fn_show_state,   fn_send_intr,   fn_lastcons,   fn_caps_toggle,\
  87    fn_num,      fn_hold,   fn_scroll_forw,   fn_scroll_back,\
  88    fn_boot_it,   fn_caps_on,   fn_compose,   fn_SAK,\
  89    fn_dec_console, fn_inc_console, fn_spawn_con,   fn_bare_num
  90 
  91 typedef void (fn_handler_fn)(struct vc_data *vc, struct pt_regs *regs);
  92 static fn_handler_fn FN_HANDLERS;
  93 static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
  94 
  95 /*
  96  * Variables exported for vt_ioctl.c
  97  */
  98 
  99 /* maximum values each key_handler can handle */
  100 const int max_vals[] = {
  101    255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
  102    NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
  103    255, NR_LOCK - 1, 255
  104 };
  105 
  106 const int NR_TYPES = ARRAY_SIZE(max_vals);
  107 
  108 struct kbd_struct kbd_table[MAX_NR_CONSOLES];
  109 static struct kbd_struct *kbd = kbd_table;
  110 static struct kbd_struct kbd0;
  111 
  112 int spawnpid, spawnsig;
  113 
  114 /*
  115  * Variables exported for vt.c
  116  */
  117 
  118 int shift_state = 0;
  119 
  120 /*
  121  * Internal Data.
  122  */
  123 
  124 static struct input_handler kbd_handler;
  125 static unsigned long key_down[NBITS(KEY_MAX)];      /* keyboard key bitmap */
  126 static unsigned char shift_down[NR_SHIFT];      /* shift state counters.. */
  127 static int dead_key_next;
  128 static int npadch = -1;               /* -1 or number assembled on pad */
  129 static unsigned char diacr;
  130 static char rep;               /* flag telling character repeat */
  131 
  132 static unsigned char ledstate = 0xff;         /* undefined */
  133 static unsigned char ledioctl;
  134 
  135 static struct ledptr {
  136    unsigned int *addr;
  137    unsigned int mask;
  138    unsigned char valid:1;
  139 } ledptrs[3];
  140 
  141 /* Simple translation table for the SysRq keys */
  142 
  143 #ifdef CONFIG_MAGIC_SYSRQ
  144 unsigned char kbd_sysrq_xlate[KEY_MAX + 1] =
  145         "\000\0331234567890-=\177\t"                    /* 0x00 - 0x0f */
  146         "qwertyuiop[]\r\000as"                          /* 0x10 - 0x1f */
  147         "dfghjkl;'`\000\\zxcv"                          /* 0x20 - 0x2f */
  148         "bnm,./\000*\000 \000\201\202\203\204\205"      /* 0x30 - 0x3f */
  149         "\206\207\210\211\212\000\000789-456+1"         /* 0x40 - 0x4f */
  150         "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
  151         "\r\000/";                                      /* 0x60 - 0x6f */
  152 static int sysrq_down;
  153 #endif
  154 static int sysrq_alt;
  155 
  156 /*
  157  * Translation of scancodes to keycodes. We set them on only the first attached
  158  * keyboard - for per-keyboard setting, /dev/input/event is more useful.
  159  */
 
- 160 int getkeycode(unsigned int scancode)
  161 {
  162    struct list_head *node;
  163    struct input_dev *dev = NULL;
  164 
- 165    list_for_each(node, &kbd_handler.h_list) {
  166       struct input_handle *handle = to_handle_h(node);
- 167       if (handle->dev->keycodesize) {
  168          dev = handle->dev;
 - 169          break;
  170       }
  171    }
  172 
- 173    if (!dev)
 - 174       return -ENODEV;
  175 
- 176    if (scancode >= dev->keycodemax)
 - 177       return -EINVAL;
  178 
    179    return INPUT_KEYCODE(dev, scancode);
- 179 ternary-?: ( dev -> keycodesize == 1 )
- 179 ternary-?: ( dev -> keycodesize == 2 )
 - 179 return ( ( dev -> keycodesize == 1 ) ? ( ( u8 ..
  180 }
  181 
 
30   182 int setkeycode(unsigned int scancode, unsigned int keycode)
  183 {
  184    struct list_head *node;
  185    struct input_dev *dev = NULL;
  186    unsigned int i, oldkey;
  187 
30 - 188    list_for_each(node, &kbd_handler.h_list) {
  189       struct input_handle *handle = to_handle_h(node);
30 - 190       if (handle->dev->keycodesize) {
  191          dev = handle->dev;
30    192          break;
  193       }
  194    }
  195 
30 - 196    if (!dev)
 - 197       return -ENODEV;
  198 
30 - 199    if (scancode >= dev->keycodemax)
 - 200       return -EINVAL;
30 - 201    if (keycode < 0 || keycode > KEY_MAX)
 - 201   T || _
 - 201   F || T
 30   201   F || F
 - 202       return -EINVAL;
30 - 203    if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
 - 203   T && (T)
 30   203   T && (F)
 - 203   F && (_)
 - 204       return -EINVAL;
  205 
  206    oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode);
  207 
  208    clear_bit(oldkey, dev->keybit);
  209    set_bit(keycode, dev->keybit);
  210 
15360 30   211    for (i = 0; i < dev->keycodemax; i++)
10860 4500   212       if (INPUT_KEYCODE(dev,i) == oldkey)
15360 - 212   ternary-?: ( dev -> keycodesize == 1 )
- 212   ternary-?: ( dev -> keycodesize == 2 )
  213          set_bit(oldkey, dev->keybit);
  214 
30    215    return 0;
  216 }
  217 
  218 /*
  219  * Making beeps and bells.
  220  */
 
2015 2015   221 static void kd_nosound(unsigned long ignored)
  222 {
  223    struct list_head *node;
  224 
2015 2015   225    list_for_each(node,&kbd_handler.h_list) {
  226       struct input_handle *handle = to_handle_h(node);
2015 - 227       if (test_bit(EV_SND, handle->dev->evbit)) {
2015 - 227   ternary-?: __builtin_constant_p ( 0x12 )
- 228          if (test_bit(SND_TONE, handle->dev->sndbit))
- 228     ternary-?: __builtin_constant_p ( 0x02 )
  229             input_event(handle->dev, EV_SND, SND_TONE, 0);
- 230          if (test_bit(SND_BELL, handle->dev->sndbit))
- 230     ternary-?: __builtin_constant_p ( 0x01 )
  231             input_event(handle->dev, EV_SND, SND_BELL, 0);
  232       }
  233    }
  234 }
  235 
  236 static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0);
  237 
 
2049 2049   238 void kd_mksound(unsigned int hz, unsigned int ticks)
  239 {
  240    struct list_head *node;
  241 
  242    del_timer(&kd_mksound_timer);
  243 
2049 - 244    if (hz) {
2049 2049   245       list_for_each_prev(node, &kbd_handler.h_list) {
  246          struct input_handle *handle = to_handle_h(node);
2049 - 247          if (test_bit(EV_SND, handle->dev->evbit)) {
2049 - 247     ternary-?: __builtin_constant_p ( 0x12 )
- 248             if (test_bit(SND_TONE, handle->dev->sndbit)) {
- 248       ternary-?: __builtin_constant_p ( 0x02 )
  249                input_event(handle->dev, EV_SND, SND_TONE, hz);
 - 250                break;
  251             }
- 252             if (test_bit(SND_BELL, handle->dev->sndbit)) {
- 252       ternary-?: __builtin_constant_p ( 0x01 )
  253                input_event(handle->dev, EV_SND, SND_BELL, 1);
 - 254                break;
  255             }
  256          }
  257       }
2049 - 258       if (ticks)
  259          mod_timer(&kd_mksound_timer, jiffies + ticks);
    260    } else
  261       kd_nosound(0);
  262 }
  263 
  264 /*
  265  * Setting the keyboard rate.
  266  */
  267 
 
12   268 int kbd_rate(struct kbd_repeat *rep)
  269 {
  270    struct list_head *node;
  271    unsigned int d = 0;
  272    unsigned int p = 0;
  273 
12 12   274    list_for_each(node,&kbd_handler.h_list) {
  275       struct input_handle *handle = to_handle_h(node);
  276       struct input_dev *dev = handle->dev;
  277 
12 - 278       if (test_bit(EV_REP, dev->evbit)) {
12 - 278   ternary-?: __builtin_constant_p ( 0x14 )
  279          if (rep->delay > 0)
  280             input_event(dev, EV_REP, REP_DELAY, rep->delay);
  281          if (rep->period > 0)
  282             input_event(dev, EV_REP, REP_PERIOD, rep->period);
  283          d = dev->rep[REP_DELAY];
  284          p = dev->rep[REP_PERIOD];
  285       }
  286    }
  287    rep->delay  = d;
  288    rep->period = p;
12    289    return 0;
  290 }
  291 
  292 /*
  293  * Helper Functions.
  294  */
 
249213 249213   295 static void put_queue(struct vc_data *vc, int ch)
  296 {
  297    struct tty_struct *tty = vc->vc_tty;
  298 
249213 - 299    if (tty) {
  300       tty_insert_flip_char(tty, ch, 0);
  301       con_schedule_flip(tty);
  302    }
  303 }
  304 
 
  305 static void puts_queue(struct vc_data *vc, char *cp)
  306 {
  307    struct tty_struct *tty = vc->vc_tty;
  308 
- 309    if (!tty)
 - 310       return;
  311 
12   312    while (*cp) {
  313       tty_insert_flip_char(tty, *cp, 0);
  314       cp++;
  315    }
  316    con_schedule_flip(tty);
  317 }
  318 
 
  319 static void applkey(struct vc_data *vc, int key, char mode)
  320 {
  321    static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
  322 
    323    buf[1] = (mode ? 'O' : '[');
- 323 ternary-?: mode
  324    buf[2] = key;
  325    puts_queue(vc, buf);
  326 }
  327 
  328 /*
  329  * Many other routines do put_queue, but I think either
  330  * they produce ASCII, or they produce some user-assigned
  331  * string, and in both cases we might assume that it is
  332  * in utf-8 already. UTF-8 is defined for words of up to 31 bits,
  333  * but we need only 16 bits here
  334  */
 
- 335 static void to_utf8(struct vc_data *vc, ushort c)
  336 {
- 337    if (c < 0x80)
  338       /*  0******* */
  339       put_queue(vc, c);
- 340    else if (c < 0x800) {
  341       /* 110***** 10****** */
  342       put_queue(vc, 0xc0 | (c >> 6));
  343       put_queue(vc, 0x80 | (c & 0x3f));
    344    } else {
  345       /* 1110**** 10****** 10****** */
  346       put_queue(vc, 0xe0 | (c >> 12));
  347       put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
  348       put_queue(vc, 0x80 | (c & 0x3f));
  349    }
  350 }
  351 
  352 /*
  353  * Called after returning from RAW mode or when changing consoles - recompute
  354  * shift_down[] and shift_state from key_down[] maybe called when keymap is
  355  * undefined, so that shiftkey release is seen
  356  */
 
52 52   357 void compute_shiftstate(void)
  358 {
  359    unsigned int i, j, k, sym, val;
  360 
  361    shift_state = 0;
  362    memset(shift_down, 0, sizeof(shift_down));
  363 
416 52   364    for (i = 0; i < ARRAY_SIZE(key_down); i++) {
  365 
390 26   366       if (!key_down[i])
390    367          continue;
  368 
  369       k = i * BITS_PER_LONG;
  370 
1664 26   371       for (j = 0; j < BITS_PER_LONG; j++, k++) {
  372 
1624 40   373          if (!test_bit(k, key_down))
1664 - 373     ternary-?: __builtin_constant_p ( k )
1624    374             continue;
  375 
  376          sym = U(key_maps[0][k]);
14 26   377          if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
14    377       T && T
 - 377       T && F
 26   377       F && _
14    378             continue;
  379 
  380          val = KVAL(sym);
26 - 381          if (val == KVAL(K_CAPSSHIFT))
  382             val = KVAL(K_SHIFT);
  383 
  384          shift_down[val]++;
  385          shift_state |= (1 << val);
  386       }
  387    }
  388 }
  389 
  390 /*
  391  * We have a combining character DIACR here, followed by the character CH.
  392  * If the combination occurs in the table, return the corresponding value.
  393  * Otherwise, if CH is a space or equals DIACR, return DIACR.
  394  * Otherwise, conclude that DIACR was not combining after all,
  395  * queue it and return CH.
  396  */
 
- 397 static unsigned char handle_diacr(struct vc_data *vc, unsigned char ch)
  398 {
  399    int d = diacr;
  400    unsigned int i;
  401 
  402    diacr = 0;
  403 
- 404    for (i = 0; i < accent_table_size; i++) {
- 405       if (accent_table[i].diacr == d && accent_table[i].base == ch)
 - 405     T && T
 - 405     T && F
 - 405     F && _
 - 406          return accent_table[i].result;
  407    }
  408 
- 409    if (ch == ' ' || ch == d)
 - 409   T || _
 - 409   F || T
 - 409   F || F
 - 410       return d;
  411 
  412    put_queue(vc, d);
 - 413    return ch;
  414 }
  415 
  416 /*
  417  * Special function handlers
  418  */
 
51 51   419 static void fn_enter(struct vc_data *vc, struct pt_regs *regs)
  420 {
51 - 421    if (diacr) {
  422       put_queue(vc, diacr);
  423       diacr = 0;
  424    }
  425    put_queue(vc, 13);
51 - 426    if (vc_kbd_mode(kbd, VC_CRLF))
  427       put_queue(vc, 10);
  428 }
  429 
 
- 430 static void fn_caps_toggle(struct vc_data *vc, struct pt_regs *regs)
  431 {
- 432    if (rep)
 - 433       return;
  434    chg_vc_kbd_led(kbd, VC_CAPSLOCK);
  435 }
  436 
 
- 437 static void fn_caps_on(struct vc_data *vc, struct pt_regs *regs)
  438 {
- 439    if (rep)
 - 440       return;
  441    set_vc_kbd_led(kbd, VC_CAPSLOCK);
  442 }
  443 
 
- 444 static void fn_show_ptregs(struct vc_data *vc, struct pt_regs *regs)
  445 {
- 446    if (regs)
  447       show_regs(regs);
  448 }
  449 
 
- 450 static void fn_hold(struct vc_data *vc, struct pt_regs *regs)
  451 {
  452    struct tty_struct *tty = vc->vc_tty;
  453 
- 454    if (rep || !tty)
 - 454   T || _
 - 454   F || T
 - 454   F || F
 - 455       return;
  456 
  457    /*
  458     * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty);
  459     * these routines are also activated by ^S/^Q.
  460     * (And SCROLLOCK can also be set by the ioctl KDSKBLED.)
  461     */
- 462    if (tty->stopped)
  463       start_tty(tty);
    464    else
  465       stop_tty(tty);
  466 }
  467 
 
- 468 static void fn_num(struct vc_data *vc, struct pt_regs *regs)
  469 {
- 470    if (vc_kbd_mode(kbd,VC_APPLIC))
  471       applkey(vc, 'P', 1);
    472    else
  473       fn_bare_num(vc, regs);
  474 }
  475 
  476 /*
  477  * Bind this to Shift-NumLock if you work in application keypad mode
  478  * but want to be able to change the NumLock flag.
  479  * Bind this to NumLock if you prefer that the NumLock key always
  480  * changes the NumLock flag.
  481  */
 
- 482 static void fn_bare_num(struct vc_data *vc, struct pt_regs *regs)
  483 {
- 484    if (!rep)
  485       chg_vc_kbd_led(kbd, VC_NUMLOCK);
  486 }
  487 
 
- 488 static void fn_lastcons(struct vc_data *vc, struct pt_regs *regs)
  489 {
  490    /* switch to the last used console, ChN */
  491    set_console(last_console);
  492 }
  493 
 
- 494 static void fn_dec_console(struct vc_data *vc, struct pt_regs *regs)
  495 {
  496    int i, cur = fg_console;
  497 
  498    /* Currently switching?  Queue this next switch relative to that. */
- 499    if (want_console != -1)
  500       cur = want_console;
  501 
- 502    for (i = cur - 1; i != cur; i--) {
- 503       if (i == -1)
  504          i = MAX_NR_CONSOLES - 1;
- 505       if (vc_cons_allocated(i))
 - 506          break;
  507    }
  508    set_console(i);
  509 }
  510 
 
- 511 static void fn_inc_console(struct vc_data *vc, struct pt_regs *regs)
  512 {
  513    int i, cur = fg_console;
  514