/** @file
  PS2 Mouse Communication Interface.
  
Copyright (c) 2006 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Ps2MouseAbsolutePointer.h"
#include "CommPs2.h"

UINT8 SampleRateTbl[MaxSampleRate]  = { 0xa, 0x14, 0x28, 0x3c, 0x50, 0x64, 0xc8 };

UINT8 ResolutionTbl[MaxResolution]  = { 0, 1, 2, 3 };

/**
  Issue self test command via IsaIo interface.
  
  @param IsaIo Pointer to instance of EFI_ISA_IO_PROTOCOL
  
  @return EFI_SUCCESS  Success to do keyboard self testing.
  @return others       Fail to do keyboard self testing.
**/
EFI_STATUS
KbcSelfTest (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo
  )
{
  EFI_STATUS  Status;
  UINT8       Data;

  //
  // Keyboard controller self test
  //
  Status = Out8042Command (IsaIo, SELF_TEST);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Read return code
  //
  Status = In8042Data (IsaIo, &Data);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (Data != 0x55) {
    return EFI_DEVICE_ERROR;
  }
  //
  // Set system flag
  //
  Status = Out8042Command (IsaIo, READ_CMD_BYTE);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = In8042Data (IsaIo, &Data);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = Out8042Command (IsaIo, WRITE_CMD_BYTE);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Data |= CMD_SYS_FLAG;
  Status = Out8042Data (IsaIo, Data);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  Issue command to enable keyboard AUX functionality.
  
  @param IsaIo  Pointer to instance of EFI_ISA_IO_PROTOCOL
  
  @return Status of command issuing.
**/
EFI_STATUS
KbcEnableAux (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo
  )
{
  //
  // Send 8042 enable mouse command
  //
  return Out8042Command (IsaIo, ENABLE_AUX);
}

/**
  Issue command to disable keyboard AUX functionality.
  
  @param IsaIo  Pointer to instance of EFI_ISA_IO_PROTOCOL
  
  @return Status of command issuing.
**/
EFI_STATUS
KbcDisableAux (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo
  )
{
  //
  // Send 8042 disable mouse command
  //
  return Out8042Command (IsaIo, DISABLE_AUX);
}

/**
  Issue command to enable keyboard.
  
  @param IsaIo  Pointer to instance of EFI_ISA_IO_PROTOCOL
  
  @return Status of command issuing.
**/
EFI_STATUS
KbcEnableKb (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo
  )
{
  //
  // Send 8042 enable keyboard command
  //
  return Out8042Command (IsaIo, ENABLE_KB);
}

/**
  Issue command to disable keyboard.
  
  @param IsaIo  Pointer to instance of EFI_ISA_IO_PROTOCOL
  
  @return Status of command issuing.
**/
EFI_STATUS
KbcDisableKb (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo
  )
{
  //
  // Send 8042 disable keyboard command
  //
  return Out8042Command (IsaIo, DISABLE_KB);
}

/**
  Issue command to check keyboard status.
  
  @param IsaIo          Pointer to instance of EFI_ISA_IO_PROTOCOL
  @param KeyboardEnable return whether keyboard is enable.
  
  @return Status of command issuing.
**/
EFI_STATUS
CheckKbStatus (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo,
  OUT BOOLEAN                             *KeyboardEnable
  )
{
  EFI_STATUS  Status;
  UINT8       Data;

  //
  // Send command to read KBC command byte
  //
  Status = Out8042Command (IsaIo, READ_CMD_BYTE);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = In8042Data (IsaIo, &Data);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Check keyboard enable or not
  //
  if ((Data & CMD_KB_STS) == CMD_KB_DIS) {
    *KeyboardEnable = FALSE;
  } else {
    *KeyboardEnable = TRUE;
  }

  return EFI_SUCCESS;
}

/**
  Issue command to reset keyboard.
  
  @param IsaIo  Pointer to instance of EFI_ISA_IO_PROTOCOL
  
  @return Status of command issuing.
**/
EFI_STATUS
PS2MouseReset (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo
  )
{
  EFI_STATUS  Status;
  UINT8       Data;

  Status = Out8042AuxCommand (IsaIo, RESET_CMD, FALSE);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = In8042AuxData (IsaIo, &Data);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Check BAT Complete Code
  //
  if (Data != PS2MOUSE_BAT1) {
    return EFI_DEVICE_ERROR;
  }

  Status = In8042AuxData (IsaIo, &Data);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Check BAT Complete Code
  //
  if (Data != PS2MOUSE_BAT2) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

/**
  Issue command to set mouse's sample rate
  
  @param IsaIo  Pointer to instance of EFI_ISA_IO_PROTOCOL
  @param SampleRate value of sample rate 
  
  @return Status of command issuing.
**/
EFI_STATUS
PS2MouseSetSampleRate (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo,
  IN MOUSE_SR                             SampleRate
  )
{
  EFI_STATUS  Status;

  //
  // Send auxiliary command to set mouse sample rate
  //
  Status = Out8042AuxCommand (IsaIo, SETSR_CMD, FALSE);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = Out8042AuxData (IsaIo, SampleRateTbl[SampleRate]);

  return Status;
}

/**
  Issue command to set mouse's resolution.
  
  @param IsaIo  Pointer to instance of EFI_ISA_IO_PROTOCOL
  @param Resolution value of resolution
  
  @return Status of command issuing.
**/
EFI_STATUS
PS2MouseSetResolution (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo,
  IN MOUSE_RE                             Resolution
  )
{
  EFI_STATUS  Status;

  //
  // Send auxiliary command to set mouse resolution
  //
  Status = Out8042AuxCommand (IsaIo, SETRE_CMD, FALSE);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = Out8042AuxData (IsaIo, ResolutionTbl[Resolution]);

  return Status;
}

/**
  Issue command to set mouse's scaling.
  
  @param IsaIo  Pointer to instance of EFI_ISA_IO_PROTOCOL
  @param Scaling value of scaling
  
  @return Status of command issuing.
**/
EFI_STATUS
PS2MouseSetScaling (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo,
  IN MOUSE_SF                             Scaling
  )
{
  UINT8 Command;

  Command = (UINT8) (Scaling == Scaling1 ? SETSF1_CMD : SETSF2_CMD);

  //
  // Send auxiliary command to set mouse scaling data
  //
  return Out8042AuxCommand (IsaIo, Command, FALSE);
}

/**
  Issue command to enable Ps2 mouse.
  
  @param IsaIo  Pointer to instance of EFI_ISA_IO_PROTOCOL
  
  @return Status of command issuing.
**/
EFI_STATUS
PS2MouseEnable (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo
  )
{
  //
  // Send auxiliary command to enable mouse
  //
  return Out8042AuxCommand (IsaIo, ENABLE_CMD, FALSE);
}

/**
  Get mouse packet . Only care first 3 bytes

  @param MouseAbsolutePointerDev  Pointer to PS2 Absolute Pointer Simulation Device Private Data Structure 

  @retval EFI_NOT_READY  Mouse Device not ready to input data packet, or some error happened during getting the packet
  @retval EFI_SUCCESS    The data packet is gotten successfully.

**/
EFI_STATUS
PS2MouseGetPacket (
  PS2_MOUSE_ABSOLUTE_POINTER_DEV     *MouseAbsolutePointerDev
  )

{
  EFI_STATUS  Status;
  BOOLEAN     KeyboardEnable;
  UINT8       Packet[PS2_PACKET_LENGTH];
  UINT8       Data;
  UINTN       Count;
  UINTN       State;
  INT16       RelativeMovementX;
  INT16       RelativeMovementY;
  BOOLEAN     LButton;
  BOOLEAN     RButton;

  KeyboardEnable  = FALSE;
  Count           = 1;
  State           = PS2_READ_BYTE_ONE;

  //
  // State machine to get mouse packet
  //
  while (1) {

    switch (State) {
    case PS2_READ_BYTE_ONE:
      //
      // Read mouse first byte data, if failed, immediately return
      //
      KbcDisableAux (MouseAbsolutePointerDev->IsaIo);
      Status = PS2MouseRead (MouseAbsolutePointerDev->IsaIo, &Data, &Count, State);
      if (EFI_ERROR (Status)) {
        KbcEnableAux (MouseAbsolutePointerDev->IsaIo);
        return EFI_NOT_READY;
      }

      if (Count != 1) {
        KbcEnableAux (MouseAbsolutePointerDev->IsaIo);
        return EFI_NOT_READY;
      }

      if (IS_PS2_SYNC_BYTE (Data)) {
        Packet[0] = Data;
        State     = PS2_READ_DATA_BYTE;

        CheckKbStatus (MouseAbsolutePointerDev->IsaIo, &KeyboardEnable);
        KbcDisableKb (MouseAbsolutePointerDev->IsaIo);
        KbcEnableAux (MouseAbsolutePointerDev->IsaIo);
      }
      break;

    case PS2_READ_DATA_BYTE:
      Count   = 2;
      Status  = PS2MouseRead (MouseAbsolutePointerDev->IsaIo, (Packet + 1), &Count, State);
      if (EFI_ERROR (Status)) {
        if (KeyboardEnable) {
          KbcEnableKb (MouseAbsolutePointerDev->IsaIo);
        }

        return EFI_NOT_READY;
      }

      if (Count != 2) {
        if (KeyboardEnable) {
          KbcEnableKb (MouseAbsolutePointerDev->IsaIo);
        }

        return EFI_NOT_READY;
      }

      State = PS2_PROCESS_PACKET;
      break;

    case PS2_PROCESS_PACKET:
      if (KeyboardEnable) {
        KbcEnableKb (MouseAbsolutePointerDev->IsaIo);
      }
      //
      // Decode the packet
      //
      RelativeMovementX = Packet[1];
      RelativeMovementY = Packet[2];
      //
      //               Bit 7   |    Bit 6   |    Bit 5   |   Bit 4    |   Bit 3  |   Bit 2    |   Bit 1   |   Bit 0 
      //  Byte 0  | Y overflow | X overflow | Y sign bit | X sign bit | Always 1 | Middle Btn | Right Btn | Left Btn 
      //  Byte 1  |                                           8 bit X Movement 
      //  Byte 2  |                                           8 bit Y Movement 
      // 
      // X sign bit + 8 bit X Movement : 9-bit signed twos complement integer that presents the relative displacement of the device in the X direction since the last data transmission.
      // Y sign bit + 8 bit Y Movement : Same as X sign bit + 8 bit X Movement.
      //
      //
      // First, Clear X and Y high 8 bits
      //
      RelativeMovementX = (INT16) (RelativeMovementX & 0xFF); 
      RelativeMovementY = (INT16) (RelativeMovementY & 0xFF); 
      //
      // Second, if the 9-bit signed twos complement integer is negative, set the high 8 bit 0xff
      //
      if ((Packet[0] & 0x10) != 0) {
        RelativeMovementX = (INT16) (RelativeMovementX | 0xFF00);
      }
      if ((Packet[0] & 0x20) != 0) {
        RelativeMovementY = (INT16) (RelativeMovementY | 0xFF00);
      }

      
      RButton           = (UINT8) (Packet[0] & 0x2);
      LButton           = (UINT8) (Packet[0] & 0x1);

      //
      // Update mouse state
      //
      MouseAbsolutePointerDev->State.CurrentX += RelativeMovementX;
      MouseAbsolutePointerDev->State.CurrentY -= RelativeMovementY;
      MouseAbsolutePointerDev->State.CurrentZ = 0;
      MouseAbsolutePointerDev->State.ActiveButtons = (UINT8) (LButton || RButton) & 0x3;
      MouseAbsolutePointerDev->StateChanged      = TRUE;

      return EFI_SUCCESS;
    }
  }
}

/**
  Read data via IsaIo protocol with given number.
  
  @param IsaIo   Pointer to instance of EFI_ISA_IO_PROTOCOL
  @param Buffer  Buffer receive data of mouse
  @param BufSize The size of buffer
  @param State   Check input or read data
  
  @return status of reading mouse data.
**/
EFI_STATUS
PS2MouseRead (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo,
  OUT VOID                                *Buffer,
  IN OUT UINTN                            *BufSize,
  IN  UINTN                               State
  )
{
  EFI_STATUS  Status;
  UINTN       BytesRead;

  Status    = EFI_SUCCESS;
  BytesRead = 0;

  if (State == PS2_READ_BYTE_ONE) {
    //
    // Check input for mouse
    //
    Status = CheckForInput (IsaIo);

    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  while (BytesRead < *BufSize) {

    Status = WaitOutputFull (IsaIo, TIMEOUT);
    if (EFI_ERROR (Status)) {
      break;
    }

    IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, Buffer);

    BytesRead++;
    Buffer = (UINT8 *) Buffer + 1;
  }
  //
  // Verify the correct number of bytes read
  //
  if (BytesRead == 0 || BytesRead != *BufSize) {
    Status = EFI_NOT_FOUND;
  }

  *BufSize = BytesRead;
  return Status;
}

//
// 8042 I/O function
//
/**
  I/O work flow of outing 8042 command.
  
  @param IsaIo   Pointer to instance of EFI_ISA_IO_PROTOCOL
  @param Command I/O command.
  
  @retval EFI_SUCCESS Success to excute I/O work flow
  @retval EFI_TIMEOUT Keyboard controller time out.
**/
EFI_STATUS
Out8042Command (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo,
  IN UINT8                                Command
  )
{
  EFI_STATUS  Status;
  UINT8       Data;

  //
  // Wait keyboard controller input buffer empty
  //
  Status = WaitInputEmpty (IsaIo, TIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Send command
  //
  Data = Command;
  IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);

  Status = WaitInputEmpty (IsaIo, TIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  I/O work flow of outing 8042 data.
  
  @param IsaIo   Pointer to instance of EFI_ISA_IO_PROTOCOL
  @param Data    Data value
  
  @retval EFI_SUCCESS Success to excute I/O work flow
  @retval EFI_TIMEOUT Keyboard controller time out.
**/
EFI_STATUS
Out8042Data (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo,
  IN UINT8                                Data
  )
{
  EFI_STATUS  Status;
  UINT8       Temp;
  //
  // Wait keyboard controller input buffer empty
  //
  Status = WaitInputEmpty (IsaIo, TIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Temp = Data;
  IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Temp);

  Status = WaitInputEmpty (IsaIo, TIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  I/O work flow of in 8042 data.
  
  @param IsaIo   Pointer to instance of EFI_ISA_IO_PROTOCOL
  @param Data    Data value
  
  @retval EFI_SUCCESS Success to excute I/O work flow
  @retval EFI_TIMEOUT Keyboard controller time out.
**/
EFI_STATUS
In8042Data (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo,
  IN OUT UINT8                            *Data
  )
{
  UINTN Delay;
  UINT8 Temp;

  Delay = TIMEOUT / 50;

  do {
    IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Temp);

    //
    // Check keyboard controller status bit 0(output buffer status)
    //
    if ((Temp & KBC_OUTB) == KBC_OUTB) {
      break;
    }

    gBS->Stall (50);
    Delay--;
  } while (Delay != 0);

  if (Delay == 0) {
    return EFI_TIMEOUT;
  }

  IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, Data);

  return EFI_SUCCESS;
}

/**
  I/O work flow of outing 8042 Aux command.
  
  @param IsaIo   Pointer to instance of EFI_ISA_IO_PROTOCOL
  @param Command Aux I/O command
  @param Resend  Whether need resend the Aux command.
  
  @retval EFI_SUCCESS Success to excute I/O work flow
  @retval EFI_TIMEOUT Keyboard controller time out.
**/
EFI_STATUS
Out8042AuxCommand (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo,
  IN UINT8                                Command,
  IN BOOLEAN                              Resend
  )
{
  EFI_STATUS  Status;
  UINT8       Data;

  //
  // Wait keyboard controller input buffer empty
  //
  Status = WaitInputEmpty (IsaIo, TIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Send write to auxiliary device command
  //
  Data = WRITE_AUX_DEV;
  IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);

  Status = WaitInputEmpty (IsaIo, TIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Send auxiliary device command
  //
  IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Command);

  //
  // Read return code
  //
  Status = In8042AuxData (IsaIo, &Data);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (Data == PS2_ACK) {
    //
    // Receive mouse acknowledge, command send success
    //
    return EFI_SUCCESS;

  } else if (Resend) {
    //
    // Resend fail
    //
    return EFI_DEVICE_ERROR;

  } else if (Data == PS2_RESEND) {
    //
    // Resend command
    //
    Status = Out8042AuxCommand (IsaIo, Command, TRUE);
    if (EFI_ERROR (Status)) {
      return Status;
    }

  } else {
    //
    // Invalid return code
    //
    return EFI_DEVICE_ERROR;

  }

  return EFI_SUCCESS;
}

/**
  I/O work flow of outing 8042 Aux data.
  
  @param IsaIo   Pointer to instance of EFI_ISA_IO_PROTOCOL
  @param Data    Buffer holding return value  
  
  @retval EFI_SUCCESS Success to excute I/O work flow.
  @retval EFI_TIMEOUT Keyboard controller time out.
**/
EFI_STATUS
Out8042AuxData (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo,
  IN UINT8                                Data
  )
{
  EFI_STATUS  Status;
  UINT8       Temp;
  //
  // Wait keyboard controller input buffer empty
  //
  Status = WaitInputEmpty (IsaIo, TIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Send write to auxiliary device command
  //
  Temp = WRITE_AUX_DEV;
  IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Temp);

  Status = WaitInputEmpty (IsaIo, TIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Temp = Data;
  IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Temp);

  Status = WaitInputEmpty (IsaIo, TIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  I/O work flow of in 8042 Aux data.
  
  @param IsaIo   Pointer to instance of EFI_ISA_IO_PROTOCOL
  @param Data    Buffer holding return value.
  
  @retval EFI_SUCCESS Success to excute I/O work flow
  @retval EFI_TIMEOUT Keyboard controller time out.
**/
EFI_STATUS
In8042AuxData (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo,
  IN OUT UINT8                            *Data
  )
{
  EFI_STATUS  Status;

  //
  // wait for output data
  //
  Status = WaitOutputFull (IsaIo, BAT_TIMEOUT);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, Data);

  return EFI_SUCCESS;
}


/**
  Check keyboard controller status, if it is output buffer full and for auxiliary device.
  
  @param IsaIo   Pointer to instance of EFI_ISA_IO_PROTOCOL
  
  @retval EFI_SUCCESS   Keyboard controller is ready
  @retval EFI_NOT_READY Keyboard controller is not ready
**/
EFI_STATUS
CheckForInput (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo
  )
{
  UINT8 Data;

  IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);

  //
  // Check keyboard controller status, if it is output buffer full and for auxiliary device
  //
  if ((Data & (KBC_OUTB | KBC_AUXB)) != (KBC_OUTB | KBC_AUXB)) {
    return EFI_NOT_READY;
  }

  return EFI_SUCCESS;
}

/**
  I/O work flow to wait input buffer empty in given time.
  
  @param IsaIo   Pointer to instance of EFI_ISA_IO_PROTOCOL
  @param Timeout Wating time.
  
  @retval EFI_TIMEOUT if input is still not empty in given time.
  @retval EFI_SUCCESS input is empty.
**/
EFI_STATUS
WaitInputEmpty (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo,
  IN UINTN                                Timeout
  )
{
  UINTN Delay;
  UINT8 Data;

  Delay = Timeout / 50;

  do {
    IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);

    //
    // Check keyboard controller status bit 1(input buffer status)
    //
    if ((Data & KBC_INPB) == 0) {
      break;
    }

    gBS->Stall (50);
    Delay--;
  } while (Delay != 0);

  if (Delay == 0) {
    return EFI_TIMEOUT;
  }

  return EFI_SUCCESS;
}

/**
  I/O work flow to wait output buffer full in given time.
  
  @param IsaIo   Pointer to instance of EFI_ISA_IO_PROTOCOL
  @param Timeout given time
  
  @retval EFI_TIMEOUT  output is not full in given time
  @retval EFI_SUCCESS  output is full in given time.
**/
EFI_STATUS
WaitOutputFull (
  IN EFI_ISA_IO_PROTOCOL                  *IsaIo,
  IN UINTN                                Timeout
  )
{
  UINTN Delay;
  UINT8 Data;

  Delay = Timeout / 50;

  do {
    IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);

    //
    // Check keyboard controller status bit 0(output buffer status)
    //  & bit5(output buffer for auxiliary device)
    //
    if ((Data & (KBC_OUTB | KBC_AUXB)) == (KBC_OUTB | KBC_AUXB)) {
      break;
    }

    gBS->Stall (50);
    Delay--;
  } while (Delay != 0);

  if (Delay == 0) {
    return EFI_TIMEOUT;
  }

  return EFI_SUCCESS;
}

