[PATCH] Use BIOS Keyboard variable to set Numlock

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



As discussed in the thread "Linus' laptop and Num lock status", the 
numlock setting may cause some laptop keyboards to turn on the numeric key 
part, so cannot be safely enabled on those systems. Unfortunately we can't 
tell if the current system is one of these laptops nor can we read the 
numlock status from the keyboard, so we can't enable Numlock based on one of
these facts and therefore it was disabled by default on most architectures.

This is very unfortunate, since the MF-II keyboards feature a way better 
set of cursor keys, freeing the numeric keypad for numeric input. Having
to enable this each time you boot is a nuisance, especially if the 
keyboard does not feature LED to remind you.

This patch uses the IBM-PC (1981) BIOS data area to determine the initial 
state of theNumlock key. This data area holds a bitmap for the current 
keyboard status, including the numlock bit. All PC-compatible systems that 
can operate DOS or i386 expansion cards need to support this. This data 
area is not destroyed by booting linux from lilo.

Instead of the byte at 0x497 as suggested in that thread, I'm using the 
byte at 0x417, which reflects the intended LED state. In order to change 
the keyboard LED, DOS programs would change this byte and call INT 5
(which is the keyboard software interrupt).

It is yet unknown if booting from non-classic BIOS will provide this data 
area, therefore I've set it to depend on EXPERIMENTAL. The worst thing 
that should happen is a wrongly set keyboard LED.

This patch adds 48 bytes of init-text on x86_32.


Signed-Off-By: Bodo Eggert <[email protected]>


diff -X dontdiff -pruN linux-2.6.22/drivers/char/keyboard.c linux-2.6.22.changed/drivers/char/keyboard.c
--- linux-2.6.22/drivers/char/keyboard.c	2007-07-11 23:26:01.000000000 +0200
+++ linux-2.6.22.changed/drivers/char/keyboard.c	2007-07-11 23:27:39.000000000 +0200
@@ -24,6 +24,7 @@
  * 21-08-02: Converted to input API, major cleanup. (Vojtech Pavlik)
  */
 
+#include <asm/io.h>
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/tty.h>
@@ -56,7 +57,10 @@ extern void ctrl_alt_del(void);
  * to be used for numbers.
  */
 
-#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
+#ifdef CONFIG_KBD_DEFLEDS_PCBIOS
+/* KBD_DEFLEDS is a variable */
+#undef KBD_DEFLEDS
+#elif defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
 #define KBD_DEFLEDS (1 << VC_NUMLOCK)
 #else
 #define KBD_DEFLEDS 0
@@ -1352,8 +1356,17 @@ int __init kbd_init(void)
 {
 	int i;
 	int error;
+#ifdef CONFIG_KBD_DEFLEDS_PCBIOS
+	int KBD_DEFLEDS = 0;
+	/* address 0x40:0x17 */
+	char * bios_kbd_status=xlate_dev_mem_ptr(0x417);
+
+	/* Numlock status bit set? */
+	if (*bios_kbd_status & 0x20)
+		KBD_DEFLEDS = 1 << VC_NUMLOCK;
+#endif
 
-        for (i = 0; i < MAX_NR_CONSOLES; i++) {
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
 		kbd_table[i].ledflagstate = KBD_DEFLEDS;
 		kbd_table[i].default_ledflagstate = KBD_DEFLEDS;
 		kbd_table[i].ledmode = LED_SHOW_FLAGS;
diff -X dontdiff -pruN linux-2.6.22/drivers/input/keyboard/Kconfig linux-2.6.22.changed/drivers/input/keyboard/Kconfig
--- linux-2.6.22/drivers/input/keyboard/Kconfig	2007-07-11 23:26:01.000000000 +0200
+++ linux-2.6.22.changed/drivers/input/keyboard/Kconfig	2007-07-11 23:27:39.000000000 +0200
@@ -12,6 +12,17 @@ menuconfig INPUT_KEYBOARD
 
 if INPUT_KEYBOARD
 
+config KBD_DEFLEDS_PCBIOS
+	bool "Enable Num-Lock based on BIOS settings"
+	depends on X86_PC && EXPERIMENTAL
+	help
+	  Turns on Numlock depending on the BIOS settings.
+	  This works by reading the BIOS data area as defined for IBM PCs (1981).
+
+	  If you have an alternative firmware like OpenFirmware or LinuxBIOS,
+	  this flag might not be set correctly, which results in a random state
+	  of the Numlock key.
+
 config KEYBOARD_ATKBD
 	tristate "AT keyboard" if EMBEDDED || !X86_PC
 	default y
diff -X dontdiff -pruN linux-2.6.22/drivers/char/keyboard.c linux-2.6.22.changed/drivers/char/keyboard.c
--- linux-2.6.22/drivers/char/keyboard.c	2007-07-11 23:26:01.000000000 +0200
+++ linux-2.6.22.changed/drivers/char/keyboard.c	2007-07-11 23:27:39.000000000 +0200
@@ -24,6 +24,7 @@
  * 21-08-02: Converted to input API, major cleanup. (Vojtech Pavlik)
  */
 
+#include <asm/io.h>
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/tty.h>
@@ -56,7 +57,10 @@ extern void ctrl_alt_del(void);
  * to be used for numbers.
  */
 
-#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
+#ifdef CONFIG_KBD_DEFLEDS_PCBIOS
+/* KBD_DEFLEDS is a variable */
+#undef KBD_DEFLEDS
+#elif defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD))
 #define KBD_DEFLEDS (1 << VC_NUMLOCK)
 #else
 #define KBD_DEFLEDS 0
@@ -1352,8 +1356,17 @@ int __init kbd_init(void)
 {
 	int i;
 	int error;
+#ifdef CONFIG_KBD_DEFLEDS_PCBIOS
+	int KBD_DEFLEDS = 0;
+	/* address 0x40:0x17 */
+	char * bios_kbd_status=xlate_dev_mem_ptr(0x417);
+
+	/* Numlock status bit set? */
+	if (*bios_kbd_status & 0x20)
+		KBD_DEFLEDS = 1 << VC_NUMLOCK;
+#endif
 
-        for (i = 0; i < MAX_NR_CONSOLES; i++) {
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
 		kbd_table[i].ledflagstate = KBD_DEFLEDS;
 		kbd_table[i].default_ledflagstate = KBD_DEFLEDS;
 		kbd_table[i].ledmode = LED_SHOW_FLAGS;
diff -X dontdiff -pruN linux-2.6.22/drivers/input/keyboard/Kconfig linux-2.6.22.changed/drivers/input/keyboard/Kconfig
--- linux-2.6.22/drivers/input/keyboard/Kconfig	2007-07-11 23:26:01.000000000 +0200
+++ linux-2.6.22.changed/drivers/input/keyboard/Kconfig	2007-07-11 23:27:39.000000000 +0200
@@ -12,6 +12,17 @@ menuconfig INPUT_KEYBOARD
 
 if INPUT_KEYBOARD
 
+config KBD_DEFLEDS_PCBIOS
+	bool "Enable Num-Lock based on BIOS settings"
+	depends on X86_PC && EXPERIMENTAL
+	help
+	  Turns on Numlock depending on the BIOS settings.
+	  This works by reading the BIOS data area as defined for IBM PCs (1981).
+
+	  If you have an alternative firmware like OpenFirmware or LinuxBios,
+	  this flag might not be set correctly, which results in a random state
+	  of the Numlock key.
+
 config KEYBOARD_ATKBD
 	tristate "AT keyboard" if EMBEDDED || !X86_PC
 	default y

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux