/** @file
  Top level C file for debugport driver.  Contains initialization function.
  This driver layers on top of SerialIo.
  ALL CODE IN THE SERIALIO STACK MUST BE RE-ENTRANT AND CALLABLE FROM
  INTERRUPT CONTEXT

Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "DebugPort.h"

//
// Globals
//
EFI_DRIVER_BINDING_PROTOCOL  gDebugPortDriverBinding = {
  DebugPortSupported,
  DebugPortStart,
  DebugPortStop,
  DEBUGPORT_DRIVER_VERSION,
  NULL,
  NULL
};

DEBUGPORT_DEVICE  mDebugPortDevice = {
  DEBUGPORT_DEVICE_SIGNATURE,
  (EFI_HANDLE)0,
  (EFI_HANDLE)0,
  (EFI_DEVICE_PATH_PROTOCOL *)NULL,
  {
    DebugPortReset,
    DebugPortWrite,
    DebugPortRead,
    DebugPortPoll
  },
  (EFI_HANDLE)0,
  (EFI_SERIAL_IO_PROTOCOL *)NULL,
  DEBUGPORT_UART_DEFAULT_BAUDRATE,
  DEBUGPORT_UART_DEFAULT_FIFO_DEPTH,
  DEBUGPORT_UART_DEFAULT_TIMEOUT,
  (EFI_PARITY_TYPE)DEBUGPORT_UART_DEFAULT_PARITY,
  DEBUGPORT_UART_DEFAULT_DATA_BITS,
  (EFI_STOP_BITS_TYPE)DEBUGPORT_UART_DEFAULT_STOP_BITS
};

/**
  Local worker function to obtain device path information from DebugPort variable.

  Records requested settings in DebugPort device structure.

**/
EFI_DEVICE_PATH_PROTOCOL *
GetDebugPortVariable (
  VOID
  )
{
  UINTN                     DataSize;
  EFI_DEVICE_PATH_PROTOCOL  *DebugPortVariable;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

  GetVariable2 (EFI_DEBUGPORT_VARIABLE_NAME, &gEfiDebugPortVariableGuid, (VOID **)&DebugPortVariable, &DataSize);
  if (DebugPortVariable == NULL) {
    return NULL;
  }

  DevicePath = DebugPortVariable;
  while (!IsDevicePathEnd (DevicePath) && !IS_UART_DEVICEPATH (DevicePath)) {
    DevicePath = NextDevicePathNode (DevicePath);
  }

  if (IsDevicePathEnd (DevicePath)) {
    FreePool (DebugPortVariable);
    return NULL;
  } else {
    CopyMem (
      &mDebugPortDevice.BaudRate,
      &((UART_DEVICE_PATH *)DevicePath)->BaudRate,
      sizeof (((UART_DEVICE_PATH *)DevicePath)->BaudRate)
      );
    mDebugPortDevice.ReceiveFifoDepth = DEBUGPORT_UART_DEFAULT_FIFO_DEPTH;
    mDebugPortDevice.Timeout          = DEBUGPORT_UART_DEFAULT_TIMEOUT;
    CopyMem (
      &mDebugPortDevice.Parity,
      &((UART_DEVICE_PATH *)DevicePath)->Parity,
      sizeof (((UART_DEVICE_PATH *)DevicePath)->Parity)
      );
    CopyMem (
      &mDebugPortDevice.DataBits,
      &((UART_DEVICE_PATH *)DevicePath)->DataBits,
      sizeof (((UART_DEVICE_PATH *)DevicePath)->DataBits)
      );
    CopyMem (
      &mDebugPortDevice.StopBits,
      &((UART_DEVICE_PATH *)DevicePath)->StopBits,
      sizeof (((UART_DEVICE_PATH *)DevicePath)->StopBits)
      );
    return DebugPortVariable;
  }
}

