Beispiel #1
0
int
test_aux_port(KBDC p)
{
    int retry = KBD_MAXRETRY;
    int again = KBD_MAXWAIT;
    int c = -1;

    while (retry-- > 0) {
        empty_both_buffers(p, 10);
        if (write_controller_command(p, KBDC_TEST_AUX_PORT))
    	    break;
    }
    if (retry < 0)
        return FALSE;

    emptyq(&kbdcp(p)->kbd);
    while (again-- > 0) {
        c = read_controller_data(p);
        if (c != -1) 	/* try again if the controller is not ready */
    	    break;
    }
    if (verbose || bootverbose)
        log(LOG_DEBUG, "kbdc: TEST_AUX_PORT status:%04x\n", c);
    return c;
}
Beispiel #2
0
/* write a one byte auxiliary device command */
int
write_aux_command(KBDC p, int c)
{
    if (!write_controller_command(p, KBDC_WRITE_TO_AUX))
	return FALSE;
    return write_controller_data(p, c);
}
Beispiel #3
0
int
test_controller(KBDC p)
{
    int retry = KBD_MAXRETRY;
    int again = KBD_MAXWAIT;
    int c = KBD_DIAG_FAIL;

    while (retry-- > 0) {
        empty_both_buffers(p, 10);
        if (write_controller_command(p, KBDC_DIAGNOSE))
    	    break;
    }
    if (retry < 0)
        return FALSE;

    emptyq(&kbdcp(p)->kbd);
    while (again-- > 0) {
        /* wait awhile */
        DELAY(KBD_RESETDELAY*1000);
        c = read_controller_data(p);	/* DIAG_DONE/DIAG_FAIL */
        if (c != -1) 	/* wait again if the controller is not ready */
    	    break;
    }
    if (verbose || bootverbose)
        log(LOG_DEBUG, "kbdc: DIAGNOSE status:%04x\n", c);
    return (c == KBD_DIAG_DONE);
}
Beispiel #4
0
static
int
atkbd_setmuxmode(KBDC kbdc, int enable, int *mux_version)
{
	int param;
	int val;
	int i;

	kbdc->mux_active = 0;
	empty_both_buffers(kbdc, 100);
	val = 0xf0;
	if ((param = write_controller_w1r1(kbdc, KBDC_AUX_LOOP, val)) != val) {
		kprintf("setmuxmode: fail1\n");
		return(-1);
	}
	val = enable ? 0x56 : 0xf6;
	if ((param = write_controller_w1r1(kbdc, KBDC_AUX_LOOP, val)) != val) {
		kprintf("setmuxmode: fail2\n");
		return(-1);
	}
	val = enable ? 0xa4 : 0xa5;
	if ((param = write_controller_w1r1(kbdc, KBDC_AUX_LOOP, val)) != val) {
		kprintf("setmuxmode: fail3\n");
		return(-1);
	}
	kprintf("mux version %02x\n", param);
	if (param == 0xac) {
		kprintf("setmuxmode: fail4\n");
		return(-1);
	}

	if (enable) {
		for (i = 0; i < KBD_NUM_MUX_PORTS; ++i) {
			write_controller_command(kbdc, KBDC_MUX_PFX + i);
			write_controller_command(kbdc, KBDC_ENABLE_AUX_PORT);

		}
	}
	kbdc->mux_active = 1;
	if (mux_version)
		*mux_version = param;
	return 0;
}
Beispiel #5
0
int
get_controller_command_byte(KBDC p)
{
    if (kbdcp(p)->command_byte != -1)
	return kbdcp(p)->command_byte;
    if (!write_controller_command(p, KBDC_GET_COMMAND_BYTE))
	return -1;
    emptyq(&kbdcp(p)->kbd);
    kbdcp(p)->command_byte = read_controller_data(p);
    return kbdcp(p)->command_byte;
}
Beispiel #6
0
int
set_controller_command_byte(KBDC p, int mask, int command)
{
    if (get_controller_command_byte(p) == -1)
	return FALSE;

    command = (kbdcp(p)->command_byte & ~mask) | (command & mask);
    if (command & KBD_DISABLE_KBD_PORT) {
	if (!write_controller_command(p, KBDC_DISABLE_KBD_PORT))
	    return FALSE;
    }
    if (!write_controller_command(p, KBDC_SET_COMMAND_BYTE))
	return FALSE;
    if (!write_controller_data(p, command))
	return FALSE;
    kbdcp(p)->command_byte = command;

    if (verbose)
        log(LOG_DEBUG, "kbdc: new command byte:%04x (set_controller...)\n",
	    command);

    return TRUE;
}
Beispiel #7
0
static int
init_keyboard(KBDC kbdc, int *type, int flags)
{
    int codeset;
    int id;
    int c;

    if (!kbdc_lock(kbdc, TRUE)) {
        /* driver error? */
        return EIO;
    }

    /* temporarily block data transmission from the keyboard */
    write_controller_command(kbdc, KBDC_DISABLE_KBD_PORT);

    /* save the current controller command byte */
    empty_both_buffers(kbdc, 200);
    c = get_controller_command_byte(kbdc);
    if (c == -1) {
        /* CONTROLLER ERROR */
        kbdc_lock(kbdc, FALSE);
        printf("atkbd: unable to get the current command byte value.\n");
        return EIO;
    }
    if (bootverbose)
        printf("atkbd: the current kbd controller command byte %04x\n",
               c);
#if 0
    /* override the keyboard lock switch */
    c |= KBD_OVERRIDE_KBD_LOCK;
#endif

    /* enable the keyboard port, but disable the keyboard intr. */
    if (setup_kbd_port(kbdc, TRUE, FALSE)) {
        /* CONTROLLER ERROR: there is very little we can do... */
        printf("atkbd: unable to set the command byte.\n");
        kbdc_lock(kbdc, FALSE);
        return EIO;
    }

    /*
     * Check if we have an XT keyboard before we attempt to reset it.
     * The procedure assumes that the keyboard and the controller have
     * been set up properly by BIOS and have not been messed up
     * during the boot process.
     */
    codeset = -1;
    if (flags & KB_CONF_ALT_SCANCODESET)
        /* the user says there is a XT keyboard */
        codeset = 1;
#ifdef KBD_DETECT_XT_KEYBOARD
    else if ((c & KBD_TRANSLATION) == 0) {
        /* SET_SCANCODE_SET is not always supported; ignore error */
        if (send_kbd_command_and_data(kbdc, KBDC_SET_SCANCODE_SET, 0)
                == KBD_ACK)
            codeset = read_kbd_data(kbdc);
    }
    if (bootverbose)
        printf("atkbd: scancode set %d\n", codeset);
#endif /* KBD_DETECT_XT_KEYBOARD */

    *type = KB_OTHER;
    id = get_kbd_id(kbdc);
    switch(id) {
    case 0x41ab:	/* 101/102/... Enhanced */
    case 0x83ab:	/* ditto */
    case 0x54ab:	/* SpaceSaver */
    case 0x84ab:	/* ditto */
#if 0
    case 0x90ab:	/* 'G' */
    case 0x91ab:	/* 'P' */
    case 0x92ab:	/* 'A' */
#endif
        *type = KB_101;
        break;
    case -1:	/* AT 84 keyboard doesn't return ID */
        *type = KB_84;
        break;
    default:
        break;
    }
    if (bootverbose)
        printf("atkbd: keyboard ID 0x%x (%d)\n", id, *type);

    /* reset keyboard hardware */
    if (!(flags & KB_CONF_NO_RESET) && !reset_kbd(kbdc)) {
        /*
         * KEYBOARD ERROR
         * Keyboard reset may fail either because the keyboard
         * doen't exist, or because the keyboard doesn't pass
         * the self-test, or the keyboard controller on the
         * motherboard and the keyboard somehow fail to shake hands.
         * It is just possible, particularly in the last case,
         * that the keyboard controller may be left in a hung state.
         * test_controller() and test_kbd_port() appear to bring
         * the keyboard controller back (I don't know why and how,
         * though.)
         */
        empty_both_buffers(kbdc, 10);
        test_controller(kbdc);
        test_kbd_port(kbdc);
        /*
         * We could disable the keyboard port and interrupt... but,
         * the keyboard may still exist (see above).
         */
        set_controller_command_byte(kbdc, 0xff, c);
        kbdc_lock(kbdc, FALSE);
        if (bootverbose)
            printf("atkbd: failed to reset the keyboard.\n");
        return EIO;
    }

    /*
     * Allow us to set the XT_KEYBD flag so that keyboards
     * such as those on the IBM ThinkPad laptop computers can be used
     * with the standard console driver.
     */
    if (codeset == 1) {
        if (send_kbd_command_and_data(kbdc,
                                      KBDC_SET_SCANCODE_SET, codeset) == KBD_ACK) {
            /* XT kbd doesn't need scan code translation */
            c &= ~KBD_TRANSLATION;
        } else {
            /*
             * KEYBOARD ERROR
             * The XT kbd isn't usable unless the proper scan
             * code set is selected.
             */
            set_controller_command_byte(kbdc, 0xff, c);
            kbdc_lock(kbdc, FALSE);
            printf("atkbd: unable to set the XT keyboard mode.\n");
            return EIO;
        }
    }

#if defined(__sparc64__)
    if (send_kbd_command_and_data(
                kbdc, KBDC_SET_SCANCODE_SET, 2) != KBD_ACK) {
        printf("atkbd: can't set translation.\n");
    }
    c |= KBD_TRANSLATION;
#endif

    /* enable the keyboard port and intr. */
    if (!set_controller_command_byte(kbdc,
                                     KBD_KBD_CONTROL_BITS | KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK,
                                     (c & (KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK))
                                     | KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) {
        /*
         * CONTROLLER ERROR
         * This is serious; we are left with the disabled
         * keyboard intr.
         */
        set_controller_command_byte(kbdc, 0xff, c);
        kbdc_lock(kbdc, FALSE);
        printf("atkbd: unable to enable the keyboard port and intr.\n");
        return EIO;
    }

    kbdc_lock(kbdc, FALSE);
    return 0;
}
Beispiel #8
0
static int
probe_keyboard(KBDC kbdc, int flags)
{
    /*
     * Don't try to print anything in this function.  The low-level
     * console may not have been initialized yet...
     */
    int err;
    int c;
    int m;

    if (!kbdc_lock(kbdc, TRUE)) {
        /* driver error? */
        return ENXIO;
    }

    /* temporarily block data transmission from the keyboard */
    write_controller_command(kbdc, KBDC_DISABLE_KBD_PORT);

    /* flush any noise in the buffer */
    empty_both_buffers(kbdc, 100);

    /* save the current keyboard controller command byte */
    m = kbdc_get_device_mask(kbdc) & ~KBD_KBD_CONTROL_BITS;
    c = get_controller_command_byte(kbdc);
    if (c == -1) {
        /* CONTROLLER ERROR */
        kbdc_set_device_mask(kbdc, m);
        kbdc_lock(kbdc, FALSE);
        return ENXIO;
    }

    /*
     * The keyboard may have been screwed up by the boot block.
     * We may just be able to recover from error by testing the controller
     * and the keyboard port. The controller command byte needs to be
     * saved before this recovery operation, as some controllers seem
     * to set the command byte to particular values.
     */
    test_controller(kbdc);
    if (!(flags & KB_CONF_NO_PROBE_TEST))
        test_kbd_port(kbdc);

    err = get_kbd_echo(kbdc);

    /*
     * Even if the keyboard doesn't seem to be present (err != 0),
     * we shall enable the keyboard port and interrupt so that
     * the driver will be operable when the keyboard is attached
     * to the system later.  It is NOT recommended to hot-plug
     * the AT keyboard, but many people do so...
     */
    kbdc_set_device_mask(kbdc, m | KBD_KBD_CONTROL_BITS);
    setup_kbd_port(kbdc, TRUE, TRUE);
#if 0
    if (err == 0) {
        kbdc_set_device_mask(kbdc, m | KBD_KBD_CONTROL_BITS);
    } else {
        /* try to restore the command byte as before */
        set_controller_command_byte(kbdc, 0xff, c);
        kbdc_set_device_mask(kbdc, m);
    }
#endif

    kbdc_lock(kbdc, FALSE);
    return err;
}
Beispiel #9
0
static int
init_keyboard(KBDC kbdc, int *type, int flags)
{
	int codeset;
	int id;
	int c;
	int mux_version;
	int mux_mask;
	int mux_val;

	if (!kbdc_lock(kbdc, TRUE)) {
		/* driver error? */
		return EIO;
	}

	/*
	 * XXX block data transmission from the keyboard.  This can cause
	 * the keyboard to stop sending keystrokes even when re-enabled
	 * under certain circumstances if not followed by a full reset.
	 */
	write_controller_command(kbdc, KBDC_DISABLE_KBD_PORT);

#if 0
	if (atkbd_setmuxmode(kbdc, 1, &mux_version)) {
		kprintf("atkbd: no mux\n");
		mux_version = -1;
	} else {
		kprintf("atkbd: mux present version %d\n", mux_version);
	}
#else
	mux_version = -1;
#endif

	/* save the current controller command byte */
	empty_both_buffers(kbdc, 200);
	c = get_controller_command_byte(kbdc);
	if (c == -1) {
		/* CONTROLLER ERROR */
		kbdc_lock(kbdc, FALSE);
		kprintf("atkbd: unable to get the current command byte value.\n");
		return EIO;
	}
	if (bootverbose)
		kprintf("atkbd: the current kbd controller command byte %04x\n",
		       c);
#if 0
	/* override the keyboard lock switch */
	c |= KBD_OVERRIDE_KBD_LOCK;
#endif

	/* enable the keyboard port, but disable the keyboard intr. */
	if (setup_kbd_port(kbdc, TRUE, FALSE)) {
		/* CONTROLLER ERROR: there is very little we can do... */
		kprintf("atkbd: unable to set the command byte.\n");
		kbdc_lock(kbdc, FALSE);
		return EIO;
	}

	/* default codeset */
	codeset = -1;

	/* reset keyboard hardware */
	if (!(flags & KB_CONF_NO_RESET) && !reset_kbd(kbdc)) {
		/*
		 * KEYBOARD ERROR
		 * Keyboard reset may fail either because the keyboard
		 * doen't exist, or because the keyboard doesn't pass
		 * the self-test, or the keyboard controller on the
		 * motherboard and the keyboard somehow fail to shake hands.
		 * It is just possible, particularly in the last case,
		 * that the keyoard controller may be left in a hung state.
		 * test_controller() and test_kbd_port() appear to bring
		 * the keyboard controller back (I don't know why and how,
		 * though.)
		 */
		empty_both_buffers(kbdc, 10);
		test_controller(kbdc);
		test_kbd_port(kbdc);
		/*
		 * We could disable the keyboard port and interrupt... but,
		 * the keyboard may still exist (see above).
		 */
		set_controller_command_byte(kbdc, KBD_KBD_CONTROL_BITS, c);
		kbdc_lock(kbdc, FALSE);
		if (bootverbose)
			kprintf("atkbd: failed to reset the keyboard.\n");
		return EIO;
	}

	/* 
	 * Check if we have an XT keyboard before we attempt to reset it. 
	 * The procedure assumes that the keyboard and the controller have 
	 * been set up properly by BIOS and have not been messed up 
	 * during the boot process.
	 */
	codeset = -1;
	if (flags & KB_CONF_ALT_SCANCODESET)
		/* the user says there is a XT keyboard */
		codeset = 1;
#ifdef KBD_DETECT_XT_KEYBOARD
	else if ((c & KBD_TRANSLATION) == 0) {
		/* SET_SCANCODE_SET is not always supported; ignore error */
		if (send_kbd_command_and_data(kbdc, KBDC_SET_SCANCODE_SET, 0)
			== KBD_ACK) 
			codeset = read_kbd_data(kbdc);
	}
#endif /* KBD_DETECT_XT_KEYBOARD */
	if (bootverbose)
		kprintf("atkbd: scancode set %d\n", codeset);
 
	/*
	 * Get the keyboard id.
	 */
	*type = KB_OTHER;
	id = get_kbd_id(kbdc, ATKBD_CMD_GETID);
	switch(id) {
	case 0x41ab:	/* 101/102/... Enhanced */
	case 0x83ab:	/* ditto */
	case 0x54ab:	/* SpaceSaver */
	case 0x84ab:	/* ditto */
#if 0
	case 0x90ab:	/* 'G' */
	case 0x91ab:	/* 'P' */
	case 0x92ab:	/* 'A' */
#endif
		*type = KB_101;
		break;
	case -1:	/* AT 84 keyboard doesn't return ID */
		*type = KB_84;
		break;
	default:
		break;
	}
	if (bootverbose)
		kprintf("atkbd: keyboard ID 0x%x (%d)\n", id, *type);

	/*
	 * Allow us to set the XT_KEYBD flag in UserConfig so that keyboards
	 * such as those on the IBM ThinkPad laptop computers can be used
	 * with the standard console driver.
	 */
	if (codeset == 1) {
		if (send_kbd_command_and_data(kbdc,
			KBDC_SET_SCANCODE_SET, codeset) == KBD_ACK) {
			/* XT kbd doesn't need scan code translation */
			c &= ~KBD_TRANSLATION;
		} else {
			/*
			 * KEYBOARD ERROR 
			 * The XT kbd isn't usable unless the proper scan
			 * code set is selected. 
			 */
			set_controller_command_byte(kbdc,
						    KBD_KBD_CONTROL_BITS, c);
			kbdc_lock(kbdc, FALSE);
			kprintf("atkbd: unable to set the XT keyboard mode.\n");
			return EIO;
		}
	}

#if 0
	if (send_kbd_command_and_data(kbdc, ATKBD_CMD_EX_ENABLE, 0x71) != KBD_ACK)
		kprintf("atkbd: can't CMD_EX_ENABLE\n");

	if (send_kbd_command(kbdc, ATKBD_CMD_SETALL_MB) != KBD_ACK)
		kprintf("atkbd: can't SETALL_MB\n");
	if (send_kbd_command(kbdc, ATKBD_CMD_SETALL_MBR) != KBD_ACK)
		kprintf("atkbd: can't SETALL_MBR\n");
#endif
#if 0
	if (send_kbd_command_and_data(kbdc, ATKBD_CMD_SSCANSET, 2) != KBD_ACK)
		kprintf("atkbd: can't SSCANSET\n");
	if (send_kbd_command_and_data(kbdc, ATKBD_CMD_GSCANSET, 0) != KBD_ACK)
		kprintf("atkbd: can't SSCANSET\n");
	else
		kprintf("atkbd: scanset %d\n", read_kbd_data(kbdc));
#endif
#if 0
	kprintf("atkbd: id %04x\n", get_kbd_id(kbdc, ATKBD_CMD_OK_GETID));
	if (send_kbd_command_and_data(kbdc, ATKBD_CMD_SETLEDS, 0) != KBD_ACK)
		kprintf("atkbd: setleds failed\n");
	if (send_kbd_command_and_data(kbdc, ATKBD_CMD_SETREP, 255) != KBD_ACK)
		kprintf("atkbd: setrep failed\n");
	if (send_kbd_command(kbdc, ATKBD_CMD_RESEND) != KBD_ACK)
		kprintf("atkbd: resend failed\n");
#endif
	/*
	 * Some keyboards require a SETLEDS command to be sent after
	 * the reset command before they will send keystrokes to us
	 * (Acer C720).
	 */
	if (send_kbd_command_and_data(kbdc, ATKBD_CMD_SETLEDS, 0) != KBD_ACK)
		kprintf("atkbd: setleds failed\n");
	send_kbd_command(kbdc, ATKBD_CMD_ENABLE);

#if 0
	/* DEBUGGING */
	{
		int retry;
		int c;
		kprintf("atkbd: waiting for keypress");
		for (retry = 0; retry < 10; ++retry) {
			c = read_kbd_data_no_wait(kbdc);
			kprintf(" %d", c);
			tsleep(&c, 0, "wait", hz);
		}
		kprintf("\n");
	}
#endif

	if (mux_version == -1) {
		mux_mask = 0;
		mux_val = 0;
	} else {
		mux_mask = KBD_AUX_CONTROL_BITS;
		mux_val = 0;
		kprintf("atkbd: setaux for multiplexer\n");
	}

	/* enable the keyboard port and intr. */
	if (!set_controller_command_byte(kbdc, 
		KBD_KBD_CONTROL_BITS | KBD_TRANSLATION |
		KBD_OVERRIDE_KBD_LOCK | mux_mask,
		(c & (KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK))
		    | KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT | mux_val)) {
		/*
		 * CONTROLLER ERROR 
		 * This is serious; we are left with the disabled
		 * keyboard intr. 
		 */
		set_controller_command_byte(kbdc,
				KBD_KBD_CONTROL_BITS | KBD_TRANSLATION |
				KBD_OVERRIDE_KBD_LOCK | mux_mask,
				c);
		kbdc_lock(kbdc, FALSE);
		kprintf("atkbd: unable to enable the keyboard port and intr.\n");
		return EIO;
	}

	kbdc_lock(kbdc, FALSE);
	return 0;
}
Beispiel #10
0
static int
probe_keyboard(KBDC kbdc, int flags)
{
	/*
	 * Don't try to print anything in this function.  The low-level 
	 * console may not have been initialized yet...
	 */
	int err;
	int c;

	if (!kbdc_lock(kbdc, TRUE)) {
		/* driver error? */
		return ENXIO;
	}

	/*
	 * XXX block data transmission from the keyboard.  This can cause
	 * the keyboard to stop sending keystrokes even when re-enabled
	 * under certain circumstances if not followed by a full reset.
	 */
	write_controller_command(kbdc, KBDC_DISABLE_KBD_PORT);

	/* flush any noise in the buffer */
	empty_both_buffers(kbdc, 100);

	/* save the current keyboard controller command byte */
	c = get_controller_command_byte(kbdc);
	if (c == -1) {
		/* CONTROLLER ERROR */
		kbdc_lock(kbdc, FALSE);
		return ENXIO;
	}

	/* 
	 * The keyboard may have been screwed up by the boot block.
	 * We may just be able to recover from error by testing the controller
	 * and the keyboard port. The controller command byte needs to be
	 * saved before this recovery operation, as some controllers seem 
	 * to set the command byte to particular values.
	 */
	test_controller(kbdc);
	test_kbd_port(kbdc);

	err = get_kbd_echo(kbdc);

	/*
	 * Even if the keyboard doesn't seem to be present (err != 0),
	 * we shall enable the keyboard port and interrupt so that
	 * the driver will be operable when the keyboard is attached
	 * to the system later.  It is NOT recommended to hot-plug
	 * the AT keyboard, but many people do so...
	 */
	setup_kbd_port(kbdc, TRUE, TRUE);
#if 0
	if (err) {
		/* try to restore the command byte as before */
		set_controller_command_byte(kbdc, KBD_KBD_CONTROL_BITS, c);
	}
#endif

	kbdc_lock(kbdc, FALSE);
	return err;
}
Beispiel #11
0
static int
init_keyboard(KBDC kbdc, int *type, int flags)
{
	int codeset;
	int id;
	int c;

	if (!kbdc_lock(kbdc, TRUE)) {
		/* driver error? */
		return EIO;
	}

	/* temporarily block data transmission from the keyboard */
	write_controller_command(kbdc, KBDC_DISABLE_KBD_PORT);

	/* save the current controller command byte */
	empty_both_buffers(kbdc, 200);
	c = get_controller_command_byte(kbdc);
	if (c == -1) {
		/* CONTROLLER ERROR */
		kbdc_lock(kbdc, FALSE);
		printf("atkbd: unable to get the current command byte value.\n");
		return EIO;
	}
	if (bootverbose)
		printf("atkbd: the current kbd controller command byte %04x\n",
		   c);
#if 0
	/* override the keyboard lock switch */
	c |= KBD_OVERRIDE_KBD_LOCK;
#endif

	/* enable the keyboard port, but disable the keyboard intr. */
	if (setup_kbd_port(kbdc, TRUE, FALSE)) {
		/* CONTROLLER ERROR: there is very little we can do... */
		printf("atkbd: unable to set the command byte.\n");
		kbdc_lock(kbdc, FALSE);
		return EIO;
	}

	if (HAS_QUIRK(kbdc, KBDC_QUIRK_RESET_AFTER_PROBE) &&
	    atkbd_reset(kbdc, flags, c)) {
		kbdc_lock(kbdc, FALSE);
		return EIO;
	}

	/* 
	 * Check if we have an XT keyboard before we attempt to reset it. 
	 * The procedure assumes that the keyboard and the controller have 
	 * been set up properly by BIOS and have not been messed up 
	 * during the boot process.
	 */
	codeset = -1;
	if (flags & KB_CONF_ALT_SCANCODESET)
		/* the user says there is a XT keyboard */
		codeset = 1;
#ifdef KBD_DETECT_XT_KEYBOARD
	else if ((c & KBD_TRANSLATION) == 0) {
		/* SET_SCANCODE_SET is not always supported; ignore error */
		if (send_kbd_command_and_data(kbdc, KBDC_SET_SCANCODE_SET, 0)
			== KBD_ACK) 
			codeset = read_kbd_data(kbdc);
	}
	if (bootverbose)
		printf("atkbd: scancode set %d\n", codeset);
#endif /* KBD_DETECT_XT_KEYBOARD */
 
	*type = KB_OTHER;
	id = get_kbd_id(kbdc);
	switch(id) {
	case 0x41ab:	/* 101/102/... Enhanced */
	case 0x83ab:	/* ditto */
	case 0x54ab:	/* SpaceSaver */
	case 0x84ab:	/* ditto */
#if 0
	case 0x90ab:	/* 'G' */
	case 0x91ab:	/* 'P' */
	case 0x92ab:	/* 'A' */
#endif
		*type = KB_101;
		break;
	case -1:	/* AT 84 keyboard doesn't return ID */
		*type = KB_84;
		break;
	default:
		break;
	}
	if (bootverbose)
		printf("atkbd: keyboard ID 0x%x (%d)\n", id, *type);

	if (!HAS_QUIRK(kbdc, KBDC_QUIRK_RESET_AFTER_PROBE) &&
	    atkbd_reset(kbdc, flags, c)) {
		kbdc_lock(kbdc, FALSE);
		return EIO;
	}

	/*
	 * Allow us to set the XT_KEYBD flag so that keyboards
	 * such as those on the IBM ThinkPad laptop computers can be used
	 * with the standard console driver.
	 */
	if (codeset == 1) {
		if (send_kbd_command_and_data(kbdc,
			KBDC_SET_SCANCODE_SET, codeset) == KBD_ACK) {
			/* XT kbd doesn't need scan code translation */
			c &= ~KBD_TRANSLATION;
		} else {
			/*
			 * KEYBOARD ERROR 
			 * The XT kbd isn't usable unless the proper scan
			 * code set is selected. 
			 */
			set_controller_command_byte(kbdc, ALLOW_DISABLE_KBD(kbdc)
			    ? 0xff : KBD_KBD_CONTROL_BITS, c);
			kbdc_lock(kbdc, FALSE);
			printf("atkbd: unable to set the XT keyboard mode.\n");
			return EIO;
		}
	}

#if defined(__sparc64__)
	if (send_kbd_command_and_data(
		kbdc, KBDC_SET_SCANCODE_SET, 2) != KBD_ACK) {
		printf("atkbd: can't set translation.\n");
	}
	c |= KBD_TRANSLATION;
#endif

	/*
	 * Some keyboards require a SETLEDS command to be sent after
	 * the reset command before they will send keystrokes to us
	 */
	if (HAS_QUIRK(kbdc, KBDC_QUIRK_SETLEDS_ON_INIT) &&
	    send_kbd_command_and_data(kbdc, KBDC_SET_LEDS, 0) != KBD_ACK) {
		printf("atkbd: setleds failed\n");
	}
	if (!ALLOW_DISABLE_KBD(kbdc))
	    send_kbd_command(kbdc, KBDC_ENABLE_KBD);

	/* enable the keyboard port and intr. */
	if (!set_controller_command_byte(kbdc, 
		KBD_KBD_CONTROL_BITS | KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK,
		(c & (KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK))
		    | KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) {
		/*
		 * CONTROLLER ERROR 
		 * This is serious; we are left with the disabled
		 * keyboard intr. 
		 */
		set_controller_command_byte(kbdc, ALLOW_DISABLE_KBD(kbdc)
		    ? 0xff : (KBD_KBD_CONTROL_BITS | KBD_TRANSLATION |
			KBD_OVERRIDE_KBD_LOCK), c);
		kbdc_lock(kbdc, FALSE);
		printf("atkbd: unable to enable the keyboard port and intr.\n");
		return EIO;
	}

	kbdc_lock(kbdc, FALSE);
	return 0;
}