/** @file
  This file implements protocol interfaces for ATA bus driver.

  This file implements protocol interfaces: Driver Binding protocol,
  Block IO protocol and DiskInfo protocol.

  Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent


**/

#include "AtaBus.h"

//
// ATA Bus Driver Binding Protocol Instance
//
EFI_DRIVER_BINDING_PROTOCOL  gAtaBusDriverBinding = {
  AtaBusDriverBindingSupported,
  AtaBusDriverBindingStart,
  AtaBusDriverBindingStop,
  0x10,
  NULL,
  NULL
};

//
// Template for ATA Child Device.
//
ATA_DEVICE  gAtaDeviceTemplate = {
  ATA_DEVICE_SIGNATURE,              // Signature
  NULL,                              // Handle
  {                            // BlockIo
    EFI_BLOCK_IO_PROTOCOL_REVISION,
    NULL,
    AtaBlockIoReset,
    AtaBlockIoReadBlocks,
    AtaBlockIoWriteBlocks,
    AtaBlockIoFlushBlocks
  },
  {                            // BlockIo2
    NULL,
    AtaBlockIoResetEx,
    AtaBlockIoReadBlocksEx,
    AtaBlockIoWriteBlocksEx,
    AtaBlockIoFlushBlocksEx
  },
  {                            // BlockMedia
    0,                         // MediaId
    FALSE,                     // RemovableMedia
    TRUE,                      // MediaPresent
    FALSE,                     // LogicPartition
    FALSE,                     // ReadOnly
    FALSE,                     // WritingCache
    0x200,                     // BlockSize
    0,                         // IoAlign
    0,                         // LastBlock
    0,                         // LowestAlignedLba
    1                          // LogicalBlocksPerPhysicalBlock
  },
  {                            // DiskInfo
    EFI_DISK_INFO_IDE_INTERFACE_GUID,
    AtaDiskInfoInquiry,
    AtaDiskInfoIdentify,
    AtaDiskInfoSenseData,
    AtaDiskInfoWhichIde
  },
  NULL,                              // DevicePath
  {
    AtaStorageSecurityReceiveData,
    AtaStorageSecuritySendData
  },
  NULL,                                       // AtaBusDriverData
  0,                                          // Port
  0,                                          // PortMultiplierPort
  { 0,                                     }, // Packet
  {
    { 0 },
  },                                          // Acb
  NULL,                                       // Asb
  FALSE,                                      // UdmaValid
  FALSE,                                      // Lba48Bit
  NULL,                                       // IdentifyData
  NULL,                                       // ControllerNameTable
  { L'\0',                                 }, // ModelName
  { NULL,                            NULL  }, // AtaTaskList
  { NULL,                            NULL  }, // AtaSubTaskList
  FALSE                                       // Abort
};

/**
  Allocates an aligned buffer for ATA device.

  This function allocates an aligned buffer for the ATA device to perform
  ATA pass through operations. The alignment requirement is from ATA pass
  through interface.

  @param  AtaDevice         The ATA child device involved for the operation.
  @param  BufferSize        The request buffer size.

  @return A pointer to the aligned buffer or NULL if the allocation fails.

**/
VOID *
AllocateAlignedBuffer (
  IN ATA_DEVICE  *AtaDevice,
  IN UINTN       BufferSize
  )
{
  return AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), AtaDevice->AtaBusDriverData->AtaPassThru->Mode->IoAlign);
}

/**
  Frees an aligned buffer for ATA device.

  This function frees an aligned buffer for the ATA device to perform
  ATA pass through operations.

  @param  Buffer            The aligned buffer to be freed.
  @param  BufferSize        The request buffer size.

**/
VOID
FreeAlignedBuffer (
  IN VOID   *Buffer,
  IN UINTN  BufferSize
  )
{
  if (Buffer != NULL) {
    FreeAlignedPages (Buffer, EFI_SIZE_TO_PAGES (BufferSize));
  }
}

/**
  Release all the resources allocated for the ATA device.

  This function releases all the resources allocated for the ATA device.

  @param  AtaDevice         The ATA child device involved for the operation.

**/
VOID
ReleaseAtaResources (
  IN ATA_DEVICE  *AtaDevice
  )
{
  ATA_BUS_ASYN_SUB_TASK  *SubTask;
  ATA_BUS_ASYN_TASK      *AtaTask;
  LIST_ENTRY             *Entry;
  LIST_ENTRY             *DelEntry;
  EFI_TPL                OldTpl;

  FreeUnicodeStringTable (AtaDevice->ControllerNameTable);
  FreeAlignedBuffer (AtaDevice->Asb, sizeof (EFI_ATA_STATUS_BLOCK));
  FreeAlignedBuffer (AtaDevice->IdentifyData, sizeof (ATA_IDENTIFY_DATA));
  if (AtaDevice->DevicePath != NULL) {
    FreePool (AtaDevice->DevicePath);
  }

  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
  if (!IsListEmpty (&AtaDevice->AtaSubTaskList)) {
    //
    // Free the Subtask list.
    //
    for (Entry = AtaDevice->AtaSubTaskList.ForwardLink;
         Entry != (&AtaDevice->AtaSubTaskList);
         )
    {
      DelEntry = Entry;
      Entry    = Entry->ForwardLink;
      SubTask  = ATA_ASYN_SUB_TASK_FROM_ENTRY (DelEntry);

      RemoveEntryList (DelEntry);
      FreeAtaSubTask (SubTask);
    }
  }

  if (!IsListEmpty (&AtaDevice->AtaTaskList)) {
    //
    // Free the Subtask list.
    //
    for (Entry = AtaDevice->AtaTaskList.ForwardLink;
         Entry != (&AtaDevice->AtaTaskList);
         )
    {
      DelEntry = Entry;
      Entry    = Entry->ForwardLink;
      AtaTask  = ATA_ASYN_TASK_FROM_ENTRY (DelEntry);

      RemoveEntryList (DelEntry);
      FreePool (AtaTask);
    }
  }

  gBS->RestoreTPL (OldTpl);
  FreePool (AtaDevice);
}

