linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Use BIOS Keyboard variable to set Numlock
@ 2012-02-26 20:05 Joshua C.
  0 siblings, 0 replies; 6+ messages in thread
From: Joshua C. @ 2012-02-26 20:05 UTC (permalink / raw)
  To: linux-kernel

There was a discussion back in 2007 about using a BIOS Keyboard
variable to set the Numlock state. It's available here:
http://lkml.indiana.edu/hypermail/linux/kernel/0707.1/1834.html. I
know the pros and cons that were mentioned back then and decided to
modified the porposed patch so that it provies a kernel parameter
"numlock" which allows to manually disable the NumLock state even if
it is set by the bios. In this case all users without a separeta block
can just pass the parameter in grub and won't be affected by the
change. I know that windows doesn't override the state set by the bios
and would like to see the same behavoir also in linux. Here is the
modified patch by Bodo Eggert rebased on the current kernel-3.2.7:

----------------

--- a/drivers/tty/vt/keyboard.c	2012-02-26 20:30:14.895899072 +0100
+++ b/drivers/tty/vt/keyboard.c	2012-02-26 20:29:24.359896510 +0100
@@ -24,6 +24,7 @@

 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

+#include <asm/io.h>
 #include <linux/consolemap.h>
 #include <linux/module.h>
 #include <linux/sched.h>
@@ -59,7 +60,13 @@
  * 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
+	static int numlock = 1;
+	MODULE_PARM_DESC(numlock, "Toggle Numlock (1 = enable, 0 = disable)");
+	module_param_named(numlock, numlock, int, 0400);
+#elif defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) ||
defined(CONFIG_KEYBOARD_HIL_OLD))
 #define KBD_DEFLEDS (1 << VC_NUMLOCK)
 #else
 #define KBD_DEFLEDS 0
@@ -1432,7 +1439,17 @@
 {
 	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) && numlock)
+	KBD_DEFLEDS = 1 << VC_NUMLOCK;
+#endif
+	
         for (i = 0; i < MAX_NR_CONSOLES; i++) {
 		kbd_table[i].ledflagstate = KBD_DEFLEDS;
 		kbd_table[i].default_ledflagstate = KBD_DEFLEDS;
--- a/drivers/input/keyboard/Kconfig	2012-02-26 20:35:38.941915542 +0100
+++ b/drivers/input/keyboard/Kconfig	2012-02-26 20:38:40.890924803 +0100
@@ -84,6 +84,20 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called atkbd.

+config KBD_DEFLEDS_PCBIOS
+	bool "Enable Num-Lock based on BIOS settings"
+	depends on KEYBOARD_ATKBD && X86
+	default y
+	help
+	  Turns on Numlock depending on the BIOS settings.
+	  This works by reading the BIOS data area as defined for IBM PCs (1981).
+	  You can also controll the NumLock state with the kernel parameter
+	  numlock (1 = enable, 0 = disable).
+
+	  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_HP_KEYCODES
 	bool "Use HP keyboard scancodes"
 	depends on PARISC && KEYBOARD_ATKBD

------

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Use BIOS Keyboard variable to set Numlock
  2007-07-12  2:10     ` H. Peter Anvin
@ 2007-07-13 18:25       ` Bodo Eggert
  0 siblings, 0 replies; 6+ messages in thread
From: Bodo Eggert @ 2007-07-13 18:25 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: Bodo Eggert, Linux Kernel Mailing List, Linus Torvalds

On Wed, 11 Jul 2007, H. Peter Anvin wrote:
> Bodo Eggert wrote:

> >> That being said, one could argue that since this is a BIOS interface it
> >> should be queried via INT 16h, AH=02h and stuffed in the zeropage
> >> structure.  This would also solve the issue of it not being supported by
> >> non-BIOS firmware.
> > 
> > This is an interesting option, but it's more invasive. I'd rather like a 
> > feedback saying we can depend on that data area to be there.
> 
> I don't think we can.  You might find garbage there.

I asked you not to say that ...


Can somebody using LinuxBIOS or OpenFirmware please do

dd if=/dev/mem bs=1 count=1 skip=$((0x417)) | hexdump
 - and -
dd if=/dev/mem bs=1 count=14 skip=$((0x400)) | hexdump

You should get
 - one byte for the keyboard status, 0x20 == Numlock

 - seven words for the legacy serial and parallel ports, port address only
   (e.g. 03f8 02f8 0000 0000 0378 0000 0000)

-- 
C program run. C program crash. C programmer quit. 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Use BIOS Keyboard variable to set Numlock
  2007-07-12  1:41   ` Bodo Eggert
@ 2007-07-12  2:10     ` H. Peter Anvin
  2007-07-13 18:25       ` Bodo Eggert
  0 siblings, 1 reply; 6+ messages in thread
From: H. Peter Anvin @ 2007-07-12  2:10 UTC (permalink / raw)
  To: Bodo Eggert; +Cc: Linux Kernel Mailing List, Linus Torvalds

Bodo Eggert wrote:
> 
>> That being said, one could argue that since this is a BIOS interface it
>> should be queried via INT 16h, AH=02h and stuffed in the zeropage
>> structure.  This would also solve the issue of it not being supported by
>> non-BIOS firmware.
> 
> This is an interesting option, but it's more invasive. I'd rather like a 
> feedback saying we can depend on that data area to be there.

I don't think we can.  You might find garbage there.

	-hpa

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Use BIOS Keyboard variable to set Numlock
  2007-07-12  0:58 ` H. Peter Anvin
@ 2007-07-12  1:41   ` Bodo Eggert
  2007-07-12  2:10     ` H. Peter Anvin
  0 siblings, 1 reply; 6+ messages in thread
From: Bodo Eggert @ 2007-07-12  1:41 UTC (permalink / raw)
  To: H. Peter Anvin; +Cc: Bodo Eggert, Linux Kernel Mailing List, Linus Torvalds

On Wed, 11 Jul 2007, H. Peter Anvin wrote:
> Bodo Eggert wrote:

> > 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).
> > 
> 
> 0x417 is actually the current keyboard modifier state, which is the
> right thing to use.

