Subject: port-i386/2799: pms.c probe fails on some IBM keyboard controllers
To: None <gnats-bugs@gnats.netbsd.org>
From: Keith Moore <moore@envy.cs.utk.edu>
List: netbsd-bugs
Date: 10/03/1996 00:24:48
>Number:         2799
>Category:       port-i386
>Synopsis:       pms.c probe fails on some IBM keyboard controllers
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Oct  2 21:20:02 1996
>Last-Modified:
>Originator:     Keith Moore
>Organization:
	University of Tennessee
>Release:        1.1
>Environment:
thinkpad 750 (i386), netbsd 1.1 and 1.2, 
System: NetBSD envy.cs.utk.edu 1.2 NetBSD 1.2 (TP750) #1: Sat Sep 21 04:22:38 EDT 1996 moore@envy.cs.utk.edu:/space/usr/moore/space/netbsd-compile/usr/src/sys/arch/i386/compile/TP750 i386


>Description:
	the probe routine in pms.c fails on IBM ThinkPad 750 computers.
	according to the _IBM Personal System/2 Hardware Interface
	Technical Reference - Common Interfaces_ manual,
	the "auxiliary device interface test" function used by the 
	probe code is not present on "Type 2" keyboard controllers.
	apparently the ThinkPad has one of those controllers.

>How-To-Repeat:
	Boot a netbsd 1.1 or 1.2 kernel on a thinkpad 750,
	(after first fixing the boot code to support the bios
	return value for 2.88 Mb disks), or presumably any
	other IBM machine with a Type 2 keyboard controller.
	(Make sure the pms driver is configured in the kernel.)
	Watch the autoconfigure output go by and note that
	the pms device was not found.

>Fix:
	This works for me:

int
pmsprobe(parent, match, aux)
        struct device *parent;
        void *match, *aux;
{
        struct cfdata *cf = match;
        u_char x;

        /*
         * We only attach to the keyboard controller via
         * the console drivers. (We really wish we could be the
         * child of a real keyboard controller driver.)
         */
        if ((parent == NULL) ||
           ((strcmp(parent->dv_cfdata->cf_driver->cd_name, "pc") != 0) &&
            (strcmp(parent->dv_cfdata->cf_driver->cd_name, "vt") != 0)))
                return (0);

        /* Can't wildcard IRQ. */
        if (cf->cf_loc[0] == -1)
                return (0);

#if 0
        pms_dev_cmd(PMS_RESET);
        pms_aux_cmd(PMS_AUX_TEST);
        delay(1000);
        x = inb(PMS_DATA);
        pms_pit_cmd(PMS_INT_DISABLE);
        if (x & 0x04)
                return 0;
#else
        /* 
         * PS/2 type 2 keyboard controllers do not support the 
         * auxiliary device test command (PMS_AUX_TEST), so
         * the old probe fails for these devices.
         * Instead, try toggling the 'system flag' in the
         * controller status register.  According to 
         * IBM Personal System/2 Hardware Technical Reference --
         * Common Interfaces, this should work for both type 1
         * and type 2 controllers.
         */
#define PMS_READ_CONTROLLER_RAM 0x20
#define PMS_CONTROLLER_SYSTEM_FLAG 0x04

        pms_dev_cmd(PMS_RESET);
        pms_pit_cmd(PMS_CONTROLLER_SYSTEM_FLAG);
        pms_aux_cmd(PMS_READ_CONTROLLER_RAM);
        x = inb (PMS_DATA);
        if ((x & PMS_CONTROLLER_SYSTEM_FLAG) == 0) {
                /* printf ("pms: probefail 1\n"); */
		return 0;
	}
        pms_pit_cmd(0);
        pms_aux_cmd(PMS_READ_CONTROLLER_RAM);
        x = inb (PMS_DATA);
        if (x & PMS_CONTROLLER_SYSTEM_FLAG) {
                /* printf ("pms: probefail 2\n"); */
		return 0;
	}
        pms_pit_cmd(PMS_INT_DISABLE);
        /* printf ("pms: probeok\n"); */
#endif
        return 1;
}

>Audit-Trail:
>Unformatted: