linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* About KDKBDREP
@ 2001-06-14 19:19 Sergey Tursanov
  0 siblings, 0 replies; only message in thread
From: Sergey Tursanov @ 2001-06-14 19:19 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 868 bytes --]

Some days ago I posted patch to introduce KDKBDREP ioctl
to i386 keyboard routines. KDKBDREP is defined in linux/kd.h
but now he is used only on m68k. In sparc architectures is used
KIOCSRATE, on i386 -- user-space utility kbdrate and I know
nothing about others. It seems to be better to use one ioctl on
all of archs because:
- it unifies keyboard rate setting;
- it will be done in kernel context avoiding cases of simultaneous
access same I/O ports by different programs. (see A.Cox msg).
In previous patch I had tried to change i386 kbd files in order
to inmplement KDKBDREP. Now I changed sparc files in such a fashion.
But I haven't sparc box and cannot test my changes so I'll be
very glad if someone test my patch. Thanks advance.

PS: please CC replies to my email because I'm not subscribed
on linux-kernel.

-- 
Sergey Tursanov         mailto:__gsr@mail.ru

[-- Attachment #2: patch-kbdrate-2.4.5 --]
[-- Type: application/octet-stream, Size: 7263 bytes --]

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 <asm/io.h>
 #include <asm/uaccess.h>
-
-#if defined(__mc68000__) || defined(CONFIG_APUS)
-#include <asm/machdep.h>
-#endif
+#include <asm/keyboard.h>
 
 #include <linux/kbd_kern.h>
 #include <linux/vt_kern.h>
@@ -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 <linux/kernel.h>
 #include <linux/ioport.h>
+#include <linux/kd.h>
 #include <asm/io.h>
 
 #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 <linux/config.h>
+#include <linux/kd.h>
 #include <asm/machdep.h>
 
 #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 <linux/ioport.h>
+#include <linux/kd.h>
 #include <asm/io.h>
 
 #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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2001-06-14 18:29 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-06-14 19:19 About KDKBDREP Sergey Tursanov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).