From: Alexey Gladkov <gladkov.alexey@gmail.com>
To: Petr Tesarik <ptesarik@suse.cz>
Cc: Jiri Kosina <jkosina@suse.cz>,
"Kirill A. Shutemov" <kirill@shutemov.name>,
Joshua Cov <joshuacov@googlemail.com>,
kbd@lists.altlinux.org
Subject: Re: [kbd] [PATCH v2] setleds: add option to reset state to the BIOS default
Date: Fri, 03 Aug 2012 00:36:31 +0400 [thread overview]
Message-ID: <501AE4CF.90902@gmail.com> (raw)
In-Reply-To: <201207270909.07319.ptesarik@suse.cz>
On 27.07.2012 11:09, Petr Tesarik wrote:
> Hello folks,
>
> please consider the following patch for kbd.
>
> As you probably know, the Linux kernel resets the LED states to all off on
> boot. However, many users would like to keep the BIOS NumLock setting, and
> others get confused after they press one of the lock keys in the boot loader
> and it gets reset again when Linux initializes the terminal.
>
> Because of that, many distros have used various ways to "improve" user
> experience: setting NumLock on by default, making OS-specific configuration
> options, or reading the BIOS area. The last option seems best to me, because
> it usually also preserves whatever you did in the boot loader. Unfortunately,
> there's no simple utility to read the state, so distros sometimes do insane
> things to get it (e.g. run hwinfo and grep only for the LED states and then
> run setleds with the appropriate arguments). Obviously, this approach isn't
> exactly fast...
>
> Since setleds must be always used in the end, the most efficient solution is
> to add an option that resets the LED states to what they were before the Linux
> kernel booted.
>
> Signed-off-by: Petr Tesarik <ptesarik@suse.cz>
It looks like what you propose has already been discussed several years ago:
http://article.gmane.org/gmane.linux.kernel/493362
I also found that some code is already in the kernel:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commitdiff;h=b2d0b7a061bfddd27155c7dcd53f365d9dc0c7c3
As far as I could learn, it is possible to query the LEDs on the USB keyboard,
but for PS/2 this is not possible.
> ---
> src/setleds.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 files changed, 58 insertions(+), 3 deletions(-)
>
> diff --git a/src/setleds.c b/src/setleds.c
> index 3577aee..3defdea 100644
> --- a/src/setleds.c
> +++ b/src/setleds.c
> @@ -11,18 +11,29 @@
> #include <fcntl.h>
> #include <linux/kd.h>
> #include <sys/ioctl.h>
> +#include <sys/mman.h>
> +#include <unistd.h>
> #include "nls.h"
> #include "version.h"
>
> +#if defined(__i386__) || defined(__x86_64__)
> +# define HAVE_BIOS 1
> +# define BIOS_KBD_ADDR 0x497
> +# define BIOS_LED_SCR 0x01
> +# define BIOS_LED_NUM 0x02
> +# define BIOS_LED_CAP 0x04
> +#endif
> +
> static void attr_noreturn
> usage(void)
> {
> fprintf(stderr, _(
> "Usage:\n"
> -" setleds [-v] [-L] [-D] [-F] [[+|-][ num | caps | scroll %s]]\n"
> +" setleds [-v] [-L] [-D] [-F] [[+|-][ num | caps | scroll %s]%s]\n"
> "Thus,\n"
> " setleds +caps -num\n"
> "will set CapsLock, clear NumLock and leave ScrollLock unchanged.\n"
> +"%s"
> "The settings before and after the change (if any) are reported\n"
> "when the -v option is given or when no change is requested.\n"
> "Normally, setleds influences the vt flag settings\n"
> @@ -32,9 +43,15 @@ usage(void)
> "that a subsequent reset will not change the flags.\n"
> ),
> #ifdef __sparc__
> - "| compose "
> + "| compose ",
> +#else
> + "",
> +#endif
> +#ifdef HAVE_BIOS
> + " | bios ",
> +"Specify \"bios\" to reset state to the BIOS default.\n"
> #else
> - ""
> + "", ""
> #endif
> );
> exit(1);
> @@ -152,6 +169,37 @@ sunsetleds(arg_state char *cur_leds) {
> #endif
> }
>
> +#ifdef HAVE_BIOS
> +static void
> +biosgetleds(char *cur_leds) {
> + int memfd;
> + long pagesz, mapoff;
> + char *map, bios_state;
> +
> + memfd = open("/dev/mem", O_RDONLY);
> + if (memfd < 0) {
> + perror("/dev/mem");
> + fprintf(stderr, _("Error opening /dev/mem.\n"));
> + exit(1);
> + }
> + pagesz = sysconf(_SC_PAGESIZE);
> + mapoff = BIOS_KBD_ADDR & ~(pagesz-1);
> + map = mmap(NULL, pagesz, PROT_READ, MAP_SHARED, memfd, mapoff);
> + if (map == MAP_FAILED) {
> + perror("/dev/mem");
> + fprintf(stderr, _("Error mapping /dev/mem.\n"));
> + exit(1);
> + }
> + bios_state = map[BIOS_KBD_ADDR - mapoff];
> + *cur_leds =
> + (bios_state & BIOS_LED_SCR ? LED_SCR : 0) |
> + (bios_state & BIOS_LED_NUM ? LED_NUM : 0) |
> + (bios_state & BIOS_LED_CAP ? LED_CAP : 0);
> + munmap(map, pagesz);
> + close(memfd);
> +}
> +#endif /* HAVE_BIOS */
> +
> int
> main(int argc, char **argv) {
> int optL = 0, optD = 0, optF = 0, verbose = 0;
> @@ -241,6 +289,13 @@ main(int argc, char **argv) {
>
> while(--argc) {
> ap = *++argv;
> +#ifdef HAVE_BIOS
> + if (!strcmp(ap, "bios")) {
> + biosgetleds(&nval);
> + ndef = LED_NUM | LED_CAP | LED_SCR;
> + goto nxtarg;
> + }
> +#endif
> sign = 1; /* by default: set */
> if(*ap == '+')
> ap++;
>
--
Rgrds, legion
prev parent reply other threads:[~2012-08-02 20:36 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-27 7:09 [kbd] [PATCH v2] setleds: add option to reset state to the BIOS default Petr Tesarik
2012-07-29 21:10 ` Alexey Gladkov
2012-07-30 17:27 ` Petr Tesarik
2012-08-02 20:36 ` Alexey Gladkov [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=501AE4CF.90902@gmail.com \
--to=gladkov.alexey@gmail.com \
--cc=jkosina@suse.cz \
--cc=joshuacov@googlemail.com \
--cc=kbd@lists.altlinux.org \
--cc=kirill@shutemov.name \
--cc=ptesarik@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.