diff -urX dontdiff v2.4.5/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c --- v2.4.5/linux/drivers/char/pc_keyb.c Fri Apr 6 22:42:55 2001 +++ linux/drivers/char/pc_keyb.c Tue Jun 12 17:33:00 2001 @@ -533,6 +533,86 @@ } } +#define DEFAULT_KEYB_REP_DELAY 250 +#define DEFAULT_KEYB_REP_RATE 30 /* cps */ + +static struct kbd_repeat kbdrate={ + DEFAULT_KEYB_REP_DELAY, + DEFAULT_KEYB_REP_RATE +}; + +static unsigned char parse_kbd_rate(struct kbd_repeat *r) +{ + static struct r2v{ + int rate; + unsigned char val; + } kbd_rates[]={ {5,0x14}, + {7,0x10}, + {10,0x0c}, + {15,0x08}, + {20,0x04}, + {25,0x02}, + {30,0x00} + }; + static struct d2v{ + int delay; + unsigned char val; + } kbd_delays[]={{250,0}, + {500,1}, + {750,2}, + {1000,3} + }; + int rate=0,delay=0; + if (r != NULL){ + int i,new_rate=30,new_delay=250; + if (r->rate <= 0) + r->rate=kbdrate.rate; + if (r->delay <= 0) + r->delay=kbdrate.delay; + for (i=0; i < sizeof(kbd_rates)/sizeof(struct r2v); i++) + if (kbd_rates[i].rate == r->rate){ + new_rate=kbd_rates[i].rate; + rate=kbd_rates[i].val; + break; + } + for (i=0; i < sizeof(kbd_delays)/sizeof(struct d2v); i++) + if (kbd_delays[i].delay == r->delay){ + new_delay=kbd_delays[i].delay; + delay=kbd_delays[i].val; + break; + } + r->rate=new_rate; + r->delay=new_delay; + } + return (delay << 5) | rate; +} + +static int write_kbd_rate(unsigned char r) +{ + if (!send_data(KBD_CMD_SET_RATE) || !send_data(r)){ + send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */ + return 0; + }else + return 1; +} + +int pckbd_rate(struct kbd_repeat *rep) +{ + if (rep == NULL) + return -EINVAL; + else{ + unsigned char r=parse_kbd_rate(rep); + struct kbd_repeat old_rep; + memcpy(&old_rep,&kbdrate,sizeof(struct kbd_repeat)); + if (write_kbd_rate(r)){ + memcpy(&kbdrate,rep,sizeof(struct kbd_repeat)); + memcpy(rep,&old_rep,sizeof(struct kbd_repeat)); + return 0; + } + } + return -EIO; +} + /* * In case we run on a non-x86 hardware we need to initialize both the * keyboard controller and the keyboard. On a x86, the BIOS will diff -urX dontdiff v2.4.5/linux/drivers/char/vt.c linux/drivers/char/vt.c --- v2.4.5/linux/drivers/char/vt.c Fri Feb 9 23:30:22 2001 +++ linux/drivers/char/vt.c Wed Jun 13 23:36:52 2001 @@ -26,10 +26,7 @@ #include #include - -#if defined(__mc68000__) || defined(CONFIG_APUS) -#include -#endif +#include #include #include @@ -497,26 +494,29 @@ (cmd == KDENABIO)) ? -ENXIO : 0; #endif -#if defined(__mc68000__) || defined(CONFIG_APUS) - /* Linux/m68k interface for setting the keyboard delay/repeat rate */ - +/* + Linux m68k/i386/sparc interface for setting the keyboard + delay/repeat rate +*/ +#if defined kbd_rate case KDKBDREP: { struct kbd_repeat kbrep; - if (!mach_kbdrate) return( -EINVAL ); + if (!kbd_rate) return( -EINVAL ); if (!suser()) return( -EPERM ); if (copy_from_user(&kbrep, (void *)arg, sizeof(struct kbd_repeat))) return -EFAULT; - if ((i = mach_kbdrate( &kbrep ))) return( i ); + if ((i = kbd_rate( &kbrep ))) + return i; if (copy_to_user((void *)arg, &kbrep, sizeof(struct kbd_repeat))) return -EFAULT; return 0; } -#endif +#endif /* kbd_rate */ case KDSETMODE: /* diff -urX dontdiff v2.4.5/linux/drivers/sbus/char/pcikbd.c linux/drivers/sbus/char/pcikbd.c --- v2.4.5/linux/drivers/sbus/char/pcikbd.c Wed May 16 22:31:27 2001 +++ linux/drivers/sbus/char/pcikbd.c Wed Jun 13 23:28:30 2001 @@ -378,6 +378,25 @@ send_data(KBD_CMD_ENABLE); } +int pcikbd_rate(struct kbd_repeat *rep) +{ + int old_rate_ticks = kbd_rate_ticks, + old_delay_ticks = kbd_delay_ticks; + if (rep->rate > 50) + return -EINVAL; + if (rep->rate == 0) + kbd_rate_ticks = 0; + else + kbd_rate_ticks = HZ / rep->rate; + kbd_delay_ticks = rep->delay; + if (old_rate_ticks == 0) + rep->rate = 0; + else + rep->rate = HZ / old_rate_ticks; + rep->delay=old_delay_ticks; + return 0; +} + static int __init pcikbd_wait_for_input(void) { int status, data; diff -urX dontdiff v2.4.5/linux/drivers/sbus/char/sunkbd.c linux/drivers/sbus/char/sunkbd.c --- v2.4.5/linux/drivers/sbus/char/sunkbd.c Tue Jan 23 01:30:20 2001 +++ linux/drivers/sbus/char/sunkbd.c Wed Jun 13 23:31:05 2001 @@ -1492,15 +1492,10 @@ copy_from_user(&rate, (struct kbd_rate *)arg, sizeof(struct kbd_rate)); - if (rate.rate > 50) - return -EINVAL; - if (rate.rate == 0) - kbd_rate_ticks = 0; - else - kbd_rate_ticks = HZ / rate.rate; - kbd_delay_ticks = rate.delay; - - return 0; + if (!(value = pcikbd_rate(&rate))) + copy_to_user((struct kbd_rate *)arg,&rate, + sizeof(struct kbd_rate)); + return value; } case FIONREAD: /* return number of bytes in kbd queue */ { diff -urX dontdiff v2.4.5/linux/include/asm-i386/keyboard.h linux/include/asm-i386/keyboard.h --- v2.4.5/linux/include/asm-i386/keyboard.h Sat May 26 06:02:51 2001 +++ linux/include/asm-i386/keyboard.h Tue Jun 12 17:31:51 2001 @@ -15,6 +15,7 @@ #include #include +#include #include #define KEYBOARD_IRQ 1 @@ -26,6 +27,7 @@ char raw_mode); extern char pckbd_unexpected_up(unsigned char keycode); extern void pckbd_leds(unsigned char leds); +extern int pckbd_rate(struct kbd_repeat *rep); extern void pckbd_init_hw(void); extern unsigned char pckbd_sysrq_xlate[128]; @@ -34,6 +36,7 @@ #define kbd_translate pckbd_translate #define kbd_unexpected_up pckbd_unexpected_up #define kbd_leds pckbd_leds +#define kbd_rate pckbd_rate #define kbd_init_hw pckbd_init_hw #define kbd_sysrq_xlate pckbd_sysrq_xlate diff -urX dontdiff v2.4.5/linux/include/asm-m68k/keyboard.h linux/include/asm-m68k/keyboard.h --- v2.4.5/linux/include/asm-m68k/keyboard.h Wed Dec 6 00:43:48 2000 +++ linux/include/asm-m68k/keyboard.h Tue Jun 12 17:32:09 2001 @@ -14,6 +14,7 @@ #ifdef __KERNEL__ #include +#include #include #ifdef CONFIG_Q40 @@ -56,6 +57,7 @@ #define kbd_init_hw mach_keyb_init #define kbd_translate mach_kbd_translate +#define kbd_rate mach_kbdrate #define kbd_sysrq_xlate mach_sysrq_xlate diff -urX dontdiff v2.4.5/linux/include/asm-sparc/keyboard.h linux/include/asm-sparc/keyboard.h --- v2.4.5/linux/include/asm-sparc/keyboard.h Tue Dec 21 10:05:52 1999 +++ linux/include/asm-sparc/keyboard.h Wed Jun 13 23:19:53 2001 @@ -14,6 +14,7 @@ #ifdef __KERNEL__ #include +#include #include #define KEYBOARD_IRQ 13 @@ -25,6 +26,7 @@ char raw_mode); extern char pcikbd_unexpected_up(unsigned char keycode); extern void pcikbd_leds(unsigned char leds); +extern int pcikbd_rate(struct kbd_repeat *rep); extern void pcikbd_init_hw(void); extern unsigned char pcikbd_sysrq_xlate[128]; @@ -33,6 +35,7 @@ #define kbd_translate pcikbd_translate #define kbd_unexpected_up pcikbd_unexpected_up #define kbd_leds pcikbd_leds +#define kbd_rate pcikbd_rate #define kbd_init_hw pcikbd_init_hw #define kbd_sysrq_xlate pcikbd_sysrq_xlate #define kbd_init pcikbd_init