/**
  Debug Port Driver entry point.

  Reads DebugPort variable to determine what device and settings to use as the
  debug port.  Binds exclusively to SerialIo. Reverts to defaults if no variable
  is found.

  @param[in] ImageHandle       The firmware allocated handle for the EFI image.
  @param[in] SystemTable       A pointer to the EFI System Table.

  @retval EFI_SUCCESS          The entry point is executed successfully.
  @retval EFI_OUT_OF_RESOURCES Fails to allocate memory for device.
  @retval other                Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
InitializeDebugPortDriver (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  //
  // Install driver model protocol(s).
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gDebugPortDriverBinding,
             ImageHandle,
             &gDebugPortComponentName,
             &gDebugPortComponentName2
             );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/**
  Checks to see if there's not already a DebugPort interface somewhere.

  If there's a DEBUGPORT variable, the device path must match exactly.  If there's
  no DEBUGPORT variable, then device path is not checked and does not matter.
  Checks to see that there's a serial io interface on the controller handle
  that can be bound BY_DRIVER | EXCLUSIVE.
  If all these tests succeed, then we return EFI_SUCCESS, else, EFI_UNSUPPORTED
  or other error returned by OpenProtocol.

  @param  This                 Protocol instance pointer.
  @param  ControllerHandle     Handle of device to test.
  @param  RemainingDevicePath  Optional parameter use to pick a specific child
                               device to start.

  @retval EFI_SUCCESS          This driver supports this device.
  @retval EFI_UNSUPPORTED      Debug Port device is not supported.
  @retval EFI_OUT_OF_RESOURCES Fails to allocate memory for device.
  @retval others               Some error occurs.

**/
EFI_STATUS
EFIAPI
DebugPortSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL  *DebugPortVariable;
  EFI_SERIAL_IO_PROTOCOL    *SerialIo;
  EFI_DEBUGPORT_PROTOCOL    *DebugPortInterface;
  EFI_HANDLE                TempHandle;

  //
  // Check to see that there's not a debugport protocol already published,
  // since only one standard UART serial port could be supported by this driver.
  //
  if (gBS->LocateProtocol (&gEfiDebugPortProtocolGuid, NULL, (VOID **)&DebugPortInterface) != EFI_NOT_FOUND) {
    return EFI_UNSUPPORTED;
  }

  //
  // Read DebugPort variable to determine debug port selection and parameters
  //
  DebugPortVariable = GetDebugPortVariable ();

  if (DebugPortVariable != NULL) {
    //
    // There's a DEBUGPORT variable, so do LocateDevicePath and check to see if
    // the closest matching handle matches the controller handle, and if it does,
    // check to see that the remaining device path has the DebugPort GUIDed messaging
    // device path only.  Otherwise, it's a mismatch and EFI_UNSUPPORTED is returned.
    //
    DevicePath = DebugPortVariable;
    Status     = gBS->LocateDevicePath (
                        &gEfiSerialIoProtocolGuid,
                        &DevicePath,
                        &TempHandle
                        );

    if ((Status == EFI_SUCCESS) && (TempHandle != ControllerHandle)) {
      Status = EFI_UNSUPPORTED;
    }

    if ((Status == EFI_SUCCESS) &&
        ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
         (DevicePath->SubType != MSG_VENDOR_DP) ||
         (*((UINT16 *)DevicePath->Length) != sizeof (DEBUGPORT_DEVICE_PATH))))
    {
      Status = EFI_UNSUPPORTED;
    }

    if ((Status == EFI_SUCCESS) && !CompareGuid (&gEfiDebugPortDevicePathGuid, (GUID *)(DevicePath + 1))) {
      Status = EFI_UNSUPPORTED;
    }

    FreePool (DebugPortVariable);
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiSerialIoProtocolGuid,
                  (VOID **)&SerialIo,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->CloseProtocol (
                  ControllerHandle,
                  &gEfiSerialIoProtocolGuid,
                  This->DriverBindingHandle,
                  ControllerHandle
                  );

  return Status;
}

