Author: cfinck
Date: Thu Mar 20 07:21:34 2008
New Revision: 32725
URL:
http://svn.reactos.org/svn/reactos?rev=3D32725&view=3Drev
Log:
- The implementation of the "Mouse Reset" command differs much from chip to=
chip.
While most return an ACK or NACK as the first byte to indicate, whether a=
mouse is plugged in or not, some systems (like ECS K7S5A Pro, SiS735 chips=
et) always return an ACK and 0xAA.
Only the last byte indicates the status of the actual mouse. It is either=
sent as 0x00 or not.
Therefore only get the first two bytes in a loop and issue just one i8042=
ReadDataWait command for the last byte.
This reduced the "black screen time" in 1st stage setup (after loading th=
e drivers and before showing the language selection screen) from 45 seconds=
to 3 seconds on my K7S5A Pro system.
I also tested this change with three other systems, with and without mous=
e, and they are still detected properly.
- Wait 50 microseconds, when we got no data after the Mouse Reset and befor=
e trying it again.
This way, the implementation doesn't depend on the system speed.
- Break the loop, when the CTRL_SELF_TEST command completed successfully.
- Remove the return values from i8042DetectKeyboard and i8042DetectMouse.
We just used them for outputting debug info if no keyboard or mouse was d=
etected. But this info is already printed by the procedures themselves.
This way, I could also drop one variable in i8042DetectMouse :-)
Modified:
trunk/reactos/drivers/input/i8042prt/pnp.c
Modified: trunk/reactos/drivers/input/i8042prt/pnp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/input/i8042pr=
t/pnp.c?rev=3D32725&r1=3D32724&r2=3D32725&view=3Ddiff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- trunk/reactos/drivers/input/i8042prt/pnp.c (original)
+++ trunk/reactos/drivers/input/i8042prt/pnp.c Thu Mar 20 07:21:34 2008
@@ -4,6 +4,7 @@
* FILE: drivers/input/i8042prt/pnp.c
* PURPOSE: IRP_MJ_PNP operations
* PROGRAMMERS: Copyright 2006-2007 Herv=C3=A9 Poussineau (hpoussin@reacto=
s.org)
+ * Copyright 2008 Colin Finck (mail(a)colinfinck.de)
*/
=
/* INCLUDES **************************************************************=
****/
@@ -100,13 +101,17 @@
return Status;
}
=
- if (Value =3D=3D KBD_RESEND)
+ if (Value =3D=3D KBD_SELF_TEST_OK)
+ {
+ INFO_(I8042PRT, "CTRL_SELF_TEST completed successfully!\n");
+ break;
+ }
+ else if (Value =3D=3D KBD_RESEND)
{
TRACE_(I8042PRT, "Resending...\n", Value);
KeStallExecutionProcessor(50);
- continue;
- }
- else if (Value !=3D KBD_SELF_TEST_OK)
+ }
+ else
{
WARN_(I8042PRT, "Got 0x%02x instead of 0x55\n", Value);
return STATUS_IO_DEVICE_ERROR;
@@ -134,7 +139,7 @@
return STATUS_SUCCESS;
}
=
-static BOOLEAN
+static VOID
i8042DetectKeyboard(
IN PPORT_DEVICE_EXTENSION DeviceExtension)
{
@@ -148,7 +153,7 @@
if (!NT_SUCCESS(Status))
{
WARN_(I8042PRT, "Can't finish SET_LEDS (0x%08lx)\n", Status);
- return FALSE;
+ return;
}
}
else
@@ -158,19 +163,18 @@
=
/* Turn on translation and SF (Some machines don't reboot if SF is not se=
t, see ReactOS bug #1842) */
if (!i8042ChangeMode(DeviceExtension, 0, CCB_TRANSLATE | CCB_SYSTEM_FLAG))
- return FALSE;
-
- return TRUE;
-}
-
-static BOOLEAN
+ return;
+
+ INFO_(I8042PRT, "Keyboard detected\n");
+}
+
+static VOID
i8042DetectMouse(
IN PPORT_DEVICE_EXTENSION DeviceExtension)
{
- BOOLEAN Ok =3D FALSE;
NTSTATUS Status;
UCHAR Value;
- UCHAR ExpectedReply[] =3D { MOUSE_ACK, 0xAA, 0x00 };
+ UCHAR ExpectedReply[] =3D { MOUSE_ACK, 0xAA };
UCHAR ReplyByte;
=
i8042Flush(DeviceExtension);
@@ -179,9 +183,20 @@
||!i8042Write(DeviceExtension, DeviceExtension->DataPort, MOU_CMD_RESET=
))
{
WARN_(I8042PRT, "Failed to write reset command to mouse\n");
- goto cleanup;
- }
-
+ goto failure;
+ }
+
+ /* The implementation of the "Mouse Reset" command differs much from chip=
to chip.
+
+ By default, the first byte is an ACK, when the mouse is plugged in and=
working and NACK when it's not.
+ On success, the next bytes are 0xAA and 0x00.
+
+ But on some systems (like ECS K7S5A Pro, SiS 735 chipset), we always g=
et an ACK and 0xAA.
+ Only the last byte indicates, whether a mouse is plugged in.
+ It is either sent or not, so there is no byte, which indicates a failu=
re here.
+
+ After the Mouse Reset command was issued, it usually takes some time u=
ntil we get a response.
+ So get the first two bytes in a loop. */
for (ReplyByte =3D 0;
ReplyByte < sizeof(ExpectedReply) / sizeof(ExpectedReply[0]);
ReplyByte++)
@@ -191,39 +206,55 @@
do
{
Status =3D i8042ReadDataWait(DeviceExtension, &Value);
+
+ if(!NT_SUCCESS(Status))
+ {
+ /* Wait some time before trying again */
+ KeStallExecutionProcessor(50);
+ }
} while (Status =3D=3D STATUS_IO_TIMEOUT && Counter--);
=
if (!NT_SUCCESS(Status))
{
WARN_(I8042PRT, "No ACK after mouse reset, status 0x%08lx\n", Status);
- goto cleanup;
+ goto failure;
}
else if (Value !=3D ExpectedReply[ReplyByte])
{
- WARN_(I8042PRT, "Unexpected reply: 0x%02x (expected 0x%02x)\n",
- Value, ExpectedReply[ReplyByte]);
- goto cleanup;
- }
- }
-
- Ok =3D TRUE;
-
-cleanup:
- 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(DeviceExtension);
- i8042Write(DeviceExtension, DeviceExtension->ControlPort, CTRL_SELF_TEST=
);
- i8042ReadDataWait(DeviceExtension, &Value);
- i8042Flush(DeviceExtension);
- }
-
- INFO_(I8042PRT, "Mouse %sdetected\n", Ok ? "" : "not ");
-
- return Ok;
+ WARN_(I8042PRT, "Unexpected reply: 0x%02x (expected 0x%02x)\n", Value, =
ExpectedReply[ReplyByte]);
+ goto failure;
+ }
+ }
+
+ /* Finally get the third byte, but only try it one time (see above).
+ Otherwise this takes around 45 seconds on a K7S5A Pro, when no mouse i=
s plugged in. */
+ Status =3D i8042ReadDataWait(DeviceExtension, &Value);
+
+ if(!NT_SUCCESS(Status))
+ {
+ WARN_(I8042PRT, "Last byte was not transmitted after mouse reset, status=
0x%08lx\n", Status);
+ goto failure;
+ }
+ else if(Value !=3D 0x00)
+ {
+ WARN_(I8042PRT, "Last byte after mouse reset was not 0x00, but 0x%02x\n"=
, Value);
+ goto failure;
+ }
+
+ INFO_(I8042PRT, "Mouse detected\n");
+ return;
+
+failure:
+ /* 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(DeviceExtension);
+ i8042Write(DeviceExtension, DeviceExtension->ControlPort, CTRL_SELF_TEST);
+ i8042ReadDataWait(DeviceExtension, &Value);
+ i8042Flush(DeviceExtension);
+
+ INFO_(I8042PRT, "Mouse not detected\n");
}
=
static NTSTATUS
@@ -387,12 +418,10 @@
return STATUS_UNSUCCESSFUL;
}
TRACE_(I8042PRT, "Detecting keyboard\n");
- if (!i8042DetectKeyboard(DeviceExtension))
- INFO_(I8042PRT, "No keyboard detected!\n");
+ i8042DetectKeyboard(DeviceExtension);
=
TRACE_(I8042PRT, "Detecting mouse\n");
- if (!i8042DetectMouse(DeviceExtension))
- INFO_(I8042PRT, "No mouse detected!\n");
+ i8042DetectMouse(DeviceExtension);
=
INFO_(I8042PRT, "Keyboard present: %s\n", DeviceExtension->Flags &
KEYBO=
ARD_PRESENT ? "YES" : "NO");
INFO_(I8042PRT, "Mouse present : %s\n", DeviceExtension->Flags &
MOUSE=
_PRESENT ? "YES" : "NO");