/** @file
  This file implements ATA_PASSTHRU_PROCTOCOL and EXT_SCSI_PASSTHRU_PROTOCOL interfaces
  for managed ATA controllers.

  Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#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,                  // 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
};

/**
  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 Taks from the Taks 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 ingore 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 failded 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                            Supports;
  UINT64                            OriginalPciAttributes;

  Status                = EFI_SUCCESS;
  IdeControllerInit     = NULL;
  Instance              = NULL;
  OriginalPciAttributes = 0;

  DEBUG ((EFI_D_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 ((EFI_D_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 ((EFI_D_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,
                    &Supports
                    );
  if (!EFI_ERROR (Status)) {
    Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
    Status = PciIo->Attributes (
                      PciIo,
                      EfiPciIoAttributeOperationEnable,
                      Supports,
                      NULL
                      );
  }

  if (EFI_ERROR (Status)) {
    goto ErrorExit;
  }

  //
  // 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->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);
  }

  //
  // Remove all inserted ATA devices.
  //
  DestroyDeviceInfoList(Instance);

  if (Instance != NULL) {
    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;
  UINT64                            Supports;

  DEBUG ((EFI_D_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);

  //
  // If the current working mode is AHCI mode, then pre-allocated resource
  // for AHCI initialization should be released.
  //
  PciIo = Instance->PciIo;

  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
             );
  }

  //
  // Disable this ATA host controller.
  //
  Status = PciIo->Attributes (
                    PciIo,
                    EfiPciIoAttributeOperationSupported,
                    0,
                    &Supports
                    );
  if (!EFI_ERROR (Status)) {
    Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;
    PciIo->Attributes (
             PciIo,
             EfiPciIoAttributeOperationDisable,
             Supports,
             NULL
             );
  }

  //
  // 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) && !IS_ALIGNED(Packet->InDataBuffer, This->Mode->IoAlign)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((This->Mode->IoAlign > 1) && !IS_ALIGNED(Packet->OutDataBuffer, This->Mode->IoAlign)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((This->Mode->IoAlign > 1) && !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) (((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.

  @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) && !IS_ALIGNED(Packet->InDataBuffer, This->Mode->IoAlign)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((This->Mode->IoAlign > 1) && !IS_ALIGNED(Packet->OutDataBuffer, This->Mode->IoAlign)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((This->Mode->IoAlign > 1) && !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;
}