/**
  Binds exclusively to serial io on the controller handle, Produces DebugPort
  protocol and DevicePath on new handle.

  @param  This                 Protocol instance pointer.
  @param  ControllerHandle     Handle of device to bind driver to.
  @param  RemainingDevicePath  Optional parameter use to pick a specific child
                               device to start.

  @retval EFI_SUCCESS          This driver is added to ControllerHandle.
  @retval EFI_OUT_OF_RESOURCES Fails to allocate memory for device.
  @retval others               Some error occurs.

**/
EFI_STATUS
EFIAPI
DebugPortStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                Status;
  DEBUGPORT_DEVICE_PATH     DebugPortDP;
  EFI_DEVICE_PATH_PROTOCOL  EndDP;
  EFI_DEVICE_PATH_PROTOCOL  *Dp1;

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiSerialIoProtocolGuid,
                  (VOID **)&mDebugPortDevice.SerialIoBinding,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  mDebugPortDevice.SerialIoDeviceHandle = ControllerHandle;

  //
  // Initialize the Serial Io interface...
  //
  Status = mDebugPortDevice.SerialIoBinding->SetAttributes (
                                               mDebugPortDevice.SerialIoBinding,
                                               mDebugPortDevice.BaudRate,
                                               mDebugPortDevice.ReceiveFifoDepth,
                                               mDebugPortDevice.Timeout,
                                               mDebugPortDevice.Parity,
                                               mDebugPortDevice.DataBits,
                                               mDebugPortDevice.StopBits
                                               );
  if (EFI_ERROR (Status)) {
    mDebugPortDevice.BaudRate         = 0;
    mDebugPortDevice.Parity           = DefaultParity;
    mDebugPortDevice.DataBits         = 0;
    mDebugPortDevice.StopBits         = DefaultStopBits;
    mDebugPortDevice.ReceiveFifoDepth = 0;
    Status                            = mDebugPortDevice.SerialIoBinding->SetAttributes (
                                                                            mDebugPortDevice.SerialIoBinding,
                                                                            mDebugPortDevice.BaudRate,
                                                                            mDebugPortDevice.ReceiveFifoDepth,
                                                                            mDebugPortDevice.Timeout,
                                                                            mDebugPortDevice.Parity,
                                                                            mDebugPortDevice.DataBits,
                                                                            mDebugPortDevice.StopBits
                                                                            );
    if (EFI_ERROR (Status)) {
      gBS->CloseProtocol (
             ControllerHandle,
             &gEfiSerialIoProtocolGuid,
             This->DriverBindingHandle,
             ControllerHandle
             );
      return Status;
    }
  }

  mDebugPortDevice.SerialIoBinding->Reset (mDebugPortDevice.SerialIoBinding);

  //
  // Create device path instance for DebugPort
  //
  DebugPortDP.Header.Type    = MESSAGING_DEVICE_PATH;
  DebugPortDP.Header.SubType = MSG_VENDOR_DP;
  SetDevicePathNodeLength (&(DebugPortDP.Header), sizeof (DebugPortDP));
  CopyGuid (&DebugPortDP.Guid, &gEfiDebugPortDevicePathGuid);

  Dp1 = DevicePathFromHandle (ControllerHandle);
  if (Dp1 == NULL) {
    Dp1 = &EndDP;
    SetDevicePathEndNode (Dp1);
  }

  mDebugPortDevice.DebugPortDevicePath = AppendDevicePathNode (Dp1, (EFI_DEVICE_PATH_PROTOCOL *)&DebugPortDP);
  if (mDebugPortDevice.DebugPortDevicePath == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Publish DebugPort and Device Path protocols
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &mDebugPortDevice.DebugPortDeviceHandle,
                  &gEfiDevicePathProtocolGuid,
                  mDebugPortDevice.DebugPortDevicePath,
                  &gEfiDebugPortProtocolGuid,
                  &mDebugPortDevice.DebugPortInterface,
                  NULL
                  );

  if (EFI_ERROR (Status)) {
    gBS->CloseProtocol (
           ControllerHandle,
           &gEfiSerialIoProtocolGuid,
           This->DriverBindingHandle,
           ControllerHandle
           );
    return Status;
  }

  //
  // Connect debugport child to serial io
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiSerialIoProtocolGuid,
                  (VOID **)&mDebugPortDevice.SerialIoBinding,
                  This->DriverBindingHandle,
                  mDebugPortDevice.DebugPortDeviceHandle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );

  if (EFI_ERROR (Status)) {
    gBS->CloseProtocol (
           ControllerHandle,
           &gEfiSerialIoProtocolGuid,
           This->DriverBindingHandle,
           ControllerHandle
           );
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  Stop this driver on ControllerHandle by removing Serial IO protocol on
  the ControllerHandle.

  @param  This              Protocol instance pointer.
  @param  ControllerHandle  Handle of device to stop driver on
  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
                            children is zero stop the entire bus driver.
  @param  ChildHandleBuffer List of Child Handles to Stop.

  @retval EFI_SUCCESS       This driver is removed ControllerHandle.
  @retval other             This driver was not removed from this device.

**/
EFI_STATUS
EFIAPI
DebugPortStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  UINTN                        NumberOfChildren,
  IN  EFI_HANDLE                   *ChildHandleBuffer
  )
{
  EFI_STATUS  Status;

  if (NumberOfChildren == 0) {
    //
    // Close the bus driver
    //
    gBS->CloseProtocol (
           ControllerHandle,
           &gEfiSerialIoProtocolGuid,
           This->DriverBindingHandle,
           ControllerHandle
           );

    mDebugPortDevice.SerialIoBinding = NULL;

    gBS->CloseProtocol (
           ControllerHandle,
           &gEfiDevicePathProtocolGuid,
           This->DriverBindingHandle,
           ControllerHandle
           );

    FreePool (mDebugPortDevice.DebugPortDevicePath);

    return EFI_SUCCESS;
  } else {
    //
    // Disconnect SerialIo child handle
    //
    Status = gBS->CloseProtocol (
                    mDebugPortDevice.SerialIoDeviceHandle,
                    &gEfiSerialIoProtocolGuid,
                    This->DriverBindingHandle,
                    mDebugPortDevice.DebugPortDeviceHandle
                    );

    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Unpublish our protocols (DevicePath, DebugPort)
    //
    Status = gBS->UninstallMultipleProtocolInterfaces (
                    mDebugPortDevice.DebugPortDeviceHandle,
                    &gEfiDevicePathProtocolGuid,
                    mDebugPortDevice.DebugPortDevicePath,
                    &gEfiDebugPortProtocolGuid,
                    &mDebugPortDevice.DebugPortInterface,
                    NULL
                    );

    if (EFI_ERROR (Status)) {
      gBS->OpenProtocol (
             ControllerHandle,
             &gEfiSerialIoProtocolGuid,
             (VOID **)&mDebugPortDevice.SerialIoBinding,
             This->DriverBindingHandle,
             mDebugPortDevice.DebugPortDeviceHandle,
             EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
             );
    } else {
      mDebugPortDevice.DebugPortDeviceHandle = NULL;
    }
  }

  return Status;
}

