OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [char/] [keyboard.c] - Blame information for rev 685

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * linux/drivers/char/keyboard.c
3
 *
4
 * Keyboard driver for Linux v0.99 using Latin-1.
5
 *
6
 * Written for linux by Johan Myreen as a translation from
7
 * the assembly version by Linus (with diacriticals added)
8
 *
9
 * Some additional features added by Christoph Niemann (ChN), March 1993
10
 *
11
 * Loadable keymaps by Risto Kankkunen, May 1993
12
 *
13
 * Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
14
 * Added decr/incr_console, dynamic keymaps, Unicode support,
15
 * dynamic function/string keys, led setting,  Sept 1994
16
 * `Sticky' modifier keys, 951006.
17
 *
18
 */
19
 
20 685 lampret
#define KEYBOARD_IRQ 21
21 199 simons
#define DISABLE_KBD_DURING_INTERRUPTS 0
22
 
23
#include <linux/sched.h>
24
#include <linux/interrupt.h>
25
#include <linux/tty.h>
26
#include <linux/tty_flip.h>
27
#include <linux/mm.h>
28
#include <linux/ptrace.h>
29
#include <linux/signal.h>
30
#include <linux/string.h>
31
#include <linux/ioport.h>
32
#include <linux/random.h>
33
 
34
#include <asm/bitops.h>
35
 
36
#include "kbd_kern.h"
37
#include "diacr.h"
38
#include "vt_kern.h"
39
 
40
/*
41
 * On non-x86 hardware we do a full keyboard controller
42
 * initialization, in case the bootup software hasn't done
43
 * it. On a x86, the BIOS will already have initialized the
44
 * keyboard.
45
 */
46
#ifndef __i386__
47
#define INIT_KBD
48
static int initialize_kbd(void);
49
#endif
50
 
51
#define SIZE(x) (sizeof(x)/sizeof((x)[0]))
52
 
53
#define KBD_REPORT_ERR
54
#define KBD_REPORT_UNKN
55
/* #define KBD_IS_FOCUS_9000 */
56
 
57
#ifndef KBD_DEFMODE
58
#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
59
#endif
60
 
61
#ifndef KBD_DEFLEDS
62
/*
63
 * Some laptops take the 789uiojklm,. keys as number pad when NumLock
64
 * is on. This seems a good reason to start with NumLock off.
65
 */
66
#define KBD_DEFLEDS 0
67
#endif
68
 
69
#ifndef KBD_DEFLOCK
70
#define KBD_DEFLOCK 0
71
#endif
72
 
73
#include <asm/io.h>
74
#include <asm/system.h>
75
 
76
extern void poke_blanked_console(void);
77
extern void ctrl_alt_del(void);
78
extern void reset_vc(unsigned int new_console);
79
extern void scrollback(int);
80
extern void scrollfront(int);
81
 
82
unsigned char kbd_read_mask = 0x01;     /* modified by psaux.c */
83
 
84
/*
85
 * global state includes the following, and various static variables
86
 * in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next.
87
 * (last_console is now a global variable)
88
 */
89
 
90
/* shift state counters.. */
91
static unsigned char k_down[NR_SHIFT] = {0, };
92
/* keyboard key bitmap */
93
#define BITS_PER_LONG (8*sizeof(unsigned long))
94
static unsigned long key_down[256/BITS_PER_LONG] = { 0, };
95
 
96
static int dead_key_next = 0;
97
/*
98
 * In order to retrieve the shift_state (for the mouse server), either
99
 * the variable must be global, or a new procedure must be created to
100
 * return the value. I chose the former way.
101
 */
102
/*static*/ int shift_state = 0;
103
static int npadch = -1;                 /* -1 or number assembled on pad */
104
static unsigned char diacr = 0;
105
static char rep = 0;                     /* flag telling character repeat */
106
struct kbd_struct kbd_table[MAX_NR_CONSOLES];
107
static struct tty_struct **ttytab;
108
static struct kbd_struct * kbd = kbd_table;
109
static struct tty_struct * tty = NULL;
110
 
111
/* used only by send_data - set by keyboard_interrupt */
112
static volatile unsigned char reply_expected = 0;
113
static volatile unsigned char acknowledge = 0;
114
static volatile unsigned char resend = 0;
115
 
116
extern void compute_shiftstate(void);
117
 
118
typedef void (*k_hand)(unsigned char value, char up_flag);
119
typedef void (k_handfn)(unsigned char value, char up_flag);
120
 
121
static k_handfn
122
        do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
123
        do_meta, do_ascii, do_lock, do_lowercase, do_slock, do_ignore;
124
 
125
static k_hand key_handler[16] = {
126
        do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
127
        do_meta, do_ascii, do_lock, do_lowercase, do_slock,
128
        do_ignore, do_ignore, do_ignore
129
};
130
 
131
typedef void (*void_fnp)(void);
132
typedef void (void_fn)(void);
133
 
134
static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle,
135
        num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose,
136
        SAK, decr_console, incr_console, spawn_console, bare_num;
137
 
138
static void_fnp spec_fn_table[] = {
139
        do_null,        enter,          show_ptregs,    show_mem,
140
        show_state,     send_intr,      lastcons,       caps_toggle,
141
        num,            hold,           scroll_forw,    scroll_back,
142
        boot_it,        caps_on,        compose,        SAK,
143
        decr_console,   incr_console,   spawn_console,  bare_num
144
};
145
 
146
/* maximum values each key_handler can handle */
147
const int max_vals[] = {
148
        255, SIZE(func_table) - 1, SIZE(spec_fn_table) - 1, NR_PAD - 1,
149
        NR_DEAD - 1, 255, 3, NR_SHIFT - 1,
150
        255, NR_ASCII - 1, NR_LOCK - 1, 255,
151
        NR_LOCK - 1
152
};
153
 
154
const int NR_TYPES = SIZE(max_vals);
155
 
156
static void put_queue(int);
157
static unsigned char handle_diacr(unsigned char);
158
 
159
/* pt_regs - set by keyboard_interrupt(), used by show_ptregs() */
160
static struct pt_regs * pt_regs;
161
 
162
static inline void kb_wait(void)
163
{
164
        int i;
165
 
166
        for (i=0; i<0x100000; i++)
167 685 lampret
                if ((inb_p(KBD_BASE_ADD+0x4) & 0x02) == 0)
168 199 simons
                        return;
169
        printk(KERN_WARNING "Keyboard timed out\n");
170
}
171
 
172
static inline void send_cmd(unsigned char c)
173
{
174
        kb_wait();
175 685 lampret
        outb(c,KBD_BASE_ADD+0x4);
176 199 simons
}
177
 
178
/*
179
 * Many other routines do put_queue, but I think either
180
 * they produce ASCII, or they produce some user-assigned
181
 * string, and in both cases we might assume that it is
182
 * in utf-8 already.
183
 */
184
void to_utf8(ushort c) {
185
    if (c < 0x80)
186
        put_queue(c);                   /*  0*******  */
187
    else if (c < 0x800) {
188
        put_queue(0xc0 | (c >> 6));     /*  110***** 10******  */
189
        put_queue(0x80 | (c & 0x3f));
190
    } else {
191
        put_queue(0xe0 | (c >> 12));    /*  1110**** 10****** 10******  */
192
        put_queue(0x80 | ((c >> 6) & 0x3f));
193
        put_queue(0x80 | (c & 0x3f));
194
    }
195
    /* UTF-8 is defined for words of up to 31 bits,
196
       but we need only 16 bits here */
197
}
198
 
199
/*
200
 * Translation of escaped scancodes to keycodes.
201
 * This is now user-settable.
202
 * The keycodes 1-88,96-111,119 are fairly standard, and
203
 * should probably not be changed - changing might confuse X.
204
 * X also interprets scancode 0x5d (KEY_Begin).
205
 *
206
 * For 1-88 keycode equals scancode.
207
 */
208
 
209
#define E0_KPENTER 96
210
#define E0_RCTRL   97
211
#define E0_KPSLASH 98
212
#define E0_PRSCR   99
213
#define E0_RALT    100
214
#define E0_BREAK   101  /* (control-pause) */
215
#define E0_HOME    102
216
#define E0_UP      103
217
#define E0_PGUP    104
218
#define E0_LEFT    105
219
#define E0_RIGHT   106
220
#define E0_END     107
221
#define E0_DOWN    108
222
#define E0_PGDN    109
223
#define E0_INS     110
224
#define E0_DEL     111
225
 
226
#define E1_PAUSE   119
227
 
228
/*
229
 * The keycodes below are randomly located in 89-95,112-118,120-127.
230
 * They could be thrown away (and all occurrences below replaced by 0),
231
 * but that would force many users to use the `setkeycodes' utility, where
