318 lines
5.2 KiB
C
318 lines
5.2 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1991 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
Kbdtest.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module implements the Keyboard and mouse test for the self-test.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Lluis Abello (lluis) 10-Feb-1991
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Rom self-test.
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
#include <ntos.h>
|
|||
|
#include "iodevice.h"
|
|||
|
#include "kbdmouse.h"
|
|||
|
#include "ioaccess.h"
|
|||
|
|
|||
|
volatile ULONG TimerTicks;
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
ClearKbdFifo(
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine empties the Keyboard controller Fifo.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
UCHAR Trash, Stat;
|
|||
|
volatile Timeout;
|
|||
|
|
|||
|
//
|
|||
|
// wait until the previous command is processed.
|
|||
|
//
|
|||
|
|
|||
|
while ((READ_REGISTER_UCHAR(&KEYBOARD_READ->Status) & KBD_IBF_MASK) != 0) {
|
|||
|
}
|
|||
|
while ((READ_REGISTER_UCHAR(&KEYBOARD_READ->Status) & KBD_OBF_MASK) != 0) {
|
|||
|
Trash= READ_REGISTER_UCHAR(&KEYBOARD_READ->Data);
|
|||
|
for (Timeout=0;Timeout<10000;Timeout++) {
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
GetKbdData(
|
|||
|
PUCHAR C,
|
|||
|
ULONG msec
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine polls the Status Register until Data is available or timeout,
|
|||
|
then it reads and returns the Data.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
C - pointer to a byte where to write the read value
|
|||
|
msec - time-out time in milliseconds
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if timeout, FALSE if OK;
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
TimerTicks=msec;
|
|||
|
while (TimerTicks) {
|
|||
|
if (READ_REGISTER_UCHAR(&KEYBOARD_READ->Status) & KBD_OBF_MASK) {
|
|||
|
*C = READ_REGISTER_UCHAR(&KEYBOARD_READ->Data);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
SendKbdData(
|
|||
|
IN UCHAR Data
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine polls the Status Register until the controller is ready to
|
|||
|
accept a data or timeout, then it send the Data.
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if timeout, FALSE if OK;
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
ULONG i;
|
|||
|
|
|||
|
for (i=0; i <KBD_TIMEOUT; i++) {
|
|||
|
if ((READ_REGISTER_UCHAR(&KEYBOARD_READ->Status) & KBD_IBF_MASK) == 0) {
|
|||
|
WRITE_REGISTER_UCHAR(&KEYBOARD_WRITE->Data,Data);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
SendKbdCommand(
|
|||
|
IN UCHAR Command
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine polls the Status Register until the controller is ready to
|
|||
|
accept a command or timeout, then it send the Command.
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if timeout, FALSE if OK;
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
ULONG i;
|
|||
|
|
|||
|
for (i=0; i <KBD_TIMEOUT; i++) {
|
|||
|
if ((READ_REGISTER_UCHAR(&KEYBOARD_READ->Status) & KBD_IBF_MASK) == 0) {
|
|||
|
WRITE_REGISTER_UCHAR(&KEYBOARD_WRITE->Command,Command);
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
ULONG
|
|||
|
InitKeyboard(
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine enables amd initializes the keyboard.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
FALSE if passed,
|
|||
|
TRUE if bad ACK or BAT received,
|
|||
|
TIME_OUT if no response is received from the keyboard.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
UCHAR Result;
|
|||
|
ULONG i;
|
|||
|
|
|||
|
//
|
|||
|
// Send Reset to Keyboard.
|
|||
|
//
|
|||
|
|
|||
|
ClearKbdFifo();
|
|||
|
for (;;) {
|
|||
|
if (SendKbdData(KbdReset)) {
|
|||
|
return TIME_OUT;
|
|||
|
}
|
|||
|
if (GetKbdData(&Result,1000)) {
|
|||
|
return TIME_OUT;
|
|||
|
}
|
|||
|
if (Result == KbdResend) {
|
|||
|
if (GetKbdData(&Result,1000)) {
|
|||
|
return TIME_OUT;
|
|||
|
}
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (Result != KbdAck) {
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
if (GetKbdData(&Result,7000)) {
|
|||
|
return TIME_OUT;
|
|||
|
}
|
|||
|
if (Result != KbdBat) {
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Enable Kbd and Select keyboard Scan code.
|
|||
|
//
|
|||
|
|
|||
|
if (SendKbdCommand(KBD_CTR_ENABLE_KBD)) {
|
|||
|
return TIME_OUT;
|
|||
|
}
|
|||
|
if (SendKbdData(KbdSelScanCode)) {
|
|||
|
return TIME_OUT;
|
|||
|
}
|
|||
|
if (GetKbdData(&Result,1000)) {
|
|||
|
return TIME_OUT;
|
|||
|
}
|
|||
|
if (SendKbdData(1)) { // select Scan code 1
|
|||
|
return TIME_OUT;
|
|||
|
}
|
|||
|
if (GetKbdData(&Result,1000)) {
|
|||
|
return TIME_OUT;
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
ULONG
|
|||
|
InitKeyboardController(
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine Initializes the Keyboard controller.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
FALSE if passed,
|
|||
|
TRUE if bad response received from keyboard controller,
|
|||
|
TIME_OUT if no response is received from the keyboard controller.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
UCHAR Result;
|
|||
|
|
|||
|
//
|
|||
|
// Clear both fifos.
|
|||
|
//
|
|||
|
|
|||
|
ClearKbdFifo();
|
|||
|
|
|||
|
//
|
|||
|
// Send Selftest Command. This has to be done before anything else.
|
|||
|
//
|
|||
|
|
|||
|
if (SendKbdCommand(KBD_CTR_SELFTEST)) {
|
|||
|
return TIME_OUT;
|
|||
|
}
|
|||
|
if (GetKbdData(&Result,1000)) {
|
|||
|
return TIME_OUT;
|
|||
|
}
|
|||
|
if (Result != Kbd_Ctr_Selftest_Passed) {
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Now the Keyboard and Mouse are disabled.
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// Test Keyboard lines.
|
|||
|
//
|
|||
|
|
|||
|
if (SendKbdCommand(KBD_CTR_KBDLINES_TEST)) {
|
|||
|
return TIME_OUT;
|
|||
|
}
|
|||
|
if (GetKbdData(&Result,1000)) {
|
|||
|
return TIME_OUT;
|
|||
|
}
|
|||
|
if (Result != INTERFACE_NO_ERROR) {
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Test Aux lines.
|
|||
|
//
|
|||
|
|
|||
|
if (SendKbdCommand(KBD_CTR_AUXLINES_TEST)) {
|
|||
|
return TIME_OUT;
|
|||
|
}
|
|||
|
if (GetKbdData(&Result,1000)) {
|
|||
|
return TIME_OUT;
|
|||
|
}
|
|||
|
if (Result != INTERFACE_NO_ERROR) {
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
return FALSE;
|
|||
|
}
|