lkml.org 
[lkml]   [1998]   [Nov]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subjectfor comment: multi-keyboard patch
    I'm working with Inaky Gonzalez on USB keyboard support.  The current
    keyboard driver in linux really only allows one keyboard, or at best
    one type of keyboard. I have hacked the keyboard driver to allow
    multiple keyboards of different types (patch at the end of this
    message). I have added register_keyboard() and unregister_keyboard()
    functions which are used to create new keyboard instances and specify
    sets of low-level keyboard operations to be used with them.

    I have also hacked the PC and mac low-level keyboard drivers to work
    with the new scheme. Other low-level keyboard drivers should still
    work using some compatibility stuff I put in keyboard.c.

    At present input from all keyboards goes to the current foreground
    VC. Ultimately it would be nice to be able to bind a keyboard, screen
    and mouse together into a "console" which would have its own set of
    VCs.

    Comments, anyone?

    Paul.


    diff -ur linux/Documentation/Configure.help linux-pmac/Documentation/Configure.help
    --- linux/Documentation/Configure.help Tue Oct 27 16:32:16 1998
    +++ linux-pmac/Documentation/Configure.help Wed Oct 28 15:32:07 1998
    @@ -9064,12 +9064,14 @@
    Support for PowerMac keyboard
    CONFIG_MAC_KEYBOARD
    This option allows you to use an ADB keyboard attached to your
    - machine. Note that this disables any other (ie. PS/2) keyboard
    - support, even if your machine is physically capable of using both
    - at the same time.
    -
    - If you use an ADB keyboard (4 pin connector), say Y here.
    - If you use a PS/2 keyboard (6 pin connector), say N here.
    + machine. Say Y if you have a Power Macintosh or a CHRP machine
    + with an ADB keyboard.
    +
    +Support for PC-style keyboard
    +CONFIG_PC_KEYBOARD
    + This option allows you to use a PC-style or PS/2-style keyboard
    + attached to your machine. PReP and some CHRP machines have this
    + style of keyboard; say Y if you have such a machine.

    Support for PowerMac floppy
    CONFIG_MAC_FLOPPY
    diff -ur linux/arch/ppc/config.in linux-pmac/arch/ppc/config.in
    --- linux/arch/ppc/config.in Tue Oct 20 11:07:47 1998
    +++ linux-pmac/arch/ppc/config.in Sat Oct 24 18:11:24 1998
    @@ -61,6 +61,7 @@
    tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
    tristate 'Kernel support for JAVA binaries (obsolete)' CONFIG_BINFMT_JAVA

    +bool 'PC-style keyboard support' CONFIG_PC_KEYBOARD
    tristate 'Parallel port support' CONFIG_PARPORT
    if [ "$CONFIG_PARPORT" != "n" ]; then
    dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT
    diff -ur linux/drivers/char/Makefile linux-pmac/drivers/char/Makefile
    --- linux/drivers/char/Makefile Tue Oct 27 16:44:51 1998
    +++ linux-pmac/drivers/char/Makefile Tue Nov 3 15:49:37 1998
    @@ -42,7 +42,7 @@

    ifndef CONFIG_SUN_KEYBOARD
    ifdef CONFIG_VT
    -L_OBJS += keyboard.o
    +LX_OBJS += keyboard.o
    endif
    ifneq ($(ARCH),m68k)
    ifndef CONFIG_MBX
    @@ -51,7 +51,8 @@
    endif
    else
    ifdef CONFIG_PCI
    -L_OBJS += defkeymap.o keyboard.o
    +L_OBJS += defkeymap.o
    +LX_OBJS += keyboard.o
    endif
    endif

    diff -ur linux/drivers/char/keyboard.c linux-pmac/drivers/char/keyboard.c
    --- linux/drivers/char/keyboard.c Thu Oct 1 22:36:47 1998
    +++ linux-pmac/drivers/char/keyboard.c Tue Nov 3 15:48:30 1998
    @@ -31,6 +31,7 @@
    #include <linux/string.h>
    #include <linux/random.h>
    #include <linux/init.h>
    +#include <linux/malloc.h>

    #include <asm/keyboard.h>
    #include <asm/bitops.h>
    @@ -71,35 +72,56 @@
    }

    /*
    - * global state includes the following, and various static variables
    - * in this module: prev_scancode, shift_state, diacr, npadch, dead_key_next.
    - * (last_console is now a global variable)
    + * Per-keyboard state.
    + * At present all keyboards are connected to the current fg_console -
    + * this needs to be generalized a bit.
    */
    +struct keyboard_state {
    + struct keyboard_state *next;
    + struct kbd_ll_operations *k_op;
    + void *devid;
    + ushort **key_maps;
    + struct kbd_struct *kbd;
    + struct tty_struct *tty;
    + int last_scancode;
    + struct timer_list repeat_timer;
    + int repeat_timer_running;
    + int dead_key_next;
    + int shift_state;
    + int npadch; /* -1 or number assembled on pad */
    +#ifdef CONFIG_MAGIC_SYSRQ
    + int sysrq_pressed;
    +#endif
    + char rep; /* flag telling character repeat */
    + unsigned char diacr;
    + unsigned char k_down[NR_SHIFT]; /* shift state counters.. */
    + unsigned long key_down[256/BITS_PER_LONG]; /* keyboard key bitmap */
    +};

    -/* shift state counters.. */
    -static unsigned char k_down[NR_SHIFT] = {0, };
    -/* keyboard key bitmap */
    -static unsigned long key_down[256/BITS_PER_LONG] = { 0, };
    +/*
    + * List of all keyboards (and a spinlock for it).
    + */
    +static struct keyboard_state *all_kbds;
    +static spinlock_t all_kbds_lock = SPIN_LOCK_UNLOCKED;

    -static int dead_key_next = 0;
    /*
    * In order to retrieve the shift_state (for the mouse server), either
    * the variable must be global, or a new procedure must be created to
    * return the value. I chose the former way.
    + * This now reflects the shift_state of the last keyboard
    + * whose shift_state changed - paulus.
    */
    int shift_state = 0;
    -static int npadch = -1; /* -1 or number assembled on pad */
    -static unsigned char diacr = 0;
    -static char rep = 0; /* flag telling character repeat */
    +
    struct kbd_struct kbd_table[MAX_NR_CONSOLES];
    static struct tty_struct **ttytab;
    -static struct kbd_struct * kbd = kbd_table;
    -static struct tty_struct * tty = NULL;

    -void compute_shiftstate(void);
    +void kbd_compute_shiftstate(struct keyboard_state *);

    -typedef void (*k_hand)(unsigned char value, char up_flag);
    -typedef void (k_handfn)(unsigned char value, char up_flag);
    +typedef void (*k_hand)(struct keyboard_state *, unsigned char value,
    + char up_flag);
    +typedef void (k_handfn)(struct keyboard_state *, unsigned char value,
    + char up_flag);

    static k_handfn
    do_self, do_fn, do_spec, do_pad, do_dead, do_cons, do_cur, do_shift,
    @@ -116,16 +138,17 @@

    #define TYPES_ALLOWED_IN_RAW_MODE ((1 << KT_SPEC) | (1 << KT_SHIFT))

    -typedef void (*void_fnp)(void);
    -typedef void (void_fn)(void);
    +typedef void (*void_fnp)(struct keyboard_state *);
    +typedef void (void_fn)(struct keyboard_state *);

    static void_fn do_null, enter, show_ptregs, send_intr, lastcons, caps_toggle,
    num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose,
    - SAK, decr_console, incr_console, spawn_console, bare_num;
    + SAK, decr_console, incr_console, spawn_console, bare_num,
    + do_show_mem, do_show_state;

    static void_fnp spec_fn_table[] = {
    - do_null, enter, show_ptregs, show_mem,
    - show_state, send_intr, lastcons, caps_toggle,
    + do_null, enter, show_ptregs, do_show_mem,
    + do_show_state, send_intr, lastcons, caps_toggle,
    num, hold, scroll_forw, scroll_back,
    boot_it, caps_on, compose, SAK,
    decr_console, incr_console, spawn_console, bare_num
    @@ -143,33 +166,28 @@

    const int NR_TYPES = SIZE(max_vals);

    -/* N.B. drivers/macintosh/mac_keyb.c needs to call put_queue */
    -void put_queue(int);
    -static unsigned char handle_diacr(unsigned char);
    +static void put_queue(struct tty_struct *, int);
    +static unsigned char handle_diacr(struct keyboard_state *, unsigned char);

    /* kbd_pt_regs - set by keyboard_interrupt(), used by show_ptregs() */
    struct pt_regs * kbd_pt_regs;

    -#ifdef CONFIG_MAGIC_SYSRQ
    -static int sysrq_pressed;
    -#endif
    -
    /*
    * Many other routines do put_queue, but I think either
    * they produce ASCII, or they produce some user-assigned
    * string, and in both cases we might assume that it is
    * in utf-8 already.
    */
    -void to_utf8(ushort c) {
    +void to_utf8(struct tty_struct *tty, ushort c) {
    if (c < 0x80)
    - put_queue(c); /* 0******* */
    + put_queue(tty, c); /* 0******* */
    else if (c < 0x800) {
    - put_queue(0xc0 | (c >> 6)); /* 110***** 10****** */
    - put_queue(0x80 | (c & 0x3f));
    + put_queue(tty, 0xc0 | (c >> 6)); /* 110***** 10****** */
    + put_queue(tty, 0x80 | (c & 0x3f));
    } else {
    - put_queue(0xe0 | (c >> 12)); /* 1110**** 10****** 10****** */
    - put_queue(0x80 | ((c >> 6) & 0x3f));
    - put_queue(0x80 | (c & 0x3f));
    + put_queue(tty, 0xe0 | (c >> 12)); /* 1110**** 10****** 10****** */
    + put_queue(tty, 0x80 | ((c >> 6) & 0x3f));
    + put_queue(tty, 0x80 | (c & 0x3f));
    }
    /* UTF-8 is defined for words of up to 31 bits,
    but we need only 16 bits here */
    @@ -178,76 +196,123 @@
    /*
    * Translation of escaped scancodes to keycodes.
    * This is now user-settable (for machines were it makes sense).
    + * (XXX It doesn't make much sense with multiple keyboards :-()
    */

    int setkeycode(unsigned int scancode, unsigned int keycode)
    {
    - return kbd_setkeycode(scancode, keycode);
    + struct keyboard_state *ks;
    + int err = 0;
    +
    + spin_lock(&all_kbds_lock);
    + for (ks = all_kbds; ks != NULL && err == 0; ks = ks->next)
    + if (ks->key_maps == key_maps)
    + err = ks->k_op->setkeycode(ks->devid, scancode, keycode);
    + spin_unlock(&all_kbds_lock);
    + return err;
    }

    +/* XXX and this makes even less sense... :-* */
    int getkeycode(unsigned int scancode)
    {
    - return kbd_getkeycode(scancode);
    + struct keyboard_state *ks = all_kbds;
    +
    + if (ks == NULL)
    + return -ENODEV;
    + return ks->k_op->getkeycode(ks->devid, scancode);
    }

    -void handle_scancode(unsigned char scancode)
    +static void kbd_repeat(unsigned long devid)
    +{
    + struct keyboard_state *ks = (struct keyboard_state *) devid;
    + unsigned long flags;
    +
    + save_flags(flags);
    + cli();
    + ks->repeat_timer_running = 0;
    + kbd_handle_scancode((void *)ks, ks->last_scancode);
    + restore_flags(flags);
    +}
    +
    +void kbd_handle_scancode(void *kbdid, int scancode)
    {
    + struct keyboard_state *ks = (struct keyboard_state *) kbdid;
    unsigned char keycode;
    char up_flag; /* 0 or 0200 */
    - char raw_mode;
    + char raw_mode, rep;
    + struct kbd_struct *kbd;
    + struct tty_struct *tty;

    do_poke_blanked_console = 1;
    mark_bh(CONSOLE_BH);
    add_keyboard_randomness(scancode);

    - tty = ttytab? ttytab[fg_console]: NULL;
    - kbd = kbd_table + fg_console;
    + if (ks->repeat_timer_running) {
    + del_timer(&ks->repeat_timer);
    + ks->repeat_timer_running = 0;
    + }
    +
    + ks->tty = tty = ttytab? ttytab[fg_console]: NULL;
    + ks->kbd = kbd = kbd_table + fg_console;
    if ((raw_mode = (kbd->kbdmode == VC_RAW))) {
    - put_queue(scancode);
    + put_queue(tty, scancode);
    /* we do not return yet, because we want to maintain
    the key_down array, so that we have the correct
    values when finishing RAW mode or when changing VT's */
    }

    - if (!kbd_pretranslate(scancode, raw_mode))
    - return;
    + if (!ks->k_op->pretranslate(ks->devid, scancode, raw_mode))
    + return;
    +
    /*
    * Convert scancode to keycode
    */
    up_flag = (scancode & 0200);
    scancode &= 0x7f;

    - if (!kbd_translate(scancode, &keycode, raw_mode))
    - return;
    + if (!ks->k_op->translate(ks->devid, scancode, &keycode, raw_mode))
    + return;

    /*
    * At this point the variable `keycode' contains the keycode.
    - * Note: the keycode must not be 0 (++Geert: on m68k 0 is valid).
    * We keep track of the up/down status of the key, and
    * return the keycode if in MEDIUMRAW mode.
    */

    if (up_flag) {
    rep = 0;
    - if(!test_and_clear_bit(keycode, key_down))
    - up_flag = kbd_unexpected_up(keycode);
    + if (!test_and_clear_bit(keycode, ks->key_down))
    + up_flag = ks->k_op->unexpected_up(ks->devid, keycode);
    } else
    - rep = test_and_set_bit(keycode, key_down);
    + rep = test_and_set_bit(keycode, ks->key_down);
    + ks->rep = rep;
    +
    + if (!raw_mode && !up_flag
    + && ks->k_op->dont_repeat && !ks->k_op->dont_repeat[keycode]) {
    + ks->last_scancode = scancode;
    + ks->repeat_timer.function = kbd_repeat;
    + ks->repeat_timer.data = (unsigned long) ks;
    + ks->repeat_timer.expires = jiffies +
    + (rep? ks->k_op->repeat_delay: ks->k_op->repeat_initial);
    + add_timer(&ks->repeat_timer);
    + ks->repeat_timer_running = 1;
    + }

    #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
    - if (keycode == SYSRQ_KEY) {
    - sysrq_pressed = !up_flag;
    + if (keycode == ks->k_op->sysrq_key) {
    + ks->sysrq_pressed = !up_flag;
    return;
    - } else if (sysrq_pressed) {
    + } else if (ks->sysrq_pressed) {
    if (!up_flag)
    - handle_sysrq(kbd_sysrq_xlate[keycode], kbd_pt_regs, kbd, tty);
    + handle_sysrq(ks->k_op->sysrq_xlate[keycode],
    + kbd_pt_regs, kbd, tty);
    return;
    }
    #endif

    if (kbd->kbdmode == VC_MEDIUMRAW) {
    /* soon keycodes will require more than one byte */
    - put_queue(keycode + up_flag);
    + put_queue(tty, keycode + up_flag);
    raw_mode = 1; /* Most key classes will be ignored */
    }

    @@ -271,8 +336,8 @@
    u_char type;

    /* the XOR below used to be an OR */
    - int shift_final = shift_state ^ kbd->lockstate ^ kbd->slockstate;
    - ushort *key_map = key_maps[shift_final];
    + int shift_final = ks->shift_state ^ kbd->lockstate ^ kbd->slockstate;
    + ushort *key_map = ks->key_maps[shift_final];

    if (key_map != NULL) {
    keysym = key_map[keycode];
    @@ -285,36 +350,36 @@
    if (type == KT_LETTER) {
    type = KT_LATIN;
    if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
    - key_map = key_maps[shift_final ^ (1<<KG_SHIFT)];
    + key_map = ks->key_maps[shift_final ^ (1<<KG_SHIFT)];
    if (key_map)
    keysym = key_map[keycode];
    }
    }
    - (*key_handler[type])(keysym & 0xff, up_flag);
    + (*key_handler[type])(ks, keysym & 0xff, up_flag);
    if (type != KT_SLOCK)
    kbd->slockstate = 0;
    } else {
    /* maybe only if (kbd->kbdmode == VC_UNICODE) ? */
    if (!up_flag && !raw_mode)
    - to_utf8(keysym);
    + to_utf8(tty, keysym);
    }
    } else {
    /* maybe beep? */
    /* we have at least to update shift_state */
    #if 1 /* how? two almost equivalent choices follow */
    - compute_shiftstate();
    + kbd_compute_shiftstate(ks);
    #else
    - keysym = U(plain_map[keycode]);
    + keysym = U(ks->key_maps[0][keycode]);
    type = KTYP(keysym);
    if (type == KT_SHIFT)
    - (*key_handler[type])(keysym & 0xff, up_flag);
    + (*key_handler[type])(ks, keysym & 0xff, up_flag);
    #endif
    }
    }
    }


    -void put_queue(int ch)
    +static void put_queue(struct tty_struct *tty, int ch)
    {
    wake_up(&keypress_wait);
    if (tty) {
    @@ -323,7 +388,7 @@
    }
    }

    -static void puts_queue(char *cp)
    +static void puts_queue(struct tty_struct *tty, char *cp)
    {
    wake_up(&keypress_wait);
    if (!tty)
    @@ -336,49 +401,61 @@
    con_schedule_flip(tty);
    }

    -static void applkey(int key, char mode)
    +static void applkey(struct tty_struct *tty, int key, char mode)
    {
    static char buf[] = { 0x1b, 'O', 0x00, 0x00 };

    buf[1] = (mode ? 'O' : '[');
    buf[2] = key;
    - puts_queue(buf);
    + puts_queue(tty, buf);
    }

    -static void enter(void)
    +static void enter(struct keyboard_state *ks)
    {
    - if (diacr) {
    - put_queue(diacr);
    - diacr = 0;
    + if (ks->diacr) {
    + put_queue(ks->tty, ks->diacr);
    + ks->diacr = 0;
    }
    - put_queue(13);
    - if (vc_kbd_mode(kbd,VC_CRLF))
    - put_queue(10);
    + put_queue(ks->tty, 13);
    + if (vc_kbd_mode(ks->kbd, VC_CRLF))
    + put_queue(ks->tty, 10);
    }

    -static void caps_toggle(void)
    +static void caps_toggle(struct keyboard_state *ks)
    {
    - if (rep)
    + if (ks->rep)
    return;
    - chg_vc_kbd_led(kbd, VC_CAPSLOCK);
    + chg_vc_kbd_led(ks->kbd, VC_CAPSLOCK);
    }

    -static void caps_on(void)
    +static void caps_on(struct keyboard_state *ks)
    {
    - if (rep)
    + if (ks->rep)
    return;
    - set_vc_kbd_led(kbd, VC_CAPSLOCK);
    + set_vc_kbd_led(ks->kbd, VC_CAPSLOCK);
    }

    -static void show_ptregs(void)
    +static void show_ptregs(struct keyboard_state *ks)
    {
    if (kbd_pt_regs)
    show_regs(kbd_pt_regs);
    }

    -static void hold(void)
    +static void do_show_mem(struct keyboard_state *ks)
    +{
    + show_mem();
    +}
    +
    +static void do_show_state(struct keyboard_state *ks)
    {
    - if (rep || !tty)
    + show_state();
    +}
    +
    +static void hold(struct keyboard_state *ks)
    +{
    + struct tty_struct *tty = ks->tty;
    +
    + if (ks->rep || !tty)
    return;

    /*
    @@ -392,12 +469,12 @@
    stop_tty(tty);
    }

    -static void num(void)
    +static void num(struct keyboard_state *ks)
    {
    - if (vc_kbd_mode(kbd,VC_APPLIC))
    - applkey('P', 1);
    + if (vc_kbd_mode(ks->kbd, VC_APPLIC))
    + applkey(ks->tty, 'P', 1);
    else
    - bare_num();
    + bare_num(ks);
    }

    /*
    @@ -406,19 +483,19 @@
    * Bind this to NumLock if you prefer that the NumLock key always
    * changes the NumLock flag.
    */
    -static void bare_num(void)
    +static void bare_num(struct keyboard_state *ks)
    {
    - if (!rep)
    - chg_vc_kbd_led(kbd,VC_NUMLOCK);
    + if (!ks->rep)
    + chg_vc_kbd_led(ks->kbd, VC_NUMLOCK);
    }

    -static void lastcons(void)
    +static void lastcons(struct keyboard_state *ks)
    {
    /* switch to the last used console, ChN */
    set_console(last_console);
    }

    -static void decr_console(void)
    +static void decr_console(struct keyboard_state *ks)
    {
    int i;

    @@ -431,7 +508,7 @@
    set_console(i);
    }

    -static void incr_console(void)
    +static void incr_console(struct keyboard_state *ks)
    {
    int i;

    @@ -444,45 +521,49 @@
    set_console(i);
    }

    -static void send_intr(void)
    +static void send_intr(struct keyboard_state *ks)
    {
    + struct tty_struct *tty = ks->tty;
    +
    if (!tty)
    return;
    tty_insert_flip_char(tty, 0, TTY_BREAK);
    con_schedule_flip(tty);
    }

    -static void scroll_forw(void)
    +static void scroll_forw(struct keyboard_state *ks)
    {
    scrollfront(0);
    }

    -static void scroll_back(void)
    +static void scroll_back(struct keyboard_state *ks)
    {
    scrollback(0);
    }

    -static void boot_it(void)
    +static void boot_it(struct keyboard_state *ks)
    {
    ctrl_alt_del();
    }

    -static void compose(void)
    +static void compose(struct keyboard_state *ks)
    {
    - dead_key_next = 1;
    + ks->dead_key_next = 1;
    }

    int spawnpid, spawnsig;

    -static void spawn_console(void)
    +static void spawn_console(struct keyboard_state *ks)
    {
    if (spawnpid)
    if(kill_proc(spawnpid, spawnsig, 1))
    spawnpid = 0;
    }

    -static void SAK(void)
    +static void SAK(struct keyboard_state *ks)
    {
    + struct tty_struct *tty = ks->tty;
    +
    /*
    * SAK should also work in all raw modes and reset
    * them properly.
    @@ -495,17 +576,19 @@
    #endif
    }

    -static void do_ignore(unsigned char value, char up_flag)
    +static void do_ignore(struct keyboard_state *ks, unsigned char value, char up_flag)
    {
    }

    -static void do_null()
    +static void do_null(struct keyboard_state *ks)
    {
    - compute_shiftstate();
    + kbd_compute_shiftstate(ks);
    }

    -static void do_spec(unsigned char value, char up_flag)
    +static void do_spec(struct keyboard_state *ks, unsigned char value, char up_flag)
    {
    + struct kbd_struct *kbd = ks->kbd;
    +
    if (up_flag)
    return;
    if (value >= SIZE(spec_fn_table))
    @@ -513,29 +596,29 @@
    if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) &&
    !(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value)))
    return;
    - spec_fn_table[value]();
    + spec_fn_table[value](ks);
    }

    -static void do_lowercase(unsigned char value, char up_flag)
    +static void do_lowercase(struct keyboard_state *ks, unsigned char value, char up_flag)
    {
    printk(KERN_ERR "keyboard.c: do_lowercase was called - impossible\n");
    }

    -static void do_self(unsigned char value, char up_flag)
    +static void do_self(struct keyboard_state *ks, unsigned char value, char up_flag)
    {
    if (up_flag)
    return; /* no action, if this is a key release */

    - if (diacr)
    - value = handle_diacr(value);
    + if (ks->diacr)
    + value = handle_diacr(ks, value);

    - if (dead_key_next) {
    - dead_key_next = 0;
    - diacr = value;
    + if (ks->dead_key_next) {
    + ks->dead_key_next = 0;
    + ks->diacr = value;
    return;
    }

    - put_queue(value);
    + put_queue(ks->tty, value);
    }

    #define A_GRAVE '`'
    @@ -548,10 +631,10 @@
    {A_GRAVE, A_ACUTE, A_CFLEX, A_TILDE, A_DIAER, A_CEDIL };

    /* Obsolete - for backwards compatibility only */
    -static void do_dead(unsigned char value, char up_flag)
    +static void do_dead(struct keyboard_state *ks, unsigned char value, char up_flag)
    {
    value = ret_diacr[value];
    - do_dead2(value,up_flag);
    + do_dead2(ks, value, up_flag);
    }

    /*
    @@ -559,12 +642,12 @@
    * dead keys modifying the same character. Very useful
    * for Vietnamese.
    */
    -static void do_dead2(unsigned char value, char up_flag)
    +static void do_dead2(struct keyboard_state *ks, unsigned char value, char up_flag)
    {
    if (up_flag)
    return;

    - diacr = (diacr ? handle_diacr(value) : value);
    + ks->diacr = (ks->diacr ? handle_diacr(ks, value) : value);
    }


    @@ -575,12 +658,12 @@
    * Otherwise, conclude that DIACR was not combining after all,
    * queue it and return CH.
    */
    -unsigned char handle_diacr(unsigned char ch)
    +unsigned char handle_diacr(struct keyboard_state *ks, unsigned char ch)
    {
    - int d = diacr;
    + int d = ks->diacr;
    int i;

    - diacr = 0;
    + ks->diacr = 0;

    for (i = 0; i < accent_table_size; i++) {
    if (accent_table[i].diacr == d && accent_table[i].base == ch)
    @@ -590,30 +673,31 @@
    if (ch == ' ' || ch == d)
    return d;

    - put_queue(d);
    + put_queue(ks->tty, d);
    return ch;
    }

    -static void do_cons(unsigned char value, char up_flag)
    +static void do_cons(struct keyboard_state *ks, unsigned char value, char up_flag)
    {
    if (up_flag)
    return;
    set_console(value);
    }

    -static void do_fn(unsigned char value, char up_flag)
    +static void do_fn(struct keyboard_state *ks, unsigned char value, char up_flag)
    {
    if (up_flag)
    return;
    if (value < SIZE(func_table)) {
    if (func_table[value])
    - puts_queue(func_table[value]);
    + puts_queue(ks->tty, func_table[value]);
    } else
    printk(KERN_ERR "do_fn called with value=%d\n", value);
    }

    -static void do_pad(unsigned char value, char up_flag)
    +static void do_pad(struct keyboard_state *ks, unsigned char value, char up_flag)
    {
    + struct kbd_struct *kbd = ks->kbd;
    static const char *pad_chars = "0123456789+-*/\015,.?()";
    static const char *app_map = "pqrstuvwxylSRQMnnmPQ";

    @@ -621,8 +705,8 @@
    return; /* no action, if this is a key release */

    /* kludge... shift forces cursor/number keys */
    - if (vc_kbd_mode(kbd,VC_APPLIC) && !k_down[KG_SHIFT]) {
    - applkey(app_map[value], 1);
    + if (vc_kbd_mode(kbd,VC_APPLIC) && !ks->k_down[KG_SHIFT]) {
    + applkey(ks->tty, app_map[value], 1);
    return;
    }

    @@ -630,59 +714,60 @@
    switch (value) {
    case KVAL(K_PCOMMA):
    case KVAL(K_PDOT):
    - do_fn(KVAL(K_REMOVE), 0);
    + do_fn(ks, KVAL(K_REMOVE), 0);
    return;
    case KVAL(K_P0):
    - do_fn(KVAL(K_INSERT), 0);
    + do_fn(ks, KVAL(K_INSERT), 0);
    return;
    case KVAL(K_P1):
    - do_fn(KVAL(K_SELECT), 0);
    + do_fn(ks, KVAL(K_SELECT), 0);
    return;
    case KVAL(K_P2):
    - do_cur(KVAL(K_DOWN), 0);
    + do_cur(ks, KVAL(K_DOWN), 0);
    return;
    case KVAL(K_P3):
    - do_fn(KVAL(K_PGDN), 0);
    + do_fn(ks, KVAL(K_PGDN), 0);
    return;
    case KVAL(K_P4):
    - do_cur(KVAL(K_LEFT), 0);
    + do_cur(ks, KVAL(K_LEFT), 0);
    return;
    case KVAL(K_P6):
    - do_cur(KVAL(K_RIGHT), 0);
    + do_cur(ks, KVAL(K_RIGHT), 0);
    return;
    case KVAL(K_P7):
    - do_fn(KVAL(K_FIND), 0);
    + do_fn(ks, KVAL(K_FIND), 0);
    return;
    case KVAL(K_P8):
    - do_cur(KVAL(K_UP), 0);
    + do_cur(ks, KVAL(K_UP), 0);
    return;
    case KVAL(K_P9):
    - do_fn(KVAL(K_PGUP), 0);
    + do_fn(ks, KVAL(K_PGUP), 0);
    return;
    case KVAL(K_P5):
    - applkey('G', vc_kbd_mode(kbd, VC_APPLIC));
    + applkey(ks->tty, 'G', vc_kbd_mode(kbd, VC_APPLIC));
    return;
    }

    - put_queue(pad_chars[value]);
    + put_queue(ks->tty, pad_chars[value]);
    if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
    - put_queue(10);
    + put_queue(ks->tty, 10);
    }

    -static void do_cur(unsigned char value, char up_flag)
    +static void do_cur(struct keyboard_state *ks, unsigned char value, char up_flag)
    {
    static const char *cur_chars = "BDCA";
    if (up_flag)
    return;

    - applkey(cur_chars[value], vc_kbd_mode(kbd,VC_CKMODE));
    + applkey(ks->tty, cur_chars[value], vc_kbd_mode(ks->kbd,VC_CKMODE));
    }

    -static void do_shift(unsigned char value, char up_flag)
    +static void do_shift(struct keyboard_state *ks, unsigned char value, char up_flag)
    {
    - int old_state = shift_state;
    + struct kbd_struct *kbd = ks->kbd;
    + int old_state = ks->shift_state;

    - if (rep)
    + if (ks->rep)
    return;

    /* Mimic typewriter:
    @@ -696,23 +781,23 @@
    if (up_flag) {
    /* handle the case that two shift or control
    keys are depressed simultaneously */
    - if (k_down[value])
    - k_down[value]--;
    + if (ks->k_down[value])
    + ks->k_down[value]--;
    } else
    - k_down[value]++;
    + ks->k_down[value]++;

    - if (k_down[value])
    - shift_state |= (1 << value);
    + if (ks->k_down[value])
    + ks->shift_state |= (1 << value);
    else
    - shift_state &= ~ (1 << value);
    + ks->shift_state &= ~ (1 << value);

    /* kludge */
    - if (up_flag && shift_state != old_state && npadch != -1) {
    + if (up_flag && ks->shift_state != old_state && ks->npadch != -1) {
    if (kbd->kbdmode == VC_UNICODE)
    - to_utf8(npadch & 0xffff);
    + to_utf8(ks->tty, ks->npadch & 0xffff);
    else
    - put_queue(npadch & 0xff);
    - npadch = -1;
    + put_queue(ks->tty, ks->npadch & 0xff);
    + ks->npadch = -1;
    }
    }

    @@ -721,42 +806,55 @@
    /* maybe called when keymap is undefined, so that shiftkey release is seen */
    void compute_shiftstate(void)
    {
    + struct keyboard_state *ks;
    +
    + spin_lock(&all_kbds_lock);
    + for (ks = all_kbds; ks != NULL; ks = ks->next)
    + kbd_compute_shiftstate(ks);
    + spin_unlock(&all_kbds_lock);
    +}
    +
    +void kbd_compute_shiftstate(struct keyboard_state *ks)
    +{
    int i, j, k, sym, val;

    - shift_state = 0;
    - for(i=0; i < SIZE(k_down); i++)
    - k_down[i] = 0;
    -
    - for(i=0; i < SIZE(key_down); i++)
    - if(key_down[i]) { /* skip this word if not a single bit on */
    - k = i*BITS_PER_LONG;
    - for(j=0; j<BITS_PER_LONG; j++,k++)
    - if(test_bit(k, key_down)) {
    - sym = U(plain_map[k]);
    - if(KTYP(sym) == KT_SHIFT) {
    - val = KVAL(sym);
    - if (val == KVAL(K_CAPSSHIFT))
    - val = KVAL(K_SHIFT);
    - k_down[val]++;
    - shift_state |= (1<<val);
    + ks->shift_state = 0;
    + for (i = 0; i < SIZE(ks->k_down); i++)
    + ks->k_down[i] = 0;
    +
    + for (i = 0; i < SIZE(ks->key_down); i++) {
    + if (ks->key_down[i] == 0)
    + continue; /* skip this word if not a single bit on */
    + k = i * BITS_PER_LONG;
    + for (j = 0; j < BITS_PER_LONG; j++, k++) {
    + if (test_bit(k, ks->key_down) == 0)
    + continue;
    + sym = U(ks->key_maps[0][k]);
    + if (KTYP(sym) == KT_SHIFT) {
    + val = KVAL(sym);
    + if (val == KVAL(K_CAPSSHIFT))
    + val = KVAL(K_SHIFT);
    + ks->k_down[val]++;
    + ks->shift_state |= (1<<val);
    + }
    }
    - }
    - }
    + }
    + shift_state = ks->shift_state; /* XXX */
    }

    -static void do_meta(unsigned char value, char up_flag)
    +static void do_meta(struct keyboard_state *ks, unsigned char value, char up_flag)
    {
    if (up_flag)
    return;

    - if (vc_kbd_mode(kbd, VC_META)) {
    - put_queue('\033');
    - put_queue(value);
    + if (vc_kbd_mode(ks->kbd, VC_META)) {
    + put_queue(ks->tty, '\033');
    + put_queue(ks->tty, value);
    } else
    - put_queue(value | 0x80);
    + put_queue(ks->tty, value | 0x80);
    }

    -static void do_ascii(unsigned char value, char up_flag)
    +static void do_ascii(struct keyboard_state *ks, unsigned char value, char up_flag)
    {
    int base;

    @@ -764,30 +862,30 @@
    return;

    if (value < 10) /* decimal input of code, while Alt depressed */
    - base = 10;
    + base = 10;
    else { /* hexadecimal input of code, while AltGr depressed */
    - value -= 10;
    - base = 16;
    + value -= 10;
    + base = 16;
    }

    - if (npadch == -1)
    - npadch = value;
    + if (ks->npadch == -1)
    + ks->npadch = value;
    else
    - npadch = npadch * base + value;
    + ks->npadch = ks->npadch * base + value;
    }

    -static void do_lock(unsigned char value, char up_flag)
    +static void do_lock(struct keyboard_state *ks, unsigned char value, char up_flag)
    {
    - if (up_flag || rep)
    + if (up_flag || ks->rep)
    return;
    - chg_vc_kbd_lock(kbd, value);
    + chg_vc_kbd_lock(ks->kbd, value);
    }

    -static void do_slock(unsigned char value, char up_flag)
    +static void do_slock(struct keyboard_state *ks, unsigned char value, char up_flag)
    {
    - if (up_flag || rep)
    + if (up_flag || ks->rep)
    return;
    - chg_vc_kbd_slock(kbd, value);
    + chg_vc_kbd_slock(ks->kbd, value);
    }

    /*
    @@ -799,8 +897,8 @@
    static unsigned char ledstate = 0xff; /* undefined */
    static unsigned char ledioctl;

    -unsigned char getledstate(void) {
    - return ledstate;
    +unsigned char getledstate() {
    + return ledstate;
    }

    void setledstate(struct kbd_struct *kbd, unsigned int led) {
    @@ -876,13 +974,74 @@
    static void kbd_bh(void)
    {
    unsigned char leds = getleds();
    + struct keyboard_state *ks;

    if (leds != ledstate) {
    ledstate = leds;
    - kbd_leds(leds);
    + spin_lock(&all_kbds_lock);
    + for (ks = all_kbds; ks != NULL; ks = ks->next)
    + ks->k_op->leds(ks, leds);
    + spin_unlock(&all_kbds_lock);
    }
    }

    +#ifndef NEW_STYLE_KEYBOARD
    +int oldkbd_setkeycode(void *devid, unsigned int scancode, unsigned int keycode)
    +{
    + return kbd_setkeycode(scancode, keycode);
    +}
    +
    +int oldkbd_getkeycode(void *devid, unsigned int scancode)
    +{
    + return kbd_getkeycode(scancode);
    +}
    +
    +int oldkbd_pretranslate(void *devid, unsigned char scancode, char raw_mode)
    +{
    + return kbd_pretranslate(scancode, raw_mode);
    +}
    +
    +int oldkbd_translate(void *devid, unsigned char scancode,
    + unsigned char *keycode, char raw_mode)
    +{
    + return kbd_translate(scancode, keycode, raw_mode);
    +}
    +
    +int oldkbd_unexpected_up(void *devid, unsigned char keycode)
    +{
    + return kbd_unexpected_up(keycode);
    +}
    +
    +void oldkbd_leds(void *devid, unsigned char leds)
    +{
    + return kbd_leds(leds);
    +}
    +
    +struct kbd_ll_operations oldkbd_operations = {
    + oldkbd_setkeycode,
    + oldkbd_getkeycode,
    + oldkbd_pretranslate,
    + oldkbd_translate,
    + oldkbd_unexpected_up,
    + oldkbd_leds,
    +#ifdef CONFIG_MAGIC_SYSRQ
    + SYSRQ_KEY,
    + kbd_sysrq_xlate,
    +#else
    + -1, NULL,
    +#endif
    + 0, 0, NULL
    +};
    +
    +void *old_kbdid;
    +
    +void handle_scancode(unsigned char scancode)
    +{
    + if (old_kbdid)
    + kbd_handle_scancode(old_kbdid, scancode);
    +}
    +#endif /* NEW_STYLE_KEYBOARD */
    +
    __initfunc(int kbd_init(void))
    {
    int i;
    @@ -902,7 +1061,54 @@
    ttytab = console_driver.table;

    kbd_init_hw();
    +
    +#ifndef NEW_STYLE_KEYBOARD
    + old_kbdid = register_keyboard(oldkbd_operations, NULL, key_maps);
    +#endif /* NEW_STYLE_KEYBOARD */
    +
    init_bh(KEYBOARD_BH, kbd_bh);
    mark_bh(KEYBOARD_BH);
    return 0;
    }
    +
    +void *register_keyboard(struct kbd_ll_operations *ops, void *devid,
    + ushort **key_maps)
    +{
    + struct keyboard_state *ks, **ksp;
    +
    + ks = (struct keyboard_state *) kmalloc(sizeof(*ks), GFP_KERNEL);
    + if (ks == 0)
    + return NULL;
    + memset(ks, 0, sizeof(*ks));
    +
    + ks->next = NULL;
    + ks->k_op = ops;
    + ks->devid = devid;
    + ks->key_maps = key_maps;
    + ks->npadch = -1;
    +
    + spin_lock(&all_kbds_lock);
    + for (ksp = &all_kbds; *ksp != NULL; ksp = &(*ksp)->next)
    + ;
    + *ksp = ks;
    + spin_unlock(&all_kbds_lock);
    +
    + return (void *) ks;
    +}
    +
    +void unregister_keyboard(void *kbdid)
    +{
    + struct keyboard_state **ksp;
    +
    + spin_lock(&all_kbds_lock);
    + for (ksp = &all_kbds; *ksp != NULL; ksp = &(*ksp)->next) {
    + if (*ksp == kbdid) {
    + *ksp = (*ksp)->next;
    + kfree(kbdid);
    + break;
    + }
    + }
    +}
    +
    +EXPORT_SYMBOL (register_keyboard);
    +EXPORT_SYMBOL (unregister_keyboard);
    diff -ur linux/drivers/char/pc_keyb.c linux-pmac/drivers/char/pc_keyb.c
    --- linux/drivers/char/pc_keyb.c Tue Oct 27 16:45:38 1998
    +++ linux-pmac/drivers/char/pc_keyb.c Wed Oct 28 15:38:11 1998
    @@ -24,6 +24,7 @@
    #include <linux/init.h>
    #include <linux/kbd_ll.h>
    #include <linux/delay.h>
    +#include <linux/keyboard.h>
    #include <linux/random.h>
    #include <linux/poll.h>
    #include <linux/miscdevice.h>
    @@ -52,6 +53,8 @@
    "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
    "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
    "\r\000/"; /* 0x60 - 0x6f */
    +#else
    +#define pckbd_sysrq_xlate NULL
    #endif

    static void kbd_write(int address, int data);
    @@ -85,6 +88,30 @@
    #endif
    #endif /* CONFIG_PSMOUSE */

    +extern int pckbd_setkeycode(void *, unsigned int scancode,
    + unsigned int keycode);
    +extern int pckbd_getkeycode(void *, unsigned int scancode);
    +extern int pckbd_pretranslate(void *, unsigned char scancode, char raw_mode);
    +extern int pckbd_translate(void *, unsigned char scancode,
    + unsigned char *keycode, char raw_mode);
    +extern char pckbd_unexpected_up(void *, unsigned char keycode);
    +extern void pckbd_leds(void *, unsigned char leds);
    +#define SYSRQ_KEY 0x54
    +
    +struct kbd_ll_operations pckbd_operations = {
    + pckbd_setkeycode,
    + pckbd_getkeycode,
    + pckbd_pretranslate,
    + pckbd_translate,
    + pckbd_unexpected_up,
    + pckbd_leds,
    + SYSRQ_KEY,
    + pckbd_sysrq_xlate,
    + 0, 0, NULL
    +};
    +
    +static void *pckbd_id;
    +
    /*
    * Wait for keyboard controller input buffer is empty.
    *
    @@ -237,7 +264,7 @@

    static unsigned int prev_scancode = 0; /* remember E0, E1 */

    -int pckbd_setkeycode(unsigned int scancode, unsigned int keycode)
    +int pckbd_setkeycode(void *devid, unsigned int scancode, unsigned int keycode)
    {
    if (scancode < SC_LIM || scancode > 255 || keycode > 127)
    return -EINVAL;
    @@ -248,7 +275,7 @@
    return 0;
    }

    -int pckbd_getkeycode(unsigned int scancode)
    +int pckbd_getkeycode(void *devid, unsigned int scancode)
    {
    return
    (scancode < SC_LIM || scancode > 255) ? -EINVAL :
    @@ -308,7 +335,7 @@
    return 1;
    }

    -int pckbd_pretranslate(unsigned char scancode, char raw_mode)
    +int pckbd_pretranslate(void *devid, unsigned char scancode, char raw_mode)
    {
    if (scancode == 0xff) {
    /* in scancode mode 1, my ESC key generates 0xff */
    @@ -330,8 +357,8 @@
    return 1;
    }

    -int pckbd_translate(unsigned char scancode, unsigned char *keycode,
    - char raw_mode)
    +int pckbd_translate(void *devid, unsigned char scancode,
    + unsigned char *keycode, char raw_mode)
    {
    if (prev_scancode) {
    /*
    @@ -409,7 +436,7 @@
    return 1;
    }

    -char pckbd_unexpected_up(unsigned char keycode)
    +char pckbd_unexpected_up(void *devid, unsigned char keycode)
    {
    /* unexpected, but this can happen: maybe this was a key release for a
    FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */
    @@ -452,7 +479,7 @@
    #endif
    } else {
    if (do_acknowledge(scancode))
    - handle_scancode(scancode);
    + kbd_handle_scancode(pckbd_id, scancode);
    mark_bh(KEYBOARD_BH);
    }

    @@ -501,7 +528,7 @@
    return 0;
    }

    -void pckbd_leds(unsigned char leds)
    +void pckbd_leds(void *devid, unsigned char leds)
    {
    if (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))
    send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */
    @@ -713,6 +740,10 @@

    /* Ok, finally allocate the IRQ, and off we go.. */
    request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard", NULL);
    +
    + pckbd_id = register_keyboard(&pckbd_operations, NULL, key_maps);
    + if (pckbd_id == NULL)
    + printk(KERN_ERR "Couldn't register PC keyboard!\n");
    }

    #if defined CONFIG_PSMOUSE
    diff -ur linux/drivers/macintosh/mac_keyb.c linux-pmac/drivers/macintosh/mac_keyb.c
    --- linux/drivers/macintosh/mac_keyb.c Mon Oct 12 10:32:52 1998
    +++ linux-pmac/drivers/macintosh/mac_keyb.c Sun Oct 25 16:13:14 1998
    @@ -31,7 +31,27 @@
    #define KEYB_LEDREG 2 /* register # for leds on ADB keyboard */
    #define MOUSE_DATAREG 0 /* reg# for movement/button codes from mouse */

    -static u_short macplain_map[NR_KEYS] __initdata = {
    +int mackbd_setkeycode(void *devid, unsigned int scancode, unsigned int keycode);
    +int mackbd_getkeycode(void *devid, unsigned int scancode);
    +int mackbd_pretranslate(void *devid, unsigned char scancode, char raw_mode);
    +int mackbd_translate(void *devid, unsigned char scancode,
    + unsigned char *keycode, char raw_mode);
    +char mackbd_unexpected_up(void *devid, unsigned char keycode);
    +void mackbd_leds(void *devid, unsigned char leds);
    +
    +/* this map indicates which keys shouldn't autorepeat. */
    +static unsigned char dont_repeat[128] = {
    + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    + 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* esc...option */
    + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /* num lock */
    + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, /* scroll lock */
    + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    +};
    +
    +static u_short plain_map[NR_KEYS] = {
    0xfb61, 0xfb73, 0xfb64, 0xfb66, 0xfb68, 0xfb67, 0xfb7a, 0xfb78,
    0xfb63, 0xfb76, 0xf200, 0xfb62, 0xfb71, 0xfb77, 0xfb65, 0xfb72,
    0xfb79, 0xfb74, 0xf031, 0xf032, 0xf033, 0xf034, 0xf036, 0xf035,
    @@ -50,7 +70,7 @@
    0xf101, 0xf119, 0xf100, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
    };

    -static u_short macshift_map[NR_KEYS] __initdata = {
    +static u_short shift_map[NR_KEYS] = {
    0xfb41, 0xfb53, 0xfb44, 0xfb46, 0xfb48, 0xfb47, 0xfb5a, 0xfb58,
    0xfb43, 0xfb56, 0xf200, 0xfb42, 0xfb51, 0xfb57, 0xfb45, 0xfb52,
    0xfb59, 0xfb54, 0xf021, 0xf040, 0xf023, 0xf024, 0xf05e, 0xf025,
    @@ -69,7 +89,7 @@
    0xf10b, 0xf20a, 0xf10a, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
    };

    -static u_short macaltgr_map[NR_KEYS] __initdata = {
    +static u_short altgr_map[NR_KEYS] = {
    0xf914, 0xfb73, 0xf917, 0xf919, 0xfb68, 0xfb67, 0xfb7a, 0xfb78,
    0xf916, 0xfb76, 0xf200, 0xf915, 0xfb71, 0xfb77, 0xf918, 0xfb72,
    0xfb79, 0xfb74, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
    @@ -88,7 +108,7 @@
    0xf50d, 0xf119, 0xf50c, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
    };

    -static u_short macctrl_map[NR_KEYS] __initdata = {
    +static u_short ctrl_map[NR_KEYS] = {
    0xf001, 0xf013, 0xf004, 0xf006, 0xf008, 0xf007, 0xf01a, 0xf018,
    0xf003, 0xf016, 0xf200, 0xf002, 0xf011, 0xf017, 0xf005, 0xf012,
    0xf019, 0xf014, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01e, 0xf01d,
    @@ -107,7 +127,7 @@
    0xf101, 0xf119, 0xf100, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
    };

    -static u_short macshift_ctrl_map[NR_KEYS] __initdata = {
    +static u_short shift_ctrl_map[NR_KEYS] = {
    0xf001, 0xf013, 0xf004, 0xf006, 0xf008, 0xf007, 0xf01a, 0xf018,
    0xf003, 0xf016, 0xf200, 0xf002, 0xf011, 0xf017, 0xf005, 0xf012,
    0xf019, 0xf014, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
    @@ -126,7 +146,7 @@
    0xf200, 0xf119, 0xf200, 0xf700, 0xf701, 0xf702, 0xf200, 0xf20c,
    };

    -static u_short macalt_map[NR_KEYS] __initdata = {
    +static u_short alt_map[NR_KEYS] = {
    0xf861, 0xf873, 0xf864, 0xf866, 0xf868, 0xf867, 0xf87a, 0xf878,
    0xf863, 0xf876, 0xf200, 0xf862, 0xf871, 0xf877, 0xf865, 0xf872,
    0xf879, 0xf874, 0xf831, 0xf832, 0xf833, 0xf834, 0xf836, 0xf835,
    @@ -145,7 +165,7 @@
    0xf501, 0xf119, 0xf500, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
    };

    -static u_short macctrl_alt_map[NR_KEYS] __initdata = {
    +static u_short ctrl_alt_map[NR_KEYS] = {
    0xf801, 0xf813, 0xf804, 0xf806, 0xf808, 0xf807, 0xf81a, 0xf818,
    0xf803, 0xf816, 0xf200, 0xf802, 0xf811, 0xf817, 0xf805, 0xf812,
    0xf819, 0xf814, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
    @@ -164,13 +184,28 @@
    0xf501, 0xf119, 0xf500, 0xf700, 0xf701, 0xf702, 0xf200, 0xf200,
    };

    +static ushort *mackey_maps[MAX_NR_KEYMAPS] = {
    + plain_map, shift_map, altgr_map, 0,
    + ctrl_map, shift_ctrl_map, 0, 0,
    + alt_map, 0, 0, 0,
    + ctrl_alt_map, 0
    +};

    -static void kbd_repeat(unsigned long);
    -static struct timer_list repeat_timer = { NULL, NULL, 0, 0, kbd_repeat };
    -static int last_keycode;
    +struct kbd_ll_operations mackbd_operations = {
    + mackbd_setkeycode,
    + mackbd_getkeycode,
    + mackbd_pretranslate,
    + mackbd_translate,
    + mackbd_unexpected_up,
    + mackbd_leds,
    + -1, /* no SysRq key */
    + NULL,
    + HZ/2, HZ/15,
    + dont_repeat
    +};

    static void keyboard_input(unsigned char *, int, struct pt_regs *, int);
    -static void input_keycode(int, int);
    +static void input_keycode(void *, int);
    static void leds_done(struct adb_request *);
    static void mac_put_queue(int);

    @@ -185,44 +220,39 @@
    extern int console_loglevel;

    extern struct kbd_struct kbd_table[];
    -extern struct wait_queue * keypress_wait;
    -
    -extern void handle_scancode(unsigned char);
    +extern struct wait_queue *keypress_wait;

    static struct adb_ids keyboard_ids;
    static struct adb_ids mouse_ids;

    -/* this map indicates which keys shouldn't autorepeat. */
    -static unsigned char dont_repeat[128] = {
    - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    - 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* esc...option */
    - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, /* num lock */
    - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, /* scroll lock */
    - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    +struct mackbd_state {
    + int adb_id;
    + void *kbd_id;
    + struct adb_request led_request;
    + int leds_pending;
    };

    +struct mackbd_state mackbd_states[16];
    +
    __openfirmware

    -int mackbd_setkeycode(unsigned int scancode, unsigned int keycode)
    +int mackbd_setkeycode(void *devid, unsigned int scancode, unsigned int keycode)
    {
    return -EINVAL;
    }

    -int mackbd_getkeycode(unsigned int scancode)
    +int mackbd_getkeycode(void *devid, unsigned int scancode)
    {
    return -EINVAL;
    }

    -int mackbd_pretranslate(unsigned char scancode, char raw_mode)
    +int mackbd_pretranslate(void *devid, unsigned char scancode, char raw_mode)
    {
    return 1;
    }

    -int mackbd_translate(unsigned char keycode, unsigned char *keycodep,
    - char raw_mode)
    +int mackbd_translate(void *devid, unsigned char keycode,
    + unsigned char *keycodep, char raw_mode)
    {
    if (!raw_mode) {
    /*
    @@ -238,7 +268,7 @@
    return 1;
    }

    -int mackbd_unexpected_up(unsigned char keycode)
    +char mackbd_unexpected_up(void *devid, unsigned char keycode)
    {
    return 0x80;
    }
    @@ -246,17 +276,22 @@
    static void
    keyboard_input(unsigned char *data, int nb, struct pt_regs *regs, int apoll)
    {
    + void *kbd_id;
    +
    /* first check this is from register 0 */
    if (nb != 3 || (data[0] & 3) != KEYB_KEYREG)
    return; /* ignore it */
    + kbd_id = mackbd_states[data[0] >> 4].kbd_id;
    + if (kbd_id == NULL)
    + return;
    kbd_pt_regs = regs;
    - input_keycode(data[1], 0);
    + input_keycode(kbd_id, data[1]);
    if (!(data[2] == 0xff || (data[2] == 0x7f && data[1] == 0x7f)))
    - input_keycode(data[2], 0);
    + input_keycode(kbd_id, data[2]);
    }

    static void
    -input_keycode(int keycode, int repeat)
    +input_keycode(void *kbdid, int keycode)
    {
    struct kbd_struct *kbd;
    int up_flag;
    @@ -269,9 +304,6 @@
    if (keycode == 0x7e)
    keycode = 0x7f;

    - if (!repeat)
    - del_timer(&repeat_timer);
    -
    #ifdef CONFIG_ADBMOUSE
    /*
    * XXX: Add mouse button 2+3 fake codes here if mouse open.
    @@ -305,12 +337,6 @@
    #endif /* CONFIG_ADBMOUSE */

    if (kbd->kbdmode != VC_RAW) {
    - if (!up_flag && !dont_repeat[keycode]) {
    - last_keycode = keycode;
    - repeat_timer.expires = jiffies + (repeat? HZ/15: HZ/2);
    - add_timer(&repeat_timer);
    - }
    -
    /*
    * adb kludge!! Imitate pc caps lock behaviour by
    * generating an up/down event for each time caps
    @@ -320,8 +346,8 @@
    switch (keycode) {
    /*case 0xb9:*/
    case 0x39:
    - handle_scancode(0x39);
    - handle_scancode(0xb9);
    + kbd_handle_scancode(kbdid, 0x39);
    + kbd_handle_scancode(kbdid, 0xb9);
    mark_bh(KEYBOARD_BH);
    return;
    case 0x47:
    @@ -331,18 +357,7 @@
    }
    }

    - handle_scancode(keycode + up_flag);
    -}
    -
    -static void
    -kbd_repeat(unsigned long xxx)
    -{
    - unsigned long flags;
    -
    - save_flags(flags);
    - cli();
    - input_keycode(last_keycode, 1);
    - restore_flags(flags);
    + kbd_handle_scancode(kbdid, keycode + up_flag);
    }

    static void mac_put_queue(int ch)
    @@ -479,132 +494,120 @@
    7, /* caps + num + scroll lock */
    };

    -static struct adb_request led_request;
    -static int leds_pending[16];
    -static int pending_devs[16];
    -static int pending_led_start=0;
    -static int pending_led_end=0;
    -
    -static void real_mackbd_leds(unsigned char leds, int device)
    -{
    -
    - if (led_request.complete) {
    - adb_request(&led_request, leds_done, 0, 3,
    - ADB_WRITEREG(device, KEYB_LEDREG), 0xff,
    - ~mac_ledmap[leds]);
    - } else {
    - if (!(leds_pending[device] & 0x100)) {
    - pending_devs[pending_led_end] = device;
    - pending_led_end++;
    - pending_led_end = (pending_led_end < 16) ? pending_led_end : 0;
    - }
    - leds_pending[device] = leds | 0x100;
    - }
    -}
    -
    -void mackbd_leds(unsigned char leds)
    +void mackbd_leds(void *devid, unsigned char leds)
    {
    - int i;
    + struct mackbd_state *ms = (struct mackbd_state *) devid;

    - for(i = 0; i < keyboard_ids.nids; i++)
    - real_mackbd_leds(leds,keyboard_ids.id[i]);
    + if (ms->led_request.complete) {
    + ms->led_request.arg = devid;
    + adb_request(&ms->led_request, leds_done, 0, 3,
    + ADB_WRITEREG(ms->adb_id, KEYB_LEDREG), 0xff,
    + ~mac_ledmap[leds]);
    + } else {
    + ms->leds_pending = leds | 0x100;
    + }
    }

    static void leds_done(struct adb_request *req)
    {
    - int leds,device;
    -
    - if (pending_led_start != pending_led_end) {
    - device = pending_devs[pending_led_start];
    - leds = leds_pending[device] & 0xff;
    - leds_pending[device] = 0;
    - pending_led_start++;
    - pending_led_start = (pending_led_start < 16) ? pending_led_start : 0;
    - real_mackbd_leds(leds,device);
    - }
    + struct mackbd_state *ms = (struct mackbd_state *) req->arg;
    + int leds;

    + if (ms->leds_pending) {
    + leds = ms->leds_pending & 0xff;
    + ms->leds_pending = 0;
    + mackbd_leds(ms, leds);
    + }
    }

    -__initfunc(void mackbd_init_hw(void))
    +__initfunc(static void init_mouse(int id))
    {
    struct adb_request req;
    - int i;
    -
    - if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
    - return;
    -
    - /* setup key map */
    - memcpy(key_maps[0], macplain_map, sizeof(plain_map));
    - memcpy(key_maps[1], macshift_map, sizeof(plain_map));
    - memcpy(key_maps[2], macaltgr_map, sizeof(plain_map));
    - memcpy(key_maps[4], macctrl_map, sizeof(plain_map));
    - memcpy(key_maps[5], macshift_ctrl_map, sizeof(plain_map));
    - memcpy(key_maps[8], macalt_map, sizeof(plain_map));
    - memcpy(key_maps[12], macctrl_alt_map, sizeof(plain_map));
    -
    -#ifdef CONFIG_ADBMOUSE
    - /* initialize mouse interrupt hook */
    - adb_mouse_interrupt_hook = NULL;
    -
    - adb_register(ADB_MOUSE, 1, &mouse_ids, mouse_input);
    -#endif /* CONFIG_ADBMOUSE */
    -
    - adb_register(ADB_KEYBOARD, 5, &keyboard_ids, keyboard_input);
    -
    - for(i = 0; i < keyboard_ids.nids; i++) {
    - /* turn off all leds */
    - adb_request(&req, NULL, ADBREQ_SYNC, 3,
    - ADB_WRITEREG(keyboard_ids.id[i], KEYB_LEDREG), 0xff, 0xff);
    - }

    - /* get the keyboard to send separate codes for
    - left and right shift, control, option keys. */
    - for(i = 0;i < keyboard_ids.nids; i++) {
    - /* get the keyboard to send separate codes for
    - left and right shift, control, option keys. */
    - adb_request(&req, NULL, ADBREQ_SYNC, 3,
    - ADB_WRITEREG(keyboard_ids.id[i], 3), 0, 3);
    - }
    + adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
    + ADB_READREG(id, 1));

    - led_request.complete = 1;
    + if ((req.reply_len) &&
    + (req.reply[1] == 0x9a) && (req.reply[2] == 0x21)) {
    + printk("aha, trackball found at %d\n", id);

    - /* Try to switch the mouse (id 3) to handler 4, for three-button
    - mode. (0x20 is Service Request Enable, 0x03 is Device ID). */
    - for(i = 0; i < mouse_ids.nids; i++) {
    - adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
    - ADB_READREG(mouse_ids.id[i], 1));
    -
    - if ((req.reply_len) &&
    - (req.reply[1] == 0x9a) && (req.reply[2] == 0x21)) {
    + adb_request(&req, NULL, ADBREQ_SYNC, 3,
    + ADB_WRITEREG(id, 3), 0x63, 4 );

    - printk("aha, trackball found at %d\n", mouse_ids.id[i]);
    + adb_request(&req, NULL, ADBREQ_SYNC, 3,
    + ADB_WRITEREG(id,1), 00,0x81);

    adb_request(&req, NULL, ADBREQ_SYNC, 3,
    - ADB_WRITEREG(mouse_ids.id[i], 3), 0x63, 4 );
    + ADB_WRITEREG(id,1), 01,0x81);

    adb_request(&req, NULL, ADBREQ_SYNC, 3,
    - ADB_WRITEREG(mouse_ids.id[i],1), 00,0x81);
    + ADB_WRITEREG(id,1), 02,0x81);

    adb_request(&req, NULL, ADBREQ_SYNC, 3,
    - ADB_WRITEREG(mouse_ids.id[i],1), 01,0x81);
    + ADB_WRITEREG(id,1), 03,0x38);

    adb_request(&req, NULL, ADBREQ_SYNC, 3,
    - ADB_WRITEREG(mouse_ids.id[i],1), 02,0x81);
    + ADB_WRITEREG(id,1), 00,0x81);

    adb_request(&req, NULL, ADBREQ_SYNC, 3,
    - ADB_WRITEREG(mouse_ids.id[i],1), 03,0x38);
    + ADB_WRITEREG(id,1), 01,0x81);

    adb_request(&req, NULL, ADBREQ_SYNC, 3,
    - ADB_WRITEREG(mouse_ids.id[i],1), 00,0x81);
    + ADB_WRITEREG(id,1), 02,0x81);

    adb_request(&req, NULL, ADBREQ_SYNC, 3,
    - ADB_WRITEREG(mouse_ids.id[i],1), 01,0x81);
    + ADB_WRITEREG(id,1), 03,0x38);
    + }
    +}

    +__initfunc(void mackbd_init_hw(void))
    +{
    + int i;
    +
    + if ((_machine != _MACH_chrp) && (_machine != _MACH_Pmac))
    + return;
    +
    +#ifdef CONFIG_ADBMOUSE
    + /* initialize mouse interrupt hook */
    + adb_mouse_interrupt_hook = NULL;
    +
    + adb_register(ADB_MOUSE, 1, &mouse_ids, mouse_input);
    +
    + /* Try to switch the mouse (id 3) to handler 4, for three-button
    + mode. (0x20 is Service Request Enable, 0x03 is Device ID). */
    + for (i = 0; i < mouse_ids.nids; i++) {
    + init_mouse(mouse_ids.id[i]);
    + }
    +#endif /* CONFIG_ADBMOUSE */
    +
    + adb_register(ADB_KEYBOARD, 5, &keyboard_ids, keyboard_input);
    + if (keyboard_ids.nids == 0)
    + return;
    +
    + for (i = 0; i < keyboard_ids.nids; i++) {
    + int id = keyboard_ids.id[i];
    + struct mackbd_state *ms = &mackbd_states[id];
    + struct adb_request req;
    +
    + memset(ms, 0, sizeof(*ms));
    + ms->adb_id = id;
    + ms->led_request.complete = 1;
    + ms->kbd_id = register_keyboard(&mackbd_operations, ms,
    + mackey_maps);
    + if (ms->kbd_id == NULL)
    + printk(KERN_ERR "Couldn't register ADB keyboard %d\n",
    + id);
    +
    + /* turn off all leds */
    adb_request(&req, NULL, ADBREQ_SYNC, 3,
    - ADB_WRITEREG(mouse_ids.id[i],1), 02,0x81);
    + ADB_WRITEREG(id, KEYB_LEDREG), 0xff, 0xff);

    + /* get the keyboard to send separate codes for
    + left and right shift, control, option keys. */
    adb_request(&req, NULL, ADBREQ_SYNC, 3,
    - ADB_WRITEREG(mouse_ids.id[i],1), 03,0x38);
    - }
    + ADB_WRITEREG(id, 3), 0, 3);
    }
    +
    + /* setup default key map */
    + memcpy(key_maps, mackey_maps, sizeof(mackey_maps));
    }
    diff -ur linux/include/asm-i386/keyboard.h linux-pmac/include/asm-i386/keyboard.h
    --- linux/include/asm-i386/keyboard.h Mon Jul 21 18:16:55 1997
    +++ linux-pmac/include/asm-i386/keyboard.h Sun Oct 25 15:56:37 1998
    @@ -15,27 +15,11 @@

    #define KEYBOARD_IRQ 1
    #define DISABLE_KBD_DURING_INTERRUPTS 0
    +#define NEW_STYLE_KEYBOARD

    -extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
    -extern int pckbd_getkeycode(unsigned int scancode);
    -extern int pckbd_pretranslate(unsigned char scancode, char raw_mode);
    -extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
    - char raw_mode);
    -extern char pckbd_unexpected_up(unsigned char keycode);
    -extern void pckbd_leds(unsigned char leds);
    extern void pckbd_init_hw(void);
    -extern unsigned char pckbd_sysrq_xlate[128];

    -#define kbd_setkeycode pckbd_setkeycode
    -#define kbd_getkeycode pckbd_getkeycode
    -#define kbd_pretranslate pckbd_pretranslate
    -#define kbd_translate pckbd_translate
    -#define kbd_unexpected_up pckbd_unexpected_up
    -#define kbd_leds pckbd_leds
    #define kbd_init_hw pckbd_init_hw
    -#define kbd_sysrq_xlate pckbd_sysrq_xlate
    -
    -#define SYSRQ_KEY 0x54

    #endif /* __KERNEL__ */

    diff -ur linux/include/asm-ppc/keyboard.h linux-pmac/include/asm-ppc/keyboard.h
    --- linux/include/asm-ppc/keyboard.h Thu Oct 22 16:31:01 1998
    +++ linux-pmac/include/asm-ppc/keyboard.h Wed Oct 28 15:45:57 1998
    @@ -16,7 +16,7 @@
    #ifdef __KERNEL__

    #include <linux/config.h>
    -#include <asm/adb.h>
    +#include <asm/processor.h>

    #ifdef CONFIG_APUS
    #include <asm-m68k/keyboard.h>
    @@ -24,152 +24,22 @@

    #define KEYBOARD_IRQ 1
    #define DISABLE_KBD_DURING_INTERRUPTS 0
    -#define INIT_KBD
    +#define NEW_STYLE_KEYBOARD

    -extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
    -extern int mackbd_getkeycode(unsigned int scancode);
    -extern int mackbd_pretranslate(unsigned char scancode, char raw_mode);
    -extern int mackbd_translate(unsigned char scancode, unsigned char *keycode,
    - char raw_mode);
    -extern int mackbd_unexpected_up(unsigned char keycode);
    -extern void mackbd_leds(unsigned char leds);
    extern void mackbd_init_hw(void);

    -extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
    -extern int pckbd_getkeycode(unsigned int scancode);
    -extern int pckbd_pretranslate(unsigned char scancode, char raw_mode);
    -extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
    - char raw_mode);
    -extern char pckbd_unexpected_up(unsigned char keycode);
    -extern void pckbd_leds(unsigned char leds);
    extern void pckbd_init_hw(void);

    -static inline int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
    -{
    - if ( is_prep )
    - return pckbd_setkeycode(scancode,keycode);
    - else if ( is_chrp )
    -#ifndef CONFIG_MAC_KEYBOARD
    - return pckbd_setkeycode(scancode,keycode);
    -#else
    - /* I'm not actually sure if it's legal to have a CHRP machine
    - * without an ADB controller. In any case, this should really
    - * be changed to be a test to see if an ADB _keyboard_ exists
    - * (not just a controller), but that's another story for
    - * another night.
    - */
    - if ( adb_hardware == ADB_NONE )
    - return pckbd_setkeycode(scancode,keycode);
    - else
    - return mackbd_setkeycode(scancode,keycode);
    -#endif
    - else
    - return mackbd_setkeycode(scancode,keycode);
    -}
    -
    -static inline int kbd_getkeycode(unsigned int x)
    -{
    - if ( is_prep )
    - return pckbd_getkeycode(x);
    - else if ( is_chrp )
    -#ifndef CONFIG_MAC_KEYBOARD
    - return pckbd_getkeycode(x);
    -#else
    - if ( adb_hardware == ADB_NONE )
    - return pckbd_getkeycode(x);
    - else
    - return mackbd_getkeycode(x);
    -#endif
    - else
    - return mackbd_getkeycode(x);
    -}
    -
    -static inline int kbd_pretranslate(unsigned char x,char y)
    -{
    - if ( is_prep )
    - return pckbd_pretranslate(x,y);
    - else if ( is_chrp )
    -#ifndef CONFIG_MAC_KEYBOARD
    - return pckbd_pretranslate(x,y);
    -#else
    - if ( adb_hardware == ADB_NONE )
    - return pckbd_pretranslate(x,y);
    - else
    - return mackbd_pretranslate(x,y);
    -#endif
    - else
    - return mackbd_pretranslate(x,y);
    -}
    -
    -static inline int kbd_translate(unsigned char keycode, unsigned char *keycodep,
    - char raw_mode)
    -{
    - if ( is_prep )
    - return pckbd_translate(keycode,keycodep,raw_mode);
    - else if ( is_chrp )
    -#ifndef CONFIG_MAC_KEYBOARD
    - return pckbd_translate(keycode,keycodep,raw_mode);
    -#else
    - if ( adb_hardware == ADB_NONE )
    - return pckbd_translate(keycode,keycodep,raw_mode);
    - else
    - return mackbd_translate(keycode,keycodep,raw_mode);
    -#endif
    - else
    - return mackbd_translate(keycode,keycodep,raw_mode);
    -
    -}
    -
    -static inline int kbd_unexpected_up(unsigned char keycode)
    -{
    - if ( is_prep )
    - return pckbd_unexpected_up(keycode);
    - else if ( is_chrp )
    -#ifndef CONFIG_MAC_KEYBOARD
    - return pckbd_unexpected_up(keycode);
    -#else
    - if ( adb_hardware == ADB_NONE )
    - return pckbd_unexpected_up(keycode);
    - else
    - return mackbd_unexpected_up(keycode);
    -#endif
    - else
    - return mackbd_unexpected_up(keycode);
    -
    -}
    -
    -static inline void kbd_leds(unsigned char leds)
    -{
    - if ( is_prep )
    - pckbd_leds(leds);
    - else if ( is_chrp )
    -#ifndef CONFIG_MAC_KEYBOARD
    - pckbd_leds(leds);
    -#else
    - if ( adb_hardware == ADB_NONE )
    - pckbd_leds(leds);
    - else
    - mackbd_leds(leds);
    -#endif
    - else
    - mackbd_leds(leds);
    -}
    -
    static inline void kbd_init_hw(void)
    {
    - if ( is_prep )
    - pckbd_init_hw();
    - else if ( is_chrp )
    -#ifndef CONFIG_MAC_KEYBOARD
    +#ifdef CONFIG_MAC_KEYBOARD
    + if (!is_prep)
    + mackbd_init_hw();
    +#endif
    +#ifdef CONFIG_PC_KEYBOARD
    + if (is_prep || is_chrp)
    pckbd_init_hw();
    -#else
    - if ( adb_hardware == ADB_NONE )
    - pckbd_init_hw();
    - else
    - mackbd_init_hw();
    #endif
    - else
    - mackbd_init_hw();
    }

    #endif /* CONFIG_APUS */
    diff -ur linux/include/linux/kbd_ll.h linux-pmac/include/linux/kbd_ll.h
    --- linux/include/linux/kbd_ll.h Mon Jul 21 18:44:40 1997
    +++ linux-pmac/include/linux/kbd_ll.h Sat Oct 24 21:12:14 1998
    @@ -5,8 +5,35 @@
    #ifndef _KBD_LL_H
    #define _KBD_LL_H

    +/*
    + * The kbd_operations struct contains pointers to the procedures
    + * which are supplied by the low-level keyboard driver and used
    + * by the keymapper (drivers/char/keyboard.c).
    + */
    +struct kbd_ll_operations {
    + int (*setkeycode)(void *devid, unsigned int scancode,
    + unsigned int keycode);
    + int (*getkeycode)(void *devid, unsigned int scancode);
    + int (*pretranslate)(void *devid, unsigned char scancode,
    + char raw_mode);
    + int (*translate)(void *devid, unsigned char scancode,
    + unsigned char *keycode, char raw_mode);
    + char (*unexpected_up)(void *devid, unsigned char keycode);
    + void (*leds)(void *devid, unsigned char leds);
    + int sysrq_key;
    + unsigned char *sysrq_xlate;
    + int repeat_initial; /* initial delay for soft auto-repeat */
    + int repeat_delay; /* delay between auto-repeats */
    + unsigned char *dont_repeat; /* keys which don't auto-repeat */
    +};
    +
    extern struct pt_regs *kbd_pt_regs;

    void handle_scancode(unsigned char scancode);
    +
    +void *register_keyboard(struct kbd_ll_operations *ops, void *devid,
    + ushort **key_maps); /* returns kbd id */
    +void unregister_keyboard(void *kbdid);
    +void kbd_handle_scancode(void *kbdid, int scancode);

    #endif /* _KBD_LL_H */
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.rutgers.edu
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:45    [W:0.130 / U:29.984 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site