/**
  Registers an ATA device.

  This function allocates an ATA device structure for the ATA device specified by
  Port and PortMultiplierPort if the ATA device is identified as a valid one.
  Then it will create child handle and install Block IO and Disk Info protocol on
  it.

  @param  AtaBusDriverData      The parent ATA bus driver data structure.
  @param  Port                  The port number of the ATA device.
  @param  PortMultiplierPort    The port multiplier port number of the ATA device.

  @retval EFI_SUCCESS           The ATA device is successfully registered.
  @retval EFI_OUT_OF_RESOURCES  There is not enough memory to allocate the ATA device
                                and related data structures.
  @return Others                Some error occurs when registering the ATA device.
**/
EFI_STATUS
RegisterAtaDevice (
  IN OUT ATA_BUS_DRIVER_DATA  *AtaBusDriverData,
  IN     UINT16               Port,
  IN     UINT16               PortMultiplierPort
  )
{
  EFI_STATUS                  Status;
  ATA_DEVICE                  *AtaDevice;
  EFI_ATA_PASS_THRU_PROTOCOL  *AtaPassThru;
  EFI_DEVICE_PATH_PROTOCOL    *NewDevicePathNode;
  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath;
  EFI_HANDLE                  DeviceHandle;

  AtaDevice           = NULL;
  NewDevicePathNode   = NULL;
  DevicePath          = NULL;
  RemainingDevicePath = NULL;

  //
  // Build device path
  //
  AtaPassThru = AtaBusDriverData->AtaPassThru;
  Status      = AtaPassThru->BuildDevicePath (AtaPassThru, Port, PortMultiplierPort, &NewDevicePathNode);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  DevicePath = AppendDevicePathNode (AtaBusDriverData->ParentDevicePath, NewDevicePathNode);
  if (DevicePath == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  DeviceHandle        = NULL;
  RemainingDevicePath = DevicePath;
  Status              = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &DeviceHandle);
  if (!EFI_ERROR (Status) && (DeviceHandle != NULL) && IsDevicePathEnd (RemainingDevicePath)) {
    Status = EFI_ALREADY_STARTED;
    FreePool (DevicePath);
    goto Done;
  }

  //
  // Allocate ATA device from the template.
  //
  AtaDevice = AllocateCopyPool (sizeof (ATA_DEVICE), &gAtaDeviceTemplate);
  if (AtaDevice == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  //
  // Initializes ATA device structures and allocates the required buffer.
  //
  AtaDevice->BlockIo.Media      = &AtaDevice->BlockMedia;
  AtaDevice->BlockIo2.Media     = &AtaDevice->BlockMedia;
  AtaDevice->AtaBusDriverData   = AtaBusDriverData;
  AtaDevice->DevicePath         = DevicePath;
  AtaDevice->Port               = Port;
  AtaDevice->PortMultiplierPort = PortMultiplierPort;
  AtaDevice->Asb                = AllocateAlignedBuffer (AtaDevice, sizeof (EFI_ATA_STATUS_BLOCK));
  if (AtaDevice->Asb == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  AtaDevice->IdentifyData = AllocateAlignedBuffer (AtaDevice, sizeof (ATA_IDENTIFY_DATA));
  if (AtaDevice->IdentifyData == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Done;
  }

  //
  // Initial Ata Task List
  //
  InitializeListHead (&AtaDevice->AtaTaskList);
  InitializeListHead (&AtaDevice->AtaSubTaskList);

  //
  // Report Status Code to indicate the ATA device will be enabled
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_ENABLE),
    AtaBusDriverData->ParentDevicePath
    );

  //
  // Try to identify the ATA device via the ATA pass through command.
  //
  Status = DiscoverAtaDevice (AtaDevice);
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // Build controller name for Component Name (2) protocol.
  //
  Status = AddUnicodeString2 (
             "eng",
             gAtaBusComponentName.SupportedLanguages,
             &AtaDevice->ControllerNameTable,
             AtaDevice->ModelName,
             TRUE
             );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  Status = AddUnicodeString2 (
             "en",
             gAtaBusComponentName2.SupportedLanguages,
             &AtaDevice->ControllerNameTable,
             AtaDevice->ModelName,
             FALSE
             );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // Update to AHCI interface GUID based on device path node. The default one
  // is IDE interface GUID copied from template.
  //
  if (NewDevicePathNode->SubType == MSG_SATA_DP) {
    CopyGuid (&AtaDevice->DiskInfo.Interface, &gEfiDiskInfoAhciInterfaceGuid);
  }

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &AtaDevice->Handle,
                  &gEfiDevicePathProtocolGuid,
                  AtaDevice->DevicePath,
                  &gEfiBlockIoProtocolGuid,
                  &AtaDevice->BlockIo,
                  &gEfiBlockIo2ProtocolGuid,
                  &AtaDevice->BlockIo2,
                  &gEfiDiskInfoProtocolGuid,
                  &AtaDevice->DiskInfo,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  //
  // See if the ata device support trust computing feature or not.
  // If yes, then install Storage Security Protocol at the ata device handle.
  //
  if ((AtaDevice->IdentifyData->trusted_computing_support & BIT0) != 0) {
    DEBUG ((DEBUG_INFO, "Found TCG support in Port %x PortMultiplierPort %x\n", Port, PortMultiplierPort));
    Status = gBS->InstallProtocolInterface (
                    &AtaDevice->Handle,
                    &gEfiStorageSecurityCommandProtocolGuid,
                    EFI_NATIVE_INTERFACE,
                    &AtaDevice->StorageSecurity
                    );
    if (EFI_ERROR (Status)) {
      goto Done;
    }

    DEBUG ((DEBUG_INFO, "Successfully Install Storage Security Protocol on the ATA device\n"));
  }

  gBS->OpenProtocol (
         AtaBusDriverData->Controller,
         &gEfiAtaPassThruProtocolGuid,
         (VOID **)&AtaPassThru,
         AtaBusDriverData->DriverBindingHandle,
         AtaDevice->Handle,
         EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
         );

Done:
  if (NewDevicePathNode != NULL) {
    FreePool (NewDevicePathNode);
  }

  if (EFI_ERROR (Status) && (AtaDevice != NULL)) {
    ReleaseAtaResources (AtaDevice);
    DEBUG ((DEBUG_ERROR | DEBUG_INIT, "Failed to initialize Port %x PortMultiplierPort %x, status = %r\n", Port, PortMultiplierPort, Status));
  }

  return Status;
}

