/** @file
  Produces Simple Text Input Protocol, Simple Text Input Extended Protocol and
  Simple Text Output Protocol upon Serial IO Protocol.

Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
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 "Terminal.h"

//
// Globals
//
EFI_DRIVER_BINDING_PROTOCOL gTerminalDriverBinding = {
  TerminalDriverBindingSupported,
  TerminalDriverBindingStart,
  TerminalDriverBindingStop,
  0xa,
  NULL,
  NULL
};


EFI_GUID  *gTerminalType[] = {
  &gEfiPcAnsiGuid,
  &gEfiVT100Guid,
  &gEfiVT100PlusGuid,
  &gEfiVTUTF8Guid
};


TERMINAL_DEV  mTerminalDevTemplate = {
  TERMINAL_DEV_SIGNATURE,
  NULL,
  0,
  NULL,
  NULL,
  {   // SimpleTextInput
    TerminalConInReset,
    TerminalConInReadKeyStroke,
    NULL
  },
  {   // SimpleTextOutput
    TerminalConOutReset,
    TerminalConOutOutputString,
    TerminalConOutTestString,
    TerminalConOutQueryMode,
    TerminalConOutSetMode,
    TerminalConOutSetAttribute,
    TerminalConOutClearScreen,
    TerminalConOutSetCursorPosition,
    TerminalConOutEnableCursor,
    NULL
  },
  {   // SimpleTextOutputMode
    1,                                           // MaxMode
    0,                                           // Mode
    EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK),    // Attribute
    0,                                           // CursorColumn
    0,                                           // CursorRow
    TRUE                                         // CursorVisible
  },
  NULL, // TerminalConsoleModeData
  0,  // SerialInTimeOut

  NULL, // RawFifo
  NULL, // UnicodeFiFo
  NULL, // EfiKeyFiFo

  NULL, // ControllerNameTable
  NULL, // TimerEvent
  NULL, // TwoSecondTimeOut
  INPUT_STATE_DEFAULT,
  RESET_STATE_DEFAULT,
  FALSE,
  {   // SimpleTextInputEx
    TerminalConInResetEx,
    TerminalConInReadKeyStrokeEx,
    NULL,
    TerminalConInSetState,
    TerminalConInRegisterKeyNotify,
    TerminalConInUnregisterKeyNotify,
  },
  {   // NotifyList
    NULL,
    NULL,
  }
};

TERMINAL_CONSOLE_MODE_DATA mTerminalConsoleModeData[] = {
  {100, 31},
  //
  // New modes can be added here.
  //
};

/**
  Test to see if this driver supports Controller.

  @param  This                Protocol instance pointer.
  @param  Controller          Handle of device to test
  @param  RemainingDevicePath Optional parameter use to pick a specific child
                              device to start.

  @retval EFI_SUCCESS         This driver supports this device.
  @retval EFI_ALREADY_STARTED This driver is already running on this device.
  @retval other               This driver does not support this device.

**/
EFI_STATUS
EFIAPI
TerminalDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;
  EFI_SERIAL_IO_PROTOCOL    *SerialIo;
  VENDOR_DEVICE_PATH        *Node;

  //
  // If remaining device path is not NULL, then make sure it is a
  // device path that describes a terminal communications protocol.
  //
  if (RemainingDevicePath != NULL) {
    //
    // Check if RemainingDevicePath is the End of Device Path Node,
    // if yes, go on checking other conditions
    //
    if (!IsDevicePathEnd (RemainingDevicePath)) {
      //
      // If RemainingDevicePath isn't the End of Device Path Node,
      // check its validation
      //
      Node = (VENDOR_DEVICE_PATH *) RemainingDevicePath;

      if (Node->Header.Type != MESSAGING_DEVICE_PATH ||
          Node->Header.SubType != MSG_VENDOR_DP ||
          DevicePathNodeLength(&Node->Header) != sizeof(VENDOR_DEVICE_PATH)) {

        return EFI_UNSUPPORTED;

      }
      //
      // only supports PC ANSI, VT100, VT100+ and VT-UTF8 terminal types
      //
      if (!CompareGuid (&Node->Guid, &gEfiPcAnsiGuid) &&
          !CompareGuid (&Node->Guid, &gEfiVT100Guid) &&
          !CompareGuid (&Node->Guid, &gEfiVT100PlusGuid) &&
          !CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {

        return EFI_UNSUPPORTED;
      }
    }
  }
  //
  // Open the IO Abstraction(s) needed to perform the supported test
  // The Controller must support the Serial I/O Protocol.
  // This driver is a bus driver with at most 1 child device, so it is
  // ok for it to be already started.
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiSerialIoProtocolGuid,
                  (VOID **) &SerialIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Close the I/O Abstraction(s) used to perform the supported test
  //
  gBS->CloseProtocol (
        Controller,
        &gEfiSerialIoProtocolGuid,
        This->DriverBindingHandle,
        Controller
        );

  //
  // Open the EFI Device Path protocol needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Close protocol, don't use device path protocol in the Support() function
  //
  gBS->CloseProtocol (
        Controller,
        &gEfiDevicePathProtocolGuid,
        This->DriverBindingHandle,
        Controller
        );

  return Status;
}

/**
  Build the terminal device path for the child device according to the
  terminal type.

  @param  ParentDevicePath         Parent device path.
  @param  RemainingDevicePath      A specific child device.

  @return The child device path built.

**/
EFI_DEVICE_PATH_PROTOCOL*
EFIAPI
BuildTerminalDevpath  (
  IN EFI_DEVICE_PATH_PROTOCOL       *ParentDevicePath,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
{
  EFI_DEVICE_PATH_PROTOCOL          *TerminalDevicePath;
  UINT8                             TerminalType;
  VENDOR_DEVICE_PATH                *Node;
  EFI_STATUS                        Status;

  TerminalDevicePath = NULL;
  TerminalType = PCANSITYPE;

  //
  // Use the RemainingDevicePath to determine the terminal type
  //
  Node = (VENDOR_DEVICE_PATH *) RemainingDevicePath;
  if (Node == NULL) {
    TerminalType = PCANSITYPE;

  } else if (CompareGuid (&Node->Guid, &gEfiPcAnsiGuid)) {

    TerminalType = PCANSITYPE;

  } else if (CompareGuid (&Node->Guid, &gEfiVT100Guid)) {

    TerminalType = VT100TYPE;

  } else if (CompareGuid (&Node->Guid, &gEfiVT100PlusGuid)) {

    TerminalType = VT100PLUSTYPE;

  } else if (CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {

    TerminalType = VTUTF8TYPE;

  } else {
    return NULL;
  }

  //
  // Build the device path for the child device
  //
  Status = SetTerminalDevicePath (
            TerminalType,
            ParentDevicePath,
            &TerminalDevicePath
            );
  if (EFI_ERROR (Status)) {
    return NULL;
  }
  return TerminalDevicePath;
}

/**
  Compare a device path data structure to that of all the nodes of a
  second device path instance.

  @param  Multi          A pointer to a multi-instance device path data structure.
  @param  Single         A pointer to a single-instance device path data structure.

  @retval TRUE           If the Single is contained within Multi.
  @retval FALSE          The Single is not match within Multi.

**/
BOOLEAN
MatchDevicePaths (
  IN  EFI_DEVICE_PATH_PROTOCOL  *Multi,
  IN  EFI_DEVICE_PATH_PROTOCOL  *Single
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;
  UINTN                     Size;

  DevicePath      = Multi;
  DevicePathInst  = GetNextDevicePathInstance (&DevicePath, &Size);
  //
  // Search for the match of 'Single' in 'Multi'
  //
  while (DevicePathInst != NULL) {
    //
    // If the single device path is found in multiple device paths,
    // return success
    //
    if (CompareMem (Single, DevicePathInst, Size) == 0) {
      FreePool (DevicePathInst);
      return TRUE;
    }

    FreePool (DevicePathInst);
    DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);
  }

  return FALSE;
}

/**
  Check whether the terminal device path is in the global variable.

  @param  VariableName          Pointer to one global variable.
  @param  TerminalDevicePath    Pointer to the terminal device's device path.

  @retval TRUE                  The devcie is in the global variable.
  @retval FALSE                 The devcie is not in the global variable.

**/
BOOLEAN
IsTerminalInConsoleVariable (
  IN CHAR16                    *VariableName,
  IN EFI_DEVICE_PATH_PROTOCOL  *TerminalDevicePath
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *Variable;
  BOOLEAN                   ReturnFlag;

  //
  // Get global variable and its size according to the name given.
  //
  GetEfiGlobalVariable2 (VariableName, (VOID**)&Variable, NULL);
  if (Variable == NULL) {
    return FALSE;
  }

  //
  // Check whether the terminal device path is one of the variable instances.
  //
  ReturnFlag = MatchDevicePaths (Variable, TerminalDevicePath);

  FreePool (Variable);

  return ReturnFlag;
}

/**
  Free notify functions list.

  @param  ListHead               The list head

  @retval EFI_SUCCESS            Free the notify list successfully.
  @retval EFI_INVALID_PARAMETER  ListHead is NULL.

**/
EFI_STATUS
TerminalFreeNotifyList (
  IN OUT LIST_ENTRY           *ListHead
  )
{
  TERMINAL_CONSOLE_IN_EX_NOTIFY *NotifyNode;

  if (ListHead == NULL) {
    return EFI_INVALID_PARAMETER;
  }
  while (!IsListEmpty (ListHead)) {
    NotifyNode = CR (
                   ListHead->ForwardLink,
                   TERMINAL_CONSOLE_IN_EX_NOTIFY,
                   NotifyEntry,
                   TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE
                   );
    RemoveEntryList (ListHead->ForwardLink);
    FreePool (NotifyNode);
  }

  return EFI_SUCCESS;
}

/**
  Initialize all the text modes which the terminal console supports.

  It returns information for available text modes that the terminal can support.

  @param[out] TextModeCount      The total number of text modes that terminal console supports.
  @param[out] TextModeData       The buffer to the text modes column and row information.
                                 Caller is responsible to free it when it's non-NULL.

  @retval EFI_SUCCESS            The supporting mode information is returned.
  @retval EFI_INVALID_PARAMETER  The parameters are invalid.

**/
EFI_STATUS
InitializeTerminalConsoleTextMode (
  OUT UINTN                         *TextModeCount,
  OUT TERMINAL_CONSOLE_MODE_DATA    **TextModeData
  )
{
  UINTN                       Index;
  UINTN                       Count;
  TERMINAL_CONSOLE_MODE_DATA  *ModeBuffer;
  TERMINAL_CONSOLE_MODE_DATA  *NewModeBuffer;
  UINTN                       ValidCount;
  UINTN                       ValidIndex;
  
  if ((TextModeCount == NULL) || (TextModeData == NULL)) {
    return EFI_INVALID_PARAMETER;
  }
  
  Count = sizeof (mTerminalConsoleModeData) / sizeof (TERMINAL_CONSOLE_MODE_DATA);
  
  //
  // Get defined mode buffer pointer.
  //
  ModeBuffer = mTerminalConsoleModeData;
    
  //
  // Here we make sure that the final mode exposed does not include the duplicated modes,
  // and does not include the invalid modes which exceed the max column and row.
  // Reserve 2 modes for 80x25, 80x50 of terminal console.
  //
  NewModeBuffer = AllocateZeroPool (sizeof (TERMINAL_CONSOLE_MODE_DATA) * (Count + 2));
  ASSERT (NewModeBuffer != NULL);

  //
  // Mode 0 and mode 1 is for 80x25, 80x50 according to UEFI spec.
  //
  ValidCount = 0;  

  NewModeBuffer[ValidCount].Columns = 80;
  NewModeBuffer[ValidCount].Rows    = 25;
  ValidCount++;

  NewModeBuffer[ValidCount].Columns = 80;
  NewModeBuffer[ValidCount].Rows    = 50;
  ValidCount++;
  
  //
  // Start from mode 2 to put the valid mode other than 80x25 and 80x50 in the output mode buffer.
  //
  for (Index = 0; Index < Count; Index++) {
    if ((ModeBuffer[Index].Columns == 0) || (ModeBuffer[Index].Rows == 0)) {
      //
      // Skip the pre-defined mode which is invalid.
      //
      continue;
    }
    for (ValidIndex = 0; ValidIndex < ValidCount; ValidIndex++) {
      if ((ModeBuffer[Index].Columns == NewModeBuffer[ValidIndex].Columns) &&
          (ModeBuffer[Index].Rows == NewModeBuffer[ValidIndex].Rows)) {
        //
        // Skip the duplicated mode.
        //
        break;
      }
    }
    if (ValidIndex == ValidCount) {
      NewModeBuffer[ValidCount].Columns = ModeBuffer[Index].Columns;
      NewModeBuffer[ValidCount].Rows    = ModeBuffer[Index].Rows;
      ValidCount++;
    }
  }
 
  DEBUG_CODE (
    for (Index = 0; Index < ValidCount; Index++) {
      DEBUG ((EFI_D_INFO, "Terminal - Mode %d, Column = %d, Row = %d\n", 
                           Index, NewModeBuffer[Index].Columns, NewModeBuffer[Index].Rows));  
    }
  );
  
  //
  // Return valid mode count and mode information buffer.
  //
  *TextModeCount = ValidCount;
  *TextModeData  = NewModeBuffer;
  return EFI_SUCCESS;
}

/**
  Start this driver on Controller by opening a Serial IO protocol,
  reading Device Path, and creating a child handle with a Simple Text In,
  Simple Text In Ex and Simple Text Out protocol, and device path protocol.
  And store Console Device Environment Variables.

  @param  This                 Protocol instance pointer.
  @param  Controller           Handle of device to bind driver to
  @param  RemainingDevicePath  Optional parameter use to pick a specific child
                               device to start.

  @retval EFI_SUCCESS          This driver is added to Controller.
  @retval EFI_ALREADY_STARTED  This driver is already running on Controller.
  @retval other                This driver does not support this device.

**/
EFI_STATUS
EFIAPI
TerminalDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL    *This,
  IN EFI_HANDLE                     Controller,
  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath
  )
{
  EFI_STATUS                          Status;
  EFI_SERIAL_IO_PROTOCOL              *SerialIo;
  EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;
  VENDOR_DEVICE_PATH                  *Node;
  VENDOR_DEVICE_PATH                  *DefaultNode;
  EFI_SERIAL_IO_MODE                  *Mode;
  UINTN                               SerialInTimeOut;
  TERMINAL_DEV                        *TerminalDevice;
  UINT8                               TerminalType;
  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
  UINTN                               EntryCount;
  UINTN                               Index;
  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL     *SimpleTextOutput;
  EFI_SIMPLE_TEXT_INPUT_PROTOCOL      *SimpleTextInput;
  BOOLEAN                             ConInSelected;
  BOOLEAN                             ConOutSelected;
  BOOLEAN                             NullRemaining;
  BOOLEAN                             SimTxtInInstalled;
  BOOLEAN                             SimTxtOutInstalled;
  BOOLEAN                             FirstEnter;
  UINTN                               ModeCount;

  TerminalDevice     = NULL;
  DefaultNode        = NULL;
  ConInSelected       = FALSE;
  ConOutSelected      = FALSE;
  NullRemaining      = TRUE;
  SimTxtInInstalled  = FALSE;
  SimTxtOutInstalled = FALSE;
  FirstEnter         = FALSE;
  //
  // Get the Device Path Protocol to build the device path of the child device
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    return Status;
  }

  //
  // Open the Serial I/O Protocol BY_DRIVER.  It might already be started.
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiSerialIoProtocolGuid,
                  (VOID **) &SerialIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
    return Status;
  }

  if (Status != EFI_ALREADY_STARTED) {
    //
    // the serial I/O protocol never be opened before, it is the first
    // time to start the serial Io controller
    //
    FirstEnter = TRUE;
  }

  //
  // Serial I/O is not already open by this driver, then tag the handle
  // with the Terminal Driver GUID and update the ConInDev, ConOutDev, and
  // StdErrDev variables with the list of possible terminal types on this
  // serial port.
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiCallerIdGuid,
                  NULL,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &Controller,
                    &gEfiCallerIdGuid,
                    DuplicateDevicePath (ParentDevicePath),
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      goto Error;
    }

    if (!IsHotPlugDevice (ParentDevicePath)) {
      //
      // if the serial device is a hot plug device, do not update the
      // ConInDev, ConOutDev, and StdErrDev variables.
      //
      TerminalUpdateConsoleDevVariable (L"ConInDev", ParentDevicePath);
      TerminalUpdateConsoleDevVariable (L"ConOutDev", ParentDevicePath);
      TerminalUpdateConsoleDevVariable (L"ErrOutDev", ParentDevicePath);
    }
  }

  //
  // Check the requirement for the SimpleTxtIn and SimpleTxtOut protocols
  //
  // Simple In/Out Protocol will not be installed onto the handle if the
  // device path to the handle is not present in the ConIn/ConOut
  // environment variable. But If RemainingDevicePath is NULL, then always
  // produce both Simple In and Simple Text Output Protocols. This is required
  // for the connect all sequences to make sure all possible consoles are
  // produced no matter what the current values of ConIn, ConOut, or StdErr are.
  //
  if (RemainingDevicePath == NULL) {
    NullRemaining = TRUE;
  }

  DevicePath = BuildTerminalDevpath (ParentDevicePath, RemainingDevicePath);
  if (DevicePath != NULL) {
    ConInSelected  = IsTerminalInConsoleVariable (L"ConIn", DevicePath);
    ConOutSelected = IsTerminalInConsoleVariable (L"ConOut", DevicePath);
    FreePool (DevicePath);
  } else {
    goto Error;
  }
  //
  // Not create the child terminal handle if both Simple In/In Ex and
  // Simple text Out protocols are not required to be published
  //
  if ((!ConInSelected)&&(!ConOutSelected)&&(!NullRemaining)) {
    goto Error;
  }

  //
  // create the child terminal handle during first entry
  //
  if (FirstEnter) {
    //
    // First enther the start funciton
    //
    FirstEnter = FALSE;
    //
    // Make sure a child handle does not already exist.  This driver can only
    // produce one child per serial port.
    //
    Status = gBS->OpenProtocolInformation (
                    Controller,
                    &gEfiSerialIoProtocolGuid,
                    &OpenInfoBuffer,
                    &EntryCount
                    );
    if (!EFI_ERROR (Status)) {
      Status = EFI_SUCCESS;
      for (Index = 0; Index < EntryCount; Index++) {
        if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
          Status = EFI_ALREADY_STARTED;
        }
      }

      FreePool (OpenInfoBuffer);
      if (EFI_ERROR (Status)) {
          goto Error;
      }
    }

    //
    // If RemainingDevicePath is NULL, then create default device path node
    //
    if (RemainingDevicePath == NULL) {
      DefaultNode = AllocateZeroPool (sizeof (VENDOR_DEVICE_PATH));
      if (DefaultNode == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Error;
      }

      TerminalType = PcdGet8 (PcdDefaultTerminalType);
      //
      // Must be between PCANSITYPE (0) and VTUTF8TYPE (3)
      //
      ASSERT (TerminalType <= VTUTF8TYPE);

      CopyMem (&DefaultNode->Guid, gTerminalType[TerminalType], sizeof (EFI_GUID));
      RemainingDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) DefaultNode;
    } else if (!IsDevicePathEnd (RemainingDevicePath)) {
      //
      // If RemainingDevicePath isn't the End of Device Path Node,
      // Use the RemainingDevicePath to determine the terminal type
      //
      Node = (VENDOR_DEVICE_PATH *)RemainingDevicePath;
      if (CompareGuid (&Node->Guid, &gEfiPcAnsiGuid)) {
        TerminalType = PCANSITYPE;
      } else if (CompareGuid (&Node->Guid, &gEfiVT100Guid)) {
        TerminalType = VT100TYPE;
      } else if (CompareGuid (&Node->Guid, &gEfiVT100PlusGuid)) {
        TerminalType = VT100PLUSTYPE;
      } else if (CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {
        TerminalType = VTUTF8TYPE;
      } else {
        goto Error;
      }
    } else {
      //
      // If RemainingDevicePath is the End of Device Path Node,
      // skip enumerate any device and return EFI_SUCESSS
      //
      return EFI_SUCCESS;
    }

    //
    // Initialize the Terminal Dev
    //
    TerminalDevice = AllocateCopyPool (sizeof (TERMINAL_DEV), &mTerminalDevTemplate);
    if (TerminalDevice == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Error;
    }

    TerminalDevice->TerminalType  = TerminalType;
    TerminalDevice->SerialIo      = SerialIo;

    InitializeListHead (&TerminalDevice->NotifyList);
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_WAIT,
                    TPL_NOTIFY,
                    TerminalConInWaitForKeyEx,
                    TerminalDevice,
                    &TerminalDevice->SimpleInputEx.WaitForKeyEx
                    );
    if (EFI_ERROR (Status)) {
      goto Error;
    }

    Status = gBS->CreateEvent (
                    EVT_NOTIFY_WAIT,
                    TPL_NOTIFY,
                    TerminalConInWaitForKey,
                    TerminalDevice,
                    &TerminalDevice->SimpleInput.WaitForKey
                    );
    if (EFI_ERROR (Status)) {
      goto Error;
    }
    //
    // Allocates and initializes the FIFO buffer to be zero, used for accommodating
    // the pre-read pending characters.
    //
    TerminalDevice->RawFiFo     = AllocateZeroPool (sizeof (RAW_DATA_FIFO));
    if (TerminalDevice->RawFiFo == NULL) {
      goto Error;
    }
    TerminalDevice->UnicodeFiFo = AllocateZeroPool (sizeof (UNICODE_FIFO));
    if (TerminalDevice->UnicodeFiFo == NULL) {
      goto Error;
    }
    TerminalDevice->EfiKeyFiFo  = AllocateZeroPool (sizeof (EFI_KEY_FIFO));
    if (TerminalDevice->EfiKeyFiFo == NULL) {
      goto Error;
    }

    //
    // Set the timeout value of serial buffer for
    // keystroke response performance issue
    //
    Mode            = TerminalDevice->SerialIo->Mode;

    SerialInTimeOut = 0;
    if (Mode->BaudRate != 0) {
      SerialInTimeOut = (1 + Mode->DataBits + Mode->StopBits) * 2 * 1000000 / (UINTN) Mode->BaudRate;
    }

    Status = TerminalDevice->SerialIo->SetAttributes (
                                        TerminalDevice->SerialIo,
                                        Mode->BaudRate,
                                        Mode->ReceiveFifoDepth,
                                        (UINT32) SerialInTimeOut,
                                        (EFI_PARITY_TYPE) (Mode->Parity),
                                        (UINT8) Mode->DataBits,
                                        (EFI_STOP_BITS_TYPE) (Mode->StopBits)
                                        );
    if (EFI_ERROR (Status)) {
      //
      // if set attributes operation fails, invalidate
      // the value of SerialInTimeOut,thus make it
      // inconsistent with the default timeout value
      // of serial buffer. This will invoke the recalculation
      // in the readkeystroke routine.
      //
      TerminalDevice->SerialInTimeOut = 0;
    } else {
      TerminalDevice->SerialInTimeOut = SerialInTimeOut;
    }
    //
    // Set Simple Text Output Protocol from template.
    //
    SimpleTextOutput = CopyMem (
                         &TerminalDevice->SimpleTextOutput,
                         &mTerminalDevTemplate.SimpleTextOutput,
                         sizeof (mTerminalDevTemplate.SimpleTextOutput)
                         );
    SimpleTextOutput->Mode = &TerminalDevice->SimpleTextOutputMode;
    
    Status = InitializeTerminalConsoleTextMode (&ModeCount, &TerminalDevice->TerminalConsoleModeData);
    if (EFI_ERROR (Status)) {
      goto ReportError;
    }
    TerminalDevice->SimpleTextOutputMode.MaxMode = (INT32) ModeCount;
    
    //
    // For terminal devices, cursor is always visible
    //
    TerminalDevice->SimpleTextOutputMode.CursorVisible = TRUE;
    Status = TerminalConOutSetAttribute (
               SimpleTextOutput,
               EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)
               );
    if (EFI_ERROR (Status)) {
      goto ReportError;
    }

    //
    // Build the component name for the child device
    //
    TerminalDevice->ControllerNameTable = NULL;
    switch (TerminalDevice->TerminalType) {
    case PCANSITYPE:
      AddUnicodeString2 (
        "eng",
        gTerminalComponentName.SupportedLanguages,
        &TerminalDevice->ControllerNameTable,
        (CHAR16 *)L"PC-ANSI Serial Console",
        TRUE
        );
      AddUnicodeString2 (
        "en",
        gTerminalComponentName2.SupportedLanguages,
        &TerminalDevice->ControllerNameTable,
        (CHAR16 *)L"PC-ANSI Serial Console",
        FALSE
        );

      break;

    case VT100TYPE:
      AddUnicodeString2 (
        "eng",
        gTerminalComponentName.SupportedLanguages,
        &TerminalDevice->ControllerNameTable,
        (CHAR16 *)L"VT-100 Serial Console",
        TRUE
        );
      AddUnicodeString2 (
        "en",
        gTerminalComponentName2.SupportedLanguages,
        &TerminalDevice->ControllerNameTable,
        (CHAR16 *)L"VT-100 Serial Console",
        FALSE
        );

      break;

    case VT100PLUSTYPE:
      AddUnicodeString2 (
        "eng",
        gTerminalComponentName.SupportedLanguages,
        &TerminalDevice->ControllerNameTable,
        (CHAR16 *)L"VT-100+ Serial Console",
        TRUE
        );
      AddUnicodeString2 (
        "en",
        gTerminalComponentName2.SupportedLanguages,
        &TerminalDevice->ControllerNameTable,
        (CHAR16 *)L"VT-100+ Serial Console",
        FALSE
        );

      break;

    case VTUTF8TYPE:
      AddUnicodeString2 (
        "eng",
        gTerminalComponentName.SupportedLanguages,
        &TerminalDevice->ControllerNameTable,
        (CHAR16 *)L"VT-UTF8 Serial Console",
        TRUE
        );
      AddUnicodeString2 (
        "en",
        gTerminalComponentName2.SupportedLanguages,
        &TerminalDevice->ControllerNameTable,
        (CHAR16 *)L"VT-UTF8 Serial Console",
        FALSE
        );

      break;
    }

    //
    // Build the device path for the child device
    //
    Status = SetTerminalDevicePath (
              TerminalDevice->TerminalType,
              ParentDevicePath,
              &TerminalDevice->DevicePath
              );
    if (EFI_ERROR (Status)) {
      goto Error;
    }

    Status = TerminalConOutReset (SimpleTextOutput, FALSE);
    if (EFI_ERROR (Status)) {
      goto ReportError;
    }

    Status = TerminalConOutSetMode (SimpleTextOutput, 0);
    if (EFI_ERROR (Status)) {
      goto ReportError;
    }

    Status = TerminalConOutEnableCursor (SimpleTextOutput, TRUE);
    if (EFI_ERROR (Status)) {
      goto ReportError;
    }

    Status = gBS->CreateEvent (
                    EVT_TIMER | EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    TerminalConInTimerHandler,
                    TerminalDevice,
                    &TerminalDevice->TimerEvent
                    );
    ASSERT_EFI_ERROR (Status);

    Status = gBS->SetTimer (
                    TerminalDevice->TimerEvent,
                    TimerPeriodic,
                    KEYBOARD_TIMER_INTERVAL
                    );
    ASSERT_EFI_ERROR (Status);

    Status = gBS->CreateEvent (
                    EVT_TIMER,
                    TPL_CALLBACK,
                    NULL,
                    NULL,
                    &TerminalDevice->TwoSecondTimeOut
                    );
    ASSERT_EFI_ERROR (Status);

    Status = gBS->InstallProtocolInterface (
                    &TerminalDevice->Handle,
                    &gEfiDevicePathProtocolGuid,
                    EFI_NATIVE_INTERFACE,
                    TerminalDevice->DevicePath
                    );
    if (EFI_ERROR (Status)) {
      goto Error;
    }

    //
    // Register the Parent-Child relationship via
    // EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
    //
    Status = gBS->OpenProtocol (
                    Controller,
                    &gEfiSerialIoProtocolGuid,
                    (VOID **) &TerminalDevice->SerialIo,
                    This->DriverBindingHandle,
                    TerminalDevice->Handle,
                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                    );
    if (EFI_ERROR (Status)) {
      goto Error;
    }
  }

  //
  // Find the child handle, and get its TerminalDevice private data
  //
  Status = gBS->OpenProtocolInformation (
                  Controller,
                  &gEfiSerialIoProtocolGuid,
                  &OpenInfoBuffer,
                  &EntryCount
                  );
  if (!EFI_ERROR (Status)) {
    Status = EFI_NOT_FOUND;
    ASSERT (OpenInfoBuffer != NULL);
    for (Index = 0; Index < EntryCount; Index++) {
      if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
        //
        // Find the child terminal handle.
        // Test whether the SimpleTxtIn and SimpleTxtOut have been published
        //
        Status = gBS->OpenProtocol (
                        OpenInfoBuffer[Index].ControllerHandle,
                        &gEfiSimpleTextInProtocolGuid,
                        (VOID **) &SimpleTextInput,
                        This->DriverBindingHandle,
                        OpenInfoBuffer[Index].ControllerHandle,
                        EFI_OPEN_PROTOCOL_GET_PROTOCOL
                        );
        if (!EFI_ERROR (Status)) {
          SimTxtInInstalled = TRUE;
          TerminalDevice = TERMINAL_CON_IN_DEV_FROM_THIS (SimpleTextInput);
        }

        Status = gBS->OpenProtocol (
                        OpenInfoBuffer[Index].ControllerHandle,
                        &gEfiSimpleTextOutProtocolGuid,
                        (VOID **) &SimpleTextOutput,
                        This->DriverBindingHandle,
                        OpenInfoBuffer[Index].ControllerHandle,
                        EFI_OPEN_PROTOCOL_GET_PROTOCOL
                        );
        if (!EFI_ERROR (Status)) {
          SimTxtOutInstalled = TRUE;
          TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);
        }
        Status = EFI_SUCCESS;
        break;
      }
    }

    FreePool (OpenInfoBuffer);
    if (EFI_ERROR (Status)) {
      goto ReportError;
    }
  } else {
    goto ReportError;
  }

  ASSERT (TerminalDevice != NULL);
  //
  // Only do the reset if the device path is in the Conout variable
  //
  if (ConInSelected && !SimTxtInInstalled) {
    Status = TerminalDevice->SimpleInput.Reset (
                                          &TerminalDevice->SimpleInput,
                                          FALSE
                                          );
    if (EFI_ERROR (Status)) {
      //
      // Need to report Error Code first
      //
      goto ReportError;
    }
  }

  //
  // Only output the configure string to remote terminal if the device path
  // is in the Conout variable
  //
  if (ConOutSelected && !SimTxtOutInstalled) {
    Status = TerminalDevice->SimpleTextOutput.SetAttribute (
                                                        &TerminalDevice->SimpleTextOutput,
                                                        EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)
                                                        );
    if (EFI_ERROR (Status)) {
      goto ReportError;
    }

    Status = TerminalDevice->SimpleTextOutput.Reset (
                                                &TerminalDevice->SimpleTextOutput,
                                                FALSE
                                                );
    if (EFI_ERROR (Status)) {
      goto ReportError;
    }

    Status = TerminalDevice->SimpleTextOutput.SetMode (
                                                &TerminalDevice->SimpleTextOutput,
                                                0
                                                );
    if (EFI_ERROR (Status)) {
      goto ReportError;
    }

    Status = TerminalDevice->SimpleTextOutput.EnableCursor (
                                                &TerminalDevice->SimpleTextOutput,
                                                TRUE
                                                );
    if (EFI_ERROR (Status)) {
      goto ReportError;
    }
  }

  //
  // Simple In/Out Protocol will not be installed onto the handle if the
  // device path to the handle is not present in the ConIn/ConOut
  // environment variable. But If RemainingDevicePath is NULL, then always
  // produce both Simple In and Simple Text Output Protocols. This is required
  // for the connect all sequences to make sure all possible consoles are
  // produced no matter what the current values of ConIn, ConOut, or StdErr are.
  //
  if (!SimTxtInInstalled && (ConInSelected || NullRemaining)) {
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &TerminalDevice->Handle,
                    &gEfiSimpleTextInProtocolGuid,
                    &TerminalDevice->SimpleInput,
                    &gEfiSimpleTextInputExProtocolGuid,
                    &TerminalDevice->SimpleInputEx,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      goto Error;
    }
  }

  if (!SimTxtOutInstalled && (ConOutSelected || NullRemaining)) {
    Status = gBS->InstallProtocolInterface (
                    &TerminalDevice->Handle,
                    &gEfiSimpleTextOutProtocolGuid,
                    EFI_NATIVE_INTERFACE,
                    &TerminalDevice->SimpleTextOutput
                    );
    if (EFI_ERROR (Status)) {
      goto Error;
    }
  }
  if (DefaultNode != NULL) {
    FreePool (DefaultNode);
  }

  return EFI_SUCCESS;

