/** @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", 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;
}