/**
  Unregisters an ATA device.

  This function removes the protocols installed on the controller handle and
  frees the resources allocated for the ATA device.

  @param  This                  The pointer to EFI_DRIVER_BINDING_PROTOCOL instance.
  @param  Controller            The controller handle of the ATA device.
  @param  Handle                The child handle.

  @retval EFI_SUCCESS           The ATA device is successfully unregistered.
  @return Others                Some error occurs when unregistering the ATA device.

**/
EFI_STATUS
UnregisterAtaDevice (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   Controller,
  IN  EFI_HANDLE                   Handle
  )
{
  EFI_STATUS                             Status;
  EFI_BLOCK_IO_PROTOCOL                  *BlockIo;
  EFI_BLOCK_IO2_PROTOCOL                 *BlockIo2;
  ATA_DEVICE                             *AtaDevice;
  EFI_ATA_PASS_THRU_PROTOCOL             *AtaPassThru;
  EFI_STORAGE_SECURITY_COMMAND_PROTOCOL  *StorageSecurity;

  BlockIo2 =     NULL;
  BlockIo  =     NULL;

  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiBlockIoProtocolGuid,
                  (VOID **)&BlockIo,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    //
    // Locate BlockIo2 protocol
    //
    Status = gBS->OpenProtocol (
                    Handle,
                    &gEfiBlockIo2ProtocolGuid,
                    (VOID **)&BlockIo2,
                    This->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  }

  //
  // Get AtaDevice data.
  //
  if (BlockIo != NULL) {
    AtaDevice = ATA_DEVICE_FROM_BLOCK_IO (BlockIo);
  } else {
    ASSERT (BlockIo2 != NULL);
    AtaDevice = ATA_DEVICE_FROM_BLOCK_IO2 (BlockIo2);
  }

  //
  // Close the child handle
  //
  gBS->CloseProtocol (
         Controller,
         &gEfiAtaPassThruProtocolGuid,
         This->DriverBindingHandle,
         Handle
         );

  //
  // The Ata Bus driver installs the BlockIo and BlockIo2 in the DriverBindingStart().
  // Here should uninstall both of them.
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  Handle,
                  &gEfiDevicePathProtocolGuid,
                  AtaDevice->DevicePath,
                  &gEfiBlockIoProtocolGuid,
                  &AtaDevice->BlockIo,
                  &gEfiBlockIo2ProtocolGuid,
                  &AtaDevice->BlockIo2,
                  &gEfiDiskInfoProtocolGuid,
                  &AtaDevice->DiskInfo,
                  NULL
                  );

  if (EFI_ERROR (Status)) {
    gBS->OpenProtocol (
           Controller,
           &gEfiAtaPassThruProtocolGuid,
           (VOID **)&AtaPassThru,
           This->DriverBindingHandle,
           Handle,
           EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
           );
    return Status;
  }

  //
  // If Storage Security Command Protocol is installed, then uninstall this protocol.
  //
  Status = gBS->OpenProtocol (
                  Handle,
                  &gEfiStorageSecurityCommandProtocolGuid,
                  (VOID **)&StorageSecurity,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );

  if (!EFI_ERROR (Status)) {
    Status = gBS->UninstallProtocolInterface (
                    Handle,
                    &gEfiStorageSecurityCommandProtocolGuid,
                    &AtaDevice->StorageSecurity
                    );
    if (EFI_ERROR (Status)) {
      gBS->OpenProtocol (
             Controller,
             &gEfiAtaPassThruProtocolGuid,
             (VOID **)&AtaPassThru,
             This->DriverBindingHandle,
             Handle,
             EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
             );
      return Status;
    }
  }

  ReleaseAtaResources (AtaDevice);
  return EFI_SUCCESS;
}

/**
  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().
  Since 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
AtaBusDriverBindingSupported (
  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_ATA_PASS_THRU_PROTOCOL  *AtaPassThru;
  UINT16                      Port;
  UINT16                      PortMultiplierPort;

  //
  // Test EFI_ATA_PASS_THRU_PROTOCOL on controller handle.
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiAtaPassThruProtocolGuid,
                  (VOID **)&AtaPassThru,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );

  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Test to see if this ATA Pass Thru Protocol is for a LOGICAL channel
  //
  if ((AtaPassThru->Mode->Attributes & EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL) == 0) {
    //
    // Close the I/O Abstraction(s) used to perform the supported test
    //
    gBS->CloseProtocol (
           Controller,
           &gEfiAtaPassThruProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );
    return EFI_UNSUPPORTED;
  }

  //
  // Test RemainingDevicePath is valid or not.
  //
  if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {
    Status = AtaPassThru->GetDevice (AtaPassThru, RemainingDevicePath, &Port, &PortMultiplierPort);
    if (EFI_ERROR (Status)) {
      //
      // Close the I/O Abstraction(s) used to perform the supported test
      //
      gBS->CloseProtocol (
             Controller,
             &gEfiAtaPassThruProtocolGuid,
             This->DriverBindingHandle,
             Controller
             );
      return Status;
    }
  }

  //
  // Close the I/O Abstraction(s) used to perform the supported test
  //
  gBS->CloseProtocol (
         Controller,
         &gEfiAtaPassThruProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  //
  // Open the EFI Device Path protocol needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  return Status;
}

/**
  Starts a device controller or a bus controller.

  The Start() function is designed to be invoked from the EFI boot service ConnectController().
  As a result, much of the error checking on the parameters to Start() has been moved into this
  common boot service. It is legal to call Start() from other locations,
  but the following calling restrictions must be followed or the system behavior will not be deterministic.
  1. ControllerHandle must be a valid EFI_HANDLE.
  2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
     EFI_DEVICE_PATH_PROTOCOL.
  3. Prior to calling Start(), the Supported() function for the driver specified by This must
     have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.

  @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
  @param[in]  ControllerHandle     The handle of the controller to start. This handle
                                   must support a protocol interface that supplies
                                   an I/O abstraction to the driver.
  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
                                   parameter is ignored by device drivers, and is optional for bus
                                   drivers. For a bus driver, if this parameter is NULL, then handles
                                   for all the children of Controller are created by this driver.
                                   If this parameter is not NULL and the first Device Path Node is
                                   not the End of Device Path Node, then only the handle for the
                                   child device specified by the first Device Path Node of
                                   RemainingDevicePath is created by this driver.
                                   If the first Device Path Node of RemainingDevicePath is
                                   the End of Device Path Node, no child handle is created by this
                                   driver.

  @retval EFI_SUCCESS              The device was started.
  @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
  @retval Others                   The driver failed to start the device.

**/
EFI_STATUS
EFIAPI
AtaBusDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   Controller,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                  Status;
  EFI_ATA_PASS_THRU_PROTOCOL  *AtaPassThru;
  EFI_DEVICE_PATH_PROTOCOL    *ParentDevicePath;
  ATA_BUS_DRIVER_DATA         *AtaBusDriverData;
  UINT16                      Port;
  UINT16                      PortMultiplierPort;

  AtaBusDriverData = NULL;

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&ParentDevicePath,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Report Status Code to indicate ATA bus starts
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_INIT),
    ParentDevicePath
    );

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiAtaPassThruProtocolGuid,
                  (VOID **)&AtaPassThru,
                  This->DriverBindingHandle,
                  Controller,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
    goto ErrorExit;
  }

  //
  // Check EFI_ALREADY_STARTED to reuse the original ATA_BUS_DRIVER_DATA.
  //
  if (Status != EFI_ALREADY_STARTED) {
    AtaBusDriverData = AllocateZeroPool (sizeof (ATA_BUS_DRIVER_DATA));
    if (AtaBusDriverData == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto ErrorExit;
    }

    AtaBusDriverData->AtaPassThru         = AtaPassThru;
    AtaBusDriverData->Controller          = Controller;
    AtaBusDriverData->ParentDevicePath    = ParentDevicePath;
    AtaBusDriverData->DriverBindingHandle = This->DriverBindingHandle;

    Status = gBS->InstallMultipleProtocolInterfaces (
                    &Controller,
                    &gEfiCallerIdGuid,
                    AtaBusDriverData,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      goto ErrorExit;
    }
  } else {
    Status = gBS->OpenProtocol (
                    Controller,
                    &gEfiCallerIdGuid,
                    (VOID **)&AtaBusDriverData,
                    This->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      AtaBusDriverData = NULL;
      goto ErrorExit;
    }
  }

  //
  // Report Status Code to indicate detecting devices on bus
  //
  REPORT_STATUS_CODE_WITH_DEVICE_PATH (
    EFI_PROGRESS_CODE,
    (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_DETECT),
    ParentDevicePath
    );

  if (RemainingDevicePath == NULL) {
    Port = 0xFFFF;
    while (TRUE) {
      Status = AtaPassThru->GetNextPort (AtaPassThru, &Port);
      if (EFI_ERROR (Status)) {
        //
        // We cannot find more legal port then we are done.
        //
        break;
      }

      PortMultiplierPort = 0xFFFF;
      while (TRUE) {
        Status = AtaPassThru->GetNextDevice (AtaPassThru, Port, &PortMultiplierPort);
        if (EFI_ERROR (Status)) {
          //
          // We cannot find more legal port multiplier port number for ATA device
          // on the port, then we are done.
          //
          break;
        }

        RegisterAtaDevice (AtaBusDriverData, Port, PortMultiplierPort);
      }
    }

    Status = EFI_SUCCESS;
  } else if (!IsDevicePathEnd (RemainingDevicePath)) {
    Status = AtaPassThru->GetDevice (AtaPassThru, RemainingDevicePath, &Port, &PortMultiplierPort);
    if (!EFI_ERROR (Status)) {
      Status = RegisterAtaDevice (AtaBusDriverData, Port, PortMultiplierPort);
    }
  }

  return Status;

ErrorExit:

  if (AtaBusDriverData != NULL) {
    gBS->UninstallMultipleProtocolInterfaces (
           Controller,
           &gEfiCallerIdGuid,
           AtaBusDriverData,
           NULL
           );
    FreePool (AtaBusDriverData);
  }

  gBS->CloseProtocol (
         Controller,
         &gEfiAtaPassThruProtocolGuid,
         This->DriverBindingHandle,
         Controller
         );

  return Status;
}

/**
  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
AtaBusDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   Controller,
  IN  UINTN                        NumberOfChildren,
  IN  EFI_HANDLE                   *ChildHandleBuffer
  )
{
  EFI_STATUS           Status;
  BOOLEAN              AllChildrenStopped;
  UINTN                Index;
  ATA_BUS_DRIVER_DATA  *AtaBusDriverData;

  if (NumberOfChildren == 0) {
    Status = gBS->OpenProtocol (
                    Controller,
                    &gEfiCallerIdGuid,
                    (VOID **)&AtaBusDriverData,
                    This->DriverBindingHandle,
                    Controller,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      gBS->UninstallMultipleProtocolInterfaces (
             Controller,
             &gEfiCallerIdGuid,
             AtaBusDriverData,
             NULL
             );
      FreePool (AtaBusDriverData);
    }

    gBS->CloseProtocol (
           Controller,
           &gEfiAtaPassThruProtocolGuid,
           This->DriverBindingHandle,
           Controller
           );

    return EFI_SUCCESS;
  }

  AllChildrenStopped = TRUE;

  for (Index = 0; Index < NumberOfChildren; Index++) {
    Status = UnregisterAtaDevice (This, Controller, ChildHandleBuffer[Index]);
    if (EFI_ERROR (Status)) {
      AllChildrenStopped = FALSE;
    }
  }

  if (!AllChildrenStopped) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

/**
  Reset the Block Device.

  @param  This                 Indicates a pointer to the calling context.
  @param  ExtendedVerification Driver may perform diagnostics on reset.

  @retval EFI_SUCCESS          The device was reset.
  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could
                               not be reset.

**/
EFI_STATUS
EFIAPI
AtaBlockIoReset (
  IN  EFI_BLOCK_IO_PROTOCOL  *This,
  IN  BOOLEAN                ExtendedVerification
  )
{
  EFI_STATUS  Status;
  ATA_DEVICE  *AtaDevice;
  EFI_TPL     OldTpl;

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  AtaDevice = ATA_DEVICE_FROM_BLOCK_IO (This);

  Status = ResetAtaDevice (AtaDevice);

  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
  }

  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Read/Write BufferSize bytes from Lba from/into Buffer.

  @param[in]       This       Indicates a pointer to the calling context. Either be
                              block I/O or block I/O2.
  @param[in]       MediaId    The media ID that the read/write request is for.
  @param[in]       Lba        The starting logical block address to be read/written.
                              The caller is responsible for reading/writing to only
                              legitimate locations.
  @param[in, out]  Token      A pointer to the token associated with the transaction.
  @param[in]       BufferSize Size of Buffer, must be a multiple of device block size.
  @param[out]      Buffer     A pointer to the destination/source buffer for the data.
  @param[in]       IsBlockIo2 Indicate the calling is from BlockIO or BlockIO2. TRUE is
                              from BlockIO2, FALSE is for BlockIO.
  @param[in]       IsWrite    Indicates whether it is a write operation.

  @retval EFI_SUCCESS           The data was read/written correctly to the device.
  @retval EFI_WRITE_PROTECTED   The device can not be read/written to.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the read/write.
  @retval EFI_NO_MEDIA          There is no media in the device.
  @retval EFI_MEDIA_CHANGED     The MediaId does not match the current device.
  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
  @retval EFI_INVALID_PARAMETER The read/write request contains LBAs that are not valid,
                                or the buffer is not on proper alignment.