/**
  DebugPort protocol member function.  Calls SerialIo:GetControl to flush buffer.
  We cannot call SerialIo:SetAttributes because it uses pool services, which use
  locks, which affect TPL, so it's not interrupt context safe or re-entrant.
  SerialIo:Reset() calls SetAttributes, so it can't be used either.

  The port itself should be fine since it was set up during initialization.

  @param  This              Protocol instance pointer.

  @return EFI_SUCCESS       Always.

**/
EFI_STATUS
EFIAPI
DebugPortReset (
  IN EFI_DEBUGPORT_PROTOCOL  *This
  )
{
  UINTN  BufferSize;
  UINTN  BitBucket;

  while (This->Poll (This) == EFI_SUCCESS) {
    BufferSize = 1;
    This->Read (This, 0, &BufferSize, &BitBucket);
  }

  return EFI_SUCCESS;
}

/**
  DebugPort protocol member function.  Calls SerialIo:Read() after setting
  if it's different than the last SerialIo access.

  @param  This                Pointer to DebugPort protocol.
  @param  Timeout             Timeout value.
  @param  BufferSize          On input, the size of Buffer.
                              On output, the amount of data actually written.
  @param  Buffer              Pointer to buffer to read.

  @retval EFI_SUCCESS
  @retval others

**/
EFI_STATUS
EFIAPI
DebugPortRead (
  IN EFI_DEBUGPORT_PROTOCOL  *This,
  IN UINT32                  Timeout,
  IN OUT UINTN               *BufferSize,
  IN VOID                    *Buffer
  )
{
  DEBUGPORT_DEVICE  *DebugPortDevice;
  UINTN             LocalBufferSize;
  EFI_STATUS        Status;
  UINT8             *BufferPtr;

  DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);
  BufferPtr       = Buffer;
  LocalBufferSize = *BufferSize;

  do {
    Status = DebugPortDevice->SerialIoBinding->Read (
                                                 DebugPortDevice->SerialIoBinding,
                                                 &LocalBufferSize,
                                                 BufferPtr
                                                 );
    if (Status == EFI_TIMEOUT) {
      if (Timeout > DEBUGPORT_UART_DEFAULT_TIMEOUT) {
        Timeout -= DEBUGPORT_UART_DEFAULT_TIMEOUT;
      } else {
        Timeout = 0;
      }
    } else if (EFI_ERROR (Status)) {
      break;
    }

    BufferPtr      += LocalBufferSize;
    LocalBufferSize = *BufferSize - (BufferPtr - (UINT8 *)Buffer);
  } while (LocalBufferSize != 0 && Timeout > 0);

  *BufferSize = (UINTN)BufferPtr - (UINTN)Buffer;

  return Status;
}

