Re: How to read a timestamp in kernel driver code?

From: Mike A. Harris (mharris@meteng.on.ca)
Date: Sat Feb 26 2000 - 02:05:39 EST


On Fri, 25 Feb 2000, Riley Williams wrote:

> > Correct. All I need to know is how many "X" units of time have
> > expired between keycode Y's down event, and it's up event. The
> > time units are irrelevant - microseconds, nanoseconds, jiffies,
> > whatever ... and todays date is certainly not important. ;o)
>
>Reading through your description of what it's for, what you actually
>need is a simple go/no-go test that says "did these two codes arrive
>too fast?" with the definition of "too fast" being the problem.

No real problem. I put code to print the current "jiffies" count
upon SYSRQ make or break. When I press SYSRQ, it prints the
exact same time for both events. I figured I could just time how
long it really takes and get an idea of what an appropriate
"threshold" value would be. Unfortunately it didn't work. The
values were indeed the same. I pressed it several times to see
if anything changed. Sure enough, the odd press generated a
jiffie count for the break event that was +1 from the make event.

This tells me two things:

1) My code is correct for measuring the time.
2) The jiffy counter is not fast enough for my needs.

So, I need an existing in kernel counter that is a bit
faster. Jiffies are 1/100 of a second on x86 if I'm correct, so
that would be 10ms per jiffy. The keyboard appears to send the
two codes faster than that, and I'm guessing not much faster, but
a higher resolution would be needed to catch things properly.

Is there another counter in kernel with higher res? Please let
me know. I'm going to go snoop around for one right now...

Here is my current code:

#ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
        if(sysrq_debugmode) {
            printk(KERN_DEBUG "keyboard.c: keycode=%x up_flag=%4x " \
                   "sysrq_pressed=%d\n", keycode, up_flag, sysrq_pressed);
        }

        if (keycode == SYSRQ_KEY) {
                sysrq_debugmode++; /* Increment debug counter */
                sysrq_debugmode &= 3; /* Keep counter in range 0 - 3 */

                if(sysrq_pressed) {
                    printk(KERN_DEBUG "keyboard.c: SYSRQ break - jiffies=%ld\n", jiffies);
                }
                else {
                    printk(KERN_DEBUG "keyboard.c: SYSRQ make - jiffies=%ld\n", jiffies);
                }

                if(sysrq_debugmode == 1) {
                    printk(KERN_DEBUG "keyboard.c: sysrq_debugmode enabled\n");
                    printk(KERN_DEBUG "keyboard.c: keycode=%x up_flag=%4x " \
                           "sysrq_pressed=%d\n", keycode, up_flag, \
                           sysrq_pressed);
                }
                else if (!sysrq_debugmode) {
                    printk(KERN_DEBUG "keyboard.c: sysrq_debugmode disabled\n");
                }

                sysrq_pressed = !up_flag;
                return;
        } else if (sysrq_pressed) {
                if (!up_flag && sysrq_enabled)
                        handle_sysrq(kbd_sysrq_xlate[keycode], kbd_pt_regs, kbd, tty);
                return;
        }
#endif

> > I figured if I had the keyboard driver detect the broken
> > keyboard and only use my special SYSRQ code when a broken
> > keyboard is there, otherwise make SYSRQ work the same as it
> > always did, that my patch would have a better chance of getting
> > in.
>
>Have you ever heard of "sticky keys" ? If not, it's a standard
>accessibility tweak for computers under several operating systems
>(originally under Windows 2.0 and available under all later versions
>thereof) that enables disabled people with limited finger control to
>use a keyboard, and it's also used by people with no hand control at
>all, including those who have had both hands amputated.

Yes, I'm familiar with the sticky keys concept, but I have no use
for it.

>I suspect this is the tweak you refer to, and if so, and you can
>extend it to provide a full "sticky keys" implementation as standard
>in the kernel, then I for one would have no problem endorsing it in
>that disguise. I know several people with suchlike disabilities who
>would be willing to use Linux were it not for their disability.

No, thats not what its for. ;o)

What it is for is this: My keyboard sends SYSRQ make and break
simultaneously, thus SYSRQ doesn't work on my machine with the
existing SYSRQ keyboard code. The existing SYSRQ code sets
sysrq_enabled when the make code is captured, and clears
sysrq_enabled when the break code is captured. My patch changes
this so that the make code enables sysrq_enabled, but the break
code is completely ignored. Instead, the ALT key's break code is
used to clear sysrq_enabled.

The idea is that ALT *HAS* to be pressed down anyways in order
for either SYSRQ make or break to be received, so we can use the
ALT break code to get out of SYSRQ mode.

The solution works and works well, HOWEVER, it changes the way
that SYSRQ works from what people are used to. SYSRQ normally
works where you press ALT, hold it, press SYSRQ, hold it, and
then press the final key, then let go of everything. With my
patch, you press ALT, hold it, press SYSRQ, and can hold it or
let go, and then press the final key. You do not need to
continue to hold the SYSRQ key down.

Since this changes the behaviour of the SYSRQ key combo, I
figured that if I submitted the patch it would be rejected
because it changes the behaviour that everyone is used to, just
so that SYSRQ works on a foobar keyboard that maybe 1 in 500
developers have. So... I figured if I could have the patch
detect if a broken keyboard was being used (by timing the time it
takes in between make and break on SYSRQ), then it could have the
existing behaviour on normal keyboards, and yet still work on my
foobar keyboard - but without having to hold down SYSRQ because
holding it down on my keyboard doesn't matter anyways.

To do this, I need to time the thing, and it is less than a
single jiffie for sure. So I need a new counter to use.

> > So, as you can see, this is a SIMPLE problem, and I do not need
> > RTC, or dedicated PCI hardware timer cards for it. ;o)
>
>Very true.

Well I hope the kernel has a finer res counter that doesn't
require something like RTC, because otherwise I don't think it is
feasible - in which case I'll just submit my existing workign
sysrq patch. The other idea I had was to have
/proc/sys/kernel/sysrq use the existing code if you echo 1 into
there to turn it on, or to use my code if you echo 2 in there. I
asked someone for help on how to do this, but didn't get an
answer. I have no idea how to use the proc stuff. Would I just
check the global variable that is set? Or does the code that
acts upon that clean up the value first?

> > I'm very new to kernel code, and unfamiliar with most of it.
> > I'm certainly trying to learn though, - by trial and error.
> > The code is my book. ;o)
>
>That's the best way in my experience.

Yep. ;o)

-- 
Mike A. Harris                                     Linux advocate     
Computer Consultant                                  GNU advocate  
Capslock Consulting                          Open Source advocate

Suspicious Anagram #4: Word: PRESIDENT CLINTON OF THE USA Anagram: TO COPULATE HE FINDS INTERNS

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Tue Feb 29 2000 - 21:00:15 EST