**/
EFI_STATUS
BlockIoReadWrite (
  IN     VOID                 *This,
  IN     UINT32               MediaId,
  IN     EFI_LBA              Lba,
  IN OUT EFI_BLOCK_IO2_TOKEN  *Token,
  IN     UINTN                BufferSize,
  OUT    VOID                 *Buffer,
  IN     BOOLEAN              IsBlockIo2,
  IN     BOOLEAN              IsWrite
  )
{
  ATA_DEVICE          *AtaDevice;
  EFI_STATUS          Status;
  EFI_TPL             OldTpl;
  EFI_BLOCK_IO_MEDIA  *Media;
  UINTN               BlockSize;
  UINTN               NumberOfBlocks;
  UINTN               IoAlign;

  if (IsBlockIo2) {
    Media     = ((EFI_BLOCK_IO2_PROTOCOL *)This)->Media;
    AtaDevice = ATA_DEVICE_FROM_BLOCK_IO2 (This);
  } else {
    Media     = ((EFI_BLOCK_IO_PROTOCOL *)This)->Media;
    AtaDevice = ATA_DEVICE_FROM_BLOCK_IO (This);
  }

  if (MediaId != Media->MediaId) {
    return EFI_MEDIA_CHANGED;
  }

  //
  // Check parameters.
  //
  if (Buffer == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferSize == 0) {
    if ((Token != NULL) && (Token->Event != NULL)) {
      Token->TransactionStatus = EFI_SUCCESS;
      gBS->SignalEvent (Token->Event);
    }

    return EFI_SUCCESS;
  }

  BlockSize = Media->BlockSize;
  if ((BufferSize % BlockSize) != 0) {
    return EFI_BAD_BUFFER_SIZE;
  }

  NumberOfBlocks = BufferSize / BlockSize;
  if ((Lba + NumberOfBlocks - 1) > Media->LastBlock) {
    return EFI_INVALID_PARAMETER;
  }

  IoAlign = Media->IoAlign;
  if ((IoAlign > 0) && (((UINTN)Buffer & (IoAlign - 1)) != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Invoke low level AtaDevice Access Routine.
  //
  Status = AccessAtaDevice (AtaDevice, Buffer, Lba, NumberOfBlocks, IsWrite, Token);

  gBS->RestoreTPL (OldTpl);

  return Status;
}

/**
  Read BufferSize bytes from Lba into Buffer.

  @param  This       Indicates a pointer to the calling context.
  @param  MediaId    Id of the media, changes every time the media is replaced.
  @param  Lba        The starting Logical Block Address to read from
  @param  BufferSize Size of Buffer, must be a multiple of device block size.
  @param  Buffer     A pointer to the destination buffer for the data. The caller is
                     responsible for either having implicit or explicit ownership of the buffer.

  @retval EFI_SUCCESS           The data was read correctly from the device.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the read.
  @retval EFI_NO_MEDIA          There is no media in the device.
  @retval EFI_MEDIA_CHANGED     The MediaId does not match the current device.
  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
                                or the buffer is not on proper alignment.

**/
EFI_STATUS
EFIAPI
AtaBlockIoReadBlocks (
  IN  EFI_BLOCK_IO_PROTOCOL  *This,
  IN  UINT32                 MediaId,
  IN  EFI_LBA                Lba,
  IN  UINTN                  BufferSize,
  OUT VOID                   *Buffer
  )
{
  return BlockIoReadWrite ((VOID *)This, MediaId, Lba, NULL, BufferSize, Buffer, FALSE, FALSE);
}

/**
  Write BufferSize bytes from Lba into Buffer.

  @param  This       Indicates a pointer to the calling context.
  @param  MediaId    The media ID that the write request is for.
  @param  Lba        The starting logical block address to be written. The caller is
                     responsible for writing to only legitimate locations.
  @param  BufferSize Size of Buffer, must be a multiple of device block size.
  @param  Buffer     A pointer to the source buffer for the data.

  @retval EFI_SUCCESS           The data was written correctly to the device.
  @retval EFI_WRITE_PROTECTED   The device can not be written to.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.
  @retval EFI_NO_MEDIA          There is no media in the device.
  @retval EFI_MEDIA_CHANGED     The MediaId does not match the current device.
  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
  @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
                                or the buffer is not on proper alignment.

**/
EFI_STATUS
EFIAPI
AtaBlockIoWriteBlocks (
  IN  EFI_BLOCK_IO_PROTOCOL  *This,
  IN  UINT32                 MediaId,
  IN  EFI_LBA                Lba,
  IN  UINTN                  BufferSize,
  IN  VOID                   *Buffer
  )
{
  return BlockIoReadWrite ((VOID *)This, MediaId, Lba, NULL, BufferSize, Buffer, FALSE, TRUE);
}

/**
  Flush the Block Device.

  @param  This              Indicates a pointer to the calling context.

  @retval EFI_SUCCESS       All outstanding data was written to the device
  @retval EFI_DEVICE_ERROR  The device reported an error while writing back the data
  @retval EFI_NO_MEDIA      There is no media in the device.

**/
EFI_STATUS
EFIAPI
AtaBlockIoFlushBlocks (
  IN  EFI_BLOCK_IO_PROTOCOL  *This
  )
{
  //
  // return directly
  //
  return EFI_SUCCESS;
}

/**
  Reset the Block Device.

  @param[in]  This                 Indicates a pointer to the calling context.
  @param[in]  ExtendedVerification Driver may perform diagnostics on reset.

  @retval EFI_SUCCESS          The device was reset.
  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could
                               not be reset.

**/
EFI_STATUS
EFIAPI
AtaBlockIoResetEx (
  IN  EFI_BLOCK_IO2_PROTOCOL  *This,
  IN  BOOLEAN                 ExtendedVerification
  )
{
  EFI_STATUS  Status;
  ATA_DEVICE  *AtaDevice;
  EFI_TPL     OldTpl;

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  AtaDevice = ATA_DEVICE_FROM_BLOCK_IO2 (This);

  AtaTerminateNonBlockingTask (AtaDevice);

  Status = ResetAtaDevice (AtaDevice);

  if (EFI_ERROR (Status)) {
    Status = EFI_DEVICE_ERROR;
  }

  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Read BufferSize bytes from Lba into Buffer.

  @param[in]       This       Indicates a pointer to the calling context.
  @param[in]       MediaId    Id of the media, changes every time the media is replaced.
  @param[in]       Lba        The starting Logical Block Address to read from.
  @param[in, out]  Token      A pointer to the token associated with the transaction.
  @param[in]       BufferSize Size of Buffer, must be a multiple of device block size.
  @param[out]      Buffer     A pointer to the destination buffer for the data. The caller is
                              responsible for either having implicit or explicit ownership of the buffer.

  @retval EFI_SUCCESS           The read request was queued if Event is not NULL.
                                The data was read correctly from the device if
                                the Event is NULL.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing
                                the read.
  @retval EFI_NO_MEDIA          There is no media in the device.
  @retval EFI_MEDIA_CHANGED     The MediaId is not for the current media.
  @retval EFI_BAD_BUFFER_SIZE   The BufferSize parameter is not a multiple of the
                                intrinsic block size of the device.
  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
                                or the buffer is not on proper alignment.
  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack
                                of resources.

**/
EFI_STATUS
EFIAPI
AtaBlockIoReadBlocksEx (
  IN  EFI_BLOCK_IO2_PROTOCOL  *This,
  IN  UINT32                  MediaId,
  IN  EFI_LBA                 Lba,
  IN OUT EFI_BLOCK_IO2_TOKEN  *Token,
  IN  UINTN                   BufferSize,
  OUT VOID                    *Buffer
  )
{
  return BlockIoReadWrite ((VOID *)This, MediaId, Lba, Token, BufferSize, Buffer, TRUE, FALSE);
}

/**
  Write BufferSize bytes from Lba into Buffer.

  @param[in]       This       Indicates a pointer to the calling context.
  @param[in]       MediaId    The media ID that the write request is for.
  @param[in]       Lba        The starting logical block address to be written. The
                              caller is responsible for writing to only legitimate
                              locations.
  @param[in, out]  Token      A pointer to the token associated with the transaction.
  @param[in]       BufferSize Size of Buffer, must be a multiple of device block size.
  @param[in]       Buffer     A pointer to the source buffer for the data.

  @retval EFI_SUCCESS           The data was written correctly to the device.
  @retval EFI_WRITE_PROTECTED   The device can not be written to.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.
  @retval EFI_NO_MEDIA          There is no media in the device.
  @retval EFI_MEDIA_CHANGED     The MediaId does not match the current device.
  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
  @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
                                or the buffer is not on proper alignment.

**/
EFI_STATUS
EFIAPI
AtaBlockIoWriteBlocksEx (
  IN  EFI_BLOCK_IO2_PROTOCOL  *This,
  IN  UINT32                  MediaId,
  IN  EFI_LBA                 Lba,
  IN OUT EFI_BLOCK_IO2_TOKEN  *Token,
  IN  UINTN                   BufferSize,
  IN  VOID                    *Buffer
  )
{
  return BlockIoReadWrite ((VOID *)This, MediaId, Lba, Token, BufferSize, Buffer, TRUE, TRUE);
}

/**
  Flush the Block Device.

  @param[in]       This       Indicates a pointer to the calling context.
  @param[in, out]  Token      A pointer to the token associated with the transaction.

  @retval EFI_SUCCESS       All outstanding data was written to the device
  @retval EFI_DEVICE_ERROR  The device reported an error while writing back the data
  @retval EFI_NO_MEDIA      There is no media in the device.

**/
EFI_STATUS
EFIAPI
AtaBlockIoFlushBlocksEx (
  IN  EFI_BLOCK_IO2_PROTOCOL  *This,
  IN OUT EFI_BLOCK_IO2_TOKEN  *Token
  )
{
  //
  // Signal event and return directly.
  //
  if ((Token != NULL) && (Token->Event != NULL)) {
    Token->TransactionStatus = EFI_SUCCESS;
    gBS->SignalEvent (Token->Event);
  }

  return EFI_SUCCESS;
}

/**
  Provides inquiry information for the controller type.

  This function is used by the IDE bus driver to get inquiry data.  Data format
  of Identify data is defined by the Interface GUID.

  @param[in]      This             Pointer to the EFI_DISK_INFO_PROTOCOL instance.
  @param[in, out] InquiryData      Pointer to a buffer for the inquiry data.
  @param[in, out] InquiryDataSize  Pointer to the value for the inquiry data size.

  @retval EFI_SUCCESS            The command was accepted without any errors.
  @retval EFI_NOT_FOUND          Device does not support this data class
  @retval EFI_DEVICE_ERROR       Error reading InquiryData from device
  @retval EFI_BUFFER_TOO_SMALL   InquiryDataSize not big enough

**/
EFI_STATUS
EFIAPI
AtaDiskInfoInquiry (
  IN     EFI_DISK_INFO_PROTOCOL  *This,
  IN OUT VOID                    *InquiryData,
  IN OUT UINT32                  *InquiryDataSize
  )
{
  return EFI_NOT_FOUND;
}

/**
  Provides identify information for the controller type.

  This function is used by the IDE bus driver to get identify data.  Data format
  of Identify data is defined by the Interface GUID.

  @param[in]      This              Pointer to the EFI_DISK_INFO_PROTOCOL
                                    instance.
  @param[in, out] IdentifyData      Pointer to a buffer for the identify data.
  @param[in, out] IdentifyDataSize  Pointer to the value for the identify data
                                    size.

  @retval EFI_SUCCESS            The command was accepted without any errors.
  @retval EFI_NOT_FOUND          Device does not support this data class
  @retval EFI_DEVICE_ERROR       Error reading IdentifyData from device
  @retval EFI_BUFFER_TOO_SMALL   IdentifyDataSize not big enough

**/
EFI_STATUS
EFIAPI
AtaDiskInfoIdentify (
  IN     EFI_DISK_INFO_PROTOCOL  *This,
  IN OUT VOID                    *IdentifyData,
  IN OUT UINT32                  *IdentifyDataSize
  )
{
  EFI_STATUS  Status;
  ATA_DEVICE  *AtaDevice;

  AtaDevice = ATA_DEVICE_FROM_DISK_INFO (This);

  Status = EFI_BUFFER_TOO_SMALL;
  if (*IdentifyDataSize >= sizeof (ATA_IDENTIFY_DATA)) {
    Status = EFI_SUCCESS;
    CopyMem (IdentifyData, AtaDevice->IdentifyData, sizeof (ATA_IDENTIFY_DATA));
  }

  *IdentifyDataSize = sizeof (ATA_IDENTIFY_DATA);

  return Status;
}

/**
  Provides sense data information for the controller type.

  This function is used by the IDE bus driver to get sense data.
  Data format of Sense data is defined by the Interface GUID.

  @param[in]      This             Pointer to the EFI_DISK_INFO_PROTOCOL instance.
  @param[in, out] SenseData        Pointer to the SenseData.
  @param[in, out] SenseDataSize    Size of SenseData in bytes.
  @param[out]     SenseDataNumber  Pointer to the value for the sense data size.

  @retval EFI_SUCCESS            The command was accepted without any errors.
  @retval EFI_NOT_FOUND          Device does not support this data class.
  @retval EFI_DEVICE_ERROR       Error reading SenseData from device.
  @retval EFI_BUFFER_TOO_SMALL   SenseDataSize not big enough.

**/
EFI_STATUS
EFIAPI
AtaDiskInfoSenseData (
  IN     EFI_DISK_INFO_PROTOCOL  *This,
  IN OUT VOID                    *SenseData,
  IN OUT UINT32                  *SenseDataSize,
  OUT    UINT8                   *SenseDataNumber
  )
{
  return EFI_NOT_FOUND;
}

/**
  This function is used by the IDE bus driver to get controller information.

  @param[in]  This         Pointer to the EFI_DISK_INFO_PROTOCOL instance.
  @param[out] IdeChannel   Pointer to the Ide Channel number.  Primary or secondary.
  @param[out] IdeDevice    Pointer to the Ide Device number.  Master or slave.

  @retval EFI_SUCCESS       IdeChannel and IdeDevice are valid.
  @retval EFI_UNSUPPORTED   This is not an IDE device.

**/
EFI_STATUS
EFIAPI
AtaDiskInfoWhichIde (
  IN  EFI_DISK_INFO_PROTOCOL  *This,
  OUT UINT32                  *IdeChannel,
  OUT UINT32                  *IdeDevice
  )
{
  ATA_DEVICE  *AtaDevice;

  AtaDevice   = ATA_DEVICE_FROM_DISK_INFO (This);
  *IdeChannel = AtaDevice->Port;
  *IdeDevice  = AtaDevice->PortMultiplierPort;

  return EFI_SUCCESS;
}

/**
  Send a security protocol command to a device that receives data and/or the result
  of one or more commands sent by SendData.

  The ReceiveData function sends a security protocol command to the given MediaId.
  The security protocol command sent is defined by SecurityProtocolId and contains
  the security protocol specific data SecurityProtocolSpecificData. The function
  returns the data from the security protocol command in PayloadBuffer.

  For devices supporting the SCSI command set, the security protocol command is sent
  using the SECURITY PROTOCOL IN command defined in SPC-4.

  For devices supporting the ATA command set, the security protocol command is sent
  using one of the TRUSTED RECEIVE commands defined in ATA8-ACS if PayloadBufferSize
  is non-zero.

  If the PayloadBufferSize is zero, the security protocol command is sent using the
  Trusted Non-Data command defined in ATA8-ACS.

  If PayloadBufferSize is too small to store the available data from the security
  protocol command, the function shall copy PayloadBufferSize bytes into the
  PayloadBuffer and return EFI_WARN_BUFFER_TOO_SMALL.

  If PayloadBuffer or PayloadTransferSize is NULL and PayloadBufferSize is non-zero,
  the function shall return EFI_INVALID_PARAMETER.

  If the given MediaId does not support security protocol commands, the function shall
  return EFI_UNSUPPORTED. If there is no media in the device, the function returns
  EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the device,
  the function returns EFI_MEDIA_CHANGED.

  If the security protocol fails to complete within the Timeout period, the function
  shall return EFI_TIMEOUT.

  If the security protocol command completes without an error, the function shall
  return EFI_SUCCESS. If the security protocol command completes with an error, the
  function shall return EFI_DEVICE_ERROR.

  @param  This                         Indicates a pointer to the calling context.
  @param  MediaId                      ID of the medium to receive data from. If there is no
                                       block IO protocol supported by the physical device, the
                                       value of MediaId is undefined.
  @param  Timeout                      The timeout, in 100ns units, to use for the execution
                                       of the security protocol command. A Timeout value of 0
                                       means that this function will wait indefinitely for the
                                       security protocol command to execute. If Timeout is greater
                                       than zero, then this function will return EFI_TIMEOUT
                                       if the time required to execute the receive data command
                                       is greater than Timeout.
  @param  SecurityProtocolId           The value of the "Security Protocol" parameter of
                                       the security protocol command to be sent.
  @param  SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter
                                       of the security protocol command to be sent.
  @param  PayloadBufferSize            Size in bytes of the payload data buffer.
  @param  PayloadBuffer                A pointer to a destination buffer to store the security
                                       protocol command specific payload data for the security
                                       protocol command. The caller is responsible for having
                                       either implicit or explicit ownership of the buffer.
  @param  PayloadTransferSize          A pointer to a buffer to store the size in bytes of the
                                       data written to the payload data buffer.

  @retval EFI_SUCCESS                  The security protocol command completed successfully.
  @retval EFI_WARN_BUFFER_TOO_SMALL    The PayloadBufferSize was too small to store the available
                                       data from the device. The PayloadBuffer contains the truncated data.
  @retval EFI_UNSUPPORTED              The given MediaId does not support security protocol commands.
  @retval EFI_DEVICE_ERROR             The security protocol command completed with an error.
  @retval EFI_NO_MEDIA                 There is no media in the device.
  @retval EFI_MEDIA_CHANGED            The MediaId is not for the current media.
  @retval EFI_INVALID_PARAMETER        The PayloadBuffer or PayloadTransferSize is NULL and
                                       PayloadBufferSize is non-zero.
  @retval EFI_TIMEOUT                  A timeout occurred while waiting for the security
                                       protocol command to execute.

**/
EFI_STATUS
EFIAPI
AtaStorageSecurityReceiveData (
  IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL  *This,
  IN UINT32                                 MediaId,
  IN UINT64                                 Timeout,
  IN UINT8                                  SecurityProtocolId,
  IN UINT16                                 SecurityProtocolSpecificData,
  IN UINTN                                  PayloadBufferSize,
  OUT VOID                                  *PayloadBuffer,
  OUT UINTN                                 *PayloadTransferSize
  )
{
  EFI_STATUS  Status;
  ATA_DEVICE  *Private;
  EFI_TPL     OldTpl;

  DEBUG ((DEBUG_INFO, "EFI Storage Security Protocol - Read\n"));
  if (((PayloadBuffer == NULL) || (PayloadTransferSize == NULL)) && (PayloadBufferSize != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  Status  = EFI_SUCCESS;
  Private = ATA_DEVICE_FROM_STORAGE_SECURITY (This);

  if (MediaId != Private->BlockIo.Media->MediaId) {
    return EFI_MEDIA_CHANGED;
  }

  if (!Private->BlockIo.Media->MediaPresent) {
    return EFI_NO_MEDIA;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  Status = TrustTransferAtaDevice (
             Private,
             PayloadBuffer,
             SecurityProtocolId,
             SecurityProtocolSpecificData,
             PayloadBufferSize,
             FALSE,
             Timeout,
             PayloadTransferSize
             );

  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Send a security protocol command to a device.

  The SendData function sends a security protocol command containing the payload
  PayloadBuffer to the given MediaId. The security protocol command sent is
  defined by SecurityProtocolId and contains the security protocol specific data
  SecurityProtocolSpecificData. If the underlying protocol command requires a
  specific padding for the command payload, the SendData function shall add padding
  bytes to the command payload to satisfy the padding requirements.

  For devices supporting the SCSI command set, the security protocol command is sent
  using the SECURITY PROTOCOL OUT command defined in SPC-4.

  For devices supporting the ATA command set, the security protocol command is sent
  using one of the TRUSTED SEND commands defined in ATA8-ACS if PayloadBufferSize
  is non-zero. If the PayloadBufferSize is zero, the security protocol command is
  sent using the Trusted Non-Data command defined in ATA8-ACS.

  If PayloadBuffer is NULL and PayloadBufferSize is non-zero, the function shall
  return EFI_INVALID_PARAMETER.

  If the given MediaId does not support security protocol commands, the function
  shall return EFI_UNSUPPORTED. If there is no media in the device, the function
  returns EFI_NO_MEDIA. If the MediaId is not the ID for the current media in the
  device, the function returns EFI_MEDIA_CHANGED.

  If the security protocol fails to complete within the Timeout period, the function
  shall return EFI_TIMEOUT.

  If the security protocol command completes without an error, the function shall return
  EFI_SUCCESS. If the security protocol command completes with an error, the function
  shall return EFI_DEVICE_ERROR.

  @param  This                         Indicates a pointer to the calling context.
  @param  MediaId                      ID of the medium to receive data from. If there is no
                                       block IO protocol supported by the physical device, the
                                       value of MediaId is undefined.
  @param  Timeout                      The timeout, in 100ns units, to use for the execution
                                       of the security protocol command. A Timeout value of 0
                                       means that this function will wait indefinitely for the
                                       security protocol command to execute. If Timeout is greater
                                       than zero, then this function will return EFI_TIMEOUT
                                       if the time required to execute the receive data command
                                       is greater than Timeout.
  @param  SecurityProtocolId           The value of the "Security Protocol" parameter of
                                       the security protocol command to be sent.
  @param  SecurityProtocolSpecificData The value of the "Security Protocol Specific" parameter
                                       of the security protocol command to be sent.
  @param  PayloadBufferSize            Size in bytes of the payload data buffer.
  @param  PayloadBuffer                A pointer to a destination buffer to store the security
                                       protocol command specific payload data for the security
                                       protocol command.

  @retval EFI_SUCCESS                  The security protocol command completed successfully.
  @retval EFI_UNSUPPORTED              The given MediaId does not support security protocol commands.
  @retval EFI_DEVICE_ERROR             The security protocol command completed with an error.
  @retval EFI_NO_MEDIA                 There is no media in the device.
  @retval EFI_MEDIA_CHANGED            The MediaId is not for the current media.
  @retval EFI_INVALID_PARAMETER        The PayloadBuffer is NULL and PayloadBufferSize is non-zero.
  @retval EFI_TIMEOUT                  A timeout occurred while waiting for the security
                                       protocol command to execute.

**/
EFI_STATUS
EFIAPI
AtaStorageSecuritySendData (
  IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL  *This,
  IN UINT32                                 MediaId,
  IN UINT64                                 Timeout,
  IN UINT8                                  SecurityProtocolId,
  IN UINT16                                 SecurityProtocolSpecificData,
  IN UINTN                                  PayloadBufferSize,
  IN VOID                                   *PayloadBuffer
  )
{
  EFI_STATUS  Status;
  ATA_DEVICE  *Private;
  EFI_TPL     OldTpl;

  DEBUG ((DEBUG_INFO, "EFI Storage Security Protocol - Send\n"));
  if ((PayloadBuffer == NULL) && (PayloadBufferSize != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  Status  = EFI_SUCCESS;
  Private = ATA_DEVICE_FROM_STORAGE_SECURITY (This);

  if (MediaId != Private->BlockIo.Media->MediaId) {
    return EFI_MEDIA_CHANGED;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  Status = TrustTransferAtaDevice (
             Private,
             PayloadBuffer,
             SecurityProtocolId,
             SecurityProtocolSpecificData,
             PayloadBufferSize,
             TRUE,
             Timeout,
             NULL
             );

  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  The user Entry Point for module AtaBus. The user code starts with this function.

  @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
InitializeAtaBus (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  //
  // Install driver model protocol(s).
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gAtaBusDriverBinding,
             ImageHandle,
             &gAtaBusComponentName,
             &gAtaBusComponentName2
             );
  ASSERT_EFI_ERROR (Status);

  return Status;
}
