Andrew Benton wrote:
> Hello Everyone,
> 
> I have a boot script which sets the numlock key so I can use the number
> keypad on the end of my keyboard without thinking about having to press
> the numlock key. I think I got the code from the setleds man page and
> it goes like this:
> 
> for tty in /dev/tty{1..6}
> do setleds -D +num < ${tty}
> done
> 
> It runs in init 3, at the console. I've had it for years, it's always
> run fine without causing me any problems, until recently. With the 3.4
> kernel (currently 3.4-rc4) I get an error message printed on the screen
> 6 times:
> KDSKBLED: Invalid argument
> and then a big red error message 'cos the bootscript failed as setleds
> exited with a non zero return value of 1. Oddly, despite
> this, setleds works, it sets the numlock key :/ so I can work around
> the error messages by adding a little to the script:
> 
> for tty in /dev/tty{1..6}
> do setleds -D +num < ${tty} &> /dev/null || true
> done

Sometimes the numlock can be jsut set in the bios.  I wouldn't think the kernel 
would reset that.

> Which works, does the job, sets the numlock and doesn't complain.
> However, I'd rather get to the bottom of it and fix it properly rather
> than muffle the error message. Does anyone know what has changed in the
> 3.4 kernel that is causing this? setleds comes from kbd-1.15.2. I've
> also tried kbd-1.15.3 and current git with the same results. Digging in
> the kernel, it seems that this commit is the culprit:
> 
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blobdiff;f=drivers/tty/vt/keyboard.c;h=70d0593d3bc66331f942632130c7ddd802a65fbb;hp=898e359c54240dfa10a9c3c0dfbea5dde77f6cf3;hb=079c9534a96da9a85a2a2f9715851050fbfbf749;hpb=0fb8379dab9f97e4c56de8f9ea772c10eda27561
> 
> Specifically this bit:
> 
> +int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm)
> +{
> +       struct kbd_struct * kbd = kbd_table + console;
> +        unsigned long flags;
> +       unsigned char ucval;
> +
> +        switch(cmd) {
> +       /* the ioctls below read/set the flags usually shown in the leds */
> +       /* don't use them - they will go away without warning */
> +       case KDGKBLED:
> +                spin_lock_irqsave(&kbd_event_lock, flags);
> +               ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
> +                spin_unlock_irqrestore(&kbd_event_lock, flags);
> +               return put_user(ucval, (char __user *)arg);
> +
> +       case KDSKBLED:
> +               if (!perm)
> +                       return -EPERM;
> +               if (arg & ~0x77)
> +                       return -EINVAL;
> +                spin_lock_irqsave(&kbd_event_lock, flags);
> +               kbd->ledflagstate = (arg & 7);
> +               kbd->default_ledflagstate = ((arg >> 4) & 7);
> +               set_leds();
> +                spin_unlock_irqrestore(&kbd_event_lock, flags);
> +               break;       // <<<<<  change to return 0;
> +
> +       /* the ioctls below only set the lights, not the functions */
> +       /* for those, see KDGKBLED and KDSKBLED above */
> +       case KDGETLED:
> +               ucval = getledstate();
> +               return put_user(ucval, (char __user *)arg);
> +
> +       case KDSETLED:
> +               if (!perm)
> +                       return -EPERM;
> +               setledstate(kbd, arg);
> +               return 0;
> +        }
> +        return -ENOIOCTLCMD;
> +}

It looks like an error in the code.  The only case that doesn't return is
KDSKBLED.  The break then goes to return -ENOIOCTLCMD which doesn't seem right.
Try changing the break to return 0;

   -- Bruce
-- 
http://linuxfromscratch.org/mailman/listinfo/blfs-support
FAQ: http://www.linuxfromscratch.org/blfs/faq.html
Unsubscribe: See the above information page

Reply via email to