Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Apr 1997 18:44:09 +0900
From:      Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
To:        hackers@freebsd.org
Cc:        yokota@zodiac.mech.utsunomiya-u.ac.jp
Subject:   alternative probe_keyboard.c (was: Re: i386/3124: BOOT_PROBE_KEYBOARD hangs system in bootblocks)
Message-ID:  <199704250944.SAA20609@zodiac.mech.utsunomiya-u.ac.jp>

next in thread | raw e-mail | index | archive | help

Regarding the PR (i386/3124) that the BOOT_PROBE_KEYBOARD option fails
to determine the presence of the keyboard and hangs the system, I just
received the following report from the originator:

nsayer>> I sent you two patches: the alternative probe_keyboard.c and the patch
nsayer>> for syscons.c. I wonder how well/badly they performed in your system.
nsayer>> I would be very interested to know.
nsayer>
nsayer>> I don't care much about the syscons.c patch. But, if the alternative
nsayer>> probe_keyboard.c is found to work better than the original, I would
nsayer>> ask other FreeBSD developers to consider to commit it to the source
nsayer>> tree.
nsayer>
nsayer>> Thank you for your cooperation.
nsayer>
nsayer>> Kazu
[...]
nsayer>I just applied the boot block patch and it completely fixed the problem.
nsayer>I did not apply the syscons patch. It did not seem necessary in my
nsayer>case.

The alternative sys/i386/boot/biosboot/probe_keyboard.c code I sent to
him worked in his system.  Would anybody kindly review and/or test the
code too? If it is found to work in more systems than the existing
code did, I would like to have it committed to the source tree. But,
this is a part of the boot block. I need thorough testing, don't I?

Replace the file with the following code, define
BOOT_PROBE_KEYBOARD=true in /etc/make.conf, and rebuild the boot
block.

Keep a backup copy of the existing boot block, the `boot' and `fixit'
floppies handy when you test the code. If my code doesn't work in your
system, you are left with unbootable system; that's too bad...

Kazu

----8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---8<---
/*-
 * $Id:$
 */

#ifdef PROBE_KEYBOARD

#include <i386/include/cpufunc.h>
#include <i386/isa/isa.h>
#include <i386/isa/ic/i8042.h>
#include <i386/isa/kbdio.h>

#include "boot.h"

#define PROBE_MAXRETRY	5
#define PROBE_MAXWAIT	500

#define IO_DUMMY	0x84

/* 7 microsec delay necessary for some keyboard controllers */
static void
delay7(void)
{
    /* 
     * I know this is broken, but no timer is avaiable yet at this stage...
     * See also comments in `delay1ms()' in `io.c'.
     */
    inb(IO_DUMMY); inb(IO_DUMMY);
    inb(IO_DUMMY); inb(IO_DUMMY);
    inb(IO_DUMMY); inb(IO_DUMMY);
}

/* 
 * Perform a simple test on the keyboard; issue the ECHO command and see
 * if the right answer is returned. We don't do anything as drastic as
 * full keyboard reset; it will be too troublesome and take too much time.
 */
int
probe_keyboard(void)
{
    int retry = PROBE_MAXRETRY;
    int wait;
    int i;

    while (--retry >= 0) {
	/* flush any noise */
	while (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL) {
	    delay7();
	    inb(IO_KBD + KBD_DATA_PORT);
	    delay1ms();
	}

	/* wait until the controller can accept a command */
	for (wait = PROBE_MAXWAIT; wait > 0; --wait) {
	    if (((i = inb(IO_KBD + KBD_STATUS_PORT)) 
                & (KBDS_INPUT_BUFFER_FULL | KBDS_ANY_BUFFER_FULL)) == 0)
		break;
	    if (i & KBDS_ANY_BUFFER_FULL) {
		delay7();
	        inb(IO_KBD + KBD_DATA_PORT);
	    }
	    delay1ms();
	}
	if (wait <= 0)
	    continue;

	/* ECHO command */
	outb(IO_KBD + KBD_DATA_PORT, KBDC_ECHO);

	/* wait for a response */
	for (wait = PROBE_MAXWAIT; wait > 0; --wait) {
	     if (inb(IO_KBD + KBD_STATUS_PORT) & KBDS_ANY_BUFFER_FULL)
		 break;
	     delay1ms();
	}
	if (wait <= 0)
	    continue;

	delay7();
	i = inb(IO_KBD + KBD_DATA_PORT);
#ifdef PROBE_KBD_BEBUG
        printf("probe_keyboard: got 0x%x.\n", i);
#endif
	if (i == KBD_ECHO) {
	    /* got the right answer */
#ifdef PROBE_KBD_BEBUG
            printf("probe_keyboard: succeeded.\n");
#endif
	    return (0);
	}
    }

#ifdef PROBE_KBD_BEBUG
    printf("probe_keyboard: failed.\n");
#endif
    return (1);
}

#endif /* PROBE_KEYBOARD */






Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199704250944.SAA20609>