232
 * they needed not before. It does not matter that there are duplicates, as
233
 * long as no duplication occurs for any single keyboard.
234
 */
235
#define SC_LIM 89
236
 
237
#define FOCUS_PF1 85           /* actual code! */
238
#define FOCUS_PF2 89
239
#define FOCUS_PF3 90
240
#define FOCUS_PF4 91
241
#define FOCUS_PF5 92
242
#define FOCUS_PF6 93
243
#define FOCUS_PF7 94
244
#define FOCUS_PF8 95
245
#define FOCUS_PF9 120
246
#define FOCUS_PF10 121
247
#define FOCUS_PF11 122
248
#define FOCUS_PF12 123
249
 
250
#define JAP_86     124
251
/* tfj@olivia.ping.dk:
252
 * The four keys are located over the numeric keypad, and are
253
 * labelled A1-A4. It's an rc930 keyboard, from
254
 * Regnecentralen/RC International, Now ICL.
255
 * Scancodes: 59, 5a, 5b, 5c.
256
 */
257
#define RGN1 124
258
#define RGN2 125
259
#define RGN3 126
260
#define RGN4 127
261
 
262
static unsigned char high_keys[128 - SC_LIM] = {
263
  RGN1, RGN2, RGN3, RGN4, 0, 0, 0,                   /* 0x59-0x5f */
264
  0, 0, 0, 0, 0, 0, 0, 0,                            /* 0x60-0x67 */
265
  0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12,          /* 0x68-0x6f */
266
  0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3,    /* 0x70-0x77 */
267
  FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7,        /* 0x78-0x7b */
268
  FOCUS_PF8, JAP_86, FOCUS_PF10, 0                   /* 0x7c-0x7f */
269
};
270
 
271
/* BTC */
272
#define E0_MACRO   112
273
/* LK450 */
274
#define E0_F13     113
275
#define E0_F14     114
276
#define E0_HELP    115
277
#define E0_DO      116
278
#define E0_F17     117
279
#define E0_KPMINPLUS 118
280
/*
281
 * My OmniKey generates e0 4c for  the "OMNI" key and the
282
 * right alt key does nada. [kkoller@nyx10.cs.du.edu]
283
 */
284
#define E0_OK   124
285
/*
286
 * New microsoft keyboard is rumoured to have
287
 * e0 5b (left window button), e0 5c (right window button),
288
 * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
289
 * [or: Windows_L, Windows_R, TaskMan]
290
 */
291
#define E0_MSLW 125
292
#define E0_MSRW 126
293
#define E0_MSTM 127
294
 
295
static unsigned char e0_keys[128] = {
296
  0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x00-0x07 */
297
  0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x08-0x0f */
298
  0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x10-0x17 */
299
  0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0,           /* 0x18-0x1f */
300
  0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x20-0x27 */
301
  0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x28-0x2f */
302
  0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR,           /* 0x30-0x37 */
303
  E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP,           /* 0x38-0x3f */
304
  E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME,           /* 0x40-0x47 */
305
  E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
306
  E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0,           /* 0x50-0x57 */
307
  0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0,        /* 0x58-0x5f */
308
  0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x60-0x67 */
309
  0, 0, 0, 0, 0, 0, 0, E0_MACRO,                     /* 0x68-0x6f */
310
  0, 0, 0, 0, 0, 0, 0, 0,                             /* 0x70-0x77 */
311
  0, 0, 0, 0, 0, 0, 0, 0                              /* 0x78-0x7f */
312
};
313
 
