All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.