]> git.proxmox.com Git - mirror_edk2.git/blobdiff - Nt32Pkg/WinNtSerialIoDxe/WinNtSerialIo.c
Nt32Pkg: Remove it
[mirror_edk2.git] / Nt32Pkg / WinNtSerialIoDxe / WinNtSerialIo.c
diff --git a/Nt32Pkg/WinNtSerialIoDxe/WinNtSerialIo.c b/Nt32Pkg/WinNtSerialIoDxe/WinNtSerialIo.c
deleted file mode 100644 (file)
index 96167d5..0000000
+++ /dev/null
@@ -1,1701 +0,0 @@
-/**@file\r
-\r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-Module Name:\r
-\r
-  WinNtSerialIo.c\r
-\r
-Abstract:\r
-\r
-  Our DriverBinding member functions operate on the handles\r
-  created by the NT Bus driver.\r
-\r
-  Handle(1) - WinNtIo - DevicePath(1)\r
-\r
-  If a serial port is added to the system this driver creates a new handle.\r
-  The new handle is required, since the serial device must add an UART device\r
-  pathnode.\r
-\r
-  Handle(2) - SerialIo - DevicePath(1)\UART\r
-\r
-  The driver then adds a gEfiWinNtSerialPortGuid as a protocol to Handle(1).\r
-  The instance data for this protocol is the private data used to create\r
-  Handle(2).\r
-\r
-  Handle(1) - WinNtIo - DevicePath(1) - WinNtSerialPort\r
-\r
-  If the driver is unloaded Handle(2) is removed from the system and\r
-  gEfiWinNtSerialPortGuid is removed from Handle(1).\r
-\r
-  Note: Handle(1) is any handle created by the Win NT Bus driver that is passed\r
-  into the DriverBinding member functions of this driver. This driver requires\r
-  a Handle(1) to contain a WinNtIo protocol, a DevicePath protocol, and\r
-  the TypeGuid in the WinNtIo must be gEfiWinNtSerialPortGuid.\r
-\r
-  If Handle(1) contains a gEfiWinNtSerialPortGuid protocol then the driver is\r
-  loaded on the device.\r
-\r
-**/\r
-\r
-#include "WinNtSerialIo.h"\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL gWinNtSerialIoDriverBinding = {\r
-  WinNtSerialIoDriverBindingSupported,\r
-  WinNtSerialIoDriverBindingStart,\r
-  WinNtSerialIoDriverBindingStop,\r
-  0xa,\r
-  NULL,\r
-  NULL\r
-};\r
-\r
-//\r
-// List of supported baud rate\r
-//\r
-UINT64 mBaudRateCurrentSupport[] = {50, 75, 110, 134, 150, 300, 600, 1200, 1800, 2000, 2400, 3600, 4800, 7200, 9600, 19200, 38400, 57600, 115200, SERIAL_PORT_MAX_BAUD_RATE + 1};\r
-\r
-/**\r
-  Check the device path node whether it's the Flow Control node or not.\r
-\r
-  @param[in] FlowControl    The device path node to be checked.\r
-  \r
-  @retval TRUE              It's the Flow Control node.\r
-  @retval FALSE             It's not.\r
-\r
-**/\r
-BOOLEAN\r
-IsUartFlowControlNode (\r
-  IN UART_FLOW_CONTROL_DEVICE_PATH *FlowControl\r
-  )\r
-{\r
-  return (BOOLEAN) (\r
-           (DevicePathType (FlowControl) == MESSAGING_DEVICE_PATH) &&\r
-           (DevicePathSubType (FlowControl) == MSG_VENDOR_DP) &&\r
-           (CompareGuid (&FlowControl->Guid, &gEfiUartDevicePathGuid))\r
-           );\r
-}\r
-\r
-/**\r
-  Check the device path node whether it contains Flow Control node or not.\r
-\r
-  @param[in] DevicePath     The device path to be checked.\r
-  \r
-  @retval TRUE              It contains the Flow Control node.\r
-  @retval FALSE             It doesn't.\r
-\r
-**/\r
-BOOLEAN\r
-ContainsFlowControl (\r
-  IN EFI_DEVICE_PATH_PROTOCOL      *DevicePath\r
-  )\r
-{\r
-  while (!IsDevicePathEnd (DevicePath)) {\r
-    if (IsUartFlowControlNode ((UART_FLOW_CONTROL_DEVICE_PATH *) DevicePath)) {\r
-      return TRUE;\r
-    }\r
-    DevicePath = NextDevicePathNode (DevicePath);\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  The user Entry Point for module WinNtSerialIo. The user code starts with this function.\r
-\r
-  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  \r
-  @param[in] SystemTable    A pointer to the EFI System Table.\r
-  \r
-  @retval EFI_SUCCESS       The entry point is executed successfully.\r
-  @retval other             Some error occurs when executing this entry point.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeWinNtSerialIo(\r
-  IN EFI_HANDLE           ImageHandle,\r
-  IN EFI_SYSTEM_TABLE     *SystemTable\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-\r
-  //\r
-  // Install driver model protocol(s).\r
-  //\r
-  Status = EfiLibInstallDriverBindingComponentName2 (\r
-             ImageHandle,\r
-             SystemTable,\r
-             &gWinNtSerialIoDriverBinding,\r
-             ImageHandle,\r
-             &gWinNtSerialIoComponentName,\r
-             &gWinNtSerialIoComponentName2\r
-             );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSerialIoDriverBindingSupported (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,\r
-  IN  EFI_HANDLE                    Handle,\r
-  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-// TODO:    This - add argument and description to function comment\r
-// TODO:    Handle - add argument and description to function comment\r
-// TODO:    RemainingDevicePath - add argument and description to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-{\r
-  EFI_STATUS                          Status;\r
-  EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;\r
-  EFI_WIN_NT_IO_PROTOCOL              *WinNtIo;\r
-  UART_DEVICE_PATH                    *UartNode;\r
-  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;\r
-  UART_FLOW_CONTROL_DEVICE_PATH       *FlowControlNode;\r
-  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;\r
-  UINTN                               EntryCount;\r
-  UINTN                               Index;\r
-  BOOLEAN                             RemainingDevicePathContainsFlowControl; \r
-\r
-  //\r
-  // Check RemainingDevicePath validation\r
-  //\r
-  if (RemainingDevicePath != NULL) {\r
-    //\r
-    // Check if RemainingDevicePath is the End of Device Path Node, \r
-    // if yes, go on checking other conditions\r
-    //\r
-    if (!IsDevicePathEnd (RemainingDevicePath)) {\r
-      //\r
-      // If RemainingDevicePath isn't the End of Device Path Node,\r
-      // check its validation\r
-      //\r
-      Status = EFI_UNSUPPORTED;\r
-\r
-      UartNode  = (UART_DEVICE_PATH *) RemainingDevicePath;\r
-      if (UartNode->Header.Type != MESSAGING_DEVICE_PATH ||\r
-          UartNode->Header.SubType != MSG_UART_DP ||\r
-          DevicePathNodeLength((EFI_DEVICE_PATH_PROTOCOL *)UartNode) != sizeof(UART_DEVICE_PATH)) {\r
-        goto Error;\r
-      }\r
-      if ( UartNode->BaudRate > SERIAL_PORT_MAX_BAUD_RATE) {\r
-        goto Error;\r
-      }\r
-      if (UartNode->Parity < NoParity || UartNode->Parity > SpaceParity) {\r
-        goto Error;\r
-      }\r
-      if (UartNode->DataBits < 5 || UartNode->DataBits > 8) {\r
-        goto Error;\r
-      }\r
-      if (UartNode->StopBits < OneStopBit || UartNode->StopBits > TwoStopBits) {\r
-        goto Error;\r
-      }\r
-      if ((UartNode->DataBits == 5) && (UartNode->StopBits == TwoStopBits)) {\r
-        goto Error;\r
-      }\r
-      if ((UartNode->DataBits >= 6) && (UartNode->DataBits <= 8) && (UartNode->StopBits == OneFiveStopBits)) {\r
-        goto Error;\r
-      }\r
-\r
-      FlowControlNode = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (UartNode);\r
-      if (IsUartFlowControlNode (FlowControlNode)) {\r
-        //\r
-        // If the second node is Flow Control Node,\r
-        //   return error when it request other than hardware flow control.\r
-        //\r
-        if ((FlowControlNode->FlowControlMap & ~UART_FLOW_CONTROL_HARDWARE) != 0) {\r
-          goto Error;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  //\r
-  // Open the IO Abstraction(s) needed to perform the supported test\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Handle,\r
-                  &gEfiWinNtIoProtocolGuid,\r
-                  (VOID **) &WinNtIo,\r
-                  This->DriverBindingHandle,\r
-                  Handle,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (Status == EFI_ALREADY_STARTED) {\r
-    if (RemainingDevicePath == NULL || IsDevicePathEnd (RemainingDevicePath)) {\r
-      //\r
-      // If RemainingDevicePath is NULL or is the End of Device Path Node\r
-      //\r
-      return EFI_SUCCESS;\r
-    }\r
-    //\r
-    // When the driver has produced device path with flow control node but RemainingDevicePath only contains UART node,\r
-    //   return unsupported, and vice versa.\r
-    //\r
-    Status = gBS->OpenProtocolInformation (\r
-                    Handle,\r
-                    &gEfiWinNtIoProtocolGuid,\r
-                    &OpenInfoBuffer,\r
-                    &EntryCount\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
-    //\r
-    // See if RemainingDevicePath has a Flow Control device path node\r
-    //\r
-    RemainingDevicePathContainsFlowControl = ContainsFlowControl (RemainingDevicePath);\r
-    \r
-    for (Index = 0; Index < EntryCount; Index++) {\r
-      if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
-        Status = gBS->OpenProtocol (\r
-                        OpenInfoBuffer[Index].ControllerHandle,\r
-                        &gEfiDevicePathProtocolGuid,\r
-                        (VOID **) &DevicePath,\r
-                        This->DriverBindingHandle,\r
-                        Handle,\r
-                        EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                        );\r
-        if (!EFI_ERROR (Status)) {\r
-          if (RemainingDevicePathContainsFlowControl ^ ContainsFlowControl (DevicePath)) {\r
-            Status = EFI_UNSUPPORTED;\r
-          }\r
-        }\r
-        break;\r
-      }\r
-    }\r
-    FreePool (OpenInfoBuffer);\r
-    return Status;\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Close the I/O Abstraction(s) used to perform the supported test\r
-  //\r
-  gBS->CloseProtocol (\r
-        Handle,\r
-        &gEfiWinNtIoProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        Handle\r
-        );\r
-\r
-  //\r
-  // Open the EFI Device Path protocol needed to perform the supported test\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Handle,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID **) &ParentDevicePath,\r
-                  This->DriverBindingHandle,\r
-                  Handle,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (Status == EFI_ALREADY_STARTED) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Close protocol, don't use device path protocol in the Support() function\r
-  //\r
-  gBS->CloseProtocol (\r
-        Handle,\r
-        &gEfiDevicePathProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        Handle\r
-        );\r
-\r
-  //\r
-  // Make sure that the WinNt Thunk Protocol is valid\r
-  //\r
-  if (WinNtIo->WinNtThunk->Signature != EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) {\r
-    Status = EFI_UNSUPPORTED;\r
-    goto Error;\r
-  }\r
-\r
-  //\r
-  // Check the GUID to see if this is a handle type the driver supports\r
-  //\r
-  if (!CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtSerialPortGuid)) {\r
-    Status = EFI_UNSUPPORTED;\r
-    goto Error;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-\r
-Error:\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSerialIoDriverBindingStart (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,\r
-  IN  EFI_HANDLE                    Handle,\r
-  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-Arguments:\r
-\r
-Returns:\r
-\r
-  None\r
-\r
---*/\r
-// TODO:    This - add argument and description to function comment\r
-// TODO:    Handle - add argument and description to function comment\r
-// TODO:    RemainingDevicePath - add argument and description to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-{\r
-  EFI_STATUS                          Status;\r
-  EFI_WIN_NT_IO_PROTOCOL              *WinNtIo;\r
-  WIN_NT_SERIAL_IO_PRIVATE_DATA       *Private;\r
-  HANDLE                              NtHandle;\r
-  UART_DEVICE_PATH                    UartNode;\r
-  EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;\r
-  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;\r
-  UINTN                               EntryCount;\r
-  UINTN                               Index;\r
-  EFI_SERIAL_IO_PROTOCOL              *SerialIo;\r
-  UART_DEVICE_PATH                    *Uart;\r
-  UINT32                              FlowControlMap;\r
-  UART_FLOW_CONTROL_DEVICE_PATH       *FlowControl;\r
-  EFI_DEVICE_PATH_PROTOCOL            *TempDevicePath;\r
-  UINT32                              Control;\r
-\r
-  Private   = NULL;\r
-  NtHandle  = INVALID_HANDLE_VALUE;\r
-\r
-  //\r
-  // Get the Parent Device Path\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Handle,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID **) &ParentDevicePath,\r
-                  This->DriverBindingHandle,\r
-                  Handle,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Grab the IO abstraction we need to get any work done\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Handle,\r
-                  &gEfiWinNtIoProtocolGuid,\r
-                  (VOID **) &WinNtIo,\r
-                  This->DriverBindingHandle,\r
-                  Handle,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
-    gBS->CloseProtocol (\r
-          Handle,\r
-          &gEfiDevicePathProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          Handle\r
-          );\r
-    return Status;\r
-  }\r
-\r
-  if (Status == EFI_ALREADY_STARTED) {\r
-\r
-    if (RemainingDevicePath == NULL || IsDevicePathEnd (RemainingDevicePath)) {\r
-      //\r
-      // If RemainingDevicePath is NULL or is the End of Device Path Node\r
-      //\r
-      return EFI_SUCCESS;\r
-    }\r
-\r
-    //\r
-    // Make sure a child handle does not already exist.  This driver can only\r
-    // produce one child per serial port.\r
-    //\r
-    Status = gBS->OpenProtocolInformation (\r
-                    Handle,\r
-                    &gEfiWinNtIoProtocolGuid,\r
-                    &OpenInfoBuffer,\r
-                    &EntryCount\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
-    Status = EFI_ALREADY_STARTED;\r
-    for (Index = 0; Index < EntryCount; Index++) {\r
-      if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {\r
-        Status = gBS->OpenProtocol (\r
-                        OpenInfoBuffer[Index].ControllerHandle,\r
-                        &gEfiSerialIoProtocolGuid,\r
-                        (VOID **) &SerialIo,\r
-                        This->DriverBindingHandle,\r
-                        Handle,\r
-                        EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                        );\r
-        if (!EFI_ERROR (Status)) {\r
-          Uart   = (UART_DEVICE_PATH *) RemainingDevicePath;\r
-          Status = SerialIo->SetAttributes (\r
-                               SerialIo,\r
-                               Uart->BaudRate,\r
-                               SerialIo->Mode->ReceiveFifoDepth,\r
-                               SerialIo->Mode->Timeout,\r
-                               (EFI_PARITY_TYPE) Uart->Parity,\r
-                               Uart->DataBits,\r
-                               (EFI_STOP_BITS_TYPE) Uart->StopBits\r
-                               );\r
-          FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (Uart);\r
-          if (!EFI_ERROR (Status) && IsUartFlowControlNode (FlowControl)) {\r
-            Status = SerialIo->GetControl (SerialIo, &Control);\r
-            if (!EFI_ERROR (Status)) {\r
-              if (FlowControl->FlowControlMap == UART_FLOW_CONTROL_HARDWARE) {\r
-                Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;\r
-              } else {\r
-                Control &= ~EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;\r
-              }\r
-              //\r
-              // Clear the bits that are not allowed to pass to SetControl\r
-              //\r
-              Control &= (EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY |\r
-                          EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE | EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE | \r
-                          EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE);\r
-              Status = SerialIo->SetControl (SerialIo, Control);\r
-            }\r
-          }\r
-        }\r
-        break;\r
-      }\r
-    }\r
-\r
-    FreePool (OpenInfoBuffer);\r
-    return Status;\r
-  }\r
-\r
-  FlowControl    = NULL;\r
-  FlowControlMap = 0;\r
-  if (RemainingDevicePath == NULL) {\r
-    //\r
-    // Build the device path by appending the UART node to the ParentDevicePath\r
-    // from the WinNtIo handle. The Uart setings are zero here, since\r
-    // SetAttribute() will update them to match the default setings.\r
-    //\r
-    ZeroMem (&UartNode, sizeof (UART_DEVICE_PATH));\r
-    UartNode.Header.Type     = MESSAGING_DEVICE_PATH;\r
-    UartNode.Header.SubType  = MSG_UART_DP;\r
-    SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) &UartNode, sizeof (UART_DEVICE_PATH));\r
-\r
-  } else if (!IsDevicePathEnd (RemainingDevicePath)) {\r
-    //\r
-    // If RemainingDevicePath isn't the End of Device Path Node, \r
-    // only scan the specified device by RemainingDevicePath\r
-    //\r
-    //\r
-    // Match the configuration of the RemainingDevicePath. IsHandleSupported()\r
-    // already checked to make sure the RemainingDevicePath contains settings\r
-    // that we can support.\r
-    //\r
-    CopyMem (&UartNode, RemainingDevicePath, sizeof (UART_DEVICE_PATH));\r
-    FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);\r
-    if (IsUartFlowControlNode (FlowControl)) {\r
-      FlowControlMap = FlowControl->FlowControlMap;\r
-    } else {\r
-      FlowControl    = NULL;\r
-    }\r
-\r
-  } else {\r
-    //\r
-    // If RemainingDevicePath is the End of Device Path Node,\r
-    // skip enumerate any device and return EFI_SUCESSS\r
-    // \r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // Check to see if we can access the hardware device. If it's Open in NT we\r
-  // will not get access.\r
-  //\r
-  NtHandle = WinNtIo->WinNtThunk->CreateFile (\r
-                                    WinNtIo->EnvString,\r
-                                    GENERIC_READ | GENERIC_WRITE,\r
-                                    0,\r
-                                    NULL,\r
-                                    OPEN_EXISTING,\r
-                                    0,\r
-                                    NULL\r
-                                    );\r
-  if (NtHandle == INVALID_HANDLE_VALUE) {\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Error;\r
-  }\r
-\r
-  //\r
-  // Construct Private data\r
-  //\r
-  Private = AllocatePool (sizeof (WIN_NT_SERIAL_IO_PRIVATE_DATA));\r
-  if (Private == NULL) {\r
-    goto Error;\r
-  }\r
-\r
-  //\r
-  // This signature must be valid before any member function is called\r
-  //\r
-  Private->Signature              = WIN_NT_SERIAL_IO_PRIVATE_DATA_SIGNATURE;\r
-  Private->NtHandle               = NtHandle;\r
-  Private->ControllerHandle       = Handle;\r
-  Private->Handle                 = NULL;\r
-  Private->WinNtThunk             = WinNtIo->WinNtThunk;\r
-  Private->ParentDevicePath       = ParentDevicePath;\r
-  Private->ControllerNameTable    = NULL;\r
-\r
-  Private->SoftwareLoopbackEnable = FALSE;\r
-  Private->HardwareLoopbackEnable = FALSE;\r
-  Private->HardwareFlowControl    = (BOOLEAN) (FlowControlMap == UART_FLOW_CONTROL_HARDWARE);\r
-  Private->Fifo.First             = 0;\r
-  Private->Fifo.Last              = 0;\r
-  Private->Fifo.Surplus           = SERIAL_MAX_BUFFER_SIZE;\r
-\r
-  CopyMem (&Private->UartDevicePath, &UartNode, sizeof (UART_DEVICE_PATH));\r
-\r
-  AddUnicodeString2 (\r
-    "eng",\r
-    gWinNtSerialIoComponentName.SupportedLanguages,\r
-    &Private->ControllerNameTable,\r
-    WinNtIo->EnvString,\r
-    TRUE\r
-    );\r
-  AddUnicodeString2 (\r
-    "en",\r
-    gWinNtSerialIoComponentName2.SupportedLanguages,\r
-    &Private->ControllerNameTable,\r
-    WinNtIo->EnvString,\r
-    FALSE\r
-    );\r
-\r
-\r
-  Private->SerialIo.Revision      = SERIAL_IO_INTERFACE_REVISION;\r
-  Private->SerialIo.Reset         = WinNtSerialIoReset;\r
-  Private->SerialIo.SetAttributes = WinNtSerialIoSetAttributes;\r
-  Private->SerialIo.SetControl    = WinNtSerialIoSetControl;\r
-  Private->SerialIo.GetControl    = WinNtSerialIoGetControl;\r
-  Private->SerialIo.Write         = WinNtSerialIoWrite;\r
-  Private->SerialIo.Read          = WinNtSerialIoRead;\r
-  Private->SerialIo.Mode          = &Private->SerialIoMode;\r
-\r
-  //\r
-  // Build the device path by appending the UART node to the ParentDevicePath\r
-  // from the WinNtIo handle. The Uart setings are zero here, since\r
-  // SetAttribute() will update them to match the current setings.\r
-  //\r
-  Private->DevicePath = AppendDevicePathNode (\r
-                          ParentDevicePath,\r
-                          (EFI_DEVICE_PATH_PROTOCOL *) &Private->UartDevicePath\r
-                          );\r
-  //\r
-  // Only produce the FlowControl node when remaining device path has it\r
-  //\r
-  if (FlowControl != NULL) {\r
-    TempDevicePath = Private->DevicePath;\r
-    if (TempDevicePath != NULL) {\r
-      Private->DevicePath = AppendDevicePathNode (\r
-                              TempDevicePath,\r
-                              (EFI_DEVICE_PATH_PROTOCOL *) FlowControl\r
-                              );\r
-      FreePool (TempDevicePath);\r
-    }\r
-  }\r
-  if (Private->DevicePath == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Error;\r
-  }\r
-\r
-  //\r
-  // Fill in Serial I/O Mode structure based on either the RemainingDevicePath or defaults.\r
-  //\r
-  Private->SerialIoMode.ControlMask       = SERIAL_CONTROL_MASK;\r
-  Private->SerialIoMode.Timeout           = SERIAL_TIMEOUT_DEFAULT;\r
-  Private->SerialIoMode.BaudRate          = Private->UartDevicePath.BaudRate;\r
-  Private->SerialIoMode.ReceiveFifoDepth  = SERIAL_FIFO_DEFAULT;\r
-  Private->SerialIoMode.DataBits          = Private->UartDevicePath.DataBits;\r
-  Private->SerialIoMode.Parity            = Private->UartDevicePath.Parity;\r
-  Private->SerialIoMode.StopBits          = Private->UartDevicePath.StopBits;\r
-\r
-  //\r
-  // Issue a reset to initialize the COM port\r
-  //\r
-  Status = Private->SerialIo.Reset (&Private->SerialIo);\r
-  if (EFI_ERROR (Status)) {\r
-    goto Error;\r
-  }\r
-\r
-  //\r
-  // Create new child handle\r
-  //\r
-  Status = gBS->InstallMultipleProtocolInterfaces (\r
-                  &Private->Handle,\r
-                  &gEfiSerialIoProtocolGuid,\r
-                  &Private->SerialIo,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  Private->DevicePath,\r
-                  NULL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Error;\r
-  }\r
-\r
-  //\r
-  // Open For Child Device\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Handle,\r
-                  &gEfiWinNtIoProtocolGuid,\r
-                  (VOID **) &WinNtIo,\r
-                  This->DriverBindingHandle,\r
-                  Private->Handle,\r
-                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Error;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-\r
-Error:\r
-  //\r
-  // Use the Stop() function to free all resources allocated in Start()\r
-  //\r
-  if (Private != NULL) {\r
-    if (Private->Handle != NULL) {\r
-      This->Stop (This, Handle, 1, &Private->Handle);\r
-    } else {\r
-      if (NtHandle != INVALID_HANDLE_VALUE) {\r
-        Private->WinNtThunk->CloseHandle (NtHandle);\r
-      }\r
-\r
-      if (Private->DevicePath != NULL) {\r
-        FreePool (Private->DevicePath);\r
-      }\r
-\r
-      FreeUnicodeStringTable (Private->ControllerNameTable);\r
-\r
-      FreePool (Private);\r
-    }\r
-  }\r
-\r
-  This->Stop (This, Handle, 0, NULL);\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSerialIoDriverBindingStop (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,\r
-  IN  EFI_HANDLE                    Handle,\r
-  IN  UINTN                         NumberOfChildren,\r
-  IN  EFI_HANDLE                    *ChildHandleBuffer\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  This              - TODO: add argument description\r
-  Handle            - TODO: add argument description\r
-  NumberOfChildren  - TODO: add argument description\r
-  ChildHandleBuffer - TODO: add argument description\r
-\r
-Returns:\r
-\r
-  EFI_DEVICE_ERROR - TODO: Add description for return value\r
-  EFI_SUCCESS - TODO: Add description for return value\r
-\r
---*/\r
-{\r
-  EFI_STATUS                    Status;\r
-  UINTN                         Index;\r
-  BOOLEAN                       AllChildrenStopped;\r
-  EFI_SERIAL_IO_PROTOCOL        *SerialIo;\r
-  WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;\r
-  EFI_WIN_NT_IO_PROTOCOL        *WinNtIo;\r
-\r
-  //\r
-  // Complete all outstanding transactions to Controller.\r
-  // Don't allow any new transaction to Controller to be started.\r
-  //\r
-\r
-  if (NumberOfChildren == 0) {\r
-    //\r
-    // Close the bus driver\r
-    //\r
-    Status = gBS->CloseProtocol (\r
-                    Handle,\r
-                    &gEfiWinNtIoProtocolGuid,\r
-                    This->DriverBindingHandle,\r
-                    Handle\r
-                    );\r
-    Status = gBS->CloseProtocol (\r
-                    Handle,\r
-                    &gEfiDevicePathProtocolGuid,\r
-                    This->DriverBindingHandle,\r
-                    Handle\r
-                    );\r
-    return Status;\r
-  }\r
-\r
-  AllChildrenStopped = TRUE;\r
-\r
-  for (Index = 0; Index < NumberOfChildren; Index++) {\r
-    Status = gBS->OpenProtocol (\r
-                    ChildHandleBuffer[Index],\r
-                    &gEfiSerialIoProtocolGuid,\r
-                    (VOID **) &SerialIo,\r
-                    This->DriverBindingHandle,\r
-                    Handle,\r
-                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                    );\r
-    if (!EFI_ERROR (Status)) {\r
-      Private = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (SerialIo);\r
-\r
-      ASSERT (Private->Handle == ChildHandleBuffer[Index]);\r
-\r
-      Status = gBS->CloseProtocol (\r
-                      Handle,\r
-                      &gEfiWinNtIoProtocolGuid,\r
-                      This->DriverBindingHandle,\r
-                      ChildHandleBuffer[Index]\r
-                      );\r
-\r
-      Status = gBS->UninstallMultipleProtocolInterfaces (\r
-                      ChildHandleBuffer[Index],\r
-                      &gEfiSerialIoProtocolGuid,\r
-                      &Private->SerialIo,\r
-                      &gEfiDevicePathProtocolGuid,\r
-                      Private->DevicePath,\r
-                      NULL\r
-                      );\r
-\r
-      if (EFI_ERROR (Status)) {\r
-        gBS->OpenProtocol (\r
-              Handle,\r
-              &gEfiWinNtIoProtocolGuid,\r
-              (VOID **) &WinNtIo,\r
-              This->DriverBindingHandle,\r
-              ChildHandleBuffer[Index],\r
-              EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
-              );\r
-      } else {\r
-        Private->WinNtThunk->CloseHandle (Private->NtHandle);\r
-\r
-        FreePool (Private->DevicePath);\r
-\r
-        FreeUnicodeStringTable (Private->ControllerNameTable);\r
-\r
-        FreePool (Private);\r
-      }\r
-    }\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      AllChildrenStopped = FALSE;\r
-    }\r
-  }\r
-\r
-  if (!AllChildrenStopped) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// Serial IO Protocol member functions\r
-//\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSerialIoReset (\r
-  IN EFI_SERIAL_IO_PROTOCOL *This\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  This  - TODO: add argument description\r
-\r
-Returns:\r
-\r
-  TODO: add return values\r
-\r
---*/\r
-{\r
-  WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;\r
-  EFI_TPL                       Tpl;\r
-\r
-  Tpl     = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  Private = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  Private->WinNtThunk->PurgeComm (\r
-                        Private->NtHandle,\r
-                        PURGE_TXCLEAR | PURGE_RXCLEAR\r
-                        );\r
-\r
-  gBS->RestoreTPL (Tpl);\r
-\r
-  return This->SetAttributes (\r
-                This,\r
-                This->Mode->BaudRate,\r
-                This->Mode->ReceiveFifoDepth,\r
-                This->Mode->Timeout,\r
-                (EFI_PARITY_TYPE)This->Mode->Parity,\r
-                (UINT8) This->Mode->DataBits,\r
-                (EFI_STOP_BITS_TYPE)This->Mode->StopBits\r
-                );\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSerialIoSetAttributes (\r
-  IN EFI_SERIAL_IO_PROTOCOL *This,\r
-  IN UINT64                 BaudRate,\r
-  IN UINT32                 ReceiveFifoDepth,\r
-  IN UINT32                 Timeout,\r
-  IN EFI_PARITY_TYPE        Parity,\r
-  IN UINT8                  DataBits,\r
-  IN EFI_STOP_BITS_TYPE     StopBits\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  This function is used to set the attributes.\r
-\r
-Arguments:\r
-\r
-  This              - A pointer to the EFI_SERIAL_IO_PROTOCOL structrue.\r
-  BaudRate          - The Baud rate of the serial device.\r
-  ReceiveFifoDepth  - The request depth of fifo on receive side.\r
-  Timeout           - the request timeout for a single charact.\r
-  Parity            - The type of parity used in serial device.\r
-  DataBits          - Number of deata bits used in serial device.\r
-  StopBits          - Number of stop bits used in serial device.\r
-\r
-Returns:\r
-  Status code\r
-\r
-  None\r
-\r
---*/\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-// TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-// TODO:    EFI_DEVICE_ERROR - add return value to function comment\r
-// TODO:    EFI_SUCCESS - add return value to function comment\r
-{\r
-  EFI_STATUS                    Status;\r
-  UINTN                         Index;  \r
-  WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;\r
-  COMMTIMEOUTS                  PortTimeOuts;\r
-  DWORD                         ConvertedTime;\r
-  BOOL                          Result;\r
-  UART_DEVICE_PATH              *Uart;\r
-  EFI_TPL                       Tpl;\r
-\r
-  Private = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  //\r
-  //  Some of our arguments have defaults if a null value is passed in, and\r
-  //   we must set the default values if a null argument is passed in.\r
-  //\r
-  if (BaudRate == 0) {\r
-    BaudRate = PcdGet64 (PcdUartDefaultBaudRate);\r
-  }\r
-\r
-  if (ReceiveFifoDepth == 0) {\r
-    ReceiveFifoDepth = SERIAL_FIFO_DEFAULT;\r
-  }\r
-\r
-  if (Timeout == 0) {\r
-    Timeout = SERIAL_TIMEOUT_DEFAULT;\r
-  }\r
-\r
-  if (Parity == DefaultParity) {\r
-    Parity = (EFI_PARITY_TYPE) (PcdGet8 (PcdUartDefaultParity));\r
-  }\r
-\r
-  if (DataBits == 0) {\r
-    DataBits = PcdGet8 (PcdUartDefaultDataBits);\r
-  }\r
-\r
-  if (StopBits == DefaultStopBits) {\r
-    StopBits = (EFI_STOP_BITS_TYPE) PcdGet8 (PcdUartDefaultStopBits);\r
-  }\r
-\r
-  //\r
-  // Make sure all parameters are valid\r
-  //\r
-  if ((BaudRate > SERIAL_PORT_MAX_BAUD_RATE) || (BaudRate < SERIAL_PORT_MIN_BAUD_RATE)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  //The lower baud rate supported by the serial device will be selected without exceeding the unsupported BaudRate parameter\r
-  // \r
-  \r
-  for (Index = 1; Index < (ARRAY_SIZE (mBaudRateCurrentSupport)); Index++) {\r
-    if (BaudRate < mBaudRateCurrentSupport[Index]) {\r
-      BaudRate = mBaudRateCurrentSupport[Index-1];\r
-      break;\r
-      }\r
-  }\r
-\r
-  if ((ReceiveFifoDepth < 1) || (ReceiveFifoDepth > SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if ((Timeout < SERIAL_PORT_MIN_TIMEOUT) || (Timeout > SERIAL_PORT_MAX_TIMEOUT)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if ((Parity < NoParity) || (Parity > SpaceParity)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if ((StopBits < OneStopBit) || (StopBits > TwoStopBits)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Now we only support DataBits=7,8.\r
-  //\r
-  if ((DataBits < 7) || (DataBits > 8)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  \r
-  //\r
-  // Now we only support DataBits=7,8.\r
-  // for DataBits = 6,7,8, StopBits can not set OneFiveStopBits.\r
-  //\r
-  if (StopBits == OneFiveStopBits) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }  \r
-  \r
-  //\r
-  // See if the new attributes already match the current attributes\r
-  //\r
-  if (Private->UartDevicePath.BaudRate       == BaudRate         &&\r
-      Private->UartDevicePath.DataBits       == DataBits         &&\r
-      Private->UartDevicePath.Parity         == Parity           &&\r
-      Private->UartDevicePath.StopBits       == StopBits         &&\r
-      Private->SerialIoMode.ReceiveFifoDepth == ReceiveFifoDepth &&\r
-      Private->SerialIoMode.Timeout          == Timeout             ) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  Tpl     = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  //\r
-  //  Get current values from NT\r
-  //\r
-  ZeroMem (&Private->NtDCB, sizeof (DCB));\r
-  Private->NtDCB.DCBlength = sizeof (DCB);\r
-\r
-  if (!Private->WinNtThunk->GetCommState (Private->NtHandle, &Private->NtDCB)) {\r
-    Private->NtError = Private->WinNtThunk->GetLastError ();\r
-    DEBUG ((EFI_D_ERROR, "SerialSetAttributes: GetCommState %d\n", Private->NtError));\r
-    gBS->RestoreTPL (Tpl);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  // Map EFI com setting to NT\r
-  //\r
-  Private->NtDCB.BaudRate         = ConvertBaud2Nt (BaudRate);\r
-  Private->NtDCB.ByteSize         = ConvertData2Nt (DataBits);\r
-  Private->NtDCB.Parity           = ConvertParity2Nt (Parity);\r
-  Private->NtDCB.StopBits         = ConvertStop2Nt (StopBits);\r
-\r
-  Private->NtDCB.fBinary          = TRUE;\r
-  Private->NtDCB.fParity          = Private->NtDCB.Parity == NOPARITY ? FALSE : TRUE;\r
-  Private->NtDCB.fOutxCtsFlow     = FALSE;\r
-  Private->NtDCB.fOutxDsrFlow     = FALSE;\r
-  Private->NtDCB.fDtrControl      = DTR_CONTROL_ENABLE;\r
-  Private->NtDCB.fDsrSensitivity  = FALSE;\r
-  Private->NtDCB.fOutX            = FALSE;\r
-  Private->NtDCB.fInX             = FALSE;\r
-  Private->NtDCB.fRtsControl      = RTS_CONTROL_ENABLE;\r
-  Private->NtDCB.fNull            = FALSE;\r
-\r
-  //\r
-  //  Set new values\r
-  //\r
-  Result = Private->WinNtThunk->SetCommState (Private->NtHandle, &Private->NtDCB);\r
-  if (!Result) {\r
-    Private->NtError = Private->WinNtThunk->GetLastError ();\r
-    DEBUG ((EFI_D_ERROR, "SerialSetAttributes: SetCommState %d\n", Private->NtError));\r
-    gBS->RestoreTPL (Tpl);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  //  Set com port read/write timeout values\r
-  //\r
-  ConvertedTime = ConvertTime2Nt (Timeout);\r
-  PortTimeOuts.ReadIntervalTimeout = MAXDWORD;\r
-  PortTimeOuts.ReadTotalTimeoutMultiplier = 0;\r
-  PortTimeOuts.ReadTotalTimeoutConstant = ConvertedTime;\r
-  PortTimeOuts.WriteTotalTimeoutMultiplier = ConvertedTime == 0 ? 1 : ConvertedTime;\r
-  PortTimeOuts.WriteTotalTimeoutConstant = 0;\r
-\r
-  if (!Private->WinNtThunk->SetCommTimeouts (Private->NtHandle, &PortTimeOuts)) {\r
-    Private->NtError = Private->WinNtThunk->GetLastError ();\r
-    DEBUG ((EFI_D_ERROR, "SerialSetAttributes: SetCommTimeouts %d\n", Private->NtError));\r
-    gBS->RestoreTPL (Tpl);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  //  Update mode\r
-  //\r
-  Private->SerialIoMode.BaudRate          = BaudRate;\r
-  Private->SerialIoMode.ReceiveFifoDepth  = ReceiveFifoDepth;\r
-  Private->SerialIoMode.Timeout           = Timeout;\r
-  Private->SerialIoMode.Parity            = Parity;\r
-  Private->SerialIoMode.DataBits          = DataBits;\r
-  Private->SerialIoMode.StopBits          = StopBits;\r
-\r
-  //\r
-  // See if Device Path Node has actually changed\r
-  //\r
-  if (Private->UartDevicePath.BaudRate     == BaudRate &&\r
-      Private->UartDevicePath.DataBits     == DataBits &&\r
-      Private->UartDevicePath.Parity       == Parity   &&\r
-      Private->UartDevicePath.StopBits     == StopBits    ) {\r
-    gBS->RestoreTPL(Tpl);\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // Update the device path\r
-  //\r
-  Private->UartDevicePath.BaudRate  = BaudRate;\r
-  Private->UartDevicePath.DataBits  = DataBits;\r
-  Private->UartDevicePath.Parity    = (UINT8) Parity;\r
-  Private->UartDevicePath.StopBits  = (UINT8) StopBits;\r
-\r
-  Status = EFI_SUCCESS;\r
-  if (Private->Handle != NULL) {\r
-    Uart = (UART_DEVICE_PATH *) (\r
-             (UINTN) Private->DevicePath\r
-             + GetDevicePathSize (Private->ParentDevicePath)\r
-             - END_DEVICE_PATH_LENGTH\r
-             );\r
-    CopyMem (Uart, &Private->UartDevicePath, sizeof (UART_DEVICE_PATH));\r
-    Status = gBS->ReinstallProtocolInterface (\r
-                    Private->Handle,\r
-                    &gEfiDevicePathProtocolGuid,\r
-                    Private->DevicePath,\r
-                    Private->DevicePath\r
-                    );\r
-  }\r
-\r
-  gBS->RestoreTPL (Tpl);\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSerialIoSetControl (\r
-  IN EFI_SERIAL_IO_PROTOCOL *This,\r
-  IN UINT32                 Control\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  This    - TODO: add argument description\r
-  Control - TODO: add argument description\r
-\r
-Returns:\r
-\r
-  EFI_DEVICE_ERROR - TODO: Add description for return value\r
-  EFI_DEVICE_ERROR - TODO: Add description for return value\r
-  EFI_SUCCESS - TODO: Add description for return value\r
-\r
---*/\r
-{\r
-  WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;\r
-  BOOL                          Result;\r
-  DCB                           Dcb;\r
-  EFI_TPL                       Tpl;\r
-  UART_FLOW_CONTROL_DEVICE_PATH *FlowControl;\r
-  EFI_STATUS                    Status;\r
-\r
-  //\r
-  // first determine the parameter is invalid\r
-  //\r
-  if (Control & (~(EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY |\r
-                   EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE | EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE | \r
-                   EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  Tpl     = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  Private = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  Result  = Private->WinNtThunk->GetCommState (Private->NtHandle, &Dcb);\r
-\r
-  if (!Result) {\r
-    Private->NtError = Private->WinNtThunk->GetLastError ();\r
-    DEBUG ((EFI_D_ERROR, "SerialSetControl: GetCommState %d\n", Private->NtError));\r
-    gBS->RestoreTPL (Tpl);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  Dcb.fRtsControl                 = RTS_CONTROL_DISABLE;\r
-  Dcb.fDtrControl                 = DTR_CONTROL_DISABLE;\r
-  Private->HardwareFlowControl    = FALSE;\r
-  Private->SoftwareLoopbackEnable = FALSE;\r
-  Private->HardwareLoopbackEnable = FALSE;\r
-\r
-  if (Control & EFI_SERIAL_REQUEST_TO_SEND) {\r
-    Dcb.fRtsControl = RTS_CONTROL_ENABLE;\r
-  }\r
-\r
-  if (Control & EFI_SERIAL_DATA_TERMINAL_READY) {\r
-    Dcb.fDtrControl = DTR_CONTROL_ENABLE;\r
-  }\r
-\r
-  if (Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) {\r
-    Private->HardwareFlowControl = TRUE;\r
-  }\r
-\r
-  if (Control & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) {\r
-    Private->SoftwareLoopbackEnable = TRUE;\r
-  }\r
-\r
-  if (Control & EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE) {\r
-    Private->HardwareLoopbackEnable = TRUE;\r
-  }\r
-\r
-  Result = Private->WinNtThunk->SetCommState (\r
-                                  Private->NtHandle,\r
-                                  &Dcb\r
-                                  );\r
-\r
-  if (!Result) {\r
-    Private->NtError = Private->WinNtThunk->GetLastError ();\r
-    DEBUG ((EFI_D_ERROR, "SerialSetControl: SetCommState %d\n", Private->NtError));\r
-    gBS->RestoreTPL (Tpl);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  Status = EFI_SUCCESS;\r
-  if (Private->Handle != NULL) {\r
-    FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) (\r
-                    (UINTN) Private->DevicePath\r
-                    + GetDevicePathSize (Private->ParentDevicePath)\r
-                    - END_DEVICE_PATH_LENGTH\r
-                    + sizeof (UART_DEVICE_PATH)\r
-                    );\r
-    if (IsUartFlowControlNode (FlowControl) &&\r
-        ((FlowControl->FlowControlMap == UART_FLOW_CONTROL_HARDWARE) ^ Private->HardwareFlowControl)) {\r
-      //\r
-      // Flow Control setting is changed, need to reinstall device path protocol\r
-      //\r
-      FlowControl->FlowControlMap = Private->HardwareFlowControl ? UART_FLOW_CONTROL_HARDWARE : 0;\r
-      Status = gBS->ReinstallProtocolInterface (\r
-                      Private->Handle,\r
-                      &gEfiDevicePathProtocolGuid,\r
-                      Private->DevicePath,\r
-                      Private->DevicePath\r
-                      );\r
-    }\r
-  }\r
-\r
-  gBS->RestoreTPL (Tpl);\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSerialIoGetControl (\r
-  IN  EFI_SERIAL_IO_PROTOCOL  *This,\r
-  OUT UINT32                  *Control\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  This    - TODO: add argument description\r
-  Control - TODO: add argument description\r
-\r
-Returns:\r
-\r
-  EFI_DEVICE_ERROR - TODO: Add description for return value\r
-  EFI_DEVICE_ERROR - TODO: Add description for return value\r
-  EFI_DEVICE_ERROR - TODO: Add description for return value\r
-  EFI_SUCCESS - TODO: Add description for return value\r
-\r
---*/\r
-{\r
-  WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;\r
-  DWORD                         ModemStatus;\r
-  DWORD                         Errors;\r
-  UINT32                        Bits;\r
-  DCB                           Dcb;\r
-  EFI_TPL                       Tpl;\r
-\r
-  Tpl     = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  Private = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  //\r
-  //  Get modem status\r
-  //\r
-  if (!Private->WinNtThunk->GetCommModemStatus (Private->NtHandle, &ModemStatus)) {\r
-    Private->NtError = Private->WinNtThunk->GetLastError ();\r
-    gBS->RestoreTPL (Tpl);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  Bits = 0;\r
-  if (ModemStatus & MS_CTS_ON) {\r
-    Bits |= EFI_SERIAL_CLEAR_TO_SEND;\r
-  }\r
-\r
-  if (ModemStatus & MS_DSR_ON) {\r
-    Bits |= EFI_SERIAL_DATA_SET_READY;\r
-  }\r
-\r
-  if (ModemStatus & MS_RING_ON) {\r
-    Bits |= EFI_SERIAL_RING_INDICATE;\r
-  }\r
-\r
-  if (ModemStatus & MS_RLSD_ON) {\r
-    Bits |= EFI_SERIAL_CARRIER_DETECT;\r
-  }\r
-\r
-  //\r
-  // Get ctrl status\r
-  //\r
-  if (!Private->WinNtThunk->GetCommState (Private->NtHandle, &Dcb)) {\r
-    Private->NtError = Private->WinNtThunk->GetLastError ();\r
-    DEBUG ((EFI_D_ERROR, "SerialGetControl: GetCommState %d\n", Private->NtError));\r
-    gBS->RestoreTPL (Tpl);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  if (Dcb.fDtrControl == DTR_CONTROL_ENABLE) {\r
-    Bits |= EFI_SERIAL_DATA_TERMINAL_READY;\r
-  }\r
-\r
-  if (Dcb.fRtsControl == RTS_CONTROL_ENABLE) {\r
-    Bits |= EFI_SERIAL_REQUEST_TO_SEND;\r
-  }\r
-\r
-  if (Private->HardwareFlowControl) {\r
-    Bits |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;\r
-  }\r
-\r
-  if (Private->SoftwareLoopbackEnable) {\r
-    Bits |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE;\r
-  }\r
-\r
-  if (Private->HardwareLoopbackEnable) {\r
-    Bits |= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE;\r
-  }\r
-\r
-  //\r
-  //  Get input buffer status\r
-  //\r
-  if (!Private->WinNtThunk->ClearCommError (Private->NtHandle, &Errors, &Private->NtComStatus)) {\r
-    Private->NtError = Private->WinNtThunk->GetLastError ();\r
-    DEBUG ((EFI_D_ERROR, "SerialGetControl: ClearCommError %d\n", Private->NtError));\r
-    gBS->RestoreTPL (Tpl);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  if (Private->NtComStatus.cbInQue == 0) {\r
-    Bits |= EFI_SERIAL_INPUT_BUFFER_EMPTY;\r
-  }\r
-\r
-  *Control = Bits;\r
-\r
-  gBS->RestoreTPL (Tpl);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSerialIoWrite (\r
-  IN EFI_SERIAL_IO_PROTOCOL   *This,\r
-  IN OUT UINTN                *BufferSize,\r
-  IN VOID                     *Buffer\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  This        - TODO: add argument description\r
-  BufferSize  - TODO: add argument description\r
-  Buffer      - TODO: add argument description\r
-\r
-Returns:\r
-\r
-  EFI_DEVICE_ERROR - TODO: Add description for return value\r
-  EFI_SUCCESS - TODO: Add description for return value\r
-\r
---*/\r
-{\r
-  WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;\r
-  UINT8                         *ByteBuffer;\r
-  UINTN                         TotalBytesWritten;\r
-  DWORD                         BytesToGo;\r
-  DWORD                         BytesWritten;\r
-  BOOL                          Result;\r
-  UINT32                        Index;\r
-  UINT32                        Control;\r
-  EFI_TPL                       Tpl;\r
-\r
-  Tpl               = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  Private           = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  ByteBuffer        = (UINT8 *) Buffer;\r
-  TotalBytesWritten = 0;\r
-\r
-  if (Private->SoftwareLoopbackEnable || Private->HardwareLoopbackEnable) {\r
-    for (Index = 0; Index < *BufferSize; Index++) {\r
-      if (IsaSerialFifoAdd (&Private->Fifo, ByteBuffer[Index]) == EFI_SUCCESS) {\r
-        TotalBytesWritten++;\r
-      } else {\r
-        break;\r
-      }\r
-    }\r
-  } else {\r
-    BytesToGo = (DWORD) (*BufferSize);\r
-\r
-    do {\r
-      if (Private->HardwareFlowControl) {\r
-        //\r
-        // Send RTS\r
-        //\r
-        WinNtSerialIoGetControl (&Private->SerialIo, &Control);\r
-        Control |= EFI_SERIAL_REQUEST_TO_SEND;\r
-        WinNtSerialIoSetControl (&Private->SerialIo, Control);\r
-      }\r
-\r
-      //\r
-      //  Do the write\r
-      //\r
-      Result = Private->WinNtThunk->WriteFile (\r
-                                      Private->NtHandle,\r
-                                      &ByteBuffer[TotalBytesWritten],\r
-                                      BytesToGo,\r
-                                      &BytesWritten,\r
-                                      NULL\r
-                                      );\r
-\r
-      if (Private->HardwareFlowControl) {\r
-        //\r
-        // Assert RTS\r
-        //\r
-        WinNtSerialIoGetControl (&Private->SerialIo, &Control);\r
-        Control &= ~ (UINT32) EFI_SERIAL_REQUEST_TO_SEND;\r
-        WinNtSerialIoSetControl (&Private->SerialIo, Control);\r
-      }\r
-\r
-      TotalBytesWritten += BytesWritten;\r
-      BytesToGo -= BytesWritten;\r
-      if (!Result) {\r
-        Private->NtError = Private->WinNtThunk->GetLastError ();\r
-        DEBUG ((EFI_D_ERROR, "SerialWrite: FileWrite %d\n", Private->NtError));\r
-        *BufferSize = TotalBytesWritten;\r
-        gBS->RestoreTPL (Tpl);\r
-        return EFI_DEVICE_ERROR;\r
-      }\r
-    } while (BytesToGo > 0);\r
-  }\r
-\r
-  *BufferSize = TotalBytesWritten;\r
-\r
-  gBS->RestoreTPL (Tpl);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-WinNtSerialIoRead (\r
-  IN  EFI_SERIAL_IO_PROTOCOL  *This,\r
-  IN  OUT UINTN               *BufferSize,\r
-  OUT VOID                    *Buffer\r
-  )\r
-/*++\r
-\r
-Routine Description:\r
-\r
-  TODO: Add function description\r
-\r
-Arguments:\r
-\r
-  This        - TODO: add argument description\r
-  BufferSize  - TODO: add argument description\r
-  Buffer      - TODO: add argument description\r
-\r
-Returns:\r
-\r
-  EFI_DEVICE_ERROR - TODO: Add description for return value\r
-\r
---*/\r
-{\r
-  WIN_NT_SERIAL_IO_PRIVATE_DATA *Private;\r
-  BOOL                          Result;\r
-  DWORD                         BytesRead;\r
-  EFI_STATUS                    Status;\r
-  UINT32                        Index;\r
-  UINT8                         Data;\r
-  UINT32                        Control;\r
-  EFI_TPL                       Tpl;\r
-\r
-  Tpl     = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  Private = WIN_NT_SERIAL_IO_PRIVATE_DATA_FROM_THIS (This);\r
-\r
-  //\r
-  //  Do the read\r
-  //\r
-  if (Private->SoftwareLoopbackEnable || Private->HardwareLoopbackEnable) {\r
-    for (Index = 0, BytesRead = 0; Index < *BufferSize; Index++) {\r
-      if (IsaSerialFifoRemove (&Private->Fifo, &Data) == EFI_SUCCESS) {\r
-        ((UINT8 *) Buffer)[Index] = Data;\r
-        BytesRead++;\r
-      } else {\r
-        break;\r
-      }\r
-    }\r
-  } else {\r
-    if (Private->HardwareFlowControl) {\r
-      WinNtSerialIoGetControl (&Private->SerialIo, &Control);\r
-      Control |= EFI_SERIAL_DATA_TERMINAL_READY;\r
-      WinNtSerialIoSetControl (&Private->SerialIo, Control);\r
-    }\r
-\r
-    Result = Private->WinNtThunk->ReadFile (\r
-                                    Private->NtHandle,\r
-                                    Buffer,\r
-                                    (DWORD) *BufferSize,\r
-                                    &BytesRead,\r
-                                    NULL\r
-                                    );\r
-\r
-    if (Private->HardwareFlowControl) {\r
-      WinNtSerialIoGetControl (&Private->SerialIo, &Control);\r
-      Control &= ~ (UINT32) EFI_SERIAL_DATA_TERMINAL_READY;\r
-      WinNtSerialIoSetControl (&Private->SerialIo, Control);\r
-    }\r
-\r
-    if (!Result) {\r
-      Private->NtError = Private->WinNtThunk->GetLastError ();\r
-      gBS->RestoreTPL (Tpl);\r
-      return EFI_DEVICE_ERROR;\r
-    }\r
-  }\r
-\r
-  if (BytesRead != *BufferSize) {\r
-    Status = EFI_TIMEOUT;\r
-  } else {\r
-    Status = EFI_SUCCESS;\r
-  }\r
-\r
-  *BufferSize = (UINTN) BytesRead;\r
-\r
-  gBS->RestoreTPL (Tpl);\r
-\r
-  return Status;\r
-}\r
-\r
-BOOLEAN\r
-IsaSerialFifoFull (\r
-  IN SERIAL_DEV_FIFO *Fifo\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-  Detect whether specific FIFO is full or not\r
-\r
-  Arguments:\r
-  Fifo  SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO\r
-\r
-  Returns:\r
-  TRUE:  the FIFO is full\r
-  FALSE: the FIFO is not full\r
-\r
---*/\r
-{\r
-  if (Fifo->Surplus == 0) {\r
-    return TRUE;\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-BOOLEAN\r
-IsaSerialFifoEmpty (\r
-  IN SERIAL_DEV_FIFO *Fifo\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-  Detect whether specific FIFO is empty or not\r
-\r
-  Arguments:\r
-    Fifo  SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO\r
-\r
-  Returns:\r
-    TRUE:  the FIFO is empty\r
-    FALSE: the FIFO is not empty\r
-\r
---*/\r
-{\r
-  if (Fifo->Surplus == SERIAL_MAX_BUFFER_SIZE) {\r
-    return TRUE;\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-EFI_STATUS\r
-IsaSerialFifoAdd (\r
-  IN SERIAL_DEV_FIFO *Fifo,\r
-  IN UINT8           Data\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-  Add data to specific FIFO\r
-\r
-  Arguments:\r
-    Fifo  SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO\r
-    Data  UINT8: the data added to FIFO\r
-\r
-  Returns:\r
-    EFI_SUCCESS:  Add data to specific FIFO successfully\r
-    EFI_OUT_RESOURCE: Failed to add data because FIFO is already full\r
-\r
---*/\r
-// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment\r
-{\r
-  //\r
-  // if FIFO full can not add data\r
-  //\r
-  if (IsaSerialFifoFull (Fifo)) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  //\r
-  // FIFO is not full can add data\r
-  //\r
-  Fifo->Data[Fifo->Last] = Data;\r
-  Fifo->Surplus--;\r
-  Fifo->Last++;\r
-  if (Fifo->Last >= SERIAL_MAX_BUFFER_SIZE) {\r
-    Fifo->Last = 0;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-IsaSerialFifoRemove (\r
-  IN  SERIAL_DEV_FIFO *Fifo,\r
-  OUT UINT8           *Data\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-  Remove data from specific FIFO\r
-\r
-  Arguments:\r
-    Fifo  SERIAL_DEV_FIFO *: A pointer to the Data Structure SERIAL_DEV_FIFO\r
-    Data  UINT8*: the data removed from FIFO\r
-\r
-  Returns:\r
-    EFI_SUCCESS:  Remove data from specific FIFO successfully\r
-    EFI_OUT_RESOURCE: Failed to remove data because FIFO is empty\r
-\r
---*/\r
-// TODO:    EFI_OUT_OF_RESOURCES - add return value to function comment\r
-{\r
-  //\r
-  // if FIFO is empty, no data can remove\r
-  //\r
-  if (IsaSerialFifoEmpty (Fifo)) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  //\r
-  // FIFO is not empty, can remove data\r
-  //\r
-  *Data = Fifo->Data[Fifo->First];\r
-  Fifo->Surplus++;\r
-  Fifo->First++;\r
-  if (Fifo->First >= SERIAL_MAX_BUFFER_SIZE) {\r
-    Fifo->First = 0;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r