ReportError:
  //
  // Report error code before exiting
  //
  DevicePath = ParentDevicePath;
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_ERROR_CODE | EFI_ERROR_MINOR,
    (EFI_PERIPHERAL_REMOTE_CONSOLE | EFI_P_EC_CONTROLLER_ERROR),
    DevicePath
    );

Error:
  //
  // Use the Stop() function to free all resources allocated in Start()
  //
  if (TerminalDevice != NULL) {

    if (TerminalDevice->Handle != NULL) {
      This->Stop (This, Controller, 1, &TerminalDevice->Handle);
    } else {

      if (TerminalDevice->TwoSecondTimeOut != NULL) {
        gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);
      }

      if (TerminalDevice->TimerEvent != NULL) {
        gBS->CloseEvent (TerminalDevice->TimerEvent);
      }

      if (TerminalDevice->SimpleInput.WaitForKey != NULL) {
        gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);
      }

      if (TerminalDevice->SimpleInputEx.WaitForKeyEx != NULL) {
        gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);
      }

      TerminalFreeNotifyList (&TerminalDevice->NotifyList);

      if (TerminalDevice->RawFiFo != NULL) {
        FreePool (TerminalDevice->RawFiFo);
      }
      if (TerminalDevice->UnicodeFiFo != NULL) {
        FreePool (TerminalDevice->UnicodeFiFo);
      }
      if (TerminalDevice->EfiKeyFiFo != NULL) {
        FreePool (TerminalDevice->EfiKeyFiFo);
      }

      if (TerminalDevice->ControllerNameTable != NULL) {
        FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);
      }

      if (TerminalDevice->DevicePath != NULL) {
        FreePool (TerminalDevice->DevicePath);
      }

      if (TerminalDevice->TerminalConsoleModeData != NULL) {
        FreePool (TerminalDevice->TerminalConsoleModeData);
      }

      FreePool (TerminalDevice);
    }
  }

  if (DefaultNode != NULL) {
    FreePool (DefaultNode);
  }

  This->Stop (This, Controller, 0, NULL);

  return Status;
}

