/** @file
  This file implements ATA_PASSTHRU_PROTOCOL and EXT_SCSI_PASSTHRU_PROTOCOL interfaces
  for managed ATA controllers.

  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "AtaAtapiPassThru.h"

//
//  EFI_DRIVER_BINDING_PROTOCOL instance
//
EFI_DRIVER_BINDING_PROTOCOL  gAtaAtapiPassThruDriverBinding = {
  AtaAtapiPassThruSupported,
  AtaAtapiPassThruStart,
  AtaAtapiPassThruStop,
  0x10,
  NULL,
  NULL
};

ATA_ATAPI_PASS_THRU_INSTANCE  gAtaAtapiPassThruInstanceTemplate = {
  ATA_ATAPI_PASS_THRU_SIGNATURE,
  0,                  // Controller Handle
  NULL,               // PciIo Protocol
  NULL,               // IdeControllerInit Protocol
  {                   // AtaPassThruMode
    //
    // According to UEFI2.3 spec Section 12.10, Drivers for non-RAID ATA controllers should set
    // both EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL and EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL
    // bits.
    // Note that the driver doesn't support AtaPassThru non blocking I/O.
    //
    EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL | EFI_ATA_PASS_THRU_ATTRIBUTES_NONBLOCKIO,
    //
    // IoAlign
    //
    sizeof (UINTN)
  },
  {                   // AtaPassThru
    NULL,
    AtaPassThruPassThru,
    AtaPassThruGetNextPort,
    AtaPassThruGetNextDevice,
    AtaPassThruBuildDevicePath,
    AtaPassThruGetDevice,
    AtaPassThruResetPort,
    AtaPassThruResetDevice
  },
  {                   // ExtScsiPassThruMode
    //
    // AdapterId
    //
    0,
    //
    // According to UEFI2.3 spec Section 14.7, Drivers for non-RAID SCSI controllers should set
    // both EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL and EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL
    // bits.
    // Note that the driver doesn't support ExtScsiPassThru non blocking I/O.
    //
    EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL,
    //
    // IoAlign
    //
    sizeof (UINTN)
  },
  {                   // ExtScsiPassThru
    NULL,
    ExtScsiPassThruPassThru,
    ExtScsiPassThruGetNextTargetLun,
    ExtScsiPassThruBuildDevicePath,
    ExtScsiPassThruGetTargetLun,
    ExtScsiPassThruResetChannel,
    ExtScsiPassThruResetTargetLun,
    ExtScsiPassThruGetNextTarget
  },
  EfiAtaUnknownMode,  // Work Mode
  {                   // IdeRegisters
    { 0 },
    { 0 }
  },
  {                   // AhciRegisters
    0
  },
  {                   // DeviceList
    NULL,
    NULL
  },
  0,                  // EnabledPciAttributes
  0,                  // OriginalAttributes
  0,                  // PreviousPort
  0,                  // PreviousPortMultiplier
  0,                  // PreviousTargetId
  0,                  // PreviousLun
  NULL,               // Timer event
  {                   // NonBlocking TaskList
    NULL,
    NULL
  }
};

ATAPI_DEVICE_PATH  mAtapiDevicePathTemplate = {
  {
    MESSAGING_DEVICE_PATH,
    MSG_ATAPI_DP,
    {
      (UINT8)(sizeof (ATAPI_DEVICE_PATH)),
      (UINT8)((sizeof (ATAPI_DEVICE_PATH)) >> 8)
    }
  },
  0,
  0,
  0
};

SATA_DEVICE_PATH  mSataDevicePathTemplate = {
  {
    MESSAGING_DEVICE_PATH,
    MSG_SATA_DP,
    {
      (UINT8)(sizeof (SATA_DEVICE_PATH)),
      (UINT8)((sizeof (SATA_DEVICE_PATH)) >> 8)
    }
  },
  0,
  0,
  0
};

UINT8  mScsiId[TARGET_MAX_BYTES] = {
  0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF,
  0xFF, 0xFF, 0xFF, 0xFF
};

EDKII_ATA_ATAPI_POLICY_PROTOCOL  *mAtaAtapiPolicy;
EDKII_ATA_ATAPI_POLICY_PROTOCOL  mDefaultAtaAtapiPolicy = {
  EDKII_ATA_ATAPI_POLICY_VERSION,
  2,  // PuisEnable
  0,  // DeviceSleepEnable
  0,  // AggressiveDeviceSleepEnable
  0   // Reserved
};

/**
  Sends an ATA command to an ATA device that is attached to the ATA controller. This function
  supports both blocking I/O and non-blocking I/O. The blocking I/O functionality is required,
  and the non-blocking I/O functionality is optional.

  @param[in]      Port               The port number of the ATA device to send the command.
  @param[in]      PortMultiplierPort The port multiplier port number of the ATA device to send the command.
                                     If there is no port multiplier, then specify 0xFFFF.
  @param[in, out] Packet             A pointer to the ATA command to send to the ATA device specified by Port
                                     and PortMultiplierPort.
  @param[in]      Instance           Pointer to the ATA_ATAPI_PASS_THRU_INSTANCE.
  @param[in]      Task               Optional. Pointer to the ATA_NONBLOCK_TASK
                                     used by non-blocking mode.

  @retval EFI_SUCCESS                The ATA command was sent by the host. For
                                     bi-directional commands, InTransferLength bytes
                                     were transferred from InDataBuffer. For
                                     write and bi-directional commands, OutTransferLength
                                     bytes were transferred by OutDataBuffer.
  @retval EFI_BAD_BUFFER_SIZE        The ATA command was not executed. The number
                                     of bytes that could be transferred is returned
                                     in InTransferLength. For write and bi-directional
                                     commands, OutTransferLength bytes were transferred
                                     by OutDataBuffer.
  @retval EFI_NOT_READY              The ATA command could not be sent because
                                     there are too many ATA commands already
                                     queued. The caller may retry again later.
  @retval EFI_DEVICE_ERROR           A device error occurred while attempting
                                     to send the ATA command.
  @retval EFI_INVALID_PARAMETER      Port, PortMultiplierPort, or the contents
                                     of Acb are invalid. The ATA command was
                                     not sent, so no additional status information
                                     is available.

**/
EFI_STATUS
EFIAPI
AtaPassThruPassThruExecute (
  IN     UINT16                            Port,
  IN     UINT16                            PortMultiplierPort,
  IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET  *Packet,
  IN     ATA_ATAPI_PASS_THRU_INSTANCE      *Instance,
  IN     ATA_NONBLOCK_TASK                 *Task OPTIONAL
  )
{
  EFI_ATA_PASS_THRU_CMD_PROTOCOL  Protocol;
  EFI_ATA_HC_WORK_MODE            Mode;
  EFI_STATUS                      Status;

  Protocol = Packet->Protocol;

  Mode = Instance->Mode;
  switch (Mode) {
    case EfiAtaIdeMode:
      //
      // Reassign IDE mode io port registers' base addresses
      //
      Status = GetIdeRegisterIoAddr (Instance->PciIo, Instance->IdeRegisters);

      if (EFI_ERROR (Status)) {
        return Status;
      }

      switch (Protocol) {
        case EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA:
          Status = AtaNonDataCommandIn (
                     Instance->PciIo,
                     &Instance->IdeRegisters[Port],
                     Packet->Acb,
                     Packet->Asb,
                     Packet->Timeout,
                     Task
                     );
          break;
        case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN:
          Status = AtaPioDataInOut (
                     Instance->PciIo,
                     &Instance->IdeRegisters[Port],
                     Packet->InDataBuffer,
                     Packet->InTransferLength,
                     TRUE,
                     Packet->Acb,
                     Packet->Asb,
                     Packet->Timeout,
                     Task
                     );
          break;
        case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT:
          Status = AtaPioDataInOut (
                     Instance->PciIo,
                     &Instance->IdeRegisters[Port],
                     Packet->OutDataBuffer,
                     Packet->OutTransferLength,
                     FALSE,
                     Packet->Acb,
                     Packet->Asb,
                     Packet->Timeout,
                     Task
                     );
          break;
        case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_IN:
          Status = AtaUdmaInOut (
                     Instance,
                     &Instance->IdeRegisters[Port],
                     TRUE,
                     Packet->InDataBuffer,
                     Packet->InTransferLength,
                     Packet->Acb,
                     Packet->Asb,
                     Packet->Timeout,
                     Task
                     );
          break;
        case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_OUT:
          Status = AtaUdmaInOut (
                     Instance,
                     &Instance->IdeRegisters[Port],
                     FALSE,
                     Packet->OutDataBuffer,
                     Packet->OutTransferLength,
                     Packet->Acb,
                     Packet->Asb,
                     Packet->Timeout,
                     Task
                     );
          break;
        default:
          return EFI_UNSUPPORTED;
      }

      break;
    case EfiAtaAhciMode:
      if (PortMultiplierPort == 0xFFFF) {
        //
        // If there is no port multiplier, PortMultiplierPort will be 0xFFFF
        // according to UEFI spec. Here, we convert its value to 0 to follow
        // AHCI spec.
        //
        PortMultiplierPort = 0;
      }

      switch (Protocol) {
        case EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA:
          Status = AhciNonDataTransfer (
                     Instance->PciIo,
                     &Instance->AhciRegisters,
                     (UINT8)Port,
                     (UINT8)PortMultiplierPort,
                     NULL,
                     0,
                     Packet->Acb,
                     Packet->Asb,
                     Packet->Timeout,
                     Task
                     );
          break;
        case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN:
          Status = AhciPioTransfer (
                     Instance->PciIo,
                     &Instance->AhciRegisters,
                     (UINT8)Port,
                     (UINT8)PortMultiplierPort,
                     NULL,
                     0,
                     TRUE,
                     Packet->Acb,
                     Packet->Asb,
                     Packet->InDataBuffer,
                     Packet->InTransferLength,
                     Packet->Timeout,
                     Task
                     );
          break;
        case EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT:
          Status = AhciPioTransfer (
                     Instance->PciIo,
                     &Instance->AhciRegisters,
                     (UINT8)Port,
                     (UINT8)PortMultiplierPort,
                     NULL,
                     0,
                     FALSE,
                     Packet->Acb,
                     Packet->Asb,
                     Packet->OutDataBuffer,
                     Packet->OutTransferLength,
                     Packet->Timeout,
                     Task
                     );
          break;
        case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_IN:
          Status = AhciDmaTransfer (
                     Instance,
                     &Instance->AhciRegisters,
                     (UINT8)Port,
                     (UINT8)PortMultiplierPort,
                     NULL,
                     0,
                     TRUE,
                     Packet->Acb,
                     Packet->Asb,
                     Packet->InDataBuffer,
                     Packet->InTransferLength,
                     Packet->Timeout,
                     Task
                     );
          break;
        case EFI_ATA_PASS_THRU_PROTOCOL_UDMA_DATA_OUT:
          Status = AhciDmaTransfer (
                     Instance,
                     &Instance->AhciRegisters,
                     (UINT8)Port,
                     (UINT8)PortMultiplierPort,
                     NULL,
                     0,
                     FALSE,
                     Packet->Acb,
                     Packet->Asb,
                     Packet->OutDataBuffer,
                     Packet->OutTransferLength,
                     Packet->Timeout,
                     Task
                     );
          break;
        default:
          return EFI_UNSUPPORTED;
      }

      break;

    default:
      Status = EFI_DEVICE_ERROR;
      break;
  }

  return Status;
}

/**
  Call back function when the timer event is signaled.

  @param[in]  Event     The Event this notify function registered to.
  @param[in]  Context   Pointer to the context data registered to the
                        Event.

**/
VOID
EFIAPI
AsyncNonBlockingTransferRoutine (
  EFI_EVENT  Event,
  VOID       *Context
  )
{
  LIST_ENTRY                    *Entry;
  LIST_ENTRY                    *EntryHeader;
  ATA_NONBLOCK_TASK             *Task;
  EFI_STATUS                    Status;
  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance;

  Instance    = (ATA_ATAPI_PASS_THRU_INSTANCE *)Context;
  EntryHeader = &Instance->NonBlockingTaskList;
  //
  // Get the Tasks from the Tasks List and execute it, until there is
  // no task in the list or the device is busy with task (EFI_NOT_READY).
  //
  while (TRUE) {
    if (!IsListEmpty (EntryHeader)) {
      Entry = GetFirstNode (EntryHeader);
      Task  = ATA_NON_BLOCK_TASK_FROM_ENTRY (Entry);
    } else {
      return;
    }

    Status = AtaPassThruPassThruExecute (
               Task->Port,
               Task->PortMultiplier,
               Task->Packet,
               Instance,
               Task
               );

    //
    // If the data transfer meet a error, remove all tasks in the list since these tasks are
    // associated with one task from Ata Bus and signal the event with error status.
    //
    if ((Status != EFI_NOT_READY) && (Status != EFI_SUCCESS)) {
      DestroyAsynTaskList (Instance, TRUE);
      break;
    }

    //
    // For Non blocking mode, the Status of EFI_NOT_READY means the operation
    // is not finished yet. Otherwise the operation is successful.
    //
    if (Status == EFI_NOT_READY) {
      break;
    } else {
      RemoveEntryList (&Task->Link);
      gBS->SignalEvent (Task->Event);
      FreePool (Task);
    }
  }
}

/**
  The Entry Point of module.

  @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 other             Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
InitializeAtaAtapiPassThru (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  //
  // Install driver model protocol(s).
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gAtaAtapiPassThruDriverBinding,
             ImageHandle,
             &gAtaAtapiPassThruComponentName,
             &gAtaAtapiPassThruComponentName2
             );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

/**
  Tests to see if this driver supports a given controller. If a child device is provided,
  it further tests to see if this driver supports creating a handle for the specified child device.

  This function checks to see if the driver specified by This supports the device specified by
  ControllerHandle. Drivers will typically use the device path attached to
  ControllerHandle and/or the services from the bus I/O abstraction attached to
  ControllerHandle to determine if the driver supports ControllerHandle. This function
  may be called many times during platform initialization. In order to reduce boot times, the tests
  performed by this function must be very small, and take as little time as possible to execute. This
  function must not change the state of any hardware devices, and this function must be aware that the
  device specified by ControllerHandle may already be managed by the same driver or a
  different driver. This function must match its calls to AllocatePages() with FreePages(),
  AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
  Because ControllerHandle may have been previously started by the same driver, if a protocol is
  already in the opened state, then it must not be closed with CloseProtocol(). This is required
  to guarantee the state of ControllerHandle is not modified by this function.

  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle     The handle of the controller to test. This handle
                                   must support a protocol interface that supplies
                                   an I/O abstraction to the driver.
  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
                                   parameter is ignored by device drivers, and is optional for bus
                                   drivers. For bus drivers, if this parameter is not NULL, then
                                   the bus driver must determine if the bus controller specified
                                   by ControllerHandle and the child controller specified
                                   by RemainingDevicePath are both supported by this
                                   bus driver.

  @retval EFI_SUCCESS              The device specified by ControllerHandle and
                                   RemainingDevicePath is supported by the driver specified by This.
  @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
                                   RemainingDevicePath is already being managed by the driver
                                   specified by This.
  @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
                                   RemainingDevicePath is already being managed by a different
                                   driver or an application that requires exclusive access.
                                   Currently not implemented.
  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
                                   RemainingDevicePath is not supported by the driver specified by This.
**/
EFI_STATUS
EFIAPI
AtaAtapiPassThruSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                        Status;
  EFI_DEVICE_PATH_PROTOCOL          *ParentDevicePath;
  EFI_PCI_IO_PROTOCOL               *PciIo;
  PCI_TYPE00                        PciData;
  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeControllerInit;

  //
  // SATA Controller is a device driver, and should ignore the
  // "RemainingDevicePath" according to UEFI spec
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID *)&ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    //
    // EFI_ALREADY_STARTED is also an error
    //
    return Status;
  }

  //
  // Close the protocol because we don't use it here
  //
  gBS->CloseProtocol (
         Controller,
         &gEfiDevicePathProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiIdeControllerInitProtocolGuid,
                  (VOID **)&IdeControllerInit,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );

  if (EFI_ERROR (Status)) {
    //
    // EFI_ALREADY_STARTED is also an error
    //
    return Status;
  }

  //
  // Close the I/O Abstraction(s) used to perform the supported test
  //
  gBS->CloseProtocol (
         Controller,
         &gEfiIdeControllerInitProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  //
  // Now test the EfiPciIoProtocol
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID **)&PciIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Now further check the PCI header: Base class (offset 0x0B) and
  // Sub Class (offset 0x0A). This controller should be an ATA controller
  //
  Status = PciIo->Pci.Read (
                        PciIo,
                        EfiPciIoWidthUint8,
                        PCI_CLASSCODE_OFFSET,
                        sizeof (PciData.Hdr.ClassCode),
                        PciData.Hdr.ClassCode
                        );
  if (EFI_ERROR (Status)) {
    return EFI_UNSUPPORTED;
  }

  if (IS_PCI_IDE (&PciData) || IS_PCI_SATADPA (&PciData)) {
    return EFI_SUCCESS;
  }

  return EFI_UNSUPPORTED;
}

/**
  Starts a device controller or a bus controller.

  The Start() function is designed to be invoked from the EFI boot service ConnectController().
  As a result, much of the error checking on the parameters to Start() has been moved into this
  common boot service. It is legal to call Start() from other locations,
  but the following calling restrictions must be followed, or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE.
  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
     EFI_DEVICE_PATH_PROTOCOL.
  3. Prior to calling Start(), the Supported() function for the driver specified by This must
     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.

  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle     The handle of the controller to start. This handle
                                   must support a protocol interface that supplies
                                   an I/O abstraction to the driver.
  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
                                   parameter is ignored by device drivers, and is optional for bus
                                   drivers. For a bus driver, if this parameter is NULL, then handles
                                   for all the children of Controller are created by this driver.
                                   If this parameter is not NULL and the first Device Path Node is
                                   not the End of Device Path Node, then only the handle for the
                                   child device specified by the first Device Path Node of
                                   RemainingDevicePath is created by this driver.
                                   If the first Device Path Node of RemainingDevicePath is
                                   the End of Device Path Node, no child handle is created by this
                                   driver.

  @retval EFI_SUCCESS              The device was started.
  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
  @retval Others                   The driver failed to start the device.

**/
EFI_STATUS
EFIAPI
AtaAtapiPassThruStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                        Status;
  EFI_IDE_CONTROLLER_INIT_PROTOCOL  *IdeControllerInit;
  ATA_ATAPI_PASS_THRU_INSTANCE      *Instance;
  EFI_PCI_IO_PROTOCOL               *PciIo;
  UINT64                            EnabledPciAttributes;
  UINT64                            OriginalPciAttributes;

  Status                = EFI_SUCCESS;
  IdeControllerInit     = NULL;
  Instance              = NULL;
  OriginalPciAttributes = 0;

  DEBUG ((DEBUG_INFO, "==AtaAtapiPassThru Start== Controller = %x\n", Controller));

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiIdeControllerInitProtocolGuid,
                  (VOID **)&IdeControllerInit,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );

  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Open Ide_Controller_Init Error, Status=%r", Status));
    goto ErrorExit;
  }

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiPciIoProtocolGuid,
                  (VOID **)&PciIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "Get Pci_Io Protocol Error, Status=%r\n", Status));
    goto ErrorExit;
  }

  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationGet,
                    0,
                    &OriginalPciAttributes
                    );

  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationSupported,
                    0,
                    &EnabledPciAttributes
                    );
  if (!EFI_ERROR (Status)) {
    EnabledPciAttributes &= (UINT64)EFI_PCI_DEVICE_ENABLE;
    Status                = PciIo->Attributes (
                                     PciIo,
                                     EfiPciIoAttributeOperationEnable,
                                     EnabledPciAttributes,
                                     NULL
                                     );
  }

  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  Status = gBS->LocateProtocol (&gEdkiiAtaAtapiPolicyProtocolGuid, NULL, (VOID **)&mAtaAtapiPolicy);
  if (EFI_ERROR (Status)) {
    //
    // If there is no AtaAtapiPolicy exposed, use the default policy.
    //
    mAtaAtapiPolicy = &mDefaultAtaAtapiPolicy;
  }

  //
  // Allocate a buffer to store the ATA_ATAPI_PASS_THRU_INSTANCE data structure
  //
  Instance = AllocateCopyPool (sizeof (ATA_ATAPI_PASS_THRU_INSTANCE), &gAtaAtapiPassThruInstanceTemplate);
  if (Instance == NULL) {
    goto ErrorExit;
  }

  Instance->ControllerHandle      = Controller;
  Instance->IdeControllerInit     = IdeControllerInit;
  Instance->PciIo                 = PciIo;
  Instance->EnabledPciAttributes  = EnabledPciAttributes;
  Instance->OriginalPciAttributes = OriginalPciAttributes;
  Instance->AtaPassThru.Mode      = &Instance->AtaPassThruMode;
  Instance->ExtScsiPassThru.Mode  = &Instance->ExtScsiPassThruMode;
  InitializeListHead (&Instance->DeviceList);
  InitializeListHead (&Instance->NonBlockingTaskList);

  Instance->TimerEvent = NULL;

  Status = gBS->CreateEvent (
                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  AsyncNonBlockingTransferRoutine,
                  Instance,
                  &Instance->TimerEvent
                  );
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  //
  // Set 1ms timer.
  //
  Status = gBS->SetTimer (Instance->TimerEvent, TimerPeriodic, 10000);
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  //
  // Enumerate all inserted ATA devices.
  //
  Status = EnumerateAttachedDevice (Instance);
  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Controller,
                  &gEfiAtaPassThruProtocolGuid,
                  &(Instance->AtaPassThru),
                  &gEfiExtScsiPassThruProtocolGuid,
                  &(Instance->ExtScsiPassThru),
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  return Status;