314
int setkeycode(unsigned int scancode, unsigned int keycode)
315
{
316
        if (scancode < SC_LIM || scancode > 255 || keycode > 127)
317
          return -EINVAL;
318
        if (scancode < 128)
319
          high_keys[scancode - SC_LIM] = keycode;
320
        else
321
          e0_keys[scancode - 128] = keycode;
322
        return 0;
323
}
324
 
325
int getkeycode(unsigned int scancode)
326
{
327
        return
328
          (scancode < SC_LIM || scancode > 255) ? -EINVAL :
329
          (scancode < 128) ? high_keys[scancode - SC_LIM] :
330
            e0_keys[scancode - 128];
331
}
332
 
333
#if DISABLE_KBD_DURING_INTERRUPTS
334
#define disable_keyboard()      do { send_cmd(0xAD); kb_wait(); } while (0)
335
#define enable_keyboard()       send_cmd(0xAE)
336
#else
337
#define disable_keyboard()      /* nothing */
338
#define enable_keyboard()       /* nothing */
339
#endif
340
 
341
static void handle_scancode(unsigned char scancode)
342
{
343
        unsigned char keycode;
344
        static unsigned int prev_scancode = 0;   /* remember E0, E1 */
345
        char up_flag;                            /* 0 or 0200 */
346
        char raw_mode;
347
 
348
        if (reply_expected) {
349
          /* 0xfa, 0xfe only mean "acknowledge", "resend" for most keyboards */
350
          /* but they are the key-up scancodes for PF6, PF10 on a FOCUS 9000 */
351
                reply_expected = 0;
352
                if (scancode == 0xfa) {
353
                        acknowledge = 1;
354
                        return;
355
                } else if (scancode == 0xfe) {
356
                        resend = 1;
357
                        return;
358
                }
359
                /* strange ... */
360
                reply_expected = 1;
361
#if 0
362
                printk(KERN_DEBUG "keyboard reply expected - got %02x\n",
363
                       scancode);
364
#endif
365
        }
366
        if (scancode == 0) {
367
#ifdef KBD_REPORT_ERR
368
                printk(KERN_INFO "keyboard buffer overflow\n");
369
#endif
370
                prev_scancode = 0;
371
                return;
372
        }
373
        do_poke_blanked_console = 1;
374
        mark_bh(CONSOLE_BH);
375
        add_keyboard_randomness(scancode);
376
 
377
        tty = ttytab? ttytab[fg_console]: NULL;
378
        if (tty && (!tty->driver_data)) {
379
                /* This is to workaround ugly bug in tty_io.c, which
380
                   does not do locking when it should */
381
                tty = NULL;
382
        }
383
        kbd = kbd_table + fg_console;
384
        if ((raw_mode = (kbd->kbdmode == VC_RAW))) {
385
                put_queue(scancode);
386
                /* we do not return yet, because we want to maintain
387
                   the key_down array, so that we have the correct
388
                   values when finishing RAW mode or when changing VT's */
389
        }
390
 
391
        if (scancode == 0xff) {
392
                /* in scancode mode 1, my ESC key generates 0xff */
393
                /* the calculator keys on a FOCUS 9000 generate 0xff */
394
#ifndef KBD_IS_FOCUS_9000
395
#ifdef KBD_REPORT_ERR
396
                if (!raw_mode)
397
                  printk(KERN_DEBUG "keyboard error\n");
398
#endif
399
#endif
400
                prev_scancode = 0;
401
                return;
402
        }
403
 
404
        if (scancode == 0xe0 || scancode == 0xe1) {
405
                prev_scancode = scancode;
406
                return;
407
        }
408
 
409
        /*
410
         *  Convert scancode to keycode, using prev_scancode.
411
         */
412
        up_flag = (scancode & 0200);
413
        scancode &= 0x7f;
414
 
415
        if (prev_scancode) {
416
          /*
417
           * usually it will be 0xe0, but a Pause key generates
418
           * e1 1d 45 e1 9d c5 when pressed, and nothing when released
419
           */
420
          if (prev_scancode != 0xe0) {
421
              if (prev_scancode == 0xe1 && scancode == 0x1d) {
422
                  prev_scancode = 0x100;
423
                  return;
424
              } else if (prev_scancode == 0x100 && scancode == 0x45) {
425
                  keycode = E1_PAUSE;
426
                  prev_scancode = 0;
427
              } else {
428
#ifdef KBD_REPORT_UNKN
429
                  if (!raw_mode)
430
                    printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
431
#endif
432
                  prev_scancode = 0;
433
                  return;
434
              }
435
          } else {
436
              prev_scancode = 0;
437
              /*
438
               *  The keyboard maintains its own internal caps lock and
439
               *  num lock statuses. In caps lock mode E0 AA precedes make
440
               *  code and E0 2A follows break code. In num lock mode,
441
               *  E0 2A precedes make code and E0 AA follows break code.
442
               *  We do our own book-keeping, so we will just ignore these.
443
               */
444
              /*
445
               *  For my keyboard there is no caps lock mode, but there are
446
               *  both Shift-L and Shift-R modes. The former mode generates
447
               *  E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
448
               *  So, we should also ignore the latter. - aeb@cwi.nl
449
               */
450
              if (scancode == 0x2a || scancode == 0x36)
451
                return;
452
 
453
              if (e0_keys[scancode])
454
                keycode = e0_keys[scancode];
455
              else {
456
#ifdef KBD_REPORT_UNKN
457
                  if (!raw_mode)
458
                    printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
459
                           scancode);
460
#endif
461
                  return;
462
              }
463
          }
464
        } else if (scancode >= SC_LIM) {
465
            /* This happens with the FOCUS 9000 keyboard
466
               Its keys PF1..PF12 are reported to generate
467
               55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
468
               Moreover, unless repeated, they do not generate
469
               key-down events, so we have to zero up_flag below */
470
            /* Also, Japanese 86/106 keyboards are reported to
471
               generate 0x73 and 0x7d for \ - and \ | respectively. */
472
            /* Also, some Brazilian keyboard is reported to produce
473
               0x73 and 0x7e for \ ? and KP-dot, respectively. */
474
 
475
          keycode = high_keys[scancode - SC_LIM];
476
 
477
          if (!keycode) {
478
              if (!raw_mode) {
479
#ifdef KBD_REPORT_UNKN
480
                  printk(KERN_INFO "keyboard: unrecognized scancode (%02x)"
481
                         " - ignored\n", scancode);
482
#endif
483
              }
484
              return;
485
          }
486
        } else
