Linux console tools development discussion
 help / color / mirror / Atom feed
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
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



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

Linux console tools development discussion

This inbox may be cloned and mirrored by anyone:

	git clone --mirror http://lore.altlinux.org/kbd/0 kbd/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 kbd kbd/ http://lore.altlinux.org/kbd \
		kbd@lists.altlinux.org kbd@lists.altlinux.ru kbd@lists.altlinux.com
	public-inbox-index kbd

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://lore.altlinux.org/org.altlinux.lists.kbd


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git