ErrorExit:
  if (IdeControllerInit != NULL) {
    gBS->CloseProtocol (
           Controller,
           &gEfiIdeControllerInitProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
  }

  if ((Instance != NULL) && (Instance->TimerEvent != NULL)) {
    gBS->CloseEvent (Instance->TimerEvent);
  }

  if (Instance != NULL) {
    //
    // Remove all inserted ATA devices.
    //
    DestroyDeviceInfoList (Instance);
    FreePool (Instance);
  }

  return EFI_UNSUPPORTED;
}

/**
  Stops a device controller or a bus controller.

  The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
  As a result, much of the error checking on the parameters to Stop() has been moved
  into this common boot service. It is legal to call Stop() from other locations,
  but the following calling restrictions must be followed, or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
     same driver's Start() function.
  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
     EFI_HANDLE. In addition, all of these handles must have been created in this driver's
     Start() function, and the Start() function must have called OpenProtocol() on
     ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.

  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
                                support a bus specific I/O protocol for the driver
                                to use to stop the device.
  @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
  @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
                                if NumberOfChildren is 0.

  @retval EFI_SUCCESS           The device was stopped.
  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.

**/
EFI_STATUS
EFIAPI
AtaAtapiPassThruStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   Controller,
  IN  UINTN                        NumberOfChildren,
  IN  EFI_HANDLE                   *ChildHandleBuffer
  )
{
  EFI_STATUS                    Status;
  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance;
  EFI_ATA_PASS_THRU_PROTOCOL    *AtaPassThru;
  EFI_PCI_IO_PROTOCOL           *PciIo;
  EFI_AHCI_REGISTERS            *AhciRegisters;

  DEBUG ((DEBUG_INFO, "==AtaAtapiPassThru Stop== Controller = %x\n", Controller));

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiAtaPassThruProtocolGuid,
                  (VOID **)&AtaPassThru,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (AtaPassThru);

  Status = gBS->UninstallMultipleProtocolInterfaces (
                  Controller,
                  &gEfiAtaPassThruProtocolGuid,
                  &(Instance->AtaPassThru),
                  &gEfiExtScsiPassThruProtocolGuid,
                  &(Instance->ExtScsiPassThru),
                  NULL
                  );

  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Close protocols opened by AtaAtapiPassThru controller driver
  //
  gBS->CloseProtocol (
         Controller,
         &gEfiIdeControllerInitProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  //
  // Close Non-Blocking timer and free Task list.
  //
  if (Instance->TimerEvent != NULL) {
    gBS->CloseEvent (Instance->TimerEvent);
    Instance->TimerEvent = NULL;
  }

  DestroyAsynTaskList (Instance, FALSE);
  //
  // Free allocated resource
  //
  DestroyDeviceInfoList (Instance);

  PciIo = Instance->PciIo;

  //
  // Disable this ATA host controller.
  //
  PciIo->Attributes (
           PciIo,
           EfiPciIoAttributeOperationDisable,
           Instance->EnabledPciAttributes,
           NULL
           );

  //
  // If the current working mode is AHCI mode, then pre-allocated resource
  // for AHCI initialization should be released.
  //
  if (Instance->Mode == EfiAtaAhciMode) {
    AhciRegisters = &Instance->AhciRegisters;
    PciIo->Unmap (
             PciIo,
             AhciRegisters->MapCommandTable
             );
    PciIo->FreeBuffer (
             PciIo,
             EFI_SIZE_TO_PAGES ((UINTN)AhciRegisters->MaxCommandTableSize),
             AhciRegisters->AhciCommandTable
             );
    PciIo->Unmap (
             PciIo,
             AhciRegisters->MapCmdList
             );
    PciIo->FreeBuffer (
             PciIo,
             EFI_SIZE_TO_PAGES ((UINTN)AhciRegisters->MaxCommandListSize),
             AhciRegisters->AhciCmdList
             );
    PciIo->Unmap (
             PciIo,
             AhciRegisters->MapRFis
             );
    PciIo->FreeBuffer (
             PciIo,
             EFI_SIZE_TO_PAGES ((UINTN)AhciRegisters->MaxReceiveFisSize),
             AhciRegisters->AhciRFis
             );
  }

  //
  // Restore original PCI attributes
  //
  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationSet,
                    Instance->OriginalPciAttributes,
                    NULL
                    );
  ASSERT_EFI_ERROR (Status);

  FreePool (Instance);

  return Status;
}

/**
  Traverse the attached ATA devices list to find out the device to access.

  @param[in]  Instance            A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
  @param[in]  Port                The port number of the ATA device to send the command.
  @param[in]  PortMultiplierPort  The port multiplier port number of the ATA device to send the command.
                                  If there is no port multiplier, then specify 0xFFFF.
  @param[in]  DeviceType          The device type of the ATA device.

  @retval     The pointer to the data structure of the device info to access.

**/
LIST_ENTRY *
EFIAPI
SearchDeviceInfoList (
  IN  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
  IN  UINT16                        Port,
  IN  UINT16                        PortMultiplier,
  IN  EFI_ATA_DEVICE_TYPE           DeviceType
  )
{
  EFI_ATA_DEVICE_INFO  *DeviceInfo;
  LIST_ENTRY           *Node;

  Node = GetFirstNode (&Instance->DeviceList);
  while (!IsNull (&Instance->DeviceList, Node)) {
    DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);

    //
    // For CD-ROM working in the AHCI mode, only 8 bits are used to record
    // the PortMultiplier information. If the CD-ROM is directly attached
    // on a SATA port, the PortMultiplier should be translated from 0xFF
    // to 0xFFFF according to the UEFI spec.
    //
    if ((Instance->Mode == EfiAtaAhciMode) &&
        (DeviceInfo->Type == EfiIdeCdrom) &&
        (PortMultiplier == 0xFF))
    {
      PortMultiplier = 0xFFFF;
    }

    if ((DeviceInfo->Type == DeviceType) &&
        (Port == DeviceInfo->Port) &&
        (PortMultiplier == DeviceInfo->PortMultiplier))
    {
      return Node;
    }

    Node = GetNextNode (&Instance->DeviceList, Node);
  }

  return NULL;
}

/**
  Allocate device info data structure to contain device info.
  And insert the data structure to the tail of device list for tracing.

  @param[in]  Instance            A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
  @param[in]  Port                The port number of the ATA device to send the command.
  @param[in]  PortMultiplierPort  The port multiplier port number of the ATA device to send the command.
                                  If there is no port multiplier, then specify 0xFFFF.
  @param[in]  DeviceType          The device type of the ATA device.
  @param[in]  IdentifyData        The data buffer to store the output of the IDENTIFY cmd.

  @retval EFI_SUCCESS             Successfully insert the ata device to the tail of device list.
  @retval EFI_OUT_OF_RESOURCES    Can not allocate enough resource for use.

**/
EFI_STATUS
EFIAPI
CreateNewDeviceInfo (
  IN  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
  IN  UINT16                        Port,
  IN  UINT16                        PortMultiplier,
  IN  EFI_ATA_DEVICE_TYPE           DeviceType,
  IN  EFI_IDENTIFY_DATA             *IdentifyData
  )
{
  EFI_ATA_DEVICE_INFO  *DeviceInfo;

  DeviceInfo = AllocateZeroPool (sizeof (EFI_ATA_DEVICE_INFO));

  if (DeviceInfo == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  DeviceInfo->Signature      = ATA_ATAPI_DEVICE_SIGNATURE;
  DeviceInfo->Port           = Port;
  DeviceInfo->PortMultiplier = PortMultiplier;
  DeviceInfo->Type           = DeviceType;

  if (IdentifyData != NULL) {
    DeviceInfo->IdentifyData = AllocateCopyPool (sizeof (EFI_IDENTIFY_DATA), IdentifyData);
    if (DeviceInfo->IdentifyData == NULL) {
      FreePool (DeviceInfo);
      return EFI_OUT_OF_RESOURCES;
    }
  }

  InsertTailList (&Instance->DeviceList, &DeviceInfo->Link);

  return EFI_SUCCESS;
}

/**
  Destroy all attached ATA devices info.

  @param[in]  Instance          A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.

**/
VOID
EFIAPI
DestroyDeviceInfoList (
  IN  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance
  )
{
  EFI_ATA_DEVICE_INFO  *DeviceInfo;
  LIST_ENTRY           *Node;

  Node = GetFirstNode (&Instance->DeviceList);
  while (!IsNull (&Instance->DeviceList, Node)) {
    DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);

    Node = GetNextNode (&Instance->DeviceList, Node);

    RemoveEntryList (&DeviceInfo->Link);
    if (DeviceInfo->IdentifyData != NULL) {
      FreePool (DeviceInfo->IdentifyData);
    }

    FreePool (DeviceInfo);
  }
}

/**
  Destroy all pending non blocking tasks.

  @param[in]  Instance    A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.
  @param[in]  IsSigEvent  Indicate whether signal the task event when remove the
                          task.

**/
VOID
EFIAPI
DestroyAsynTaskList (
  IN ATA_ATAPI_PASS_THRU_INSTANCE  *Instance,
  IN BOOLEAN                       IsSigEvent
  )
{
  LIST_ENTRY         *Entry;
  LIST_ENTRY         *DelEntry;
  ATA_NONBLOCK_TASK  *Task;
  EFI_TPL            OldTpl;

  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
  if (!IsListEmpty (&Instance->NonBlockingTaskList)) {
    //
    // Free the Subtask list.
    //
    for (Entry = (&Instance->NonBlockingTaskList)->ForwardLink;
         Entry != (&Instance->NonBlockingTaskList);
         )
    {
      DelEntry = Entry;
      Entry    = Entry->ForwardLink;
      Task     = ATA_NON_BLOCK_TASK_FROM_ENTRY (DelEntry);

      RemoveEntryList (DelEntry);
      if (IsSigEvent) {
        Task->Packet->Asb->AtaStatus = 0x01;
        gBS->SignalEvent (Task->Event);
      }

      FreePool (Task);
    }
  }

  gBS->RestoreTPL (OldTpl);
}

/**
  Enumerate all attached ATA devices at IDE mode or AHCI mode separately.

  The function is designed to enumerate all attached ATA devices.

  @param[in]  Instance          A pointer to the ATA_ATAPI_PASS_THRU_INSTANCE instance.

  @retval EFI_SUCCESS           Successfully enumerate attached ATA devices.
  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.

**/
EFI_STATUS
EFIAPI
EnumerateAttachedDevice (
  IN  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance
  )
{
  EFI_STATUS  Status;
  PCI_TYPE00  PciData;
  UINT8       ClassCode;

  Status = EFI_SUCCESS;

  Status = Instance->PciIo->Pci.Read (
                                  Instance->PciIo,
                                  EfiPciIoWidthUint8,
                                  PCI_CLASSCODE_OFFSET,
                                  sizeof (PciData.Hdr.ClassCode),
                                  PciData.Hdr.ClassCode
                                  );
  ASSERT_EFI_ERROR (Status);

  ClassCode = PciData.Hdr.ClassCode[1];

  switch (ClassCode) {
    case PCI_CLASS_MASS_STORAGE_IDE:
      //
      // The ATA controller is working at IDE mode
      //
      Instance->Mode = EfiAtaIdeMode;

      Status = IdeModeInitialization (Instance);
      if (EFI_ERROR (Status)) {
        Status = EFI_DEVICE_ERROR;
        goto Done;
      }

      break;
    case PCI_CLASS_MASS_STORAGE_SATADPA:
      //
      // The ATA controller is working at AHCI mode
      //
      Instance->Mode = EfiAtaAhciMode;

      Status = AhciModeInitialization (Instance);

      if (EFI_ERROR (Status)) {
        Status = EFI_DEVICE_ERROR;
        goto Done;
      }

      break;
    default:
      Status = EFI_UNSUPPORTED;
  }

Done:
  return Status;
}

/**
  Sends an ATA command to an ATA device that is attached to the ATA controller. This function
  supports both blocking I/O and non-blocking I/O. The blocking I/O functionality is required,
  and the non-blocking I/O functionality is optional.

  @param[in]      This               A pointer to the EFI_ATA_PASS_THRU_PROTOCOL instance.
  @param[in]      Port               The port number of the ATA device to send the command.
  @param[in]      PortMultiplierPort The port multiplier port number of the ATA device to send the command.
                                     If there is no port multiplier, then specify 0xFFFF.
  @param[in, out] Packet             A pointer to the ATA command to send to the ATA device specified by Port
                                     and PortMultiplierPort.
  @param[in]      Event               If non-blocking I/O is not supported then Event is ignored, and blocking
                                     I/O is performed. If Event is NULL, then blocking I/O is performed. If
                                     Event is not NULL and non blocking I/O is supported, then non-blocking
                                     I/O is performed, and Event will be signaled when the ATA command completes.

  @retval EFI_SUCCESS                The ATA command was sent by the host. For bi-directional commands,
                                     InTransferLength bytes were transferred from InDataBuffer. For write and
                                     bi-directional commands, OutTransferLength bytes were transferred by OutDataBuffer.
  @retval EFI_BAD_BUFFER_SIZE        The ATA command was not executed. The number of bytes that could be transferred
                                     is returned in InTransferLength. For write and bi-directional commands,
                                     OutTransferLength bytes were transferred by OutDataBuffer.
  @retval EFI_NOT_READY              The ATA command could not be sent because there are too many ATA commands
                                     already queued. The caller may retry again later.
  @retval EFI_DEVICE_ERROR           A device error occurred while attempting to send the ATA command.
  @retval EFI_INVALID_PARAMETER      Port, PortMultiplierPort, or the contents of Acb are invalid. The ATA
                                     command was not sent, so no additional status information is available.

**/
EFI_STATUS
EFIAPI
AtaPassThruPassThru (
  IN     EFI_ATA_PASS_THRU_PROTOCOL        *This,
  IN     UINT16                            Port,
  IN     UINT16                            PortMultiplierPort,
  IN OUT EFI_ATA_PASS_THRU_COMMAND_PACKET  *Packet,
  IN     EFI_EVENT                         Event OPTIONAL
  )
{
  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance;
  LIST_ENTRY                    *Node;
  EFI_ATA_DEVICE_INFO           *DeviceInfo;
  EFI_IDENTIFY_DATA             *IdentifyData;
  UINT64                        Capacity;
  UINT32                        MaxSectorCount;
  ATA_NONBLOCK_TASK             *Task;
  EFI_TPL                       OldTpl;
  UINT32                        BlockSize;

  Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);

  if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->InDataBuffer, This->Mode->IoAlign)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->OutDataBuffer, This->Mode->IoAlign)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->Asb, This->Mode->IoAlign)) {
    return EFI_INVALID_PARAMETER;
  }

  Node = SearchDeviceInfoList (Instance, Port, PortMultiplierPort, EfiIdeHarddisk);

  if (Node == NULL) {
    Node = SearchDeviceInfoList (Instance, Port, PortMultiplierPort, EfiIdeCdrom);
    if (Node == NULL) {
      return EFI_INVALID_PARAMETER;
    }
  }

  //
  // Check whether this device needs 48-bit addressing (ATAPI-6 ata device).
  // Per ATA-6 spec, word83: bit15 is zero and bit14 is one.
  // If bit10 is one, it means the ata device support 48-bit addressing.
  //
  DeviceInfo     = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);
  IdentifyData   = DeviceInfo->IdentifyData;
  MaxSectorCount = 0x100;
  if ((IdentifyData->AtaData.command_set_supported_83 & (BIT10 | BIT15 | BIT14)) == 0x4400) {
    Capacity = *((UINT64 *)IdentifyData->AtaData.maximum_lba_for_48bit_addressing);
    if (Capacity > 0xFFFFFFF) {
      //
      // Capacity exceeds 120GB. 48-bit addressing is really needed
      // In this case, the max sector count is 0x10000
      //
      MaxSectorCount = 0x10000;
    }
  }

  BlockSize = 0x200;
  if ((IdentifyData->AtaData.phy_logic_sector_support & (BIT14 | BIT15)) == BIT14) {
    //
    // Check logical block size
    //
    if ((IdentifyData->AtaData.phy_logic_sector_support & BIT12) != 0) {
      BlockSize = (UINT32)(((UINT32)(IdentifyData->AtaData.logic_sector_size_hi << 16) | IdentifyData->AtaData.logic_sector_size_lo) * sizeof (UINT16));
    }
  }

  //
  // convert the transfer length from sector count to byte.
  //
  if (((Packet->Length & EFI_ATA_PASS_THRU_LENGTH_BYTES) == 0) &&
      (Packet->InTransferLength != 0))
  {
    Packet->InTransferLength = Packet->InTransferLength * BlockSize;
  }

  //
  // convert the transfer length from sector count to byte.
  //
  if (((Packet->Length & EFI_ATA_PASS_THRU_LENGTH_BYTES) == 0) &&
      (Packet->OutTransferLength != 0))
  {
    Packet->OutTransferLength = Packet->OutTransferLength * BlockSize;
  }

  //
  // If the data buffer described by InDataBuffer/OutDataBuffer and InTransferLength/OutTransferLength
  // is too big to be transferred in a single command, then no data is transferred and EFI_BAD_BUFFER_SIZE
  // is returned.
  //
  if (((Packet->InTransferLength != 0) && (Packet->InTransferLength > MaxSectorCount * BlockSize)) ||
      ((Packet->OutTransferLength != 0) && (Packet->OutTransferLength > MaxSectorCount * BlockSize)))
  {
    return EFI_BAD_BUFFER_SIZE;
  }

  //
  // For non-blocking mode, queue the Task into the list.
  //
  if (Event != NULL) {
    Task = AllocateZeroPool (sizeof (ATA_NONBLOCK_TASK));
    if (Task == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Task->Signature      = ATA_NONBLOCKING_TASK_SIGNATURE;
    Task->Port           = Port;
    Task->PortMultiplier = PortMultiplierPort;
    Task->Packet         = Packet;
    Task->Event          = Event;
    Task->IsStart        = FALSE;
    Task->RetryTimes     = DivU64x32 (Packet->Timeout, 1000) + 1;
    if (Packet->Timeout == 0) {
      Task->InfiniteWait = TRUE;
    } else {
      Task->InfiniteWait = FALSE;
    }

    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
    InsertTailList (&Instance->NonBlockingTaskList, &Task->Link);
    gBS->RestoreTPL (OldTpl);

    return EFI_SUCCESS;
  } else {
    return AtaPassThruPassThruExecute (
             Port,
             PortMultiplierPort,
             Packet,
             Instance,
             NULL
             );
  }
}

/**
  Used to retrieve the list of legal port numbers for ATA devices on an ATA controller.
  These can either be the list of ports where ATA devices are actually present or the
  list of legal port numbers for the ATA controller. Regardless, the caller of this
  function must probe the port number returned to see if an ATA device is actually
  present at that location on the ATA controller.

  The GetNextPort() function retrieves the port number on an ATA controller. If on input
  Port is 0xFFFF, then the port number of the first port on the ATA controller is returned
  in Port and EFI_SUCCESS is returned.

  If Port is a port number that was returned on a previous call to GetNextPort(), then the
  port number of the next port on the ATA controller is returned in Port, and EFI_SUCCESS
  is returned. If Port is not 0xFFFF and Port was not returned on a previous call to
  GetNextPort(), then EFI_INVALID_PARAMETER is returned.

  If Port is the port number of the last port on the ATA controller, then EFI_NOT_FOUND is
  returned.

  @param[in]      This          A pointer to the EFI_ATA_PASS_THRU_PROTOCOL instance.
  @param[in, out] Port          On input, a pointer to the port number on the ATA controller.
                                On output, a pointer to the next port number on the ATA
                                controller. An input value of 0xFFFF retrieves the first port
                                number on the ATA controller.

  @retval EFI_SUCCESS           The next port number on the ATA controller was returned in Port.
  @retval EFI_NOT_FOUND         There are no more ports on this ATA controller.
  @retval EFI_INVALID_PARAMETER Port is not 0xFFFF and Port was not returned on a previous call
                                to GetNextPort().

**/
EFI_STATUS
EFIAPI
AtaPassThruGetNextPort (
  IN EFI_ATA_PASS_THRU_PROTOCOL  *This,
  IN OUT UINT16                  *Port
  )
{
  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance;
  LIST_ENTRY                    *Node;
  EFI_ATA_DEVICE_INFO           *DeviceInfo;

  Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);

  if (Port == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (*Port == 0xFFFF) {
    //
    // If the Port is all 0xFF's, start to traverse the device list from the beginning
    //
    Node = GetFirstNode (&Instance->DeviceList);

    while (!IsNull (&Instance->DeviceList, Node)) {
      DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);

      if (DeviceInfo->Type == EfiIdeHarddisk) {
        *Port = DeviceInfo->Port;
        goto Exit;
      }

      Node = GetNextNode (&Instance->DeviceList, Node);
    }

    return EFI_NOT_FOUND;
  } else if (*Port == Instance->PreviousPort) {
    Node = GetFirstNode (&Instance->DeviceList);

    while (!IsNull (&Instance->DeviceList, Node)) {
      DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);

      if ((DeviceInfo->Type == EfiIdeHarddisk) &&
          (DeviceInfo->Port > *Port))
      {
        *Port = DeviceInfo->Port;
        goto Exit;
      }

      Node = GetNextNode (&Instance->DeviceList, Node);
    }

    return EFI_NOT_FOUND;
  } else {
    //
    // Port is not equal to 0xFFFF and also not equal to previous return value
    //
    return EFI_INVALID_PARAMETER;
  }

Exit:
  //
  // Update the PreviousPort and PreviousPortMultiplier.
  //
  Instance->PreviousPort = *Port;

  return EFI_SUCCESS;
}

/**
  Used to retrieve the list of legal port multiplier port numbers for ATA devices on a port of an ATA
  controller. These can either be the list of port multiplier ports where ATA devices are actually
  present on port or the list of legal port multiplier ports on that port. Regardless, the caller of this
  function must probe the port number and port multiplier port number returned to see if an ATA
  device is actually present.

  The GetNextDevice() function retrieves the port multiplier port number of an ATA device
  present on a port of an ATA controller.

  If PortMultiplierPort points to a port multiplier port number value that was returned on a
  previous call to GetNextDevice(), then the port multiplier port number of the next ATA device
  on the port of the ATA controller is returned in PortMultiplierPort, and EFI_SUCCESS is
  returned.

  If PortMultiplierPort points to 0xFFFF, then the port multiplier port number of the first
  ATA device on port of the ATA controller is returned in PortMultiplierPort and
  EFI_SUCCESS is returned.

  If PortMultiplierPort is not 0xFFFF and the value pointed to by PortMultiplierPort
  was not returned on a previous call to GetNextDevice(), then EFI_INVALID_PARAMETER
  is returned.

  If PortMultiplierPort is the port multiplier port number of the last ATA device on the port of
  the ATA controller, then EFI_NOT_FOUND is returned.

  When port multiplier is not connected to the Port, GetNextDevice() may either return
  EFI_SUCCESS and set PortMultiplierPort to 0xFFFF or return EFI_NOT_FOUND (in which case the
  PortMultiplierPort value is undefined).

  @param[in]      This               A pointer to the EFI_ATA_PASS_THRU_PROTOCOL instance.
  @param[in]      Port               The port number present on the ATA controller.
  @param[in, out] PortMultiplierPort On input, a pointer to the port multiplier port number of an
                                     ATA device present on the ATA controller.
                                     If on input a PortMultiplierPort of 0xFFFF is specified,
                                     then the port multiplier port number of the first ATA device
                                     is returned. On output, a pointer to the port multiplier port
                                     number of the next ATA device present on an ATA controller.

  @retval EFI_SUCCESS                The port multiplier port number of the next ATA device on the port
                                     of the ATA controller was returned in PortMultiplierPort.
  @retval EFI_NOT_FOUND              There are no more ATA devices on this port of the ATA controller.
  @retval EFI_INVALID_PARAMETER      PortMultiplierPort is not 0xFFFF, and PortMultiplierPort was not
                                     returned on a previous call to GetNextDevice().

**/
EFI_STATUS
EFIAPI
AtaPassThruGetNextDevice (
  IN EFI_ATA_PASS_THRU_PROTOCOL  *This,
  IN UINT16                      Port,
  IN OUT UINT16                  *PortMultiplierPort
  )
{
  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance;
  LIST_ENTRY                    *Node;
  EFI_ATA_DEVICE_INFO           *DeviceInfo;

  Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);

  if (PortMultiplierPort == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (Instance->PreviousPortMultiplier == 0xFFFF) {
    //
    // If a device is directly attached on a port, previous call to this
    // function will return the value 0xFFFF for PortMultiplierPort. In
    // this case, there should be no more device on the port multiplier.
    //
    Instance->PreviousPortMultiplier = 0;
    return EFI_NOT_FOUND;
  }

  if (*PortMultiplierPort == Instance->PreviousPortMultiplier) {
    Node = GetFirstNode (&Instance->DeviceList);

    while (!IsNull (&Instance->DeviceList, Node)) {
      DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);

      if ((DeviceInfo->Type == EfiIdeHarddisk) &&
          (DeviceInfo->Port == Port) &&
          (DeviceInfo->PortMultiplier > *PortMultiplierPort))
      {
        *PortMultiplierPort = DeviceInfo->PortMultiplier;
        goto Exit;
      }

      Node = GetNextNode (&Instance->DeviceList, Node);
    }

    return EFI_NOT_FOUND;
  } else if (*PortMultiplierPort == 0xFFFF) {
    //
    // If the PortMultiplierPort is all 0xFF's, start to traverse the device list from the beginning
    //
    Node = GetFirstNode (&Instance->DeviceList);

    while (!IsNull (&Instance->DeviceList, Node)) {
      DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);

      if ((DeviceInfo->Type == EfiIdeHarddisk) &&
          (DeviceInfo->Port == Port))
      {
        *PortMultiplierPort = DeviceInfo->PortMultiplier;
        goto Exit;
      }

      Node = GetNextNode (&Instance->DeviceList, Node);
    }

    return EFI_NOT_FOUND;
  } else {
    //
    // PortMultiplierPort is not equal to 0xFFFF and also not equal to previous return value
    //
    return EFI_INVALID_PARAMETER;
  }

Exit:
  //
  // Update the PreviousPort and PreviousPortMultiplier.
  //
  Instance->PreviousPortMultiplier = *PortMultiplierPort;

  return EFI_SUCCESS;
}

/**
  Used to allocate and build a device path node for an ATA device on an ATA controller.

  The BuildDevicePath() function allocates and builds a single device node for the ATA
  device specified by Port and PortMultiplierPort. If the ATA device specified by Port and
  PortMultiplierPort is not present on the ATA controller, then EFI_NOT_FOUND is returned.
  If DevicePath is NULL, then EFI_INVALID_PARAMETER is returned. If there are not enough
  resources to allocate the device path node, then EFI_OUT_OF_RESOURCES is returned.

  Otherwise, DevicePath is allocated with the boot service AllocatePool(), the contents of
  DevicePath are initialized to describe the ATA device specified by Port and PortMultiplierPort,
  and EFI_SUCCESS is returned.

  @param[in]      This               A pointer to the EFI_ATA_PASS_THRU_PROTOCOL instance.
  @param[in]      Port               Port specifies the port number of the ATA device for which a
                                     device path node is to be allocated and built.
  @param[in]      PortMultiplierPort The port multiplier port number of the ATA device for which a
                                     device path node is to be allocated and built. If there is no
                                     port multiplier, then specify 0xFFFF.
  @param[in, out] DevicePath         A pointer to a single device path node that describes the ATA
                                     device specified by Port and PortMultiplierPort. This function
                                     is responsible for allocating the buffer DevicePath with the
                                     boot service AllocatePool(). It is the caller's responsibility
                                     to free DevicePath when the caller is finished with DevicePath.
  @retval EFI_SUCCESS                The device path node that describes the ATA device specified by
                                     Port and PortMultiplierPort was allocated and returned in DevicePath.
  @retval EFI_NOT_FOUND              The ATA device specified by Port and PortMultiplierPort does not
                                     exist on the ATA controller.
  @retval EFI_INVALID_PARAMETER      DevicePath is NULL.
  @retval EFI_OUT_OF_RESOURCES       There are not enough resources to allocate DevicePath.

**/
EFI_STATUS
EFIAPI
AtaPassThruBuildDevicePath (
  IN     EFI_ATA_PASS_THRU_PROTOCOL  *This,
  IN     UINT16                      Port,
  IN     UINT16                      PortMultiplierPort,
  IN OUT EFI_DEVICE_PATH_PROTOCOL    **DevicePath
  )
{
  EFI_DEV_PATH                  *DevicePathNode;
  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance;
  LIST_ENTRY                    *Node;

  Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);

  //
  // Validate parameters passed in.
  //
  if (DevicePath == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Node = SearchDeviceInfoList (Instance, Port, PortMultiplierPort, EfiIdeHarddisk);
  if (Node == NULL) {
    return EFI_NOT_FOUND;
  }

  if (Instance->Mode == EfiAtaIdeMode) {
    DevicePathNode = AllocateCopyPool (sizeof (ATAPI_DEVICE_PATH), &mAtapiDevicePathTemplate);
    if (DevicePathNode == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    DevicePathNode->Atapi.PrimarySecondary = (UINT8)Port;
    DevicePathNode->Atapi.SlaveMaster      = (UINT8)PortMultiplierPort;
    DevicePathNode->Atapi.Lun              = 0;
  } else {
    DevicePathNode = AllocateCopyPool (sizeof (SATA_DEVICE_PATH), &mSataDevicePathTemplate);
    if (DevicePathNode == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    DevicePathNode->Sata.HBAPortNumber            = Port;
    DevicePathNode->Sata.PortMultiplierPortNumber = PortMultiplierPort;
    DevicePathNode->Sata.Lun                      = 0;
  }

  *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePathNode;

  return EFI_SUCCESS;
}

/**
  Used to translate a device path node to a port number and port multiplier port number.

  The GetDevice() function determines the port and port multiplier port number associated with
  the ATA device described by DevicePath. If DevicePath is a device path node type that the
  ATA Pass Thru driver supports, then the ATA Pass Thru driver will attempt to translate the contents
  DevicePath into a port number and port multiplier port number.

  If this translation is successful, then that port number and port multiplier port number are returned
  in Port and PortMultiplierPort, and EFI_SUCCESS is returned.

  If DevicePath, Port, or PortMultiplierPort are NULL, then EFI_INVALID_PARAMETER is returned.

  If DevicePath is not a device path node type that the ATA Pass Thru driver supports, then
  EFI_UNSUPPORTED is returned.

  If DevicePath is a device path node type that the ATA Pass Thru driver supports, but there is not
  a valid translation from DevicePath to a port number and port multiplier port number, then
  EFI_NOT_FOUND is returned.

  @param[in]  This                A pointer to the EFI_ATA_PASS_THRU_PROTOCOL instance.
  @param[in]  DevicePath          A pointer to the device path node that describes an ATA device on the
                                  ATA controller.
  @param[out] Port                On return, points to the port number of an ATA device on the ATA controller.
  @param[out] PortMultiplierPort  On return, points to the port multiplier port number of an ATA device
                                  on the ATA controller.

  @retval EFI_SUCCESS             DevicePath was successfully translated to a port number and port multiplier
                                  port number, and they were returned in Port and PortMultiplierPort.
  @retval EFI_INVALID_PARAMETER   DevicePath is NULL.
  @retval EFI_INVALID_PARAMETER   Port is NULL.
  @retval EFI_INVALID_PARAMETER   PortMultiplierPort is NULL.
  @retval EFI_UNSUPPORTED         This driver does not support the device path node type in DevicePath.
  @retval EFI_NOT_FOUND           A valid translation from DevicePath to a port number and port multiplier
                                  port number does not exist.
**/
EFI_STATUS
EFIAPI
AtaPassThruGetDevice (
  IN  EFI_ATA_PASS_THRU_PROTOCOL  *This,
  IN  EFI_DEVICE_PATH_PROTOCOL    *DevicePath,
  OUT UINT16                      *Port,
  OUT UINT16                      *PortMultiplierPort
  )
{
  EFI_DEV_PATH                  *DevicePathNode;
  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance;
  LIST_ENTRY                    *Node;

  Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);

  //
  // Validate parameters passed in.
  //
  if ((DevicePath == NULL) || (Port == NULL) || (PortMultiplierPort == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check whether the DevicePath belongs to SCSI_DEVICE_PATH or ATAPI_DEVICE_PATH
  //
  if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
      ((DevicePath->SubType != MSG_SATA_DP) &&
       (DevicePath->SubType != MSG_ATAPI_DP)) ||
      ((DevicePathNodeLength (DevicePath) != sizeof (ATAPI_DEVICE_PATH)) &&
       (DevicePathNodeLength (DevicePath) != sizeof (SATA_DEVICE_PATH))))
  {
    return EFI_UNSUPPORTED;
  }

  DevicePathNode = (EFI_DEV_PATH *)DevicePath;

  if (Instance->Mode == EfiAtaIdeMode) {
    *Port               = DevicePathNode->Atapi.PrimarySecondary;
    *PortMultiplierPort = DevicePathNode->Atapi.SlaveMaster;
  } else {
    *Port               = DevicePathNode->Sata.HBAPortNumber;
    *PortMultiplierPort = DevicePathNode->Sata.PortMultiplierPortNumber;
  }

  Node = SearchDeviceInfoList (Instance, *Port, *PortMultiplierPort, EfiIdeHarddisk);

  if (Node == NULL) {
    return EFI_NOT_FOUND;
  }

  return EFI_SUCCESS;
}

/**
  Resets a specific port on the ATA controller. This operation also resets all the ATA devices
  connected to the port.

  The ResetChannel() function resets an a specific port on an ATA controller. This operation
  resets all the ATA devices connected to that port. If this ATA controller does not support
  a reset port operation, then EFI_UNSUPPORTED is returned.

  If a device error occurs while executing that port reset operation, then EFI_DEVICE_ERROR is
  returned.

  If a timeout occurs during the execution of the port reset operation, then EFI_TIMEOUT is returned.

  If the port reset operation is completed, then EFI_SUCCESS is returned.

  @param[in]  This          A pointer to the EFI_ATA_PASS_THRU_PROTOCOL instance.
  @param[in]  Port          The port number on the ATA controller.

  @retval EFI_SUCCESS       The ATA controller port was reset.
  @retval EFI_UNSUPPORTED   The ATA controller does not support a port reset operation.
  @retval EFI_DEVICE_ERROR  A device error occurred while attempting to reset the ATA port.
  @retval EFI_TIMEOUT       A timeout occurred while attempting to reset the ATA port.

**/
EFI_STATUS
EFIAPI
AtaPassThruResetPort (
  IN EFI_ATA_PASS_THRU_PROTOCOL  *This,
  IN UINT16                      Port
  )
{
  //
  // Return success directly then upper layer driver could think reset port operation is done.
  //
  return EFI_SUCCESS;
}

/**
  Resets an ATA device that is connected to an ATA controller.

  The ResetDevice() function resets the ATA device specified by Port and PortMultiplierPort.
  If this ATA controller does not support a device reset operation, then EFI_UNSUPPORTED is
  returned.

  If Port or PortMultiplierPort are not in a valid range for this ATA controller, then
  EFI_INVALID_PARAMETER is returned.

  If a device error occurs while executing that device reset operation, then EFI_DEVICE_ERROR
  is returned.

  If a timeout occurs during the execution of the device reset operation, then EFI_TIMEOUT is
  returned.

  If the device reset operation is completed, then EFI_SUCCESS is returned.

  @param[in] This                A pointer to the EFI_ATA_PASS_THRU_PROTOCOL instance.
  @param[in] Port                Port represents the port number of the ATA device to be reset.
  @param[in] PortMultiplierPort  The port multiplier port number of the ATA device to reset.
                                 If there is no port multiplier, then specify 0xFFFF.
  @retval EFI_SUCCESS            The ATA device specified by Port and PortMultiplierPort was reset.
  @retval EFI_UNSUPPORTED        The ATA controller does not support a device reset operation.
  @retval EFI_INVALID_PARAMETER  Port or PortMultiplierPort are invalid.
  @retval EFI_DEVICE_ERROR       A device error occurred while attempting to reset the ATA device
                                 specified by Port and PortMultiplierPort.
  @retval EFI_TIMEOUT            A timeout occurred while attempting to reset the ATA device
                                 specified by Port and PortMultiplierPort.

**/
EFI_STATUS
EFIAPI
AtaPassThruResetDevice (
  IN EFI_ATA_PASS_THRU_PROTOCOL  *This,
  IN UINT16                      Port,
  IN UINT16                      PortMultiplierPort
  )
{
  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance;
  LIST_ENTRY                    *Node;

  Instance = ATA_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);

  Node = SearchDeviceInfoList (Instance, Port, PortMultiplierPort, EfiIdeHarddisk);

  if (Node == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Return success directly then upper layer driver could think reset device operation is done.
  //
  return EFI_SUCCESS;
}

/**
  Submit ATAPI request sense command.

  @param[in] This            A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
  @param[in] Target          The Target is an array of size TARGET_MAX_BYTES and it represents
                             the id of the SCSI device to send the SCSI Request Packet. Each
                             transport driver may choose to utilize a subset of this size to suit the needs
                             of transport target representation. For example, a Fibre Channel driver
                             may use only 8 bytes (WWN) to represent an FC target.
  @param[in] Lun             The LUN of the SCSI device to send the SCSI Request Packet.
  @param[in] SenseData       A pointer to store sense data.
  @param[in] SenseDataLength The sense data length.
  @param[in] Timeout         The timeout value to execute this cmd, uses 100ns as a unit.

  @retval EFI_SUCCESS        Send out the ATAPI packet command successfully.
  @retval EFI_DEVICE_ERROR   The device failed to send data.

**/
EFI_STATUS
EFIAPI
AtaPacketRequestSense (
  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN  UINT8                            *Target,
  IN  UINT64                           Lun,
  IN  VOID                             *SenseData,
  IN  UINT8                            SenseDataLength,
  IN  UINT64                           Timeout
  )
{
  EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  Packet;
  UINT8                                       Cdb[12];
  EFI_STATUS                                  Status;

  ZeroMem (&Packet, sizeof (EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET));
  ZeroMem (Cdb, 12);

  Cdb[0] = ATA_CMD_REQUEST_SENSE;
  Cdb[4] = SenseDataLength;

  Packet.Timeout          = Timeout;
  Packet.Cdb              = Cdb;
  Packet.CdbLength        = 12;
  Packet.DataDirection    = EFI_EXT_SCSI_DATA_DIRECTION_READ;
  Packet.InDataBuffer     = SenseData;
  Packet.InTransferLength = SenseDataLength;

  Status = ExtScsiPassThruPassThru (This, Target, Lun, &Packet, NULL);

  return Status;
}

/**
  Sends a SCSI Request Packet to a SCSI device that is attached to the SCSI channel. This function
  supports both blocking I/O and nonblocking I/O. The blocking I/O functionality is required, and the
  nonblocking I/O functionality is optional.

  @param  This    A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
  @param  Target  The Target is an array of size TARGET_MAX_BYTES and it represents
                  the id of the SCSI device to send the SCSI Request Packet. Each
                  transport driver may choose to utilize a subset of this size to suit the needs
                  of transport target representation. For example, a Fibre Channel driver
                  may use only 8 bytes (WWN) to represent an FC target.
  @param  Lun     The LUN of the SCSI device to send the SCSI Request Packet.
  @param  Packet  A pointer to the SCSI Request Packet to send to the SCSI device
                  specified by Target and Lun.
  @param  Event   If nonblocking I/O is not supported then Event is ignored, and blocking
                  I/O is performed. If Event is NULL, then blocking I/O is performed. If
                  Event is not NULL and non blocking I/O is supported, then
                  nonblocking I/O is performed, and Event will be signaled when the
                  SCSI Request Packet completes.

  @retval EFI_SUCCESS           The SCSI Request Packet was sent by the host. For bi-directional
                                commands, InTransferLength bytes were transferred from
                                InDataBuffer. For write and bi-directional commands,
                                OutTransferLength bytes were transferred by
                                OutDataBuffer.
  @retval EFI_BAD_BUFFER_SIZE   The SCSI Request Packet was not executed. The number of bytes that
                                could be transferred is returned in InTransferLength. For write
                                and bi-directional commands, OutTransferLength bytes were
                                transferred by OutDataBuffer.
  @retval EFI_NOT_READY         The SCSI Request Packet could not be sent because there are too many
                                SCSI Request Packets already queued. The caller may retry again later.
  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to send the SCSI Request
                                Packet.
  @retval EFI_INVALID_PARAMETER Target, Lun, or the contents of ScsiRequestPacket are invalid.
  @retval EFI_UNSUPPORTED       The command described by the SCSI Request Packet is not supported
                                by the host adapter. This includes the case of Bi-directional SCSI
                                commands not supported by the implementation. The SCSI Request
                                Packet was not sent, so no additional status information is available.
  @retval EFI_TIMEOUT           A timeout occurred while waiting for the SCSI Request Packet to execute.

**/
EFI_STATUS
EFIAPI
ExtScsiPassThruPassThru (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL                 *This,
  IN UINT8                                           *Target,
  IN UINT64                                          Lun,
  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet,
  IN EFI_EVENT                                       Event OPTIONAL
  )
{
  EFI_STATUS                    Status;
  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance;
  UINT8                         Port;
  UINT8                         PortMultiplier;
  EFI_ATA_HC_WORK_MODE          Mode;
  LIST_ENTRY                    *Node;
  EFI_ATA_DEVICE_INFO           *DeviceInfo;
  BOOLEAN                       SenseReq;
  EFI_SCSI_SENSE_DATA           *PtrSenseData;
  UINTN                         SenseDataLen;
  EFI_STATUS                    SenseStatus;

  SenseDataLen = 0;
  Instance     = EXT_SCSI_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);

  if ((Packet == NULL) || (Packet->Cdb == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Don't support variable length CDB
  //
  if ((Packet->CdbLength != 6) && (Packet->CdbLength != 10) &&
      (Packet->CdbLength != 12) && (Packet->CdbLength != 16))
  {
    return EFI_INVALID_PARAMETER;
  }

  if ((Packet->SenseDataLength != 0) && (Packet->SenseData == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->InDataBuffer, This->Mode->IoAlign)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->OutDataBuffer, This->Mode->IoAlign)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((This->Mode->IoAlign > 1) && !ADDRESS_IS_ALIGNED (Packet->SenseData, This->Mode->IoAlign)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // For ATAPI device, doesn't support multiple LUN device.
  //
  if (Lun != 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // The layout of Target array:
  //  ________________________________________________________________________
  // |       Byte 0        |       Byte 1        | ... | TARGET_MAX_BYTES - 1 |
  // |_____________________|_____________________|_____|______________________|
  // |                     | The port multiplier |     |                      |
  // |   The port number   |    port number      | N/A |         N/A          |
  // |_____________________|_____________________|_____|______________________|
  //
  // For ATAPI device, 2 bytes is enough to represent the location of SCSI device.
  //
  Port           = Target[0];
  PortMultiplier = Target[1];

  Node = SearchDeviceInfoList (Instance, Port, PortMultiplier, EfiIdeCdrom);
  if (Node == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);

  //
  // ATA_CMD_IDENTIFY_DEVICE cmd is a ATA cmd but not a SCSI cmd.
  // Normally it should NOT be passed down through ExtScsiPassThru protocol interface.
  // But to response EFI_DISK_INFO.Identify() request from ScsiDisk, we should handle this command.
  //
  if (*((UINT8 *)Packet->Cdb) == ATA_CMD_IDENTIFY_DEVICE) {
    CopyMem (Packet->InDataBuffer, DeviceInfo->IdentifyData, sizeof (EFI_IDENTIFY_DATA));
    //
    // For IDENTIFY DEVICE cmd, we don't need to get sense data.
    //
    Packet->SenseDataLength = 0;
    return EFI_SUCCESS;
  }

  Mode = Instance->Mode;
  switch (Mode) {
    case EfiAtaIdeMode:
      //
      // Reassign IDE mode io port registers' base addresses
      //
      Status = GetIdeRegisterIoAddr (Instance->PciIo, Instance->IdeRegisters);

      if (EFI_ERROR (Status)) {
        return Status;
      }

      Status = AtaPacketCommandExecute (Instance->PciIo, &Instance->IdeRegisters[Port], Port, PortMultiplier, Packet);
      break;
    case EfiAtaAhciMode:
      if (PortMultiplier == 0xFF) {
        //
        // If there is no port multiplier, the PortMultiplier will be 0xFF
        // Here, we convert its value to 0 to follow the AHCI spec.
        //
        PortMultiplier = 0;
      }

      Status = AhciPacketCommandExecute (Instance->PciIo, &Instance->AhciRegisters, Port, PortMultiplier, Packet);
      break;
    default:
      Status = EFI_DEVICE_ERROR;
      break;
  }

  //
  // If the cmd doesn't get executed correctly, then check sense data.
  //
  if (EFI_ERROR (Status) && (Packet->SenseDataLength != 0) && (*((UINT8 *)Packet->Cdb) != ATA_CMD_REQUEST_SENSE)) {
    PtrSenseData = AllocateAlignedPages (EFI_SIZE_TO_PAGES (sizeof (EFI_SCSI_SENSE_DATA)), This->Mode->IoAlign);
    if (PtrSenseData == NULL) {
      return EFI_DEVICE_ERROR;
    }

    for (SenseReq = TRUE; SenseReq;) {
      SenseStatus = AtaPacketRequestSense (
                      This,
                      Target,
                      Lun,
                      PtrSenseData,
                      sizeof (EFI_SCSI_SENSE_DATA),
                      Packet->Timeout
                      );
      if (EFI_ERROR (SenseStatus)) {
        break;
      }

      CopyMem ((UINT8 *)Packet->SenseData + SenseDataLen, PtrSenseData, sizeof (EFI_SCSI_SENSE_DATA));
      SenseDataLen += sizeof (EFI_SCSI_SENSE_DATA);

      //
      // no more sense key or number of sense keys exceeds predefined,
      // skip the loop.
      //
      if ((PtrSenseData->Sense_Key == EFI_SCSI_SK_NO_SENSE) ||
          (SenseDataLen + sizeof (EFI_SCSI_SENSE_DATA) > Packet->SenseDataLength))
      {
        SenseReq = FALSE;
      }
    }

    FreeAlignedPages (PtrSenseData, EFI_SIZE_TO_PAGES (sizeof (EFI_SCSI_SENSE_DATA)));
  }

  //
  // Update the SenseDataLength field to the data length received.
  //
  Packet->SenseDataLength = (UINT8)SenseDataLen;
  return Status;
}

/**
  Used to retrieve the list of legal Target IDs and LUNs for SCSI devices on a SCSI channel. These
  can either be the list SCSI devices that are actually present on the SCSI channel, or the list of legal
  Target Ids and LUNs for the SCSI channel. Regardless, the caller of this function must probe the
  Target ID and LUN returned to see if a SCSI device is actually present at that location on the SCSI
  channel.

  @param  This   A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
  @param  Target On input, a pointer to the Target ID (an array of size
                 TARGET_MAX_BYTES) of a SCSI device present on the SCSI channel.
                 On output, a pointer to the Target ID (an array of
                 TARGET_MAX_BYTES) of the next SCSI device present on a SCSI
                 channel. An input value of 0xF(all bytes in the array are 0xF) in the
                 Target array retrieves the Target ID of the first SCSI device present on a
                 SCSI channel.
  @param  Lun    On input, a pointer to the LUN of a SCSI device present on the SCSI
                 channel. On output, a pointer to the LUN of the next SCSI device present
                 on a SCSI channel.

  @retval EFI_SUCCESS           The Target ID and LUN of the next SCSI device on the SCSI
                                channel was returned in Target and Lun.
  @retval EFI_INVALID_PARAMETER Target array is not all 0xF, and Target and Lun were
                                not returned on a previous call to GetNextTargetLun().
  @retval EFI_NOT_FOUND         There are no more SCSI devices on this SCSI channel.

**/
EFI_STATUS
EFIAPI
ExtScsiPassThruGetNextTargetLun (
  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN OUT UINT8                         **Target,
  IN OUT UINT64                        *Lun
  )
{
  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance;
  LIST_ENTRY                    *Node;
  EFI_ATA_DEVICE_INFO           *DeviceInfo;
  UINT8                         *Target8;
  UINT16                        *Target16;

  Instance = EXT_SCSI_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);

  if ((Target == NULL) || (Lun == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (*Target == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Target8  = *Target;
  Target16 = (UINT16 *)*Target;

  if (CompareMem (Target8, mScsiId, TARGET_MAX_BYTES) != 0) {
    //
    // For ATAPI device, we use 2 least significant bytes to represent the location of SCSI device.
    // So the higher bytes in Target array should be 0xFF.
    //
    if (CompareMem (&Target8[2], &mScsiId[2], TARGET_MAX_BYTES - 2) != 0) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // When Target is not all 0xFF's, compare 2 least significant bytes with
    // previous target id to see if it is returned by previous call.
    //
    if ((*Target16 != Instance->PreviousTargetId) ||
        (*Lun != Instance->PreviousLun))
    {
      return EFI_INVALID_PARAMETER;
    }

    //
    // Traverse the whole device list to find the next cdrom closed to
    // the device signified by Target[0] and Target[1].
    //
    // Note that we here use a tricky way to find the next cdrom :
    // All ata devices are detected and inserted into the device list
    // sequentially.
    //
    Node = GetFirstNode (&Instance->DeviceList);

    while (!IsNull (&Instance->DeviceList, Node)) {
      DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);

      if ((DeviceInfo->Type == EfiIdeCdrom) &&
          ((Target8[0] < DeviceInfo->Port) ||
           ((Target8[0] == DeviceInfo->Port) &&
            (Target8[1] < (UINT8)DeviceInfo->PortMultiplier))))
      {
        Target8[0] = (UINT8)DeviceInfo->Port;
        Target8[1] = (UINT8)DeviceInfo->PortMultiplier;
        goto Exit;
      }

      Node = GetNextNode (&Instance->DeviceList, Node);
    }

    return EFI_NOT_FOUND;
  } else {
    //
    // If the array is all 0xFF's, start to traverse the device list from the beginning
    //
    Node = GetFirstNode (&Instance->DeviceList);
    while (!IsNull (&Instance->DeviceList, Node)) {
      DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);

      if (DeviceInfo->Type == EfiIdeCdrom) {
        Target8[0] = (UINT8)DeviceInfo->Port;
        Target8[1] = (UINT8)DeviceInfo->PortMultiplier;
        goto Exit;
      }

      Node = GetNextNode (&Instance->DeviceList, Node);
    }

    return EFI_NOT_FOUND;
  }

Exit:
  *Lun = 0;

  //
  // Update the PreviousTargetId.
  //
  Instance->PreviousTargetId = *Target16;
  Instance->PreviousLun      = *Lun;

  return EFI_SUCCESS;
}

/**
  Used to allocate and build a device path node for a SCSI device on a SCSI channel.

  @param  This       A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
  @param  Target     The Target is an array of size TARGET_MAX_BYTES and it specifies the
                     Target ID of the SCSI device for which a device path node is to be
                     allocated and built. Transport drivers may chose to utilize a subset of
                     this size to suit the representation of targets. For example, a Fibre
                     Channel driver may use only 8 bytes (WWN) in the array to represent a
                     FC target.
  @param  Lun        The LUN of the SCSI device for which a device path node is to be
                     allocated and built.
  @param  DevicePath A pointer to a single device path node that describes the SCSI device
                     specified by Target and Lun. This function is responsible for
                     allocating the buffer DevicePath with the boot service
                     AllocatePool(). It is the caller's responsibility to free
                     DevicePath when the caller is finished with DevicePath.

  @retval EFI_SUCCESS           The device path node that describes the SCSI device specified by
                                Target and Lun was allocated and returned in
                                DevicePath.
  @retval EFI_INVALID_PARAMETER DevicePath is NULL.
  @retval EFI_NOT_FOUND         The SCSI devices specified by Target and Lun does not exist
                                on the SCSI channel.
  @retval EFI_OUT_OF_RESOURCES  There are not enough resources to allocate DevicePath.

**/
EFI_STATUS
EFIAPI
ExtScsiPassThruBuildDevicePath (
  IN     EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN     UINT8                            *Target,
  IN     UINT64                           Lun,
  IN OUT EFI_DEVICE_PATH_PROTOCOL         **DevicePath
  )
{
  EFI_DEV_PATH                  *DevicePathNode;
  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance;
  UINT8                         Port;
  UINT8                         PortMultiplier;

  Instance = EXT_SCSI_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);

  Port           = Target[0];
  PortMultiplier = Target[1];

  //
  // Validate parameters passed in.
  //
  if (DevicePath == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // can not build device path for the SCSI Host Controller.
  //
  if (Lun != 0) {
    return EFI_NOT_FOUND;
  }

  if (SearchDeviceInfoList (Instance, Port, PortMultiplier, EfiIdeCdrom) == NULL) {
    return EFI_NOT_FOUND;
  }

  if (Instance->Mode == EfiAtaIdeMode) {
    DevicePathNode = AllocateCopyPool (sizeof (ATAPI_DEVICE_PATH), &mAtapiDevicePathTemplate);
    if (DevicePathNode == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    DevicePathNode->Atapi.PrimarySecondary = Port;
    DevicePathNode->Atapi.SlaveMaster      = PortMultiplier;
    DevicePathNode->Atapi.Lun              = (UINT16)Lun;
  } else {
    DevicePathNode = AllocateCopyPool (sizeof (SATA_DEVICE_PATH), &mSataDevicePathTemplate);
    if (DevicePathNode == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    DevicePathNode->Sata.HBAPortNumber = Port;
    //
    // For CD-ROM working in the AHCI mode, only 8 bits are used to record
    // the PortMultiplier information. If the CD-ROM is directly attached
    // on a SATA port, the PortMultiplier should be translated from 0xFF
    // to 0xFFFF according to the UEFI spec.
    //
    DevicePathNode->Sata.PortMultiplierPortNumber = PortMultiplier == 0xFF ? 0xFFFF : PortMultiplier;
    DevicePathNode->Sata.Lun                      = (UINT16)Lun;
  }

  *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePathNode;

  return EFI_SUCCESS;
}

/**
  Used to translate a device path node to a Target ID and LUN.

  @param  This       A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
  @param  DevicePath A pointer to a single device path node that describes the SCSI device
                     on the SCSI channel.
  @param  Target     A pointer to the Target Array which represents the ID of a SCSI device
                     on the SCSI channel.
  @param  Lun        A pointer to the LUN of a SCSI device on the SCSI channel.

  @retval EFI_SUCCESS           DevicePath was successfully translated to a Target ID and
                                LUN, and they were returned in Target and Lun.
  @retval EFI_INVALID_PARAMETER DevicePath or Target or Lun is NULL.
  @retval EFI_NOT_FOUND         A valid translation from DevicePath to a Target ID and LUN
                                does not exist.
  @retval EFI_UNSUPPORTED       This driver does not support the device path node type in
                                 DevicePath.

**/
EFI_STATUS
EFIAPI
ExtScsiPassThruGetTargetLun (
  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN  EFI_DEVICE_PATH_PROTOCOL         *DevicePath,
  OUT UINT8                            **Target,
  OUT UINT64                           *Lun
  )
{
  EFI_DEV_PATH                  *DevicePathNode;
  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance;
  LIST_ENTRY                    *Node;

  Instance = EXT_SCSI_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);

  //
  // Validate parameters passed in.
  //
  if ((DevicePath == NULL) || (Target == NULL) || (Lun == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (*Target == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check whether the DevicePath belongs to SCSI_DEVICE_PATH
  //
  if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
      ((DevicePath->SubType != MSG_ATAPI_DP) &&
       (DevicePath->SubType != MSG_SATA_DP)) ||
      ((DevicePathNodeLength (DevicePath) != sizeof (ATAPI_DEVICE_PATH)) &&
       (DevicePathNodeLength (DevicePath) != sizeof (SATA_DEVICE_PATH))))
  {
    return EFI_UNSUPPORTED;
  }

  SetMem (*Target, TARGET_MAX_BYTES, 0xFF);

  DevicePathNode = (EFI_DEV_PATH *)DevicePath;

  if (Instance->Mode == EfiAtaIdeMode) {
    (*Target)[0] = (UINT8)DevicePathNode->Atapi.PrimarySecondary;
    (*Target)[1] = (UINT8)DevicePathNode->Atapi.SlaveMaster;
    *Lun         = (UINT8)DevicePathNode->Atapi.Lun;
  } else {
    (*Target)[0] = (UINT8)DevicePathNode->Sata.HBAPortNumber;
    (*Target)[1] = (UINT8)DevicePathNode->Sata.PortMultiplierPortNumber;
    *Lun         = (UINT8)DevicePathNode->Sata.Lun;
  }

  Node = SearchDeviceInfoList (Instance, (*Target)[0], (*Target)[1], EfiIdeCdrom);

  if (Node == NULL) {
    return EFI_NOT_FOUND;
  }

  if (*Lun != 0) {
    return EFI_NOT_FOUND;
  }

  return EFI_SUCCESS;
}

/**
  Resets a SCSI channel. This operation resets all the SCSI devices connected to the SCSI channel.

  @param  This A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.

  @retval EFI_SUCCESS      The SCSI channel was reset.
  @retval EFI_DEVICE_ERROR A device error occurred while attempting to reset the SCSI channel.
  @retval EFI_TIMEOUT      A timeout occurred while attempting to reset the SCSI channel.
  @retval EFI_UNSUPPORTED  The SCSI channel does not support a channel reset operation.

**/
EFI_STATUS
EFIAPI
ExtScsiPassThruResetChannel (
  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This
  )
{
  //
  // Return success directly then upper layer driver could think reset channel operation is done.
  //
  return EFI_SUCCESS;
}

/**
  Resets a SCSI logical unit that is connected to a SCSI channel.

  @param  This   A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
  @param  Target The Target is an array of size TARGET_MAX_BYTE and it represents the
                 target port ID of the SCSI device containing the SCSI logical unit to
                 reset. Transport drivers may chose to utilize a subset of this array to suit
                 the representation of their targets.
  @param  Lun    The LUN of the SCSI device to reset.

  @retval EFI_SUCCESS           The SCSI device specified by Target and Lun was reset.
  @retval EFI_INVALID_PARAMETER Target or Lun is NULL.
  @retval EFI_TIMEOUT           A timeout occurred while attempting to reset the SCSI device
                                specified by Target and Lun.
  @retval EFI_UNSUPPORTED       The SCSI channel does not support a target reset operation.
  @retval EFI_DEVICE_ERROR      A device error occurred while attempting to reset the SCSI device
                                 specified by Target and Lun.

**/
EFI_STATUS
EFIAPI
ExtScsiPassThruResetTargetLun (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN UINT8                            *Target,
  IN UINT64                           Lun
  )
{
  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance;
  LIST_ENTRY                    *Node;
  UINT8                         Port;
  UINT8                         PortMultiplier;

  Instance = EXT_SCSI_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);
  //
  // For ATAPI device, doesn't support multiple LUN device.
  //
  if (Lun != 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // The layout of Target array:
  //  ________________________________________________________________________
  // |       Byte 0        |       Byte 1        | ... | TARGET_MAX_BYTES - 1 |
  // |_____________________|_____________________|_____|______________________|
  // |                     | The port multiplier |     |                      |
  // |   The port number   |    port number      | N/A |         N/A          |
  // |_____________________|_____________________|_____|______________________|
  //
  // For ATAPI device, 2 bytes is enough to represent the location of SCSI device.
  //
  Port           = Target[0];
  PortMultiplier = Target[1];

  Node = SearchDeviceInfoList (Instance, Port, PortMultiplier, EfiIdeCdrom);
  if (Node == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Return success directly then upper layer driver could think reset target LUN operation is done.
  //
  return EFI_SUCCESS;
}

/**
  Used to retrieve the list of legal Target IDs for SCSI devices on a SCSI channel. These can either
  be the list SCSI devices that are actually present on the SCSI channel, or the list of legal Target IDs
  for the SCSI channel. Regardless, the caller of this function must probe the Target ID returned to
  see if a SCSI device is actually present at that location on the SCSI channel.

  @param  This   A pointer to the EFI_EXT_SCSI_PASS_THRU_PROTOCOL instance.
  @param  Target (TARGET_MAX_BYTES) of a SCSI device present on the SCSI channel.
                 On output, a pointer to the Target ID (an array of
                 TARGET_MAX_BYTES) of the next SCSI device present on a SCSI
                 channel. An input value of 0xF(all bytes in the array are 0xF) in the
                 Target array retrieves the Target ID of the first SCSI device present on a
                 SCSI channel.

  @retval EFI_SUCCESS           The Target ID of the next SCSI device on the SCSI
                                channel was returned in Target.
  @retval EFI_INVALID_PARAMETER Target or Lun is NULL.
  @retval EFI_TIMEOUT           Target array is not all 0xF, and Target was not
                                returned on a previous call to GetNextTarget().
  @retval EFI_NOT_FOUND         There are no more SCSI devices on this SCSI channel.

**/
EFI_STATUS
EFIAPI
ExtScsiPassThruGetNextTarget (
  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN OUT UINT8                         **Target
  )
{
  ATA_ATAPI_PASS_THRU_INSTANCE  *Instance;
  LIST_ENTRY                    *Node;
  EFI_ATA_DEVICE_INFO           *DeviceInfo;
  UINT8                         *Target8;
  UINT16                        *Target16;

  Instance = EXT_SCSI_PASS_THRU_PRIVATE_DATA_FROM_THIS (This);

  if ((Target == NULL) || (*Target == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Target8  = *Target;
  Target16 = (UINT16 *)*Target;

  if (CompareMem (Target8, mScsiId, TARGET_MAX_BYTES) != 0) {
    //
    // For ATAPI device, we use 2 least significant bytes to represent the location of SCSI device.
    // So the higher bytes in Target array should be 0xFF.
    //
    if (CompareMem (&Target8[2], &mScsiId[2], TARGET_MAX_BYTES - 2) != 0) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // When Target is not all 0xFF's, compare 2 least significant bytes with
    // previous target id to see if it is returned by previous call.
    //
    if (*Target16 != Instance->PreviousTargetId) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // Traverse the whole device list to find the next cdrom closed to
    // the device signified by Target[0] and Target[1].
    //
    // Note that we here use a tricky way to find the next cdrom :
    // All ata devices are detected and inserted into the device list
    // sequentially.
    //
    Node = GetFirstNode (&Instance->DeviceList);
    while (!IsNull (&Instance->DeviceList, Node)) {
      DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);

      if ((DeviceInfo->Type == EfiIdeCdrom) &&
          ((Target8[0] < DeviceInfo->Port) ||
           ((Target8[0] == DeviceInfo->Port) &&
            (Target8[1] < (UINT8)DeviceInfo->PortMultiplier))))
      {
        Target8[0] = (UINT8)DeviceInfo->Port;
        Target8[1] = (UINT8)DeviceInfo->PortMultiplier;
        goto Exit;
      }

      Node = GetNextNode (&Instance->DeviceList, Node);
    }

    return EFI_NOT_FOUND;
  } else {
    //
    // If the array is all 0xFF's, start to traverse the device list from the beginning
    //
    Node = GetFirstNode (&Instance->DeviceList);

    while (!IsNull (&Instance->DeviceList, Node)) {
      DeviceInfo = ATA_ATAPI_DEVICE_INFO_FROM_THIS (Node);

      if (DeviceInfo->Type == EfiIdeCdrom) {
        Target8[0] = (UINT8)DeviceInfo->Port;
        Target8[1] = (UINT8)DeviceInfo->PortMultiplier;
        goto Exit;
      }

      Node = GetNextNode (&Instance->DeviceList, Node);
    }

    return EFI_NOT_FOUND;
  }

Exit:
  //
  // Update the PreviousTargetId.
  //
  Instance->PreviousTargetId = *Target16;

  return EFI_SUCCESS;
}