/**
  DebugPort protocol member function.  Calls SerialIo:Write() Writes 8 bytes at
  a time and does a GetControl between 8 byte writes to help insure reads are
  interspersed This is poor-man's flow control.

  @param  This                Pointer to DebugPort protocol.
  @param  Timeout             Timeout value.
  @param  BufferSize          On input, the size of Buffer.
                              On output, the amount of data actually written.
  @param  Buffer              Pointer to buffer to read.

  @retval EFI_SUCCESS         The data was written.
  @retval others              Fails when writting datas to debug port device.

**/
EFI_STATUS
EFIAPI
DebugPortWrite (
  IN EFI_DEBUGPORT_PROTOCOL  *This,
  IN UINT32                  Timeout,
  IN OUT UINTN               *BufferSize,
  OUT VOID                   *Buffer
  )
{
  DEBUGPORT_DEVICE  *DebugPortDevice;
  UINTN             Position;
  UINTN             WriteSize;
  EFI_STATUS        Status;
  UINT32            SerialControl;

  Status          = EFI_SUCCESS;
  DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);

  WriteSize = 8;
  for (Position = 0; Position < *BufferSize && !EFI_ERROR (Status); Position += WriteSize) {
    DebugPortDevice->SerialIoBinding->GetControl (
                                        DebugPortDevice->SerialIoBinding,
                                        &SerialControl
                                        );
    if (*BufferSize - Position < 8) {
      WriteSize = *BufferSize - Position;
    }

    Status = DebugPortDevice->SerialIoBinding->Write (
                                                 DebugPortDevice->SerialIoBinding,
                                                 &WriteSize,
                                                 &((UINT8 *)Buffer)[Position]
                                                 );
  }

  *BufferSize = Position;
  return Status;
}

