Modified: branches/ros-branch-0_2_8/reactos/drivers/input/i8042prt/i8042prt.c
Modified: branches/ros-branch-0_2_8/reactos/drivers/input/i8042prt/i8042prt.h
Modified: branches/ros-branch-0_2_8/reactos/drivers/input/i8042prt/keyboard.c
Modified: branches/ros-branch-0_2_8/reactos/drivers/input/i8042prt/mouse.c
--- branches/ros-branch-0_2_8/reactos/drivers/input/i8042prt/i8042prt.c 2005-10-21 20:28:05 UTC (rev 18664)
+++ branches/ros-branch-0_2_8/reactos/drivers/input/i8042prt/i8042prt.c 2005-10-21 20:31:59 UTC (rev 18665)
@@ -10,9 +10,7 @@
/* INCLUDES ****************************************************************/
-#ifndef NDEBUG
#define NDEBUG
-#endif
#include <debug.h>
#include "i8042prt.h"
@@ -78,7 +76,7 @@
DPRINT("Read: %x (status: %x)\n", Data[0], Status);
// If the data is valid (not timeout, not parity error)
- if (0 == (Status & (KBD_GTO | KBD_PERR)))
+ if (0 == (Status & KBD_PERR))
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
@@ -115,7 +113,7 @@
UCHAR Ignore;
while (STATUS_SUCCESS == I8042ReadData(&Ignore)) {
- ; /* drop */
+ DPRINT("Data flushed\n"); /* drop */
}
}
@@ -146,25 +144,38 @@
do {
if (Port)
if (!I8042Write(DevExt, I8042_DATA_PORT, Port))
- return STATUS_TIMEOUT;
+ {
+ DPRINT1("Failed to write Port\n");
+ return STATUS_IO_TIMEOUT;
+ }
if (!I8042Write(DevExt, I8042_DATA_PORT, Value))
- return STATUS_TIMEOUT;
+ {
+ DPRINT1("Failed to write Value\n");
+ return STATUS_IO_TIMEOUT;
+ }
if (WaitForAck) {
Status = I8042ReadDataWait(DevExt, &Ack);
if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to read Ack\n");
return Status;
+ }
if (Ack == KBD_ACK)
return STATUS_SUCCESS;
if (Ack != KBD_RESEND)
+ {
+ DPRINT1("Unexpected Ack 0x%x\n", Ack);
return STATUS_UNEXPECTED_IO_ERROR;
+ }
} else {
return STATUS_SUCCESS;
}
+ DPRINT("Reiterating\n");
ResendIterations--;
} while (ResendIterations);
- return STATUS_TIMEOUT;
+ return STATUS_IO_TIMEOUT;
}
/*
@@ -241,7 +252,7 @@
DevExt->PacketPort = 0;
if (!I8042PacketWrite(DevExt)) {
- Status = STATUS_TIMEOUT;
+ Status = STATUS_IO_TIMEOUT;
DevExt->Packet.State = Idle;
DevExt->PacketResult = STATUS_ABANDONED;
goto startpacketdone;
@@ -273,7 +284,7 @@
if (DevExt->PacketResends > DevExt->Settings.ResendIterations) {
DevExt->Packet.State = Idle;
DevExt->PacketComplete = TRUE;
- DevExt->PacketResult = STATUS_TIMEOUT;
+ DevExt->PacketResult = STATUS_IO_TIMEOUT;
DevExt->PacketResends = 0;
return TRUE;
}
@@ -301,7 +312,7 @@
if (!I8042PacketWrite(DevExt)) {
DevExt->Packet.State = Idle;
DevExt->PacketComplete = TRUE;
- DevExt->PacketResult = STATUS_TIMEOUT;
+ DevExt->PacketResult = STATUS_IO_TIMEOUT;
return TRUE;
}
DevExt->Packet.CurrentByte++;
@@ -519,23 +530,53 @@
I8042Flush();
- if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_SELF_TEST))
- return STATUS_TIMEOUT;
+ if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_SELF_TEST)) {
+ DPRINT1("Writing KBD_SELF_TEST command failed\n");
+ return STATUS_IO_TIMEOUT;
+ }
// Wait longer?
Counter = 3;
do {
Status = I8042ReadDataWait(DevExt, &Value);
- } while ((Counter--) && (STATUS_TIMEOUT == Status));
+ } while ((Counter--) && (STATUS_IO_TIMEOUT == Status));
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status)) {
+ DPRINT1("Failed to read KBD_SELF_TEST response, status 0x%x\n",
+ Status);
return Status;
+ }
if (Value != 0x55) {
DPRINT1("Got %x instead of 55\n", Value);
return STATUS_IO_DEVICE_ERROR;
}
+ if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) {
+ DPRINT1("Can't read i8042 mode\n");
+ return FALSE;
+ }
+
+ Status = I8042ReadDataWait(DevExt, &Value);
+ if (!NT_SUCCESS(Status)) {
+ DPRINT1("No response after read i8042 mode\n");
+ return FALSE;
+ }
+
+ Value |= CCB_KBD_DISAB | CCB_MOUSE_DISAB; /* disable keyboard/mouse */
+ Value &= ~(CCB_KBD_INT_ENAB | CCB_MOUSE_INT_ENAB);
+ /* don't enable keyboard and mouse interrupts */
+
+ if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) {
+ DPRINT1("Can't set i8042 mode\n");
+ return FALSE;
+ }
+
+ if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) {
+ DPRINT1("Can't send i8042 mode\n");
+ return FALSE;
+ }
+
if (I8042Write(DevExt, I8042_CTRL_PORT, KBD_LINE_TEST))
{
Status = I8042ReadDataWait(DevExt, &Value);
@@ -563,6 +604,11 @@
return Status;
}
+ if (DevExt->MouseExists) {
+ DPRINT("Aux port detected\n");
+ DevExt->MouseExists = I8042DetectMouse(DevExt);
+ }
+
if (!DevExt->KeyboardExists) {
DPRINT("Keyboard port not detected\n");
if (DevExt->Settings.Headless)
@@ -820,4 +866,3 @@
return(STATUS_SUCCESS);
}
-
--- branches/ros-branch-0_2_8/reactos/drivers/input/i8042prt/i8042prt.h 2005-10-21 20:28:05 UTC (rev 18664)
+++ branches/ros-branch-0_2_8/reactos/drivers/input/i8042prt/i8042prt.h 2005-10-21 20:31:59 UTC (rev 18665)
@@ -246,7 +246,18 @@
#define KBD_GTO 0x40
#define KBD_PERR 0x80
+/*
+ * Controller command byte bits
+ */
+#define CCB_KBD_INT_ENAB 0x01
+#define CCB_MOUSE_INT_ENAB 0x02
+#define CCB_SYSTEM_FLAG 0x04
+#define CCB_IGN_KEY_LOCK 0x08
+#define CCB_KBD_DISAB 0x10
+#define CCB_MOUSE_DISAB 0x20
+#define CCB_TRANSLATE 0x40
+
/*
* LED bits
*/
@@ -359,6 +370,7 @@
BOOLEAN STDCALL I8042MouseEnable(PDEVICE_EXTENSION DevExt);
BOOLEAN STDCALL I8042MouseDisable(PDEVICE_EXTENSION DevExt);
+BOOLEAN STDCALL I8042DetectMouse(PDEVICE_EXTENSION DevExt);
/* ps2pp.c */
VOID I8042MouseHandlePs2pp(PDEVICE_EXTENSION DevExt, UCHAR Input);
--- branches/ros-branch-0_2_8/reactos/drivers/input/i8042prt/keyboard.c 2005-10-21 20:28:05 UTC (rev 18664)
+++ branches/ros-branch-0_2_8/reactos/drivers/input/i8042prt/keyboard.c 2005-10-21 20:31:59 UTC (rev 18665)
@@ -11,13 +11,11 @@
/* INCLUDES ****************************************************************/
-#ifndef NDEBUG
+#include "i8042prt.h"
+
#define NDEBUG
-#endif
#include <debug.h>
-#include "i8042prt.h"
-
/* GLOBALS *******************************************************************/
static UCHAR TypematicTable[] = {
@@ -559,34 +557,73 @@
* some really old broken keyboard controllers which I hope won't be
* necessary.
*
- * Anyway, disabling the keyboard helps the detection and it also
- * clears the keyboard buffer and sets defaults which is what we
- * want.
+ * We change the command byte, sending KBD_ENABLE/DISABLE seems to confuse
+ * some kvm switches.
*/
BOOLEAN STDCALL I8042KeyboardEnable(PDEVICE_EXTENSION DevExt)
{
- DPRINT("Enabling keyboard\n");
- if (STATUS_SUCCESS != I8042SynchWritePort(DevExt,
- 0,
- KBD_ENABLE,
- TRUE)) {
- DPRINT("Can't enable keyboard\n");
+ UCHAR Value;
+ NTSTATUS Status;
+
+ DPRINT("Enable keyboard\n");
+
+ if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) {
+ DPRINT1("Can't read i8042 mode\n");
return FALSE;
}
+
+ Status = I8042ReadDataWait(DevExt, &Value);
+ if (!NT_SUCCESS(Status)) {
+ DPRINT1("No response after read i8042 mode\n");
+ return FALSE;
+ }
+
+ Value &= ~CCB_KBD_DISAB; // don't disable keyboard
+
+ if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) {
+ DPRINT1("Can't set i8042 mode\n");
+ return FALSE;
+ }
+
+ if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) {
+ DPRINT1("Can't send i8042 mode\n");
+ return FALSE;
+ }
+
return TRUE;
}
static BOOLEAN STDCALL I8042KeyboardDefaultsAndDisable(PDEVICE_EXTENSION DevExt)
{
+ UCHAR Value;
+ NTSTATUS Status;
+
DPRINT("Disabling keyboard\n");
- if (STATUS_SUCCESS != I8042SynchWritePort(DevExt,
- 0,
- KBD_DISABLE,
- TRUE)) {
- DPRINT("Can't disable keyboard\n");
+
+ if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_READ_MODE)) {
+ DPRINT1("Can't read i8042 mode\n");
return FALSE;
}
+
+ Status = I8042ReadDataWait(DevExt, &Value);
+ if (!NT_SUCCESS(Status)) {
+ DPRINT1("No response after read i8042 mode\n");
+ return FALSE;
+ }
+
+ Value |= CCB_KBD_DISAB; // disable keyboard
+
+ if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) {
+ DPRINT1("Can't set i8042 mode\n");
+ return FALSE;
+ }
+
+ if (!I8042Write(DevExt, I8042_DATA_PORT, Value)) {
+ DPRINT1("Can't send i8042 mode\n");
+ return FALSE;
+ }
+
return TRUE;
}
@@ -608,8 +645,8 @@
return FALSE;
}
- Value &= ~(0x10); // don't disable keyboard
- Value |= 0x01; // enable keyboard interrupts
+ Value &= ~CCB_KBD_DISAB; // don't disable keyboard
+ Value |= CCB_KBD_INT_ENAB; // enable keyboard interrupts
if (!I8042Write(DevExt, I8042_CTRL_PORT, KBD_WRITE_MODE)) {
DPRINT1("Can't set i8042 mode\n");
@@ -628,6 +665,7 @@
{
NTSTATUS Status;
UCHAR Value;
+ UCHAR Value2;
ULONG RetryCount = 10;
DPRINT("Detecting keyboard\n");
@@ -635,12 +673,15 @@
I8042KeyboardDefaultsAndDisable(DevExt);
do {
+ I8042Flush();
Status = I8042SynchWritePort(DevExt, 0, KBD_GET_ID, TRUE);
- } while (STATUS_TIMEOUT == Status && RetryCount--);
+ } while (STATUS_IO_TIMEOUT == Status && RetryCount--);
if (!NT_SUCCESS(Status)) {
DPRINT1("Can't write GET_ID (%x)\n", Status);
- return FALSE;
+ /* Could be an AT keyboard */
+ DevExt->KeyboardIsAT = TRUE;
+ goto detectsetleds;
}
Status = I8042ReadDataWait(DevExt, &Value);
@@ -658,17 +699,17 @@
return FALSE;
}
- DPRINT("Keyboard ID: %x", Value);
-
- Status = I8042ReadDataWait(DevExt, &Value);
+ Status = I8042ReadDataWait(DevExt, &Value2);
if (!NT_SUCCESS(Status)) {
DPRINT("Partial ID\n");
return FALSE;
}
- DPRINT ("%x\n", Value);
+ DPRINT("Keyboard ID: 0x%x 0x%x\n", Value, Value2);
detectsetleds:
+ I8042Flush(); /* Flush any bytes left over from GET_ID */
+
Status = I8042SynchWritePort(DevExt, 0, KBD_SET_LEDS, TRUE);
if (!NT_SUCCESS(Status)) {
DPRINT("Can't write SET_LEDS (%x)\n", Status);
--- branches/ros-branch-0_2_8/reactos/drivers/input/i8042prt/mouse.c 2005-10-21 20:28:05 UTC (rev 18664)
+++ branches/ros-branch-0_2_8/reactos/drivers/input/i8042prt/mouse.c 2005-10-21 20:31:59 UTC (rev 18665)
@@ -11,13 +11,11 @@
/* INCLUDES ****************************************************************/
-#ifndef NDEBUG
+#include "i8042prt.h"
+
#define NDEBUG
-#endif
#include <debug.h>
-#include "i8042prt.h"
-
/*
* These functions are callbacks for filter driver custom interrupt
* service routines.
@@ -897,3 +895,54 @@
return TRUE;
}
+
+BOOLEAN STDCALL I8042DetectMouse(PDEVICE_EXTENSION DevExt)
+{
+ BOOLEAN Ok = TRUE;
+ NTSTATUS Status;
+ UCHAR Value;
+ UCHAR ExpectedReply[] = { 0xFA, 0xAA, 0x00 };
+ unsigned ReplyByte;
+
+ if (! I8042Write(DevExt, I8042_CTRL_PORT, 0xD4) ||
+ ! I8042Write(DevExt, I8042_DATA_PORT, 0xFF))
+ {
+ DPRINT1("Failed to write reset command to mouse\n");
+ Ok = FALSE;
+ }
+
+ for (ReplyByte = 0;
+ ReplyByte < sizeof(ExpectedReply) / sizeof(ExpectedReply[0]) && Ok;
+ ReplyByte++)
+ {
+ Status = I8042ReadDataWait(DevExt, &Value);
+ if (! NT_SUCCESS(Status))
+ {
+ DPRINT1("No ACK after mouse reset, status 0x%08x\n",
+ Status);
+ Ok = FALSE;
+ }
+ else if (Value != ExpectedReply[ReplyByte])
+ {
+ DPRINT1("Unexpected reply: 0x%02x (expected 0x%02x)\n",
+ Value, ExpectedReply[ReplyByte]);
+ Ok = FALSE;
+ }
+ }
+
+ if (! Ok)
+ {
+ /* There is probably no mouse present. On some systems,
+ the probe locks the entire keyboard controller. Let's
+ try to get access to the keyboard again by sending a
+ reset */
+ I8042Flush();
+ I8042Write(DevExt, I8042_CTRL_PORT, KBD_SELF_TEST);
+ I8042ReadDataWait(DevExt, &Value);
+ I8042Flush();
+ }
+
+ DPRINT("Mouse %sdetected\n", Ok ? "" : "not ");
+
+ return Ok;
+}