487
          keycode = scancode;
488
 
489
        /*
490
         * At this point the variable `keycode' contains the keycode.
491
         * Note: the keycode must not be 0.
492
         * We keep track of the up/down status of the key, and
493
         * return the keycode if in MEDIUMRAW mode.
494
         */
495
 
496
        if (up_flag) {
497
                rep = 0;
498
                if(!clear_bit(keycode, key_down)) {
499
                    /* unexpected, but this can happen:
500
                       maybe this was a key release for a FOCUS 9000
501
                       PF key; if we want to see it, we have to clear
502
                       up_flag */
503
                    if (keycode >= SC_LIM || keycode == 85)
504
                      up_flag = 0;
505
                }
506
        } else
507
                rep = set_bit(keycode, key_down);
508
 
509
        if (raw_mode)
510
                return;
511
 
512
        if (kbd->kbdmode == VC_MEDIUMRAW) {
513
                /* soon keycodes will require more than one byte */
514
                put_queue(keycode + up_flag);
515
                return;
516
        }
517
 
518
        /*
519
         * Small change in philosophy: earlier we defined repetition by
520
         *       rep = keycode == prev_keycode;
521
         *       prev_keycode = keycode;
522
         * but now by the fact that the depressed key was down already.
523
         * Does this ever make a difference? Yes.
524
         */
525
 
526
        /*
527
         *  Repeat a key only if the input buffers are empty or the
528
         *  characters get echoed locally. This makes key repeat usable
529
         *  with slow applications and under heavy loads.
530
         */
531
        if (!rep ||
532
            (vc_kbd_mode(kbd,VC_REPEAT) && tty &&
533
             (L_ECHO(tty) || (tty->driver.chars_in_buffer(tty) == 0)))) {
534
                u_short keysym;
535
                u_char type;
536
 
537
                /* the XOR below used to be an OR */
538
                int shift_final = shift_state ^ kbd->lockstate ^ kbd->slockstate;
539
                ushort *key_map = key_maps[shift_final];
540
 
541
                if (key_map != NULL) {
542
                        keysym = key_map[keycode];
543
                        type = KTYP(keysym);
544
 
545
                        if (type >= 0xf0) {
546
                            type -= 0xf0;
547
                            if (type == KT_LETTER) {
548
                                type = KT_LATIN;
549
                                if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
550
                                    key_map = key_maps[shift_final ^ (1<<KG_SHIFT)];
551
                                    if (key_map)
552
                                      keysym = key_map[keycode];
553
                                }
554
                            }
555
                            (*key_handler[type])(keysym & 0xff, up_flag);
556
                            if (type != KT_SLOCK)
557
                              kbd->slockstate = 0;
558
                        } else {
559
                            /* maybe only if (kbd->kbdmode == VC_UNICODE) ? */
560
                            if (!up_flag)
561
                              to_utf8(keysym);
562
                        }
563
                } else {
564
                        /* maybe beep? */
565
                        /* we have at least to update shift_state */
566
#if 1                   /* how? two almost equivalent choices follow */
567
                        compute_shiftstate();
568
#else
569
                        keysym = U(plain_map[keycode]);
570
                        type = KTYP(keysym);
571
                        if (type == KT_SHIFT)
572
                          (*key_handler[type])(keysym & 0xff, up_flag);
573
#endif
574
                }
575
        }
576
}
577
 
578
static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
579
{
580
        unsigned char status;
581
 
582
        pt_regs = regs;
583
        disable_keyboard();
584
 
585 685 lampret
        status = inb_p(KBD_BASE_ADD+0x4);
586 199 simons
        do {
587
                unsigned char scancode;
588
 
589
                /* mouse data? */
590
                if (status & kbd_read_mask & 0x20)
591
                        break;
592
 
593 685 lampret
                scancode = inb(KBD_BASE_ADD+0x0);
594 199 simons
                if (status & 0x01)
595
                        handle_scancode(scancode);
596
 
597 685 lampret
                status = inb(KBD_BASE_ADD+0x4);
598 199 simons
        } while (status & 0x01);
599
 
600
        mark_bh(KEYBOARD_BH);
601
        enable_keyboard();
602
}
603
 
604
static void put_queue(int ch)
605
{
606
        wake_up(&keypress_wait);
607
        if (tty) {
608
                tty_insert_flip_char(tty, ch, 0);
609
                tty_schedule_flip(tty);
610
        }
611
}
612
 
613
static void puts_queue(char *cp)
614
{
615
        wake_up(&keypress_wait);
616
        if (!tty)
617
                return;
618
 
619
        while (*cp) {
620
                tty_insert_flip_char(tty, *cp, 0);
621
                cp++;
622
        }
623
        tty_schedule_flip(tty);
624
}
625
 
626
static void applkey(int key, char mode)
627
{
628
        static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
629
 
630
        buf[1] = (mode ? 'O' : '[');
631
        buf[2] = key;
632
        puts_queue(buf);
633
}
634
 
635
static void enter(void)
636
{
637
        put_queue(13);
638
        if (vc_kbd_mode(kbd,VC_CRLF))
639
                put_queue(10);
640
}
641
 
642
static void caps_toggle(void)
643
{
644
        if (rep)
645
                return;
646
        chg_vc_kbd_led(kbd, VC_CAPSLOCK);
647
}
648
 
649
static void caps_on(void)
650
{
651
        if (rep)
652
                return;
653
        set_vc_kbd_led(kbd, VC_CAPSLOCK);
654
}
655
 
656
static void show_ptregs(void)
657
{
658
        if (pt_regs)
659
                show_regs(pt_regs);
660
}
661
 
662
static void hold(void)
663
{
664
        if (rep || !tty)
665
                return;
666
 
667
        /*
668
         * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty);
669
         * these routines are also activated by ^S/^Q.
670
         * (And SCROLLOCK can also be set by the ioctl KDSKBLED.)
671
         */
672
        if (tty->stopped)
673
                start_tty(tty);
674
        else
675
                stop_tty(tty);
676
}
677
 