/**
  Stop this driver on Controller by closing Simple Text In, Simple Text
  In Ex, Simple Text Out protocol, and removing parent device path from
  Console Device Environment Variables.

  @param  This              Protocol instance pointer.
  @param  Controller        Handle of device to stop driver on
  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
                            children is zero stop the entire bus driver.
  @param  ChildHandleBuffer List of Child Handles to Stop.

  @retval EFI_SUCCESS       This driver is removed Controller.
  @retval other             This driver could not be removed from this device.

**/
EFI_STATUS
EFIAPI
TerminalDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
  IN  EFI_HANDLE                    Controller,
  IN  UINTN                         NumberOfChildren,
  IN  EFI_HANDLE                    *ChildHandleBuffer
  )
{
  EFI_STATUS                       Status;
  UINTN                            Index;
  BOOLEAN                          AllChildrenStopped;
  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *SimpleTextOutput;
  TERMINAL_DEV                     *TerminalDevice;
  EFI_DEVICE_PATH_PROTOCOL         *ParentDevicePath;
  EFI_SERIAL_IO_PROTOCOL           *SerialIo;
  EFI_DEVICE_PATH_PROTOCOL         *DevicePath;

  Status = gBS->HandleProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **) &DevicePath
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Complete all outstanding transactions to Controller.
  // Don't allow any new transaction to Controller to be started.
  //
  if (NumberOfChildren == 0) {
    //
    // Close the bus driver
    //
    Status = gBS->OpenProtocol (
                    Controller,
                    &gEfiCallerIdGuid,
                    (VOID **) &ParentDevicePath,
                    This->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      //
      // Remove Parent Device Path from
      // the Console Device Environment Variables
      //
      TerminalRemoveConsoleDevVariable (L"ConInDev", ParentDevicePath);
      TerminalRemoveConsoleDevVariable (L"ConOutDev", ParentDevicePath);
      TerminalRemoveConsoleDevVariable (L"ErrOutDev", ParentDevicePath);

      //
      // Uninstall the Terminal Driver's GUID Tag from the Serial controller
      //
      Status = gBS->UninstallMultipleProtocolInterfaces (
                      Controller,
                      &gEfiCallerIdGuid,
                      ParentDevicePath,
                      NULL
                      );

      //
      // Free the ParentDevicePath that was duplicated in Start()
      //
      if (!EFI_ERROR (Status)) {
        FreePool (ParentDevicePath);
      }
    }

    gBS->CloseProtocol (
          Controller,
          &gEfiSerialIoProtocolGuid,
          This->DriverBindingHandle,
          Controller
          );

    gBS->CloseProtocol (
          Controller,
          &gEfiDevicePathProtocolGuid,
          This->DriverBindingHandle,
          Controller
          );

    return EFI_SUCCESS;
  }

  AllChildrenStopped = TRUE;

  for (Index = 0; Index < NumberOfChildren; Index++) {

    Status = gBS->OpenProtocol (
                    ChildHandleBuffer[Index],
                    &gEfiSimpleTextOutProtocolGuid,
                    (VOID **) &SimpleTextOutput,
                    This->DriverBindingHandle,
                    ChildHandleBuffer[Index],
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {

      TerminalDevice = TERMINAL_CON_OUT_DEV_FROM_THIS (SimpleTextOutput);

      gBS->CloseProtocol (
            Controller,
            &gEfiSerialIoProtocolGuid,
            This->DriverBindingHandle,
            ChildHandleBuffer[Index]
            );

      Status = gBS->UninstallMultipleProtocolInterfaces (
                      ChildHandleBuffer[Index],
                      &gEfiSimpleTextInProtocolGuid,
                      &TerminalDevice->SimpleInput,
                      &gEfiSimpleTextInputExProtocolGuid,
                      &TerminalDevice->SimpleInputEx,
                      &gEfiSimpleTextOutProtocolGuid,
                      &TerminalDevice->SimpleTextOutput,
                      &gEfiDevicePathProtocolGuid,
                      TerminalDevice->DevicePath,
                      NULL
                      );
      if (EFI_ERROR (Status)) {
        gBS->OpenProtocol (
              Controller,
              &gEfiSerialIoProtocolGuid,
              (VOID **) &SerialIo,
              This->DriverBindingHandle,
              ChildHandleBuffer[Index],
              EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
              );
      } else {

        if (TerminalDevice->ControllerNameTable != NULL) {
          FreeUnicodeStringTable (TerminalDevice->ControllerNameTable);
        }

        gBS->CloseEvent (TerminalDevice->TimerEvent);
        gBS->CloseEvent (TerminalDevice->TwoSecondTimeOut);
        gBS->CloseEvent (TerminalDevice->SimpleInput.WaitForKey);
        gBS->CloseEvent (TerminalDevice->SimpleInputEx.WaitForKeyEx);
        TerminalFreeNotifyList (&TerminalDevice->NotifyList);
        FreePool (TerminalDevice->DevicePath);
        if (TerminalDevice->TerminalConsoleModeData != NULL) {
          FreePool (TerminalDevice->TerminalConsoleModeData);
        }
        FreePool (TerminalDevice);
      }
    }

    if (EFI_ERROR (Status)) {
      AllChildrenStopped = FALSE;
    }
  }

  if (!AllChildrenStopped) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

/**
  Update terminal device path in Console Device Environment Variables.

  @param  VariableName           The Console Device Environment Variable.
  @param  ParentDevicePath       The terminal device path to be updated.

**/
VOID
TerminalUpdateConsoleDevVariable (
  IN CHAR16                    *VariableName,
  IN EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath
  )
{
  EFI_STATUS                Status;
  UINTN                     NameSize;
  UINTN                     VariableSize;
  UINT8                     TerminalType;
  EFI_DEVICE_PATH_PROTOCOL  *Variable;
  EFI_DEVICE_PATH_PROTOCOL  *NewVariable;
  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;
  EDKII_SET_VARIABLE_STATUS *SetVariableStatus;

  //
  // Get global variable and its size according to the name given.
  //
  GetEfiGlobalVariable2 (VariableName, (VOID**)&Variable, NULL);
  if (Variable == NULL) {
    return;
  }

  //
  // Append terminal device path onto the variable.
  //
  for (TerminalType = PCANSITYPE; TerminalType <= VTUTF8TYPE; TerminalType++) {
    SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);
    NewVariable = AppendDevicePathInstance (Variable, TempDevicePath);
    ASSERT (NewVariable != NULL);
    if (Variable != NULL) {
      FreePool (Variable);
    }

    if (TempDevicePath != NULL) {
      FreePool (TempDevicePath);
    }

    Variable = NewVariable;
  }

  VariableSize = GetDevicePathSize (Variable);

  Status = gRT->SetVariable (
                  VariableName,
                  &gEfiGlobalVariableGuid,
                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                  VariableSize,
                  Variable
                  );

  if (EFI_ERROR (Status)) {
    NameSize = StrSize (VariableName);
    SetVariableStatus = AllocatePool (sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + VariableSize);
    if (SetVariableStatus != NULL) {
      CopyGuid (&SetVariableStatus->Guid, &gEfiGlobalVariableGuid);
      SetVariableStatus->NameSize   = NameSize;
      SetVariableStatus->DataSize   = VariableSize;
      SetVariableStatus->SetStatus  = Status;
      SetVariableStatus->Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
      CopyMem (SetVariableStatus + 1,                          VariableName, NameSize);
      CopyMem (((UINT8 *) (SetVariableStatus + 1)) + NameSize, Variable,     VariableSize);

      REPORT_STATUS_CODE_EX (
        EFI_ERROR_CODE,
        PcdGet32 (PcdErrorCodeSetVariable),
        0,
        NULL,
        &gEdkiiStatusCodeDataTypeVariableGuid,
        SetVariableStatus,
        sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + VariableSize
        );

      FreePool (SetVariableStatus);
    }
  }

  FreePool (Variable);

  return ;
}


/**
  Remove terminal device path from Console Device Environment Variables.

  @param  VariableName           Console Device Environment Variables.
  @param  ParentDevicePath       The terminal device path to be updated.

**/
VOID
TerminalRemoveConsoleDevVariable (
  IN CHAR16                    *VariableName,
  IN EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath
  )
{
  EFI_STATUS                Status;
  BOOLEAN                   FoundOne;
  BOOLEAN                   Match;
  UINTN                     VariableSize;
  UINTN                     InstanceSize;
  UINT8                     TerminalType;
  EFI_DEVICE_PATH_PROTOCOL  *Instance;
  EFI_DEVICE_PATH_PROTOCOL  *Variable;
  EFI_DEVICE_PATH_PROTOCOL  *OriginalVariable;
  EFI_DEVICE_PATH_PROTOCOL  *NewVariable;
  EFI_DEVICE_PATH_PROTOCOL  *SavedNewVariable;
  EFI_DEVICE_PATH_PROTOCOL  *TempDevicePath;

  Instance  = NULL;

  //
  // Get global variable and its size according to the name given.
  //
  GetEfiGlobalVariable2 (VariableName, (VOID**)&Variable, NULL);
  if (Variable == NULL) {
    return ;
  }

  FoundOne          = FALSE;
  OriginalVariable  = Variable;
  NewVariable       = NULL;

  //
  // Get first device path instance from Variable
  //
  Instance = GetNextDevicePathInstance (&Variable, &InstanceSize);
  if (Instance == NULL) {
    FreePool (OriginalVariable);
    return ;
  }
  //
  // Loop through all the device path instances of Variable
  //
  do {
    //
    // Loop through all the terminal types that this driver supports
    //
    Match = FALSE;
    for (TerminalType = PCANSITYPE; TerminalType <= VTUTF8TYPE; TerminalType++) {

      SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);

      //
      // Compare the generated device path to the current device path instance
      //
      if (TempDevicePath != NULL) {
        if (CompareMem (Instance, TempDevicePath, InstanceSize) == 0) {
          Match     = TRUE;
          FoundOne  = TRUE;
        }

        FreePool (TempDevicePath);
      }
    }
    //
    // If a match was not found, then keep the current device path instance
    //
    if (!Match) {
      SavedNewVariable  = NewVariable;
      NewVariable       = AppendDevicePathInstance (NewVariable, Instance);
      if (SavedNewVariable != NULL) {
        FreePool (SavedNewVariable);
      }
    }
    //
    // Get next device path instance from Variable
    //
    FreePool (Instance);
    Instance = GetNextDevicePathInstance (&Variable, &InstanceSize);
  } while (Instance != NULL);

  FreePool (OriginalVariable);

  if (FoundOne) {
    VariableSize = GetDevicePathSize (NewVariable);

    Status = gRT->SetVariable (
                    VariableName,
                    &gEfiGlobalVariableGuid,
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
                    VariableSize,
                    NewVariable
                    );
    //
    // Shrinking variable with existing variable driver implementation shouldn't fail.
    //
    ASSERT_EFI_ERROR (Status);
  }

  if (NewVariable != NULL) {
    FreePool (NewVariable);
  }

  return ;
}