exactly.

> Presumably you meant INT 9 (IRQ 1), not INT 5 which is the print screen
> interrupt (also used by the CPU for BOUND error, which has some amusing
> consequence if anyone ever used the BOUND instruction in DOS.)

I meant int 0x16:
   mem[0x40:0x17] |= 0x20;
   ah = 1;
   int 0x16;

> That being said, one could argue that since this is a BIOS interface it
> should be queried via INT 16h, AH=02h and stuffed in the zeropage
> structure.  This would also solve the issue of it not being supported by
> non-BIOS firmware.

This is an interesting option, but it's more invasive. I'd rather like a 
feedback saying we can depend on that data area to be there.
-- 
Top 100 things you don't want the sysadmin to say:
64. Do you really need your home directory to do any work?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] Use BIOS Keyboard variable to set Numlock
  2007-07-11 22:13 Bodo Eggert
@ 2007-07-12  0:58 ` H. Peter Anvin
  2007-07-12  1:41   ` Bodo Eggert
  0 siblings, 1 reply; 6+ messages in thread
From: H. Peter Anvin @ 2007-07-12  0:58 UTC (permalink / raw)
  To: Bodo Eggert; +Cc: Linux Kernel Mailing List, Linus Torvalds

Bodo Eggert wrote:
> 
> 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).
> 

0x417 is actually the current keyboard modifier state, which is the
right thing to use.

Presumably you meant INT 9 (IRQ 1), not INT 5 which is the print screen
interrupt (also used by the CPU for BOUND error, which has some amusing
consequence if anyone ever used the BOUND instruction in DOS.)

That being said, one could argue that since this is a BIOS interface it
should be queried via INT 16h, AH=02h and stuffed in the zeropage
structure.  This would also solve the issue of it not being supported by
non-BIOS firmware.

	-hpa

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH] Use BIOS Keyboard variable to set Numlock
@ 2007-07-11 22:13 Bodo Eggert
  2007-07-12  0:58 ` H. Peter Anvin
  0 siblings, 1 reply; 6+ messages in thread
From: Bodo Eggert @ 2007-07-11 22:13 UTC (permalink / raw)
  To: Linux Kernel Mailing List; +Cc: Linus Torvalds, 7eggert

[-- Attachment #1: Type: TEXT/PLAIN, Size: 3923 bytes --]

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 <7eggert@gmx.de>


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

[-- Attachment #2: Type: TEXT/PLAIN, Size: 2376 bytes --]

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-02-26 20:05 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-26 20:05 [PATCH] Use BIOS Keyboard variable to set Numlock Joshua C.
  -- strict thread matches above, loose matches on Subject: below --
2007-07-11 22:13 Bodo Eggert
2007-07-12  0:58 ` H. Peter Anvin
2007-07-12  1:41   ` Bodo Eggert
2007-07-12  2:10     ` H. Peter Anvin
2007-07-13 18:25       ` Bodo Eggert

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).