678
static void num(void)
679
{
680
        if (vc_kbd_mode(kbd,VC_APPLIC))
681
                applkey('P', 1);
682
        else
683
                bare_num();
684
}
685
 
686
/*
687
 * Bind this to Shift-NumLock if you work in application keypad mode
688
 * but want to be able to change the NumLock flag.
689
 * Bind this to NumLock if you prefer that the NumLock key always
690
 * changes the NumLock flag.
691
 */
692
static void bare_num(void)
693
{
694
        if (!rep)
695
                chg_vc_kbd_led(kbd,VC_NUMLOCK);
696
}
697
 
698
static void lastcons(void)
699
{
700
        /* switch to the last used console, ChN */
701
        set_console(last_console);
702
}
703
 
704
static void decr_console(void)
705
{
706
        int i;
707
 
708
        for (i = fg_console-1; i != fg_console; i--) {
709
                if (i == -1)
710
                        i = MAX_NR_CONSOLES-1;
711
                if (vc_cons_allocated(i))
712
                        break;
713
        }
714
        set_console(i);
715
}
716
 
717
static void incr_console(void)
718
{
719
        int i;
720
 
721
        for (i = fg_console+1; i != fg_console; i++) {
722
                if (i == MAX_NR_CONSOLES)
723
                        i = 0;
724
                if (vc_cons_allocated(i))
725
                        break;
726
        }
727
        set_console(i);
728
}
729
 
730
static void send_intr(void)
731
{
732
        if (!tty)
733
                return;
734
        tty_insert_flip_char(tty, 0, TTY_BREAK);
735
        tty_schedule_flip(tty);
736
}
737
 
738
static void scroll_forw(void)
739
{
740
        scrollfront(0);
741
}
742
 
743
static void scroll_back(void)
744
{
745
        scrollback(0);
746
}
747
 
748
static void boot_it(void)
749
{
750
        ctrl_alt_del();
751
}
752
 
753
static void compose(void)
754
{
755
        dead_key_next = 1;
756
}
757
 
758
int spawnpid, spawnsig;
759
 
760
static void spawn_console(void)
761
{
762
        if (spawnpid)
763
           if(kill_proc(spawnpid, spawnsig, 1))
764
             spawnpid = 0;
765
}
766
 
767
static void SAK(void)
768
{
769
        do_SAK(tty);
770
#if 0
771
        /*
772
         * Need to fix SAK handling to fix up RAW/MEDIUM_RAW and
773
         * vt_cons modes before we can enable RAW/MEDIUM_RAW SAK
774
         * handling.
775
         *
776
         * We should do this some day --- the whole point of a secure
777
         * attention key is that it should be guaranteed to always
778
         * work.
779
         */
780
        reset_vc(fg_console);
781
        do_unblank_screen();    /* not in interrupt routine? */
782
#endif
783
}
784
 
785
static void do_ignore(unsigned char value, char up_flag)
786
{
787
}
788
 
789
static void do_null()
790
{
791
        compute_shiftstate();
792
}
793
 
794
static void do_spec(unsigned char value, char up_flag)
795
{
796
        if (up_flag)
797
                return;
798
        if (value >= SIZE(spec_fn_table))
799
                return;
800
        spec_fn_table[value]();
801
}
802
 
803
static void do_lowercase(unsigned char value, char up_flag)
804
{
805
        printk(KERN_ERR "keyboard.c: do_lowercase was called - impossible\n");
806
}
807
 
808
static void do_self(unsigned char value, char up_flag)
809
{
810
        if (up_flag)
811
                return;         /* no action, if this is a key release */
812
 
813
        if (diacr)
814
                value = handle_diacr(value);
815
 
816
        if (dead_key_next) {
817
                dead_key_next = 0;
818
                diacr = value;
819
                return;
820
        }
821
 
822
        put_queue(value);
823
}
824
 
825
#define A_GRAVE  '`'
826
#define A_ACUTE  '\''
827
#define A_CFLEX  '^'
828
#define A_TILDE  '~'
829
#define A_DIAER  '"'
830
#define A_CEDIL  ','
831
static unsigned char ret_diacr[NR_DEAD] =
832
        {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL };
833
 
834
/* If a dead key pressed twice, output a character corresponding to it, */
835
/* otherwise just remember the dead key.                                */
836
 
837
static void do_dead(unsigned char value, char up_flag)
838
{
839
        if (up_flag)
840
                return;
841
 
842
        value = ret_diacr[value];
843
        if (diacr == value) {   /* pressed twice */
844
                diacr = 0;
845
                put_queue(value);
846
                return;
847
        }
848
        diacr = value;
849
}
850
 
851
 
852
/* If space is pressed, return the character corresponding the pending  */
853
/* dead key, otherwise try to combine the two.                          */
854
 
855
unsigned char handle_diacr(unsigned char ch)
856
{
857
        int d = diacr;
858
        int i;
859
 
860
        diacr = 0;
861
        if (ch == ' ')
862
                return d;
863
 
864
        for (i = 0; i < accent_table_size; i++) {
865
                if (accent_table[i].diacr == d && accent_table[i].base == ch)
866
                        return accent_table[i].result;
867
        }
868
 
869
        put_queue(d);
870
        return ch;
871
}
872
 
873
static void do_cons(unsigned char value, char up_flag)
874
{
875
        if (up_flag)
876
                return;
877
        set_console(value);
878
}
879
 
880
static void do_fn(unsigned char value, char up_flag)
881
{
882
        if (up_flag)
883
                return;
884
        if (value < SIZE(func_table)) {
885
                if (func_table[value])
886
                        puts_queue(func_table[value]);
887
        } else
888
                printk(KERN_ERR "do_fn called with value=%d\n", value);
889
}
890
 
891
static void do_pad(unsigned char value, char up_flag)
892
{
893
        static const char *pad_chars = "0123456789+-*/\015,.?";
894
        static const char *app_map = "pqrstuvwxylSRQMnn?";
895
 
896
        if (up_flag)
897
                return;         /* no action, if this is a key release */
898
 
899
        /* kludge... shift forces cursor/number keys */
900
        if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
901
                applkey(app_map[value], 1);
902
                return;
903
        }
904
 
905
        if (!vc_kbd_led(kbd,VC_NUMLOCK))
906
                switch (value) {
907
                        case KVAL(K_PCOMMA):
908
                        case KVAL(K_PDOT):
909
                                do_fn(KVAL(K_REMOVE), 0);
910
                                return;
911
                        case KVAL(K_P0):
912
                                do_fn(KVAL(K_INSERT), 0);
913
                                return;
914
                        case KVAL(K_P1):
915
                                do_fn(KVAL(K_SELECT), 0);
916
                                return;
917
                        case KVAL(K_P2):
918
                                do_cur(KVAL(K_DOWN), 0);
919
                                return;
920
                        case KVAL(K_P3):
921
                                do_fn(KVAL(K_PGDN), 0);
922
                                return;
923
                        case KVAL(K_P4):
924
                                do_cur(KVAL(K_LEFT), 0);
925
                                return;
926
                        case KVAL(K_P6):
927
                                do_cur(KVAL(K_RIGHT), 0);
928
                                return;
929
                        case KVAL(K_P7):
930
                                do_fn(KVAL(K_FIND), 0);
931
                                return;
932
                        case KVAL(K_P8):
933
                                do_cur(KVAL(K_UP), 0);
934
                                return;
935
                        case KVAL(K_P9):
936
                                do_fn(KVAL(K_PGUP), 0);
937
                                return;
938
                        case KVAL(K_P5):
939
                                applkey('G', vc_kbd_mode(kbd, VC_APPLIC));
940
                                return;
941
                }
942
 
943
        put_queue(pad_chars[value]);
944
        if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
945
                put_queue(10);
946
}
947
 
948
static void do_cur(unsigned char value, char up_flag)
949
{
950
        static const char *cur_chars = "BDCA";
951
        if (up_flag)
952
                return;
953
 
954
        applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));
955
}
956
 
957
static void do_shift(unsigned char value, char up_flag)
958
{
959
        int old_state = shift_state;
960
 
961
        if (rep)
962
                return;
963
 
964
        /* Mimic typewriter:
965
           a CapsShift key acts like Shift but undoes CapsLock */
966
        if (value == KVAL(K_CAPSSHIFT)) {
967
                value = KVAL(K_SHIFT);
968
                if (!up_flag)
969
                        clr_vc_kbd_led(kbd, VC_CAPSLOCK);
970
        }
971
 
972
        if (up_flag) {
973
                /* handle the case that two shift or control
974
                   keys are depressed simultaneously */
975
                if (k_down[value])
976
                        k_down[value]--;
977
        } else
978
                k_down[value]++;
979
 
980
        if (k_down[value])
981
                shift_state |= (1 << value);
982
        else
983
                shift_state &= ~ (1 << value);
984
 
985
        /* kludge */
986
        if (up_flag && shift_state != old_state && npadch != -1) {
987
                if (kbd->kbdmode == VC_UNICODE)
988
                  to_utf8(npadch & 0xffff);
989
                else
990
                  put_queue(npadch & 0xff);
991
                npadch = -1;
992
        }
993
}
994
 
995
/* called after returning from RAW mode or when changing consoles -
996
   recompute k_down[] and shift_state from key_down[] */
997
/* maybe called when keymap is undefined, so that shiftkey release is seen */
998
void compute_shiftstate(void)
999
{
1000
        int i, j, k, sym, val;
1001
 
1002
        shift_state = 0;
1003
        for(i=0; i < SIZE(k_down); i++)
1004
          k_down[i] = 0;
1005
 
1006
        for(i=0; i < SIZE(key_down); i++)
1007
          if(key_down[i]) {     /* skip this word if not a single bit on */
1008
            k = i*BITS_PER_LONG;
1009
            for(j=0; j<BITS_PER_LONG; j++,k++)
1010
              if(test_bit(k, key_down)) {
1011
                sym = U(plain_map[k]);
1012
                if(KTYP(sym) == KT_SHIFT) {
1013
                  val = KVAL(sym);
1014
                  if (val == KVAL(K_CAPSSHIFT))
1015
                    val = KVAL(K_SHIFT);
1016
                  k_down[val]++;
1017
                  shift_state |= (1<<val);
1018
                }
1019
              }
1020
          }
1021
}
1022
 
1023
static void do_meta(unsigned char value, char up_flag)
1024
{
1025
        if (up_flag)
1026
                return;
1027
 
1028
        if (vc_kbd_mode(kbd, VC_META)) {
1029
                put_queue('\033');
1030
                put_queue(value);
1031
        } else
1032
                put_queue(value | 0x80);
1033
}
1034
 
1035
static void do_ascii(unsigned char value, char up_flag)
1036
{
1037
        int base;
1038
 
1039
        if (up_flag)
1040
                return;
1041
 
1042
        if (value < 10)    /* decimal input of code, while Alt depressed */
1043
            base = 10;
1044
        else {       /* hexadecimal input of code, while AltGr depressed */
1045
            value -= 10;
1046
            base = 16;
1047
        }
1048
 
1049
        if (npadch == -1)
1050
          npadch = value;
1051
        else
1052
          npadch = npadch * base + value;
1053
}
1054
 
1055
static void do_lock(unsigned char value, char up_flag)
1056
{
1057
        if (up_flag || rep)
1058
                return;
1059
        chg_vc_kbd_lock(kbd, value);
1060
}
1061
 
1062
static void do_slock(unsigned char value, char up_flag)
1063
{
1064
        if (up_flag || rep)
1065
                return;
1066
        chg_vc_kbd_slock(kbd, value);
1067
}
1068
 
1069
/*
1070
 * send_data sends a character to the keyboard and waits
1071
 * for a acknowledge, possibly retrying if asked to. Returns
1072
 * the success status.
1073
 */
1074
static int send_data(unsigned char data)
1075
{
1076
        int retries = 3;
1077
        int i;
1078
 
1079
        do {
1080
                kb_wait();
1081
                acknowledge = 0;
1082
                resend = 0;
1083
                reply_expected = 1;
1084 685 lampret
 
1085
                outb_p(data, KBD_BASE_ADD+0x0);
1086 199 simons
                for(i=0; i<0x200000; i++) {
1087
                        extern void allow_interrupts(void);
1088
                        allow_interrupts();
1089 685 lampret
                        inb_p(KBD_BASE_ADD+0x4);                /* just as a delay */
1090 199 simons
                        if (acknowledge)
1091
                                return 1;
1092
                        if (resend)
1093
                                break;
1094
                }
1095
                if (!resend)
1096
                        return 0;
1097
        } while (retries-- > 0);
1098
        return 0;
1099
}
1100
 
