]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.c
Remove IntelFrameworkModulePkg
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / IsaSerialDxe / Serial.c
diff --git a/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.c b/IntelFrameworkModulePkg/Bus/Isa/IsaSerialDxe/Serial.c
deleted file mode 100644 (file)
index d31e6b0..0000000
+++ /dev/null
@@ -1,2032 +0,0 @@
-/** @file\r
-  Serial driver for standard UARTS on an ISA bus.\r
-\r
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "Serial.h"\r
-\r
-//\r
-// ISA Serial Driver Global Variables\r
-//\r
-EFI_DRIVER_BINDING_PROTOCOL gSerialControllerDriver = {\r
-  SerialControllerDriverSupported,\r
-  SerialControllerDriverStart,\r
-  SerialControllerDriverStop,\r
-  0xa,\r
-  NULL,\r
-  NULL\r
-};\r
-\r
-\r
-SERIAL_DEV  gSerialDevTempate = {\r
-  SERIAL_DEV_SIGNATURE,\r
-  NULL,\r
-  { // SerialIo\r
-    SERIAL_IO_INTERFACE_REVISION,\r
-    IsaSerialReset,\r
-    IsaSerialSetAttributes,\r
-    IsaSerialSetControl,\r
-    IsaSerialGetControl,\r
-    IsaSerialWrite,\r
-    IsaSerialRead,\r
-    NULL\r
-  },\r
-  { // SerialMode\r
-    SERIAL_PORT_SUPPORT_CONTROL_MASK,\r
-    SERIAL_PORT_DEFAULT_TIMEOUT,\r
-    0,\r
-    SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH,\r
-    0,\r
-    0,\r
-    0\r
-  },\r
-  NULL,\r
-  NULL,\r
-  { // UartDevicePath\r
-    {\r
-      MESSAGING_DEVICE_PATH,\r
-      MSG_UART_DP,\r
-      {\r
-        (UINT8) (sizeof (UART_DEVICE_PATH)),\r
-        (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8)\r
-      }\r
-    },\r
-    0,\r
-    0,\r
-    0,\r
-    0,\r
-    0\r
-  },\r
-  NULL,\r
-  0,    //BaseAddress\r
-  {\r
-    0,\r
-    0,\r
-    SERIAL_MAX_BUFFER_SIZE,\r
-    { 0 }\r
-  },\r
-  {\r
-    0,\r
-    0,\r
-    SERIAL_MAX_BUFFER_SIZE,\r
-    { 0 }\r
-  },\r
-  FALSE,\r
-  FALSE,\r
-  Uart16550A,\r
-  NULL\r
-};\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 IsaSerial. 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
-InitializeIsaSerial (\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
-             &gSerialControllerDriver,\r
-             ImageHandle,\r
-             &gIsaSerialComponentName,\r
-             &gIsaSerialComponentName2\r
-             );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Initialize UART default setting in gSerialDevTempate\r
-  //\r
-  gSerialDevTempate.SerialMode.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);\r
-  gSerialDevTempate.SerialMode.DataBits = PcdGet8 (PcdUartDefaultDataBits);\r
-  gSerialDevTempate.SerialMode.Parity   = PcdGet8 (PcdUartDefaultParity);\r
-  gSerialDevTempate.SerialMode.StopBits = PcdGet8 (PcdUartDefaultStopBits);\r
-  gSerialDevTempate.UartDevicePath.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);\r
-  gSerialDevTempate.UartDevicePath.DataBits = PcdGet8 (PcdUartDefaultDataBits);\r
-  gSerialDevTempate.UartDevicePath.Parity   = PcdGet8 (PcdUartDefaultParity);\r
-  gSerialDevTempate.UartDevicePath.StopBits = PcdGet8 (PcdUartDefaultStopBits);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Check to see if this driver supports the given controller\r
-\r
-  @param  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
-  @param  Controller           The handle of the controller to test.\r
-  @param  RemainingDevicePath  A pointer to the remaining portion of a device path.\r
-\r
-  @return EFI_SUCCESS          This driver can support the given controller\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SerialControllerDriverSupported (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
-  IN EFI_HANDLE                     Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
-  )\r
-\r
-{\r
-  EFI_STATUS                                Status;\r
-  EFI_DEVICE_PATH_PROTOCOL                  *ParentDevicePath;\r
-  EFI_ISA_IO_PROTOCOL                       *IsaIo;\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                                   HasFlowControl;\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
-          sizeof (UART_DEVICE_PATH) != DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) UartNode)\r
-                                        ) {\r
-        goto Error;\r
-      }\r
-\r
-      if (UartNode->BaudRate > SERIAL_PORT_MAX_BAUD_RATE) {\r
-        goto Error;\r
-      }\r
-\r
-      if (UartNode->Parity < NoParity || UartNode->Parity > SpaceParity) {\r
-        goto Error;\r
-      }\r
-\r
-      if (UartNode->DataBits < 5 || UartNode->DataBits > 8) {\r
-        goto Error;\r
-      }\r
-\r
-      if (UartNode->StopBits < OneStopBit || UartNode->StopBits > TwoStopBits) {\r
-        goto Error;\r
-      }\r
-\r
-      if ((UartNode->DataBits == 5) && (UartNode->StopBits == TwoStopBits)) {\r
-        goto Error;\r
-      }\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 ((ReadUnaligned32 (&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
-                  Controller,\r
-                  &gEfiIsaIoProtocolGuid,\r
-                  (VOID **) &IsaIo,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\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
-                    Controller,\r
-                    &gEfiIsaIoProtocolGuid,\r
-                    &OpenInfoBuffer,\r
-                    &EntryCount\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\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
-                        Controller,\r
-                        EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                        );\r
-        if (!EFI_ERROR (Status)) {\r
-          HasFlowControl = ContainsFlowControl (RemainingDevicePath);\r
-          if (HasFlowControl ^ 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
-         Controller,\r
-         &gEfiIsaIoProtocolGuid,\r
-         This->DriverBindingHandle,\r
-         Controller\r
-         );\r
-\r
-  //\r
-  // Open the EFI Device Path protocol needed to perform the supported test\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID **) &ParentDevicePath,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\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
-  // Use the ISA I/O Protocol to see if Controller is standard ISA UART that\r
-  // can be managed by this driver.\r
-  //\r
-  Status = EFI_SUCCESS;\r
-  if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x501)) {\r
-    Status = EFI_UNSUPPORTED;\r
-    goto Error;\r
-  }\r
-\r
-Error:\r
-  //\r
-  // Close protocol, don't use device path protocol in the Support() function\r
-  //\r
-  gBS->CloseProtocol (\r
-         Controller,\r
-         &gEfiDevicePathProtocolGuid,\r
-         This->DriverBindingHandle,\r
-         Controller\r
-         );\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Start to management the controller passed in\r
-\r
-  @param  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
-  @param  Controller           The handle of the controller to test.\r
-  @param  RemainingDevicePath  A pointer to the remaining portion of a device path.\r
-\r
-  @return EFI_SUCCESS   Driver is started successfully\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SerialControllerDriverStart (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
-  IN EFI_HANDLE                     Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
-  )\r
-\r
-{\r
-  EFI_STATUS                          Status;\r
-  EFI_ISA_IO_PROTOCOL                 *IsaIo;\r
-  SERIAL_DEV                          *SerialDevice;\r
-  UINTN                               Index;\r
-  EFI_DEVICE_PATH_PROTOCOL            *ParentDevicePath;\r
-  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;\r
-  UINTN                               EntryCount;\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
-  SerialDevice = NULL;\r
-  //\r
-  // Get the Parent Device Path\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID **) &ParentDevicePath,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
-    return Status;\r
-  }\r
-  //\r
-  // Report status code enable the serial\r
-  //\r
-  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-    EFI_PROGRESS_CODE,\r
-    EFI_P_PC_ENABLE | EFI_PERIPHERAL_SERIAL_PORT,\r
-    ParentDevicePath\r
-    );\r
-\r
-  //\r
-  // Grab the IO abstraction we need to get any work done\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiIsaIoProtocolGuid,\r
-                  (VOID **) &IsaIo,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
-    goto Error;\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
-                    Controller,\r
-                    &gEfiIsaIoProtocolGuid,\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
-                        Controller,\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
-\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 (ReadUnaligned32 (&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
-  if (RemainingDevicePath != NULL) {\r
-    if (IsDevicePathEnd (RemainingDevicePath)) {\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
-  //\r
-  // Initialize the serial device instance\r
-  //\r
-  SerialDevice = AllocateCopyPool (sizeof (SERIAL_DEV), &gSerialDevTempate);\r
-  if (SerialDevice == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Error;\r
-  }\r
-\r
-  SerialDevice->SerialIo.Mode       = &(SerialDevice->SerialMode);\r
-  SerialDevice->IsaIo               = IsaIo;\r
-  SerialDevice->ParentDevicePath    = ParentDevicePath;\r
-  FlowControl                       = NULL;\r
-  FlowControlMap                    = 0;\r
-\r
-  //\r
-  // Check if RemainingDevicePath is NULL,\r
-  // if yes, use the values from the gSerialDevTempate as no remaining device path was\r
-  // passed in.\r
-  //\r
-  if (RemainingDevicePath != NULL) {\r
-    //\r
-    // If RemainingDevicePath isn't NULL,\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 (&SerialDevice->UartDevicePath, RemainingDevicePath, sizeof (UART_DEVICE_PATH));\r
-    FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) NextDevicePathNode (RemainingDevicePath);\r
-    if (IsUartFlowControlNode (FlowControl)) {\r
-      FlowControlMap = ReadUnaligned32 (&FlowControl->FlowControlMap);\r
-    } else {\r
-      FlowControl    = NULL;\r
-    }\r
-  }\r
-\r
-  AddName (SerialDevice, IsaIo);\r
-\r
-  for (Index = 0; SerialDevice->IsaIo->ResourceList->ResourceItem[Index].Type != EfiIsaAcpiResourceEndOfList; Index++) {\r
-    if (SerialDevice->IsaIo->ResourceList->ResourceItem[Index].Type == EfiIsaAcpiResourceIo) {\r
-      SerialDevice->BaseAddress = (UINT16) SerialDevice->IsaIo->ResourceList->ResourceItem[Index].StartRange;\r
-    }\r
-  }\r
-\r
-  SerialDevice->HardwareFlowControl = (BOOLEAN) (FlowControlMap == UART_FLOW_CONTROL_HARDWARE);\r
-\r
-  //\r
-  // Report status code the serial present\r
-  //\r
-  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-    EFI_PROGRESS_CODE,\r
-    EFI_P_PC_PRESENCE_DETECT | EFI_PERIPHERAL_SERIAL_PORT,\r
-    ParentDevicePath\r
-    );\r
-\r
-  if (!IsaSerialPortPresent (SerialDevice)) {\r
-    Status = EFI_DEVICE_ERROR;\r
-    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-      EFI_ERROR_CODE,\r
-      EFI_P_EC_NOT_DETECTED | EFI_PERIPHERAL_SERIAL_PORT,\r
-      ParentDevicePath\r
-      );\r
-    goto Error;\r
-  }\r
-\r
-  //\r
-  // Build the device path by appending the UART node to the ParentDevicePath.\r
-  // The Uart setings are zero here, since  SetAttribute() will update them to match\r
-  // the default setings.\r
-  //\r
-  SerialDevice->DevicePath = AppendDevicePathNode (\r
-                               ParentDevicePath,\r
-                               (EFI_DEVICE_PATH_PROTOCOL *) &SerialDevice->UartDevicePath\r
-                               );\r
-  //\r
-  // Only produce the Flow Control node when remaining device path has it\r
-  //\r
-  if (FlowControl != NULL) {\r
-    TempDevicePath = SerialDevice->DevicePath;\r
-    if (TempDevicePath != NULL) {\r
-      SerialDevice->DevicePath = AppendDevicePathNode (\r
-                                   TempDevicePath,\r
-                                   (EFI_DEVICE_PATH_PROTOCOL *) FlowControl\r
-                                   );\r
-      FreePool (TempDevicePath);\r
-    }\r
-  }\r
-  if (SerialDevice->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
-  SerialDevice->SerialMode.BaudRate         = SerialDevice->UartDevicePath.BaudRate;\r
-  SerialDevice->SerialMode.DataBits         = SerialDevice->UartDevicePath.DataBits;\r
-  SerialDevice->SerialMode.Parity           = SerialDevice->UartDevicePath.Parity;\r
-  SerialDevice->SerialMode.StopBits         = SerialDevice->UartDevicePath.StopBits;\r
-\r
-  //\r
-  // Issue a reset to initialize the COM port\r
-  //\r
-  Status = SerialDevice->SerialIo.Reset (&SerialDevice->SerialIo);\r
-  if (EFI_ERROR (Status)) {\r
-    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-      EFI_ERROR_CODE,\r
-      EFI_P_EC_CONTROLLER_ERROR | EFI_PERIPHERAL_SERIAL_PORT,\r
-      ParentDevicePath\r
-      );\r
-    goto Error;\r
-  }\r
-  //\r
-  // Install protocol interfaces for the serial device.\r
-  //\r
-  Status = gBS->InstallMultipleProtocolInterfaces (\r
-                  &SerialDevice->Handle,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  SerialDevice->DevicePath,\r
-                  &gEfiSerialIoProtocolGuid,\r
-                  &SerialDevice->SerialIo,\r
-                  NULL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Error;\r
-  }\r
-  //\r
-  // Open For Child Device\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiIsaIoProtocolGuid,\r
-                  (VOID **) &IsaIo,\r
-                  This->DriverBindingHandle,\r
-                  SerialDevice->Handle,\r
-                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
-                  );\r
-\r
-Error:\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->CloseProtocol (\r
-           Controller,\r
-           &gEfiDevicePathProtocolGuid,\r
-           This->DriverBindingHandle,\r
-           Controller\r
-           );\r
-    gBS->CloseProtocol (\r
-           Controller,\r
-           &gEfiIsaIoProtocolGuid,\r
-           This->DriverBindingHandle,\r
-           Controller\r
-           );\r
-    if (SerialDevice != NULL) {\r
-      if (SerialDevice->DevicePath != NULL) {\r
-        gBS->FreePool (SerialDevice->DevicePath);\r
-      }\r
-\r
-      FreeUnicodeStringTable (SerialDevice->ControllerNameTable);\r
-      gBS->FreePool (SerialDevice);\r
-    }\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Disconnect this driver with the controller, uninstall related protocol instance\r
-\r
-  @param  This                  A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
-  @param  Controller            The handle of the controller to test.\r
-  @param  NumberOfChildren      Number of child device.\r
-  @param  ChildHandleBuffer     A pointer to the remaining portion of a device path.\r
-\r
-  @retval EFI_SUCCESS           Operation successfully\r
-  @retval EFI_DEVICE_ERROR      Cannot stop the driver successfully\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SerialControllerDriverStop (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,\r
-  IN  EFI_HANDLE                     Controller,\r
-  IN  UINTN                          NumberOfChildren,\r
-  IN  EFI_HANDLE                     *ChildHandleBuffer\r
-  )\r
-\r
-{\r
-  EFI_STATUS                          Status;\r
-  UINTN                               Index;\r
-  BOOLEAN                             AllChildrenStopped;\r
-  EFI_SERIAL_IO_PROTOCOL              *SerialIo;\r
-  SERIAL_DEV                          *SerialDevice;\r
-  EFI_ISA_IO_PROTOCOL                 *IsaIo;\r
-  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;\r
-\r
-  Status = gBS->HandleProtocol (\r
-                  Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  (VOID **) &DevicePath\r
-                  );\r
-\r
-  //\r
-  // Report the status code disable the serial\r
-  //\r
-  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-    EFI_PROGRESS_CODE,\r
-    EFI_P_PC_DISABLE | EFI_PERIPHERAL_SERIAL_PORT,\r
-    DevicePath\r
-    );\r
-\r
-  //\r
-  // Complete all outstanding transactions to Controller.\r
-  // Don't allow any new transaction to Controller to be started.\r
-  //\r
-  if (NumberOfChildren == 0) {\r
-    //\r
-    // Close the bus driver\r
-    //\r
-    Status = gBS->CloseProtocol (\r
-                    Controller,\r
-                    &gEfiIsaIoProtocolGuid,\r
-                    This->DriverBindingHandle,\r
-                    Controller\r
-                    );\r
-\r
-    Status = gBS->CloseProtocol (\r
-                    Controller,\r
-                    &gEfiDevicePathProtocolGuid,\r
-                    This->DriverBindingHandle,\r
-                    Controller\r
-                    );\r
-    return Status;\r
-  }\r
-\r
-  AllChildrenStopped = TRUE;\r
-\r
-  for (Index = 0; Index < NumberOfChildren; Index++) {\r
-\r
-    Status = gBS->OpenProtocol (\r
-                    ChildHandleBuffer[Index],\r
-                    &gEfiSerialIoProtocolGuid,\r
-                    (VOID **) &SerialIo,\r
-                    This->DriverBindingHandle,\r
-                    Controller,\r
-                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                    );\r
-    if (!EFI_ERROR (Status)) {\r
-\r
-      SerialDevice = SERIAL_DEV_FROM_THIS (SerialIo);\r
-\r
-      Status = gBS->CloseProtocol (\r
-                      Controller,\r
-                      &gEfiIsaIoProtocolGuid,\r
-                      This->DriverBindingHandle,\r
-                      ChildHandleBuffer[Index]\r
-                      );\r
-\r
-      Status = gBS->UninstallMultipleProtocolInterfaces (\r
-                      ChildHandleBuffer[Index],\r
-                      &gEfiDevicePathProtocolGuid,\r
-                      SerialDevice->DevicePath,\r
-                      &gEfiSerialIoProtocolGuid,\r
-                      &SerialDevice->SerialIo,\r
-                      NULL\r
-                      );\r
-      if (EFI_ERROR (Status)) {\r
-        gBS->OpenProtocol (\r
-               Controller,\r
-               &gEfiIsaIoProtocolGuid,\r
-               (VOID **) &IsaIo,\r
-               This->DriverBindingHandle,\r
-               ChildHandleBuffer[Index],\r
-               EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
-               );\r
-      } else {\r
-        if (SerialDevice->DevicePath != NULL) {\r
-          gBS->FreePool (SerialDevice->DevicePath);\r
-        }\r
-\r
-        FreeUnicodeStringTable (SerialDevice->ControllerNameTable);\r
-        gBS->FreePool (SerialDevice);\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
-  Detect whether specific FIFO is full or not.\r
-\r
-  @param Fifo    A pointer to the Data Structure SERIAL_DEV_FIFO\r
-\r
-  @return whether specific FIFO is full or not\r
-\r
-**/\r
-BOOLEAN\r
-IsaSerialFifoFull (\r
-  IN SERIAL_DEV_FIFO *Fifo\r
-  )\r
-\r
-{\r
-  if (Fifo->Surplus == 0) {\r
-    return TRUE;\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  Detect whether specific FIFO is empty or not.\r
-\r
-  @param  Fifo    A pointer to the Data Structure SERIAL_DEV_FIFO\r
-\r
-  @return whether specific FIFO is empty or not\r
-\r
-**/\r
-BOOLEAN\r
-IsaSerialFifoEmpty (\r
-  IN SERIAL_DEV_FIFO *Fifo\r
-  )\r
-\r
-{\r
-  if (Fifo->Surplus == SERIAL_MAX_BUFFER_SIZE) {\r
-    return TRUE;\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  Add data to specific FIFO.\r
-\r
-  @param Fifo                  A pointer to the Data Structure SERIAL_DEV_FIFO\r
-  @param Data                  the data added to FIFO\r
-\r
-  @retval EFI_SUCCESS           Add data to specific FIFO successfully\r
-  @retval EFI_OUT_OF_RESOURCE   Failed to add data because FIFO is already full\r
-\r
-**/\r
-EFI_STATUS\r
-IsaSerialFifoAdd (\r
-  IN SERIAL_DEV_FIFO *Fifo,\r
-  IN UINT8           Data\r
-  )\r
-\r
-{\r
-  //\r
-  // if FIFO full can not add data\r
-  //\r
-  if (IsaSerialFifoFull (Fifo)) {\r
-    return EFI_OUT_OF_RESOURCES;\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
-/**\r
-  Remove data from specific FIFO.\r
-\r
-  @param Fifo                  A pointer to the Data Structure SERIAL_DEV_FIFO\r
-  @param Data                  the data removed from FIFO\r
-\r
-  @retval EFI_SUCCESS           Remove data from specific FIFO successfully\r
-  @retval EFI_OUT_OF_RESOURCE   Failed to remove data because FIFO is empty\r
-\r
-**/\r
-EFI_STATUS\r
-IsaSerialFifoRemove (\r
-  IN  SERIAL_DEV_FIFO *Fifo,\r
-  OUT UINT8           *Data\r
-  )\r
-\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
-  // 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
-\r
-/**\r
-  Reads and writes all avaliable data.\r
-\r
-  @param SerialDevice           The device to flush\r
-\r
-  @retval EFI_SUCCESS           Data was read/written successfully.\r
-  @retval EFI_OUT_OF_RESOURCE   Failed because software receive FIFO is full.  Note, when\r
-                                this happens, pending writes are not done.\r
-\r
-**/\r
-EFI_STATUS\r
-IsaSerialReceiveTransmit (\r
-  IN SERIAL_DEV *SerialDevice\r
-  )\r
-\r
-{\r
-  SERIAL_PORT_LSR Lsr;\r
-  UINT8           Data;\r
-  BOOLEAN         ReceiveFifoFull;\r
-  SERIAL_PORT_MSR Msr;\r
-  SERIAL_PORT_MCR Mcr;\r
-  UINTN           TimeOut;\r
-\r
-  Data = 0;\r
-\r
-  //\r
-  // Begin the read or write\r
-  //\r
-  if (SerialDevice->SoftwareLoopbackEnable) {\r
-    do {\r
-      ReceiveFifoFull = IsaSerialFifoFull (&SerialDevice->Receive);\r
-      if (!IsaSerialFifoEmpty (&SerialDevice->Transmit)) {\r
-        IsaSerialFifoRemove (&SerialDevice->Transmit, &Data);\r
-        if (ReceiveFifoFull) {\r
-          return EFI_OUT_OF_RESOURCES;\r
-        }\r
-\r
-        IsaSerialFifoAdd (&SerialDevice->Receive, Data);\r
-      }\r
-    } while (!IsaSerialFifoEmpty (&SerialDevice->Transmit));\r
-  } else {\r
-    ReceiveFifoFull = IsaSerialFifoFull (&SerialDevice->Receive);\r
-    //\r
-    // For full handshake flow control, tell the peer to send data\r
-    // if receive buffer is available.\r
-    //\r
-    if (SerialDevice->HardwareFlowControl &&\r
-        !FeaturePcdGet(PcdIsaBusSerialUseHalfHandshake)&&\r
-        !ReceiveFifoFull\r
-        ) {\r
-      Mcr.Data     = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-      Mcr.Bits.Rts = 1;\r
-      WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);\r
-    }\r
-    do {\r
-      Lsr.Data = READ_LSR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-\r
-      //\r
-      // Flush incomming data to prevent a an overrun during a long write\r
-      //\r
-      if ((Lsr.Bits.Dr == 1) && !ReceiveFifoFull) {\r
-        ReceiveFifoFull = IsaSerialFifoFull (&SerialDevice->Receive);\r
-        if (!ReceiveFifoFull) {\r
-          if (Lsr.Bits.FIFOe == 1 || Lsr.Bits.Oe == 1 || Lsr.Bits.Pe == 1 || Lsr.Bits.Fe == 1 || Lsr.Bits.Bi == 1) {\r
-            REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-              EFI_ERROR_CODE,\r
-              EFI_P_EC_INPUT_ERROR | EFI_PERIPHERAL_SERIAL_PORT,\r
-              SerialDevice->DevicePath\r
-              );\r
-            if (Lsr.Bits.FIFOe == 1 || Lsr.Bits.Pe == 1|| Lsr.Bits.Fe == 1 || Lsr.Bits.Bi == 1) {\r
-              Data = READ_RBR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-              continue;\r
-            }\r
-          }\r
-\r
-          Data = READ_RBR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-\r
-          IsaSerialFifoAdd (&SerialDevice->Receive, Data);\r
-\r
-          //\r
-          // For full handshake flow control, if receive buffer full\r
-          // tell the peer to stop sending data.\r
-          //\r
-          if (SerialDevice->HardwareFlowControl &&\r
-              !FeaturePcdGet(PcdIsaBusSerialUseHalfHandshake)   &&\r
-              IsaSerialFifoFull (&SerialDevice->Receive)\r
-              ) {\r
-            Mcr.Data     = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-            Mcr.Bits.Rts = 0;\r
-            WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);\r
-          }\r
-\r
-\r
-          continue;\r
-        } else {\r
-          REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-            EFI_PROGRESS_CODE,\r
-            EFI_P_SERIAL_PORT_PC_CLEAR_BUFFER | EFI_PERIPHERAL_SERIAL_PORT,\r
-            SerialDevice->DevicePath\r
-            );\r
-        }\r
-      }\r
-      //\r
-      // Do the write\r
-      //\r
-      if (Lsr.Bits.Thre == 1 && !IsaSerialFifoEmpty (&SerialDevice->Transmit)) {\r
-        //\r
-        // Make sure the transmit data will not be missed\r
-        //\r
-        if (SerialDevice->HardwareFlowControl) {\r
-          //\r
-          // For half handshake flow control assert RTS before sending.\r
-          //\r
-          if (FeaturePcdGet(PcdIsaBusSerialUseHalfHandshake)) {\r
-            Mcr.Data     = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-            Mcr.Bits.Rts= 0;\r
-            WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);\r
-          }\r
-          //\r
-          // Wait for CTS\r
-          //\r
-          TimeOut   = 0;\r
-          Msr.Data  = READ_MSR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-          while ((Msr.Bits.Dcd == 1) && ((Msr.Bits.Cts == 0) ^ FeaturePcdGet(PcdIsaBusSerialUseHalfHandshake))) {\r
-            gBS->Stall (TIMEOUT_STALL_INTERVAL);\r
-            TimeOut++;\r
-            if (TimeOut > 5) {\r
-              break;\r
-            }\r
-\r
-            Msr.Data = READ_MSR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-          }\r
-\r
-          if ((Msr.Bits.Dcd == 0) || ((Msr.Bits.Cts == 1) ^ FeaturePcdGet(PcdIsaBusSerialUseHalfHandshake))) {\r
-            IsaSerialFifoRemove (&SerialDevice->Transmit, &Data);\r
-            WRITE_THR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Data);\r
-          }\r
-\r
-          //\r
-          // For half handshake flow control, tell DCE we are done.\r
-          //\r
-          if (FeaturePcdGet(PcdIsaBusSerialUseHalfHandshake)) {\r
-            Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-            Mcr.Bits.Rts = 1;\r
-            WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);\r
-          }\r
-        } else {\r
-          IsaSerialFifoRemove (&SerialDevice->Transmit, &Data);\r
-          WRITE_THR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Data);\r
-        }\r
-      }\r
-    } while (Lsr.Bits.Thre == 1 && !IsaSerialFifoEmpty (&SerialDevice->Transmit));\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// Interface Functions\r
-//\r
-/**\r
-  Reset serial device.\r
-\r
-  @param This               Pointer to EFI_SERIAL_IO_PROTOCOL\r
-\r
-  @retval EFI_SUCCESS        Reset successfully\r
-  @retval EFI_DEVICE_ERROR   Failed to reset\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IsaSerialReset (\r
-  IN EFI_SERIAL_IO_PROTOCOL  *This\r
-  )\r
-{\r
-  EFI_STATUS      Status;\r
-  SERIAL_DEV      *SerialDevice;\r
-  SERIAL_PORT_LCR Lcr;\r
-  SERIAL_PORT_IER Ier;\r
-  SERIAL_PORT_MCR Mcr;\r
-  SERIAL_PORT_FCR Fcr;\r
-  EFI_TPL         Tpl;\r
-  UINT32          Control;\r
-\r
-  SerialDevice = SERIAL_DEV_FROM_THIS (This);\r
-\r
-  //\r
-  // Report the status code reset the serial\r
-  //\r
-  REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-    EFI_PROGRESS_CODE,\r
-    EFI_P_PC_RESET | EFI_PERIPHERAL_SERIAL_PORT,\r
-    SerialDevice->DevicePath\r
-    );\r
-\r
-  Tpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  //\r
-  // Make sure DLAB is 0.\r
-  //\r
-  Lcr.Data      = READ_LCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-  Lcr.Bits.DLab = 0;\r
-  WRITE_LCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Lcr.Data);\r
-\r
-  //\r
-  // Turn off all interrupts\r
-  //\r
-  Ier.Data        = READ_IER (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-  Ier.Bits.Ravie  = 0;\r
-  Ier.Bits.Theie  = 0;\r
-  Ier.Bits.Rie    = 0;\r
-  Ier.Bits.Mie    = 0;\r
-  WRITE_IER (SerialDevice->IsaIo, SerialDevice->BaseAddress, Ier.Data);\r
-\r
-  //\r
-  // Disable the FIFO.\r
-  //\r
-  Fcr.Bits.TrFIFOE = 0;\r
-  WRITE_FCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Fcr.Data);\r
-\r
-  //\r
-  // Turn off loopback and disable device interrupt.\r
-  //\r
-  Mcr.Data      = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-  Mcr.Bits.Out1 = 0;\r
-  Mcr.Bits.Out2 = 0;\r
-  Mcr.Bits.Lme  = 0;\r
-  WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);\r
-\r
-  //\r
-  // Clear the scratch pad register\r
-  //\r
-  WRITE_SCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, 0);\r
-\r
-  //\r
-  // Go set the current attributes\r
-  //\r
-  Status = 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
-  if (EFI_ERROR (Status)) {\r
-    gBS->RestoreTPL (Tpl);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-  //\r
-  // Go set the current control bits\r
-  //\r
-  Control = 0;\r
-  if (SerialDevice->HardwareFlowControl) {\r
-    Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;\r
-  }\r
-  if (SerialDevice->SoftwareLoopbackEnable) {\r
-    Control |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE;\r
-  }\r
-  Status = This->SetControl (\r
-                   This,\r
-                   Control\r
-                   );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->RestoreTPL (Tpl);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-  //\r
-  // for 16550A enable FIFO, 16550 disable FIFO\r
-  //\r
-  Fcr.Bits.TrFIFOE  = 1;\r
-  Fcr.Bits.ResetRF  = 1;\r
-  Fcr.Bits.ResetTF  = 1;\r
-  WRITE_FCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Fcr.Data);\r
-\r
-  //\r
-  // Reset the software FIFO\r
-  //\r
-  SerialDevice->Receive.First     = 0;\r
-  SerialDevice->Receive.Last      = 0;\r
-  SerialDevice->Receive.Surplus   = SERIAL_MAX_BUFFER_SIZE;\r
-  SerialDevice->Transmit.First    = 0;\r
-  SerialDevice->Transmit.Last     = 0;\r
-  SerialDevice->Transmit.Surplus  = SERIAL_MAX_BUFFER_SIZE;\r
-\r
-  gBS->RestoreTPL (Tpl);\r
-\r
-  //\r
-  // Device reset is complete\r
-  //\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Set new attributes to a serial device.\r
-\r
-  @param This                     Pointer to EFI_SERIAL_IO_PROTOCOL\r
-  @param  BaudRate                 The baudrate of the serial device\r
-  @param  ReceiveFifoDepth         The depth of receive FIFO buffer\r
-  @param  Timeout                  The request timeout for a single char\r
-  @param  Parity                   The type of parity used in serial device\r
-  @param  DataBits                 Number of databits used in serial device\r
-  @param  StopBits                 Number of stopbits used in serial device\r
-\r
-  @retval  EFI_SUCCESS              The new attributes were set\r
-  @retval  EFI_INVALID_PARAMETERS   One or more attributes have an unsupported value\r
-  @retval  EFI_UNSUPPORTED          Data Bits can not set to 5 or 6\r
-  @retval  EFI_DEVICE_ERROR         The serial device is not functioning correctly (no return)\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IsaSerialSetAttributes (\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
-  EFI_STATUS                Status;\r
-  SERIAL_DEV                *SerialDevice;\r
-  UINT32                    Divisor;\r
-  UINT32                    Remained;\r
-  SERIAL_PORT_LCR           Lcr;\r
-  UART_DEVICE_PATH          *Uart;\r
-  EFI_TPL                   Tpl;\r
-\r
-  SerialDevice = SERIAL_DEV_FROM_THIS (This);\r
-\r
-  //\r
-  // Check for default settings and fill in actual values.\r
-  //\r
-  if (BaudRate == 0) {\r
-    BaudRate = PcdGet64 (PcdUartDefaultBaudRate);\r
-  }\r
-\r
-  if (ReceiveFifoDepth == 0) {\r
-    ReceiveFifoDepth = SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH;\r
-  }\r
-\r
-  if (Timeout == 0) {\r
-    Timeout = SERIAL_PORT_DEFAULT_TIMEOUT;\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
-  // 5 and 6 data bits can not be verified on a 16550A UART\r
-  // Return EFI_INVALID_PARAMETER if an attempt is made to use these settings.\r
-  //\r
-  if ((DataBits == 5) || (DataBits == 6)) {\r
-    return EFI_INVALID_PARAMETER;\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
-  // 50,75,110,134,150,300,600,1200,1800,2000,2400,3600,4800,7200,9600,19200,\r
-  // 38400,57600,115200\r
-  //\r
-  if (BaudRate < 75) {\r
-    BaudRate = 50;\r
-  } else if (BaudRate < 110) {\r
-    BaudRate = 75;\r
-  } else if (BaudRate < 134) {\r
-    BaudRate = 110;\r
-  } else if (BaudRate < 150) {\r
-    BaudRate = 134;\r
-  } else if (BaudRate < 300) {\r
-    BaudRate = 150;\r
-  } else if (BaudRate < 600) {\r
-    BaudRate = 300;\r
-  } else if (BaudRate < 1200) {\r
-    BaudRate = 600;\r
-  } else if (BaudRate < 1800) {\r
-    BaudRate = 1200;\r
-  } else if (BaudRate < 2000) {\r
-    BaudRate = 1800;\r
-  } else if (BaudRate < 2400) {\r
-    BaudRate = 2000;\r
-  } else if (BaudRate < 3600) {\r
-    BaudRate = 2400;\r
-  } else if (BaudRate < 4800) {\r
-    BaudRate = 3600;\r
-  } else if (BaudRate < 7200) {\r
-    BaudRate = 4800;\r
-  } else if (BaudRate < 9600) {\r
-    BaudRate = 7200;\r
-  } else if (BaudRate < 19200) {\r
-    BaudRate = 9600;\r
-  } else if (BaudRate < 38400) {\r
-    BaudRate = 19200;\r
-  } else if (BaudRate < 57600) {\r
-    BaudRate = 38400;\r
-  } else if (BaudRate < 115200) {\r
-    BaudRate = 57600;\r
-  } else if (BaudRate <= SERIAL_PORT_MAX_BAUD_RATE) {\r
-    BaudRate = 115200;\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 ((DataBits < 5) || (DataBits > 8)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if ((StopBits < OneStopBit) || (StopBits > TwoStopBits)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // for DataBits = 6,7,8, StopBits can not set OneFiveStopBits\r
-  //\r
-  if ((DataBits >= 6) && (DataBits <= 8) && (StopBits == OneFiveStopBits)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Compute divisor use to program the baud rate using a round determination\r
-  //\r
-  Divisor = (UINT32) DivU64x32Remainder (\r
-                       PcdGet32 (PcdSerialClockRate),\r
-                       ((UINT32) BaudRate * 16),\r
-                       &Remained\r
-                       );\r
-  if (Remained >= ((UINT32) BaudRate * 8)) {\r
-    Divisor += 1;\r
-  }\r
-\r
-  if ((Divisor == 0) || ((Divisor & 0xffff0000) != 0)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Tpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  //\r
-  // Compute the actual baud rate that the serial port will be programmed for.\r
-  //\r
-  BaudRate = PcdGet32 (PcdSerialClockRate) / Divisor / 16;\r
-\r
-  //\r
-  // Put serial port on Divisor Latch Mode\r
-  //\r
-  Lcr.Data      = READ_LCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-  Lcr.Bits.DLab = 1;\r
-  WRITE_LCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Lcr.Data);\r
-\r
-  //\r
-  // Write the divisor to the serial port\r
-  //\r
-  WRITE_DLL (SerialDevice->IsaIo, SerialDevice->BaseAddress, (UINT8) (Divisor & 0xff));\r
-  WRITE_DLM (SerialDevice->IsaIo, SerialDevice->BaseAddress, (UINT8) ((Divisor >> 8) & 0xff));\r
-\r
-  //\r
-  // Put serial port back in normal mode and set remaining attributes.\r
-  //\r
-  Lcr.Bits.DLab = 0;\r
-\r
-  switch (Parity) {\r
-  case NoParity:\r
-    Lcr.Bits.ParEn    = 0;\r
-    Lcr.Bits.EvenPar  = 0;\r
-    Lcr.Bits.SticPar  = 0;\r
-    break;\r
-\r
-  case EvenParity:\r
-    Lcr.Bits.ParEn    = 1;\r
-    Lcr.Bits.EvenPar  = 1;\r
-    Lcr.Bits.SticPar  = 0;\r
-    break;\r
-\r
-  case OddParity:\r
-    Lcr.Bits.ParEn    = 1;\r
-    Lcr.Bits.EvenPar  = 0;\r
-    Lcr.Bits.SticPar  = 0;\r
-    break;\r
-\r
-  case SpaceParity:\r
-    Lcr.Bits.ParEn    = 1;\r
-    Lcr.Bits.EvenPar  = 1;\r
-    Lcr.Bits.SticPar  = 1;\r
-    break;\r
-\r
-  case MarkParity:\r
-    Lcr.Bits.ParEn    = 1;\r
-    Lcr.Bits.EvenPar  = 0;\r
-    Lcr.Bits.SticPar  = 1;\r
-    break;\r
-\r
-  default:\r
-    break;\r
-  }\r
-\r
-  switch (StopBits) {\r
-  case OneStopBit:\r
-    Lcr.Bits.StopB = 0;\r
-    break;\r
-\r
-  case OneFiveStopBits:\r
-  case TwoStopBits:\r
-    Lcr.Bits.StopB = 1;\r
-    break;\r
-\r
-  default:\r
-    break;\r
-  }\r
-  //\r
-  // DataBits\r
-  //\r
-  Lcr.Bits.SerialDB = (UINT8) ((DataBits - 5) & 0x03);\r
-  WRITE_LCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Lcr.Data);\r
-\r
-  //\r
-  // Set the Serial I/O mode\r
-  //\r
-  This->Mode->BaudRate          = BaudRate;\r
-  This->Mode->ReceiveFifoDepth  = ReceiveFifoDepth;\r
-  This->Mode->Timeout           = Timeout;\r
-  This->Mode->Parity            = Parity;\r
-  This->Mode->DataBits          = DataBits;\r
-  This->Mode->StopBits          = StopBits;\r
-\r
-  //\r
-  // See if Device Path Node has actually changed\r
-  //\r
-  if (SerialDevice->UartDevicePath.BaudRate == BaudRate &&\r
-      SerialDevice->UartDevicePath.DataBits == DataBits &&\r
-      SerialDevice->UartDevicePath.Parity == Parity &&\r
-      SerialDevice->UartDevicePath.StopBits == StopBits\r
-      ) {\r
-    gBS->RestoreTPL (Tpl);\r
-    return EFI_SUCCESS;\r
-  }\r
-  //\r
-  // Update the device path\r
-  //\r
-  SerialDevice->UartDevicePath.BaudRate = BaudRate;\r
-  SerialDevice->UartDevicePath.DataBits = DataBits;\r
-  SerialDevice->UartDevicePath.Parity   = (UINT8) Parity;\r
-  SerialDevice->UartDevicePath.StopBits = (UINT8) StopBits;\r
-\r
-  Status = EFI_SUCCESS;\r
-  if (SerialDevice->Handle != NULL) {\r
-    Uart = (UART_DEVICE_PATH *) (\r
-             (UINTN) SerialDevice->DevicePath\r
-             + GetDevicePathSize (SerialDevice->ParentDevicePath)\r
-             - END_DEVICE_PATH_LENGTH\r
-             );\r
-    CopyMem (Uart, &SerialDevice->UartDevicePath, sizeof (UART_DEVICE_PATH));\r
-    Status = gBS->ReinstallProtocolInterface (\r
-                    SerialDevice->Handle,\r
-                    &gEfiDevicePathProtocolGuid,\r
-                    SerialDevice->DevicePath,\r
-                    SerialDevice->DevicePath\r
-                    );\r
-  }\r
-\r
-  gBS->RestoreTPL (Tpl);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Set Control Bits.\r
-\r
-  @param This              Pointer to EFI_SERIAL_IO_PROTOCOL\r
-  @param Control           Control bits that can be settable\r
-\r
-  @retval EFI_SUCCESS       New Control bits were set successfully\r
-  @retval EFI_UNSUPPORTED   The Control bits wanted to set are not supported\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IsaSerialSetControl (\r
-  IN EFI_SERIAL_IO_PROTOCOL  *This,\r
-  IN UINT32                  Control\r
-  )\r
-{\r
-  SERIAL_DEV                    *SerialDevice;\r
-  SERIAL_PORT_MCR               Mcr;\r
-  EFI_TPL                       Tpl;\r
-  UART_FLOW_CONTROL_DEVICE_PATH *FlowControl;\r
-  EFI_STATUS                    Status;\r
-\r
-  //\r
-  // The control bits that can be set are :\r
-  //     EFI_SERIAL_DATA_TERMINAL_READY: 0x0001  // WO\r
-  //     EFI_SERIAL_REQUEST_TO_SEND: 0x0002  // WO\r
-  //     EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE: 0x1000  // RW\r
-  //     EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE: 0x2000  // RW\r
-  //     EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE: 0x4000 // RW\r
-  //\r
-  SerialDevice = SERIAL_DEV_FROM_THIS (This);\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))) != 0) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  Tpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-  Mcr.Bits.DtrC = 0;\r
-  Mcr.Bits.Rts = 0;\r
-  Mcr.Bits.Lme = 0;\r
-  SerialDevice->SoftwareLoopbackEnable = FALSE;\r
-  SerialDevice->HardwareFlowControl = FALSE;\r
-\r
-  if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) == EFI_SERIAL_DATA_TERMINAL_READY) {\r
-    Mcr.Bits.DtrC = 1;\r
-  }\r
-\r
-  if ((Control & EFI_SERIAL_REQUEST_TO_SEND) == EFI_SERIAL_REQUEST_TO_SEND) {\r
-    Mcr.Bits.Rts = 1;\r
-  }\r
-\r
-  if ((Control & EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE) == EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE) {\r
-    Mcr.Bits.Lme = 1;\r
-  }\r
-\r
-  if ((Control & EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) == EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE) {\r
-    SerialDevice->HardwareFlowControl = TRUE;\r
-  }\r
-\r
-  WRITE_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Mcr.Data);\r
-\r
-  if ((Control & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) == EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) {\r
-    SerialDevice->SoftwareLoopbackEnable = TRUE;\r
-  }\r
-\r
-  Status = EFI_SUCCESS;\r
-  if (SerialDevice->Handle != NULL) {\r
-    FlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) (\r
-                    (UINTN) SerialDevice->DevicePath\r
-                    + GetDevicePathSize (SerialDevice->ParentDevicePath)\r
-                    - END_DEVICE_PATH_LENGTH\r
-                    + sizeof (UART_DEVICE_PATH)\r
-                    );\r
-    if (IsUartFlowControlNode (FlowControl) &&\r
-        ((ReadUnaligned32 (&FlowControl->FlowControlMap) == UART_FLOW_CONTROL_HARDWARE) ^ SerialDevice->HardwareFlowControl)) {\r
-      //\r
-      // Flow Control setting is changed, need to reinstall device path protocol\r
-      //\r
-      WriteUnaligned32 (&FlowControl->FlowControlMap, SerialDevice->HardwareFlowControl ? UART_FLOW_CONTROL_HARDWARE : 0);\r
-      Status = gBS->ReinstallProtocolInterface (\r
-                      SerialDevice->Handle,\r
-                      &gEfiDevicePathProtocolGuid,\r
-                      SerialDevice->DevicePath,\r
-                      SerialDevice->DevicePath\r
-                      );\r
-    }\r
-  }\r
-\r
-  gBS->RestoreTPL (Tpl);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Get ControlBits.\r
-\r
-  @param This          Pointer to EFI_SERIAL_IO_PROTOCOL\r
-  @param Control       Control signals of the serial device\r
-\r
-  @retval EFI_SUCCESS   Get Control signals successfully\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IsaSerialGetControl (\r
-  IN EFI_SERIAL_IO_PROTOCOL  *This,\r
-  OUT UINT32                 *Control\r
-  )\r
-{\r
-  SERIAL_DEV      *SerialDevice;\r
-  SERIAL_PORT_MSR Msr;\r
-  SERIAL_PORT_MCR Mcr;\r
-  EFI_TPL         Tpl;\r
-\r
-  Tpl           = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  SerialDevice  = SERIAL_DEV_FROM_THIS (This);\r
-\r
-  *Control      = 0;\r
-\r
-  //\r
-  // Read the Modem Status Register\r
-  //\r
-  Msr.Data = READ_MSR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-\r
-  if (Msr.Bits.Cts == 1) {\r
-    *Control |= EFI_SERIAL_CLEAR_TO_SEND;\r
-  }\r
-\r
-  if (Msr.Bits.Dsr == 1) {\r
-    *Control |= EFI_SERIAL_DATA_SET_READY;\r
-  }\r
-\r
-  if (Msr.Bits.Ri == 1) {\r
-    *Control |= EFI_SERIAL_RING_INDICATE;\r
-  }\r
-\r
-  if (Msr.Bits.Dcd == 1) {\r
-    *Control |= EFI_SERIAL_CARRIER_DETECT;\r
-  }\r
-  //\r
-  // Read the Modem Control Register\r
-  //\r
-  Mcr.Data = READ_MCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-\r
-  if (Mcr.Bits.DtrC == 1) {\r
-    *Control |= EFI_SERIAL_DATA_TERMINAL_READY;\r
-  }\r
-\r
-  if (Mcr.Bits.Rts == 1) {\r
-    *Control |= EFI_SERIAL_REQUEST_TO_SEND;\r
-  }\r
-\r
-  if (Mcr.Bits.Lme == 1) {\r
-    *Control |= EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE;\r
-  }\r
-\r
-  if (SerialDevice->HardwareFlowControl) {\r
-    *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;\r
-  }\r
-  //\r
-  // See if the Transmit FIFO is empty\r
-  //\r
-  IsaSerialReceiveTransmit (SerialDevice);\r
-\r
-  if (IsaSerialFifoEmpty (&SerialDevice->Transmit)) {\r
-    *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY;\r
-  }\r
-  //\r
-  // See if the Receive FIFO is empty.\r
-  //\r
-  IsaSerialReceiveTransmit (SerialDevice);\r
-\r
-  if (IsaSerialFifoEmpty (&SerialDevice->Receive)) {\r
-    *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY;\r
-  }\r
-\r
-  if (SerialDevice->SoftwareLoopbackEnable) {\r
-    *Control |= EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE;\r
-  }\r
-\r
-  gBS->RestoreTPL (Tpl);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Write the specified number of bytes to serial device.\r
-\r
-  @param This               Pointer to EFI_SERIAL_IO_PROTOCOL\r
-  @param  BufferSize         On input the size of Buffer, on output the amount of\r
-                       data actually written\r
-  @param  Buffer             The buffer of data to write\r
-\r
-  @retval EFI_SUCCESS        The data were written successfully\r
-  @retval EFI_DEVICE_ERROR   The device reported an error\r
-  @retval EFI_TIMEOUT        The write operation was stopped due to timeout\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IsaSerialWrite (\r
-  IN EFI_SERIAL_IO_PROTOCOL  *This,\r
-  IN OUT UINTN               *BufferSize,\r
-  IN VOID                    *Buffer\r
-  )\r
-{\r
-  SERIAL_DEV  *SerialDevice;\r
-  UINT8       *CharBuffer;\r
-  UINT32      Index;\r
-  UINTN       Elapsed;\r
-  UINTN       ActualWrite;\r
-  EFI_TPL     Tpl;\r
-  UINTN       Timeout;\r
-  UINTN       BitsPerCharacter;\r
-\r
-  SerialDevice  = SERIAL_DEV_FROM_THIS (This);\r
-  Elapsed       = 0;\r
-  ActualWrite   = 0;\r
-\r
-  if (*BufferSize == 0) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (Buffer == NULL) {\r
-    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-      EFI_ERROR_CODE,\r
-      EFI_P_EC_OUTPUT_ERROR | EFI_PERIPHERAL_SERIAL_PORT,\r
-      SerialDevice->DevicePath\r
-      );\r
-\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  Tpl         = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  CharBuffer  = (UINT8 *) Buffer;\r
-\r
-  //\r
-  // Compute the number of bits in a single character.  This is a start bit,\r
-  // followed by the number of data bits, followed by the number of stop bits.\r
-  // The number of stop bits is specified by an enumeration that includes\r
-  // support for 1.5 stop bits.  Treat 1.5 stop bits as 2 stop bits.\r
-  //\r
-  BitsPerCharacter =\r
-    1 +\r
-    This->Mode->DataBits +\r
-    ((This->Mode->StopBits == TwoStopBits) ? 2 : This->Mode->StopBits);\r
-\r
-  //\r
-  // Compute the timeout in microseconds to wait for a single byte to be\r
-  // transmitted.  The Mode structure contans a Timeout field that is the\r
-  // maximum time to transmit or receive a character.  However, many UARTs\r
-  // have a FIFO for transmits, so the time required to add one new character\r
-  // to the transmit FIFO may be the time required to flush a full FIFO.  If\r
-  // the Timeout in the Mode structure is smaller than the time required to\r
-  // flush a full FIFO at the current baud rate, then use a timeout value that\r
-  // is required to flush a full transmit FIFO.\r
-  //\r
-  Timeout = MAX (\r
-              This->Mode->Timeout,\r
-              (UINTN)DivU64x64Remainder (\r
-                BitsPerCharacter * (SERIAL_PORT_MAX_RECEIVE_FIFO_DEPTH + 1) * 1000000,\r
-                This->Mode->BaudRate,\r
-                NULL\r
-                )\r
-              );\r
-\r
-  for (Index = 0; Index < *BufferSize; Index++) {\r
-    IsaSerialFifoAdd (&SerialDevice->Transmit, CharBuffer[Index]);\r
-\r
-    while (IsaSerialReceiveTransmit (SerialDevice) != EFI_SUCCESS || !IsaSerialFifoEmpty (&SerialDevice->Transmit)) {\r
-      //\r
-      //  Unsuccessful write so check if timeout has expired, if not,\r
-      //  stall for a bit, increment time elapsed, and try again\r
-      //\r
-      if (Elapsed >= Timeout) {\r
-        *BufferSize = ActualWrite;\r
-        gBS->RestoreTPL (Tpl);\r
-        return EFI_TIMEOUT;\r
-      }\r
-\r
-      gBS->Stall (TIMEOUT_STALL_INTERVAL);\r
-\r
-      Elapsed += TIMEOUT_STALL_INTERVAL;\r
-    }\r
-\r
-    ActualWrite++;\r
-    //\r
-    //  Successful write so reset timeout\r
-    //\r
-    Elapsed = 0;\r
-  }\r
-\r
-  gBS->RestoreTPL (Tpl);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Read the specified number of bytes from serial device.\r
-\r
-  @param This               Pointer to EFI_SERIAL_IO_PROTOCOL\r
-  @param BufferSize         On input the size of Buffer, on output the amount of\r
-                            data returned in buffer\r
-  @param Buffer             The buffer to return the data into\r
-\r
-  @retval EFI_SUCCESS        The data were read successfully\r
-  @retval EFI_DEVICE_ERROR   The device reported an error\r
-  @retval EFI_TIMEOUT        The read operation was stopped due to timeout\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IsaSerialRead (\r
-  IN EFI_SERIAL_IO_PROTOCOL  *This,\r
-  IN OUT UINTN               *BufferSize,\r
-  OUT VOID                   *Buffer\r
-  )\r
-{\r
-  SERIAL_DEV  *SerialDevice;\r
-  UINT32      Index;\r
-  UINT8       *CharBuffer;\r
-  UINTN       Elapsed;\r
-  EFI_STATUS  Status;\r
-  EFI_TPL     Tpl;\r
-\r
-  SerialDevice  = SERIAL_DEV_FROM_THIS (This);\r
-  Elapsed       = 0;\r
-\r
-  if (*BufferSize == 0) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (Buffer == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  Tpl     = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  Status  = IsaSerialReceiveTransmit (SerialDevice);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    *BufferSize = 0;\r
-\r
-    REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
-      EFI_ERROR_CODE,\r
-      EFI_P_EC_INPUT_ERROR | EFI_PERIPHERAL_SERIAL_PORT,\r
-      SerialDevice->DevicePath\r
-      );\r
-\r
-    gBS->RestoreTPL (Tpl);\r
-\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  CharBuffer = (UINT8 *) Buffer;\r
-  for (Index = 0; Index < *BufferSize; Index++) {\r
-    while (IsaSerialFifoRemove (&SerialDevice->Receive, &(CharBuffer[Index])) != EFI_SUCCESS) {\r
-      //\r
-      //  Unsuccessful read so check if timeout has expired, if not,\r
-      //  stall for a bit, increment time elapsed, and try again\r
-      //  Need this time out to get conspliter to work.\r
-      //\r
-      if (Elapsed >= This->Mode->Timeout) {\r
-        *BufferSize = Index;\r
-        gBS->RestoreTPL (Tpl);\r
-        return EFI_TIMEOUT;\r
-      }\r
-\r
-      gBS->Stall (TIMEOUT_STALL_INTERVAL);\r
-      Elapsed += TIMEOUT_STALL_INTERVAL;\r
-\r
-      Status = IsaSerialReceiveTransmit (SerialDevice);\r
-      if (Status == EFI_DEVICE_ERROR) {\r
-        *BufferSize = Index;\r
-        gBS->RestoreTPL (Tpl);\r
-        return EFI_DEVICE_ERROR;\r
-      }\r
-    }\r
-    //\r
-    //  Successful read so reset timeout\r
-    //\r
-    Elapsed = 0;\r
-  }\r
-\r
-  IsaSerialReceiveTransmit (SerialDevice);\r
-\r
-  gBS->RestoreTPL (Tpl);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Use scratchpad register to test if this serial port is present.\r
-\r
-  @param SerialDevice   Pointer to serial device structure\r
-\r
-  @return if this serial port is present\r
-**/\r
-BOOLEAN\r
-IsaSerialPortPresent (\r
-  IN SERIAL_DEV *SerialDevice\r
-  )\r
-\r
-{\r
-  UINT8   Temp;\r
-  BOOLEAN Status;\r
-\r
-  Status = TRUE;\r
-\r
-  //\r
-  // Save SCR reg\r
-  //\r
-  Temp = READ_SCR (SerialDevice->IsaIo, SerialDevice->BaseAddress);\r
-  WRITE_SCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, 0xAA);\r
-\r
-  if (READ_SCR (SerialDevice->IsaIo, SerialDevice->BaseAddress) != 0xAA) {\r
-    Status = FALSE;\r
-  }\r
-\r
-  WRITE_SCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, 0x55);\r
-\r
-  if (READ_SCR (SerialDevice->IsaIo, SerialDevice->BaseAddress) != 0x55) {\r
-    Status = FALSE;\r
-  }\r
-  //\r
-  // Restore SCR\r
-  //\r
-  WRITE_SCR (SerialDevice->IsaIo, SerialDevice->BaseAddress, Temp);\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Use IsaIo protocol to read serial port.\r
-\r
-  @param IsaIo         Pointer to EFI_ISA_IO_PROTOCOL instance\r
-  @param BaseAddress   Serial port register group base address\r
-  @param Offset        Offset in register group\r
-\r
-  @return Data read from serial port\r
-\r
-**/\r
-UINT8\r
-IsaSerialReadPort (\r
-  IN EFI_ISA_IO_PROTOCOL                   *IsaIo,\r
-  IN UINT16                                BaseAddress,\r
-  IN UINT32                                Offset\r
-  )\r
-{\r
-  UINT8 Data;\r
-\r
-  //\r
-  // Use IsaIo to access IO\r
-  //\r
-  IsaIo->Io.Read (\r
-             IsaIo,\r
-             EfiIsaIoWidthUint8,\r
-             BaseAddress + Offset,\r
-             1,\r
-             &Data\r
-             );\r
-  return Data;\r
-}\r
-\r
-/**\r
-  Use IsaIo protocol to write serial port.\r
-\r
-  @param  IsaIo         Pointer to EFI_ISA_IO_PROTOCOL instance\r
-  @param  BaseAddress   Serial port register group base address\r
-  @param  Offset        Offset in register group\r
-  @param  Data          data which is to be written to some serial port register\r
-\r
-**/\r
-VOID\r
-IsaSerialWritePort (\r
-  IN EFI_ISA_IO_PROTOCOL                 *IsaIo,\r
-  IN UINT16                              BaseAddress,\r
-  IN UINT32                              Offset,\r
-  IN UINT8                               Data\r
-  )\r
-{\r
-  //\r
-  // Use IsaIo to access IO\r
-  //\r
-  IsaIo->Io.Write (\r
-             IsaIo,\r
-             EfiIsaIoWidthUint8,\r
-             BaseAddress + Offset,\r
-             1,\r
-             &Data\r
-             );\r
-}\r
-\r