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@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");