1101
/*
1102
 * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
1103
 * or (ii) whatever pattern of lights people want to show using KDSETLED,
1104
 * or (iii) specified bits of specified words in kernel memory.
1105
 */
1106
 
1107
static unsigned char ledstate = 0xff; /* undefined */
1108
static unsigned char ledioctl;
1109
 
1110
unsigned char getledstate(void) {
1111
    return ledstate;
1112
}
1113
 
1114
void setledstate(struct kbd_struct *kbd, unsigned int led) {
1115
    if (!(led & ~7)) {
1116
        ledioctl = led;
1117
        kbd->ledmode = LED_SHOW_IOCTL;
1118
    } else
1119
        kbd->ledmode = LED_SHOW_FLAGS;
1120
    set_leds();
1121
}
1122
 
1123
static struct ledptr {
1124
    unsigned int *addr;
1125
    unsigned int mask;
1126
    unsigned char valid:1;
1127
} ledptrs[3];
1128
 
1129
void register_leds(int console, unsigned int led,
1130
                   unsigned int *addr, unsigned int mask) {
1131
    struct kbd_struct *kbd = kbd_table + console;
1132
    if (led < 3) {
1133
        ledptrs[led].addr = addr;
1134
        ledptrs[led].mask = mask;
1135
        ledptrs[led].valid = 1;
1136
        kbd->ledmode = LED_SHOW_MEM;
1137
    } else
1138
        kbd->ledmode = LED_SHOW_FLAGS;
1139
}
1140
 
1141
static inline unsigned char getleds(void){
1142
    struct kbd_struct *kbd = kbd_table + fg_console;
1143
    unsigned char leds;
1144
 
1145
    if (kbd->ledmode == LED_SHOW_IOCTL)
1146
      return ledioctl;
1147
    leds = kbd->ledflagstate;
1148
    if (kbd->ledmode == LED_SHOW_MEM) {
1149
        if (ledptrs[0].valid) {
1150
            if (*ledptrs[0].addr & ledptrs[0].mask)
1151
              leds |= 1;
1152
            else
1153
              leds &= ~1;
1154
        }
1155
        if (ledptrs[1].valid) {
1156
            if (*ledptrs[1].addr & ledptrs[1].mask)
1157
              leds |= 2;
1158
            else
1159
              leds &= ~2;
1160
        }
1161
        if (ledptrs[2].valid) {
1162
            if (*ledptrs[2].addr & ledptrs[2].mask)
1163
              leds |= 4;
1164
            else
1165
              leds &= ~4;
1166
        }
1167
    }
1168
    return leds;
1169
}
1170
 
1171
/*
1172
 * This routine is the bottom half of the keyboard interrupt
1173
 * routine, and runs with all interrupts enabled. It does
1174
 * console changing, led setting and copy_to_cooked, which can
1175
 * take a reasonably long time.
1176
 *
1177
 * Aside from timing (which isn't really that important for
1178
 * keyboard interrupts as they happen often), using the software
1179
 * interrupt routines for this thing allows us to easily mask
1180
 * this when we don't want any of the above to happen. Not yet
1181
 * used, but this allows for easy and efficient race-condition
1182
 * prevention later on.
1183
 */
1184
static void kbd_bh(void)
1185
{
1186
        unsigned char leds = getleds();
1187
 
1188
        if (leds != ledstate) {
1189
                ledstate = leds;
1190
                if (!send_data(0xed) || !send_data(leds))
1191
                        send_data(0xf4);        /* re-enable kbd if any errors */
1192
        }
1193
}
1194
 
1195
int kbd_init(void)
1196
{
1197
        int i;
1198
        struct kbd_struct kbd0;
1199
        extern struct tty_driver console_driver;
1200
 
1201
        kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;
1202
        kbd0.ledmode = LED_SHOW_FLAGS;
1203
        kbd0.lockstate = KBD_DEFLOCK;
1204
        kbd0.slockstate = 0;
1205
        kbd0.modeflags = KBD_DEFMODE;
1206
        kbd0.kbdmode = VC_XLATE;
1207
 
1208
        for (i = 0 ; i < MAX_NR_CONSOLES ; i++)
1209
                kbd_table[i] = kbd0;
1210
 
1211
        ttytab = console_driver.table;
1212
 
1213
        request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard", NULL);
1214 685 lampret
        request_region(KBD_BASE_ADD+0x0,16,"keyboard");
1215 199 simons
#ifdef INIT_KBD
1216
        initialize_kbd();
1217
#endif
1218
        init_bh(KEYBOARD_BH, kbd_bh);
1219
        mark_bh(KEYBOARD_BH);
1220
        return 0;
1221
}
1222
 
1223
#ifdef INIT_KBD
1224
/*
1225
 * keyboard controller registers
1226
 */
1227 685 lampret
#define KBD_STATUS_REG      (unsigned int) KBD_BASE_ADD+0x4
1228
#define KBD_CNTL_REG        (unsigned int) KBD_BASE_ADD+0x4
1229
#define KBD_DATA_REG        (unsigned int) KBD_BASE_ADD+0x0
1230 199 simons
/*
1231
 * controller commands
1232
 */
1233
#define KBD_READ_MODE       (unsigned int) 0x20
1234
#define KBD_WRITE_MODE      (unsigned int) 0x60
1235
#define KBD_SELF_TEST       (unsigned int) 0xAA
1236
#define KBD_SELF_TEST2      (unsigned int) 0xAB
1237
#define KBD_CNTL_ENABLE     (unsigned int) 0xAE
1238
/*
1239
 * keyboard commands
1240
 */
1241
#define KBD_ENABLE          (unsigned int) 0xF4
1242
#define KBD_DISABLE         (unsigned int) 0xF5
1243
#define KBD_RESET           (unsigned int) 0xFF
1244
/*
1245
 * keyboard replies
1246
 */
