From 007c18f5b7a3a105d212443ec6b4245c46006c80 Mon Sep 17 00:00:00 2001 From: gikidy Date: Fri, 5 Jun 2009 03:25:09 +0000 Subject: [PATCH] Enhance Ps2Mouse and Ps2Keyboard driver and fix for random hangs in System waiting for the Key if no KBC is present. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8473 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c | 17 +++++++++- .../Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h | 6 ++++ .../Bus/Isa/Ps2MouseDxe/Ps2Mouse.c | 33 ++++++++++++++----- 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c index 59c416628c..7c7c0bf27a 100644 --- a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c +++ b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c @@ -216,6 +216,21 @@ KbdControllerDriverStart ( ConsoleIn->ConInEx.UnregisterKeyNotify = KeyboardUnregisterKeyNotify; InitializeListHead (&ConsoleIn->NotifyList); + + // + // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS. + // + KeyboardRead (ConsoleIn, &Data); + if ((KeyReadStatusRegister (ConsoleIn) & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) { + // + // If nobody decodes KBC I/O port, it will read back as 0xFF. + // Check the Time-Out and Parity bit to see if it has an active KBC in system + // + Status = EFI_DEVICE_ERROR; + StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED; + goto ErrorExit; + } + // // Setup the WaitForKey event // @@ -355,7 +370,7 @@ ErrorExit: // if (ConsoleIn != NULL) { Status1 = EFI_SUCCESS; - while (!EFI_ERROR (Status1)) { + while (!EFI_ERROR (Status1) && (Status != EFI_DEVICE_ERROR)) { Status1 = KeyboardRead (ConsoleIn, &Data);; } } diff --git a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h index cbfbbda768..fd97f28d2e 100644 --- a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h +++ b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h @@ -180,6 +180,12 @@ InstallPs2KeyboardDriver ( #define SCANCODE_SYS_REQ_MAKE 0x37 #define SCANCODE_MAX_MAKE 0x60 +// +// Keyboard Controller Status +// +#define KBC_PARE 0x80 // Parity Error +#define KBC_TIM 0x40 // General Time Out + // // Other functions that are used among .c files // diff --git a/IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.c b/IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.c index 32b527c72c..084c3244ae 100644 --- a/IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.c +++ b/IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/Ps2Mouse.c @@ -228,6 +228,18 @@ PS2MouseDriverStart ( // Initialize keyboard controller if necessary // IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data); + // + // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS. + // + if ((Data & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) { + // + // If nobody decodes KBC I/O port, it will read back as 0xFF. + // Check the Time-Out and Parity bit to see if it has an active KBC in system + // + Status = EFI_DEVICE_ERROR; + StatusCode = EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED; + goto ErrorExit; + } if ((Data & KBC_SYSF) != KBC_SYSF) { Status = KbcSelfTest (IsaIo); if (EFI_ERROR (Status)) { @@ -329,7 +341,9 @@ PS2MouseDriverStart ( ErrorExit: - KbcDisableAux (IsaIo); + if (Status != EFI_DEVICE_ERROR) { + KbcDisableAux (IsaIo); + } if (StatusCode != 0) { REPORT_STATUS_CODE_WITH_DEVICE_PATH ( @@ -350,13 +364,16 @@ ErrorExit: if ((MouseDev != NULL) && (MouseDev->ControllerNameTable != NULL)) { FreeUnicodeStringTable (MouseDev->ControllerNameTable); } - // - // Since there will be no timer handler for mouse input any more, - // exhaust input data just in case there is still mouse data left - // - EmptyStatus = EFI_SUCCESS; - while (!EFI_ERROR (EmptyStatus)) { - EmptyStatus = In8042Data (IsaIo, &Data); + + if (Status != EFI_DEVICE_ERROR) { + // + // Since there will be no timer handler for mouse input any more, + // exhaust input data just in case there is still mouse data left + // + EmptyStatus = EFI_SUCCESS; + while (!EFI_ERROR (EmptyStatus)) { + EmptyStatus = In8042Data (IsaIo, &Data); + } } if (MouseDev != NULL) {