/**
  Build terminal device path according to terminal type.

  @param  TerminalType           The terminal type is PC ANSI, VT100, VT100+ or VT-UTF8.
  @param  ParentDevicePath       Parent device path.
  @param  TerminalDevicePath     Returned terminal device path, if building successfully.

  @retval EFI_UNSUPPORTED        Terminal does not belong to the supported type.
  @retval EFI_OUT_OF_RESOURCES   Generate terminal device path failed.
  @retval EFI_SUCCESS            Build terminal device path successfully.

**/
EFI_STATUS
SetTerminalDevicePath (
  IN  UINT8                       TerminalType,
  IN  EFI_DEVICE_PATH_PROTOCOL    *ParentDevicePath,
  OUT EFI_DEVICE_PATH_PROTOCOL    **TerminalDevicePath
  )
{
  VENDOR_DEVICE_PATH  Node;

  *TerminalDevicePath = NULL;
  Node.Header.Type    = MESSAGING_DEVICE_PATH;
  Node.Header.SubType = MSG_VENDOR_DP;

  //
  // Generate terminal device path node according to terminal type.
  //
  switch (TerminalType) {

  case PCANSITYPE:
    CopyGuid (&Node.Guid, &gEfiPcAnsiGuid);
    break;

  case VT100TYPE:
    CopyGuid (&Node.Guid, &gEfiVT100Guid);
    break;

  case VT100PLUSTYPE:
    CopyGuid (&Node.Guid, &gEfiVT100PlusGuid);
    break;

  case VTUTF8TYPE:
    CopyGuid (&Node.Guid, &gEfiVTUTF8Guid);
    break;

  default:
    return EFI_UNSUPPORTED;
  }

  //
  // Get VENDOR_DEVCIE_PATH size and put into Node.Header
  //
  SetDevicePathNodeLength (
    &Node.Header,
    sizeof (VENDOR_DEVICE_PATH)
    );

  //
  // Append the terminal node onto parent device path
  // to generate a complete terminal device path.
  //
  *TerminalDevicePath = AppendDevicePathNode (
                          ParentDevicePath,
                          (EFI_DEVICE_PATH_PROTOCOL *) &Node
                          );
  if (*TerminalDevicePath == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  The user Entry Point for module Terminal. The user code starts with this function.

  @param  ImageHandle    The firmware allocated handle for the EFI image.
  @param  SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS       The entry point is executed successfully.
  @retval other             Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
InitializeTerminal(
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  EFI_STATUS              Status;

  //
  // Install driver model protocol(s).
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gTerminalDriverBinding,
             ImageHandle,
             &gTerminalComponentName,
             &gTerminalComponentName2
             );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/**
  Check if the device supports hot-plug through its device path.

  This function could be updated to check more types of Hot Plug devices.
  Currently, it checks USB and PCCard device.

  @param  DevicePath            Pointer to device's device path.

  @retval TRUE                  The devcie is a hot-plug device
  @retval FALSE                 The devcie is not a hot-plug device.

**/
BOOLEAN
IsHotPlugDevice (
  IN  EFI_DEVICE_PATH_PROTOCOL    *DevicePath
  )
{
  EFI_DEVICE_PATH_PROTOCOL     *CheckDevicePath;

  CheckDevicePath = DevicePath;
  while (!IsDevicePathEnd (CheckDevicePath)) {
    //
    // Check device whether is hot plug device or not throught Device Path
    //
    if ((DevicePathType (CheckDevicePath) == MESSAGING_DEVICE_PATH) &&
        (DevicePathSubType (CheckDevicePath) == MSG_USB_DP ||
         DevicePathSubType (CheckDevicePath) == MSG_USB_CLASS_DP ||
         DevicePathSubType (CheckDevicePath) == MSG_USB_WWID_DP)) {
      //
      // If Device is USB device
      //
      return TRUE;
    }
    if ((DevicePathType (CheckDevicePath) == HARDWARE_DEVICE_PATH) &&
        (DevicePathSubType (CheckDevicePath) == HW_PCCARD_DP)) {
      //
      // If Device is PCCard
      //
      return TRUE;
    }

    CheckDevicePath = NextDevicePathNode (CheckDevicePath);
  }

  return FALSE;
}