1247
#define KBD_ACK             (unsigned int) 0xFA
1248
#define KBD_POR             (unsigned int) 0xAA
1249
/*
1250
 * status register bits
1251
 */
1252
#define KBD_OBF             (unsigned int) 0x01
1253
#define KBD_IBF             (unsigned int) 0x02
1254
#define KBD_GTO             (unsigned int) 0x40
1255
#define KBD_PERR            (unsigned int) 0x80
1256
/*
1257
 * keyboard controller mode register bits
1258
 */
1259
#define KBD_EKI             (unsigned int) 0x01
1260
#define KBD_SYS             (unsigned int) 0x04
1261
#define KBD_DMS             (unsigned int) 0x20
1262
#define KBD_KCC             (unsigned int) 0x40
1263
 
1264
#define TIMEOUT_CONST   500000
1265
 
1266
static int kbd_wait_for_input(void)
1267
{
1268
        int     n;
1269
        int     status, data;
1270
 
1271
        n = TIMEOUT_CONST;
1272
        do {
1273
                status = inb(KBD_STATUS_REG);
1274
                /*
1275
                 * Wait for input data to become available.  This bit will
1276
                 * then be cleared by the following read of the DATA
1277
                 * register.
1278
                 */
1279
 
1280
                if (!(status & KBD_OBF))
1281
                        continue;
1282
 
1283
                data = inb(KBD_DATA_REG);
1284
 
1285
                /*
1286
                 * Check to see if a timeout error has occurred.  This means
1287
                 * that transmission was started but did not complete in the
1288
                 * normal time cycle.  PERR is set when a parity error occurred
1289
                 * in the last transmission.
1290
                 */
1291
                if (status & (KBD_GTO | KBD_PERR)) {
1292
                        continue;
1293
                }
1294
                return (data & 0xff);
1295
        } while (--n);
1296
        return (-1);    /* timed-out if fell through to here... */
1297
}
1298
 
1299
static void kbd_write(int address, int data)
1300
{
1301
        int status;
1302
 
1303
        do {
1304
                status = inb(KBD_STATUS_REG);  /* spin until input buffer empty*/
1305
        } while (status & KBD_IBF);
1306
        outb(data, address);               /* write out the data*/
1307
}
1308
 
1309
static int initialize_kbd(void)
1310
{
1311
        unsigned long flags;
1312
 
1313
        save_flags(flags); cli();
1314
 
1315
        /* Flush any pending input. */
1316
        while (kbd_wait_for_input() != -1)
1317
                continue;
1318
 
1319
        /*
1320
         * Test the keyboard interface.
1321
         * This seems to be the only way to get it going.
1322
         * If the test is successful a x55 is placed in the input buffer.
1323
         */
1324
        kbd_write(KBD_CNTL_REG, KBD_SELF_TEST);
1325
        if (kbd_wait_for_input() != 0x55) {
1326
                printk(KERN_WARNING "initialize_kbd: "
1327
                       "keyboard failed self test.\n");
1328
                restore_flags(flags);
1329
                return(-1);
1330
        }
1331
 
1332
        /*
1333
         * Perform a keyboard interface test.  This causes the controller
1334
         * to test the keyboard clock and data lines.  The results of the
1335
         * test are placed in the input buffer.
1336
         */
1337
        kbd_write(KBD_CNTL_REG, KBD_SELF_TEST2);
1338
        if (kbd_wait_for_input() != 0x00) {
1339
                printk(KERN_WARNING "initialize_kbd: "
1340
                       "keyboard failed self test 2.\n");
1341
                restore_flags(flags);
1342
                return(-1);
1343
        }
1344 685 lampret
 
1345 199 simons
        /* Enable the keyboard by allowing the keyboard clock to run. */
1346
        kbd_write(KBD_CNTL_REG, KBD_CNTL_ENABLE);
1347
 
1348
        /*
1349
         * Reset keyboard. If the read times out
1350
         * then the assumption is that no keyboard is
1351
         * plugged into the machine.
1352
         * This defaults the keyboard to scan-code set 2.
1353
         */
1354
        kbd_write(KBD_DATA_REG, KBD_RESET);
1355
        if (kbd_wait_for_input() != KBD_ACK) {
1356
                printk(KERN_WARNING "initialize_kbd: "
1357
                       "reset kbd failed, no ACK.\n");
1358
                restore_flags(flags);
1359
                return(-1);
1360
        }
1361
 
1362
        if (kbd_wait_for_input() != KBD_POR) {
1363
                printk(KERN_WARNING "initialize_kbd: "
1364
                       "reset kbd failed, not POR.\n");
1365
                restore_flags(flags);
1366
                return(-1);
1367
        }
1368
 
1369
        /*
1370
         * now do a DEFAULTS_DISABLE always
1371
         */
1372
        kbd_write(KBD_DATA_REG, KBD_DISABLE);
1373
        if (kbd_wait_for_input() != KBD_ACK) {
1374
                printk(KERN_WARNING "initialize_kbd: "
1375
                       "disable kbd failed, no ACK.\n");
1376
                restore_flags(flags);
1377
                return(-1);
1378
        }
1379
 
1380
        /*
1381
         * Enable keyboard interrupt, operate in "sys" mode,
1382
         *  enable keyboard (by clearing the disable keyboard bit),
1383
         *  disable mouse, do conversion of keycodes.
1384
         */
1385
        kbd_write(KBD_CNTL_REG, KBD_WRITE_MODE);
1386
        kbd_write(KBD_DATA_REG, KBD_EKI|KBD_SYS|KBD_DMS|KBD_KCC);
1387
 
1388
        /*
1389
         * now ENABLE the keyboard to set it scanning...
1390
         */
1391
        kbd_write(KBD_DATA_REG, KBD_ENABLE);
1392
        if (kbd_wait_for_input() != KBD_ACK) {
1393
                printk(KERN_WARNING "initialize_kbd: "
1394
                       "keyboard enable failed.\n");
1395
                restore_flags(flags);
1396
                return(-1);
1397
        }
1398
 
1399
        restore_flags(flags);
1400
 
1401 685 lampret
        printk("PS/2 Keyboard initialized.\n");
1402 199 simons
        return (1);
1403
}
1404
#endif /* INIT_KBD */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.