/**
  DebugPort protocol member function.  Calls SerialIo:Write() after setting
  if it's different than the last SerialIo access.

  @param  This                Pointer to DebugPort protocol.

  @retval EFI_SUCCESS         At least 1 character is ready to be read from
                              the DebugPort interface.
  @retval EFI_NOT_READY       There are no characters ready to read from the
                              DebugPort interface
  @retval EFI_DEVICE_ERROR    A hardware failure occurred... (from SerialIo)

**/
EFI_STATUS
EFIAPI
DebugPortPoll (
  IN EFI_DEBUGPORT_PROTOCOL  *This
  )
{
  EFI_STATUS        Status;
  UINT32            SerialControl;
  DEBUGPORT_DEVICE  *DebugPortDevice;

  DebugPortDevice = DEBUGPORT_DEVICE_FROM_THIS (This);

  Status = DebugPortDevice->SerialIoBinding->GetControl (
                                               DebugPortDevice->SerialIoBinding,
                                               &SerialControl
                                               );

  if (!EFI_ERROR (Status)) {
    if ((SerialControl & EFI_SERIAL_INPUT_BUFFER_EMPTY) != 0) {
      Status = EFI_NOT_READY;
    } else {
      Status = EFI_SUCCESS;
    }
  }

  return Status;
}

/**
  Unload function that is registered in the LoadImage protocol.  It un-installs
  protocols produced and deallocates pool used by the driver.  Called by the core
  when unloading the driver.

  @param  ImageHandle

  @retval EFI_SUCCESS     Unload Debug Port driver successfully.
  @retval EFI_ABORTED     Serial IO is still binding.

**/
EFI_STATUS
EFIAPI
ImageUnloadHandler (
  EFI_HANDLE  ImageHandle
  )
{
  EFI_STATUS  Status;
  VOID        *ComponentName;
  VOID        *ComponentName2;

  if (mDebugPortDevice.SerialIoBinding != NULL) {
    return EFI_ABORTED;
  }

  //
  // Driver is stopped already.
  //
  Status = gBS->HandleProtocol (ImageHandle, &gEfiComponentNameProtocolGuid, &ComponentName);
  if (EFI_ERROR (Status)) {
    ComponentName = NULL;
  }

  Status = gBS->HandleProtocol (ImageHandle, &gEfiComponentName2ProtocolGuid, &ComponentName2);
  if (EFI_ERROR (Status)) {
    ComponentName2 = NULL;
  }

  if (ComponentName == NULL) {
    if (ComponentName2 == NULL) {
      Status = gBS->UninstallMultipleProtocolInterfaces (
                      ImageHandle,
                      &gEfiDriverBindingProtocolGuid,
                      &gDebugPortDriverBinding,
                      NULL
                      );
    } else {
      Status = gBS->UninstallMultipleProtocolInterfaces (
                      ImageHandle,
                      &gEfiDriverBindingProtocolGuid,
                      &gDebugPortDriverBinding,
                      &gEfiComponentName2ProtocolGuid,
                      ComponentName2,
                      NULL
                      );
    }
  } else {
    if (ComponentName2 == NULL) {
      Status = gBS->UninstallMultipleProtocolInterfaces (
                      ImageHandle,
                      &gEfiDriverBindingProtocolGuid,
                      &gDebugPortDriverBinding,
                      &gEfiComponentNameProtocolGuid,
                      ComponentName,
                      NULL
                      );
    } else {
      Status = gBS->UninstallMultipleProtocolInterfaces (
                      ImageHandle,
                      &gEfiDriverBindingProtocolGuid,
                      &gDebugPortDriverBinding,
                      &gEfiComponentNameProtocolGuid,
                      ComponentName,
                      &gEfiComponentName2ProtocolGuid,
                      ComponentName2,
                      NULL
                      );
    }
  }

  return Status;
}
