kbddep.c revision 677833bc953b6cb418c701facbdcf4aa18d6c44e
/*++
Copyright (c) 1990, 1991, 1992, 1993 Microsoft Corporation
Module Name:
Abstract:
The initialization and hardware-dependent portions of
the Intel i8042 port driver which are specific to the
keyboard.
Environment:
Kernel mode only.
Notes:
NOTES: (Future/outstanding issues)
- Powerfail not implemented.
- Consolidate duplicate code, where possible and appropriate.
Revision History:
--*/
#include "stdarg.h"
#include "stdio.h"
#include "string.h"
#include "ntddk.h"
#include "i8042prt.h"
#include "i8042log.h"
//
// Use the alloc_text pragma to specify the driver initialization routines
// (they can be paged out).
//
#ifdef ALLOC_PRAGMA
#endif
)
/*++
Routine Description:
This is the interrupt service routine for the keyboard device when
scan code set 1 is in use.
Arguments:
Interrupt - A pointer to the interrupt object for this interrupt.
Context - A pointer to the device object.
Return Value:
Returns TRUE if the interrupt was expected (and therefore processed);
otherwise, FALSE is returned.
--*/
{
ULONG i;
//
// Get the device extension.
//
//
// Verify that this device really interrupted. Check the status
// register. The Output Buffer Full bit should be set, and the
// Auxiliary Device Output Buffer Full bit should be clear.
//
!= OUTPUT_BUFFER_FULL) {
//
// Stall and then try again. The Olivetti MIPS machine
// sometimes gets an interrupt before the status
// register is set. They do this for DOS compatibility (some
// DOS apps do things in polled mode, until they see a character
// in the keyboard buffer at which point they expect to get
// an interrupt???).
//
== (OUTPUT_BUFFER_FULL))
break;
}
!= (OUTPUT_BUFFER_FULL)) {
//
// Not our interrupt.
//
// NOTE: If the keyboard has not yet been "enabled", go ahead
// and read a byte from the data port anyway.
// This fixes weirdness on some Gateway machines, where
// we get an interrupt sometime during driver initialization
// after the interrupt is connected, but the output buffer
// full bit never gets set.
//
I8xPrint((
1,
"I8042PRT-I8042KeyboardInterruptService: not our interrupt!\n"
));
if (deviceExtension->KeyboardEnableCount == 0) {
scanCode =
}
return(FALSE);
}
}
//
// The interrupt is valid. Read the byte from the i8042 data port.
//
);
I8xPrint((
2,
"I8042PRT-I8042KeyboardInterruptService: scanCode 0x%x\n",
));
//
// Take the appropriate action, depending on whether the byte read
// is a keyboard command response or a real scan code.
//
switch(scanCode) {
//
// The keyboard controller requests a resend. If the resend count
// has not been exceeded, re-initiate the I/O operation.
//
case RESEND:
I8xPrint((
3,
"I8042PRT-I8042KeyboardInterruptService: RESEND, retries = %d\n",
));
//
// If the timer count is zero, don't process the interrupt
// further. The timeout routine will complete this request.
//
if (deviceExtension->TimerCount == 0) {
break;
}
//
// Reset the timeout value to indicate no timeout.
//
//
// If the maximum number of retries has not been exceeded,
// re-initiate the operation; otherwise, queue the DPC to
// complete this request.
//
//
// We weren't sending a command or parameter to the hardware.
// This must be a scan code. I hear the Brazilian keyboard
// actually uses this.
//
goto ScanCodeCase;
} else {
);
}
break;
//
// The keyboard controller has acknowledged a previous send.
// If there are more bytes to send for the current packet, initiate
// the next send operation. Otherwise, queue the completion DPC.
//
case ACKNOWLEDGE:
I8xPrint((
3,
"I8042PRT-I8042KeyboardInterruptService: ACK, "
));
//
// If the timer count is zero, don't process the interrupt
// further. The timeout routine will complete this request.
//
if (deviceExtension->TimerCount == 0) {
break;
}
//
// Reset the timeout value to indicate no timeout.
//
//
// Reset resend count.
//
== SendFirstByte) {
//
// We've successfully sent the first byte of a 2-byte
// command sequence. Initiate a send of the second byte.
//
I8xPrint((
3,
"now initiate send of last byte\n"
));
== SendLastByte) {
//
// We've successfully sent all bytes in the command sequence.
// Reset the current state and queue the completion DPC.
//
I8xPrint((
3,
"all bytes have been sent\n"
));
);
} else {
I8xPrint((
1,
"unexpected, State is 0x%x\n",
));
//
// Queue a DPC to log an internal driver error.
//
//
// Note: We don't ASSERT here, because there are some
// machines (e.g., Compaq 386/25) that send back an
// extra ACK in response to the SETLED sequence. We've
// noticed this when, for example, CAPSLOCK is pressed
// at the same time as a normal key. Just ignore
// random ACKs.
//
}
break;
//
// Assume we've got a real, live scan code (or perhaps a keyboard
// overrun code, which we treat like a scan code). I.e., a key
// has been pressed or released. Queue the ISR DPC to process
// a complete scan code sequence.
//
default:
I8xPrint((
3,
"I8042PRT-I8042KeyboardInterruptService: real scan code\n"
));
//
// Differentiate between an extended key sequence (first
// byte is E0, followed by a normal make or break byte), or
// a normal make code (one byte, the high bit is NOT set),
// or a normal break code (one byte, same as the make code
// but the high bit is set), or the key #126 byte sequence
// (requires special handling -- sequence is E11D459DC5).
//
// sends an overrun indicator (0xFF in scan code set 1).
// Map it to the overrun indicator expected by the Windows
// USER Raw Input Thread.
//
I8xPrint((
1,
"I8042PRT-I8042KeyboardInterruptService: OVERRUN\n"
));
} else {
switch (*scanState) {
case Normal:
I8xPrint((
3,
"I8042PRT-I8042KeyboardInterruptService: change state to GotE0\n"
));
break;
I8xPrint((
3,
"I8042PRT-I8042KeyboardInterruptService: change state to GotE1\n"
));
break;
}
//
// Normal case.
//
case GotE0:
case GotE1:
// Fujitsu Sep.08.1994
// We want to write debugging information to the file except stop error.
if(deviceExtension->Dump1Keys != 0) {
0x00,0x29,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x0A,0x0B,0x0C,0x0D,0x7D,0x0E,0x0F,0x10,0x11,0x12,
0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x00,
0x3A,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,
0x27,0x28,0x2B,0x1C,0x2A,0x00,0x2C,0x2D,0x2E,0x2F,
0x30,0x31,0x32,0x33,0x34,0x35,0x73,0x36,0x1D,0x00,
0x38,0x39,0xB8,0x00,0x9D,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xD2,0xD3,0x00,0x00,0xCB,
0xC7,0xCF,0x00,0xC8,0xD0,0xC9,0xD1,0x00,0x00,0xCD,
0x45,0x47,0x4B,0x4F,0x00,0xB5,0x48,0x4C,0x50,0x52,
0x37,0x49,0x4D,0x51,0x53,0x4A,0x4E,0x00,0x9C,0x00,
0x01,0x00,0x3B,0x3C,0x3D,0x3E,0x3F,0x40,0x41,0x42,
0x43,0x44,0x57,0x58,0x00,0x46,0x00,0x00,0x00,0x00,
0x00,0x7B,0x79,0x70 };
switch(deviceExtension->Dump2Key) {
case 124: // 'Print Screen'
DumpKey = 0xB7;
DumpKey2 = 0x54;
break;
default:
else
DumpKey = 0;
DumpKey2 = 0;
break;
}
//
// make code
//
switch(scanCode) {
case 0x1D: // 'CTRL'
break;
case 0x38: // 'ALT'
break;
case 0x36: // Right 'Shift'
break;
case 0x2A: // Left 'Shift'
break;
default:
if((DumpKey & 0x80) == 0) {
break;
}
else {
break;
}
if((DumpKey2 & 0x80) == 0) {
break;
}
else {
break;
}
deviceExtension->DumpFlags = 0;
break;
}
}
else {
//
// break code
//
switch(scanCode & 0x7F) {
case 0x1D: // 'CTRL'
break;
case 0x38: // 'ALT'
break;
case 0x36: // Right 'Shift'
break;
case 0x2A: // Left 'Shift'
break;
default:
onflag = 0;
if((DumpKey & 0x80) == 0) {
onflag = 1;
}
else {
onflag = 1;
}
if((DumpKey2 & 0x80) == 0) {
onflag = 1;
}
else {
onflag = 1;
}
if(onflag) {
break;
else
break;
}
deviceExtension->DumpFlags = 0;
break;
}
}
Dump1Keys |= 0x300;
deviceExtension->DumpFlags = 0;
KeBugCheckEx(0x0000FFFF,0,0,0,0);
// make occured blue screen
}
}
#endif
if (scanCode > 0x7F) {
//
// Got a break code. Strip the high bit off
// to get the associated make code and set flags
// to indicate a break code.
//
I8xPrint((
3,
"I8042PRT-I8042KeyboardInterruptService: BREAK code\n"
));
} else {
//
// Got a make code.
//
I8xPrint((
3,
"I8042PRT-I8042KeyboardInterruptService: MAKE code\n"
));
//
// If the input scan code is debug stop, then drop
// into the kernel debugger if it is active.
//
if (ENHANCED_KEYBOARD(
)) {
//
// Enhanced 101 keyboard, SysReq key is 0xE0 0x37.
//
__try {
}
}
}
//
// 84-key AT keyboard, SysReq key is 0xE0 0x54.
//
__try {
}
}
}
}
}
//
// Reset the state to Normal.
//
break;
default:
//
// Queue a DPC to log an internal driver error.
//
break;
}
}
//
// In the Normal state, if the keyboard device is enabled,
// add the data to the InputData queue and queue the ISR DPC.
//
if (deviceExtension->KeyboardEnableCount) {
)) {
//
// The InputData queue overflowed. There is
// not much that can be done about it, so just
// continue (but don't queue the ISR DPC, since
// no new packets were added to the queue).
//
// Queue a DPC to log an overrun error.
//
I8xPrint((
1,
"I8042PRT-I8042KeyboardInterruptService: queue overflow\n"
));
);
}
} else if (deviceExtension->DpcInterlockKeyboard >= 0) {
//
// The ISR DPC is already executing. Tell the ISR DPC
// it has more work to do by incrementing
// DpcInterlockKeyboard.
//
} else {
//
// Queue the ISR DPC.
//
);
}
}
//
// Reset the input state.
//
}
break;
}
return(TRUE);
}
//
// The following table is used to convert typematic rate (keys per
// second) into the value expected by the keyboard. The index into the
// array is the number of keys per second. The resulting value is
// the bit equate to send to the keyboard.
//
UCHAR TypematicPeriod[] = {
31, // 0 keys per second
31, // 1 keys per second
28, // 2 keys per second, This is really 2.5, needed for NEXUS.
26, // 3 keys per second
23, // 4 keys per second
20, // 5 keys per second
18, // 6 keys per second
17, // 7 keys per second
15, // 8 keys per second
13, // 9 keys per second
12, // 10 keys per second
11, // 11 keys per second
10, // 12 keys per second
9, // 13 keys per second
9, // 14 keys per second
8, // 15 keys per second
7, // 16 keys per second
6, // 17 keys per second
5, // 18 keys per second
4, // 19 keys per second
4, // 20 keys per second
3, // 21 keys per second
3, // 22 keys per second
2, // 23 keys per second
2, // 24 keys per second
1, // 25 keys per second
1, // 26 keys per second
1 // 27 keys per second
// > 27 keys per second, use 0
};
)
/*++
Routine Description:
This routine converts the typematic rate and delay to the form the
keyboard expects.
The byte passed to the keyboard looks like this:
- bit 7 is zero
- bits 5 and 6 indicate the delay
- bits 0-4 indicate the rate
The delay is equal to 1 plus the binary value of bits 6 and 5,
multiplied by 250 milliseconds.
The period (interval from one typematic output to the next) is
determined by the following equation:
Period = (8 + A) x (2^B) x 0.00417 seconds
where
A = binary value of bits 0-2
B = binary value of bits 3 and 4
Arguments:
Rate - Number of keys per second.
Delay - Number of milliseconds to delay before the key repeat starts.
Return Value:
The byte to pass to the keyboard.
--*/
{
//
// Calculate the delay bits.
//
//
// Put delay bits in the right place.
//
value <<= 5;
//
// Get the typematic period from the table. If keys per second
// is > 27, the typematic period value is zero.
//
if (Rate <= 27) {
}
return(value);
}
)
/*++
Routine Description:
This routine initializes the i8042 keyboard hardware. It is called
only at initialization, and does not synchronize access to the hardware.
Arguments:
DeviceObject - Pointer to the device object.
Return Value:
Returns status.
--*/
{
ULONG i;
#endif
#define DUMP_COUNT 4
for (i = 0; i < DUMP_COUNT; i++)
dumpData[i] = 0;
//
// Get the device extension.
//
//
// Reset the keyboard.
//
);
if (!NT_SUCCESS(status)) {
I8xPrint((
1,
"I8042PRT-I8xInitializeKeyboard: failed keyboard reset, status 0x%x\n",
));
//
// Set up error log info.
//
dumpCount = 3;
//
// NOTE: The following line was commented out to work around a
// problem with the Gateway 4DX2/66V when an old Compaq 286
// keyboard is attached. In this case, the keyboard reset
// is not acknowledged (at least, the system never
// receives the ack). Instead, the KEYBOARD_COMPLETE_SUCCESS
// byte is sitting in the i8042 output buffer. The workaround
// is to ignore the keyboard reset failure and continue.
//
// goto I8xInitializeKeyboardExit;
}
//
// Get the keyboard reset self-test response. A response byte of
// KEYBOARD_COMPLETE_SUCCESS indicates success; KEYBOARD_COMPLETE_FAILURE
// indicates failure.
//
// Note that it is usually necessary to stall a long time to get the
// experimentation.
//
for (i = 0; i < 11200; i++) {
&byte
);
if (NT_SUCCESS(status)) {
//
// The reset completed successfully.
//
break;
} else {
//
// There was some sort of failure during the reset
// self-test. Continue anyway.
//
//
// Log a warning.
//
I8042_ERROR_VALUE_BASE + 515,
4
);
break;
}
} else {
if (status == STATUS_IO_TIMEOUT) {
//
// Stall, and then try again to get a response from
// the reset.
//
break;
}
} else {
break;
}
}
}
if (!NT_SUCCESS(status)) {
if (waitForAckOnReset == WAIT_FOR_ACKNOWLEDGE) {
goto StartOfReset;
}
I8xPrint((
1,
"I8042PRT-I8xInitializeKeyboard: failed reset response, status 0x%x, byte 0x%x\n",
));
//
// Set up error log info.
//
dumpCount = 4;
}
//
// Turn off Keyboard Translate Mode. Call I8xTransmitControllerCommand
// to read the Controller Command Byte, modify the appropriate bits, and
// rewrite the Controller Command Byte.
//
);
//
// If failure then retry once. This is for Toshiba T3400CT.
//
);
}
I8xPrint((
1,
"I8042PRT-I8xInitializeKeyboard: could not turn off translate\n"
));
}
//
// Get a pointer to the keyboard identifier field.
//
//
// Set the typematic rate and delay. Send the Set Typematic Rate command
// Note that it is often necessary to stall a long time to get this
// to work. The stall value was determined by experimentation. Some
// broken hardware does not accept this command, so ignore errors in the
// hope that the keyboard will work okay anyway.
//
//
if ((status = I8xPutBytePolled(
)) != STATUS_SUCCESS) {
I8xPrint((
1,
"I8042PRT-I8xInitializeKeyboard: could not send SET TYPEMATIC cmd\n"
));
//
// Log an error.
//
I8042_ERROR_VALUE_BASE + 535,
3
);
} else if ((status = I8xPutBytePolled(
))) != STATUS_SUCCESS) {
I8xPrint((
1,
"I8042PRT-I8xInitializeKeyboard: could not send typematic param\n"
));
//
// Log an error.
//
dumpData[3] =
);
I8042_ERROR_VALUE_BASE + 540,
4
);
}
//
// Set the keyboard indicator lights. Ignore errors.
//
if ((status = I8xPutBytePolled(
)) != STATUS_SUCCESS) {
I8xPrint((
1,
"I8042PRT-I8xInitializeKeyboard: could not send SET LEDS cmd\n"
));
//
// Log an error.
//
I8042_ERROR_VALUE_BASE + 545,
3
);
} else if ((status = I8xPutBytePolled(
)) != STATUS_SUCCESS) {
I8xPrint((
1,
"I8042PRT-I8xInitializeKeyboard: could not send SET LEDS param\n"
));
//
// Log an error.
//
dumpData[3] =
I8042_ERROR_VALUE_BASE + 550,
4
);
}
//
// NOTE: This code is necessary until the MIPS firmware stops
// selecting scan code set 3. Select scan code set 2 here.
// Since the translate bit is set, the net effect is that
// we will receive scan code set 1 bytes.
//
if (ENHANCED_KEYBOARD(*id)) {
);
if (NT_SUCCESS(status)) {
//
// Send the associated parameter byte.
//
(UCHAR) 2
);
}
if (!NT_SUCCESS(status)) {
I8xPrint((
1,
"I8042PRT-I8xInitializeKeyboard: could not send Select Scan command\n"
));
//
// This failed so probably what we have here isn't an enhanced
// keyboard at all. Make this an old style keyboard.
//
}
}
#endif
#ifdef JAPAN
// NLS Keyboard Support Code.
if (IBM02_KEYBOARD(*id)) {
//
// IBM-J 5576-002 Keyboard should set local scan code set for
// supplied NLS key.
//
);
if (status != STATUS_SUCCESS) {
I8xPrint((
1,
"I8042PRT-I8xInitializeKeyboard: could not send Select Scan command\n"
));
I8xPrint((
0,
"I8042PRT-I8xInitializeKeyboard: WARNING - using scan set 82h\n"
));
} else {
//
// Send the associated parameter byte.
//
(UCHAR) 0x82
);
if (status != STATUS_SUCCESS) {
I8xPrint((
1,
"I8042PRT-I8xInitializeKeyboard: could not send Select Scan param\n"
));
I8xPrint((
0,
"I8042PRT-I8xInitializeKeyboard: WARNING - using scan set 82h\n"
));
}
}
}
#endif
//
// Turn translate back on. The keyboard should, by default, send
// scan code set 2. When the translate bit in the 8042 command byte
// is on, the 8042 translates the scan code set 2 bytes to scan code
// set 1 before sending them to the CPU. Scan code set 1 is
// the industry standard scan code set.
//
// N.B. It does not appear to be possible to change the translate
// bit on some models of PS/2.
//
);
I8xPrint((
1,
"I8042PRT-I8xInitializeKeyboard: couldn't turn on translate\n"
));
//
// Could not turn translate back on. This happens on some
// PS/2 machines. In this case, select scan code set 1
// for the keyboard, since the 8042 will not do the
// translation from the scan code set 2, which is what the
// KEYBOARD_RESET caused the keyboard to default to.
//
if (ENHANCED_KEYBOARD(*id)) {
);
if (!NT_SUCCESS(status)) {
I8xPrint((
1,
"I8042PRT-I8xInitializeKeyboard: could not send Select Scan command\n"
));
I8xPrint((
0,
"I8042PRT-I8xInitializeKeyboard: WARNING - using scan set 2\n"
));
//
// Log an error.
//
I8042_ERROR_VALUE_BASE + 555,
3
);
} else {
//
// Send the associated parameter byte.
//
#ifdef JAPAN
// NLS Keyboard Support Code.
#else
(UCHAR) 1
#endif
);
if (!NT_SUCCESS(status)) {
I8xPrint((
1,
"I8042PRT-I8xInitializeKeyboard: could not send Select Scan param\n"
));
I8xPrint((
0,
"I8042PRT-I8xInitializeKeyboard: WARNING - using scan set 2\n"
));
//
// Log an error.
//
I8042_ERROR_VALUE_BASE + 560,
4
);
}
}
}
} else {
}
}
}
//
// If the keyboard initialization failed, log an error.
//
if (errorCode != STATUS_SUCCESS) {
(UCHAR) (sizeof(IO_ERROR_LOG_PACKET)
);
if (errorLogEntry != NULL) {
errorLogEntry->SequenceNumber = 0;
errorLogEntry->IoControlCode = 0;
errorLogEntry->RetryCount = 0;
for (i = 0; i < dumpCount; i++)
}
}
//
// Initialize current keyboard set packet state.
//
return(status);
}
)
/*++
Routine Description:
This routine retrieves the configuration information for the keyboard.
Arguments:
InitializationData - Pointer to the initialization data, including the
device extension.
RegistryPath - Pointer to the null-terminated Unicode name of the
registry path for this driver.
KeyboardDeviceName - Pointer to the Unicode string that will receive
the keyboard port device name.
PointerDeviceName - Pointer to the Unicode string that will receive
the pointer port device name.
Return Value:
None. As a side-effect, may set DeviceExtension->HardwarePresent.
--*/
{
ULONG i;
for (i = 0; i < MaximumInterfaceType; i++) {
//
// Get the registry information for this device.
//
interfaceType = i;
NULL,
NULL,
NULL,
//
// Get the service parameters (e.g., user-configurable number
// of resends, polling iterations, etc.).
//
);
if (!ENHANCED_KEYBOARD(*keyboardId)) {
I8xPrint((
1,
"I8042PRT-I8xKeyboardConfiguration: Old AT-style keyboard\n"
));
}
//
// Initialize keyboard-specific configuration parameters.
//
break;
} else {
I8xPrint((
1,
"I8042PRT-I8xKeyboardConfiguration: IoQueryDeviceDescription for bus type %d failed\n",
));
}
}
}
)
/*++
Routine Description:
This routine is called synchronously from I8xKeyboardInitiateWrapper and
the ISR to initiate an I/O operation for the keyboard device.
Arguments:
Context - Pointer to the device object.
Return Value:
None.
--*/
{
//
// Get the device extension.
//
//
// Set the timeout value.
//
//
// Get the current set request packet to work on.
//
== SendFirstByte){
I8xPrint((
2,
"I8042PRT-I8xKeyboardInitiateIo: send first byte 0x%x\n",
));
//
// Send the first byte of a 2-byte command sequence to the
// keyboard controller, asynchronously.
//
);
== SendLastByte) {
I8xPrint((
2,
"I8042PRT-I8xKeyboardInitiateIo: send last byte 0x%x\n",
));
//
// Send the last byte of a command sequence to the keyboard
// controller, asynchronously.
//
);
} else {
//
// Queue a DPC to log an internal driver error.
//
}
return;
}
)
/*++
Routine Description:
This routine is called from StartIo synchronously. It sets up the
CurrentOutput and ResendCount fields in the device extension, and
then calls I8xKeyboardInitiateIo to do the real work.
Arguments:
Context - Pointer to the context structure containing the first and
last bytes of the send sequence.
Return Value:
None.
--*/
{
//
// Get a pointer to the device object from the context argument.
//
//
// Set up CurrentOutput state for this operation.
//
//
// We're starting a new operation, so reset the resend count.
//
//
// Initiate the keyboard I/O operation. Note that we were called
// using KeSynchronizeExecution, so I8xKeyboardInitiateIo is also
// synchronized with the keyboard ISR.
//
}
)
/*++
Routine Description:
This is the callout routine sent as a parameter to
IoQueryDeviceDescription. It grabs the keyboard controller and
peripheral configuration information.
Arguments:
Context - Context parameter that was passed in by the routine
that called IoQueryDeviceDescription.
PathName - The full pathname for the registry key.
BusType - Bus interface type (Isa, Eisa, Mca, etc.).
BusNumber - The bus sub-key (0, 1, etc.).
BusInformation - Pointer to the array of pointers to the full value
information for the bus.
ControllerType - The controller type (should be KeyboardController).
ControllerNumber - The controller sub-key (0, 1, etc.).
ControllerInformation - Pointer to the array of pointers to the full
value information for the controller key.
PeripheralType - The peripheral type (should be KeyboardPeripheral).
PeripheralNumber - The peripheral sub-key.
PeripheralInformation - Pointer to the array of pointers to the full
value information for the peripheral key.
Return Value:
None. If successful, will have the following side-effects:
- Sets DeviceObject->DeviceExtension->HardwarePresent.
- Sets configuration fields in
DeviceObject->DeviceExtension->Configuration.
--*/
{
ULONG i;
I8xPrint((
1,
"I8042PRT-I8xKeyboardPeripheralCallout: Path @ 0x%x, Bus Type 0x%x, Bus Number 0x%x\n",
));
I8xPrint((
1,
" Controller Type 0x%x, Controller Number 0x%x, Controller info @ 0x%x\n",
));
I8xPrint((
1,
" Peripheral Type 0x%x, Peripheral Number 0x%x, Peripheral info @ 0x%x\n",
));
//
// Get the length of the peripheral identifier information.
//
//
// If we already have the configuration information for the
// keyboard peripheral, or if the peripheral identifier is missing,
// just return.
//
|| (unicodeIdentifier.Length == 0)) {
return (status);
}
//
// Get the identifier information for the peripheral.
//
I8xPrint((
1,
"I8042PRT-I8xKeyboardPeripheralCallout: Keyboard type %ws\n",
));
//
// Initialize the Keyboard Type to unknown.
//
//
// Look through the peripheral's resource list for device-specific
// information. The keyboard-specific information is defined
// in sdk\inc\ntconfig.h.
//
for (i = 0; i < listCount; i++, resourceDescriptor++) {
switch(resourceDescriptor->Type) {
//
// Get the keyboard type, subtype, and the initial
// settings for the LEDs.
//
+ sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
}
break;
default:
break;
}
}
}
//
// If no keyboard-specific information (i.e., keyboard type, subtype,
// and initial LED settings) was found, use the keyboard driver
// defaults.
//
//Fujitsu Aug.23.1994
// if not connect keyboard hardware,Insert 106 keyboard type to each structure members
// for realizing "keyboard-less system".
#endif
I8xPrint((
1,
"I8042PRT-I8xKeyboardPeripheralCallout: Using default keyboard type\n"
));
}
I8xPrint((
1,
"I8042PRT-I8xKeyboardPeripheralCallout: Keyboard device specific data --\n"
));
I8xPrint((
1,
" Type = %d, Subtype = %d, Initial LEDs = 0x%x\n",
));
//
// Get the bus information.
//
if (BusType == MicroChannel) {
} else {
}
//
// Look through the controller's resource list for interrupt and port
// configuration information.
//
for (i = 0; i < listCount; i++, resourceDescriptor++) {
switch(resourceDescriptor->Type) {
case CmResourceTypePort:
//
// Copy the port information. We will sort the port list
// into ascending order based on the starting port address
// later (note that we *know* there are a max of two port
// ranges for the i8042).
//
break;
case CmResourceTypeInterrupt:
//
// Copy the interrupt information.
//
break;
break;
default:
break;
}
}
}
//
// If no interrupt configuration information was found, use the
// keyboard driver defaults.
//
I8xPrint((
1,
"I8042PRT-I8xKeyboardPeripheralCallout: Using default keyboard interrupt config\n"
));
}
I8xPrint((
1,
"I8042PRT-I8xKeyboardPeripheralCallout: Keyboard interrupt config --\n"
));
I8xPrint((
1,
" %s, %s, Irq = %d\n",
"Sharable" : "NonSharable",
"Latched" : "Level Sensitive",
));
//
// If no port configuration information was found, use the
// keyboard driver defaults.
//
if (configuration->PortListCount == 0) {
//
// No port configuration information was found, so use
// the driver defaults.
//
I8xPrint((
1,
"I8042PRT-I8xKeyboardPeripheralCallout: Using default port config\n"
));
//
// Kludge for Jazz machines. Their ARC firmware neglects to
// separate out the port addresses, so fix that up here.
//
} else {
//
// Put the lowest port address range in the DataPort element of
// the port list.
//
}
}
#ifdef PNP_IDENTIFY
//
// We're going to use the keyboard based on this data,
// so make sure we can tell PNP that we've claimed it later on
//
#endif
for (i = 0; i < configuration->PortListCount; i++) {
I8xPrint((
1,
" %s, Ports 0x%x - 0x%x\n",
));
}
return(status);
}