/** @file
  DiskIo driver that lays on every BlockIo protocol in the system.
  DiskIo converts a block oriented device to a byte oriented device.

  Disk access may have to handle unaligned request about sector boundaries.
  There are three cases:
    UnderRun - The first byte is not on a sector boundary or the read request is
               less than a sector in length.
    Aligned  - A read of N contiguous sectors.
    OverRun  - The last byte is not on a sector boundary.

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "DiskIo.h"

//
// Driver binding protocol implementation for DiskIo driver.
//
EFI_DRIVER_BINDING_PROTOCOL  gDiskIoDriverBinding = {
  DiskIoDriverBindingSupported,
  DiskIoDriverBindingStart,
  DiskIoDriverBindingStop,
  0xa,
  NULL,
  NULL
};

//
// Template for DiskIo private data structure.
// The pointer to BlockIo protocol interface is assigned dynamically.
//
DISK_IO_PRIVATE_DATA  gDiskIoPrivateDataTemplate = {
  DISK_IO_PRIVATE_DATA_SIGNATURE,
  {
    EFI_DISK_IO_PROTOCOL_REVISION,
    DiskIoReadDisk,
    DiskIoWriteDisk
  },
  {
    EFI_DISK_IO2_PROTOCOL_REVISION,
    DiskIo2Cancel,
    DiskIo2ReadDiskEx,
    DiskIo2WriteDiskEx,
    DiskIo2FlushDiskEx
  }
};

/**
  Test to see if this driver supports ControllerHandle.

  @param  This                Protocol instance pointer.
  @param  ControllerHandle    Handle of device to test
  @param  RemainingDevicePath Optional parameter use to pick a specific child
                              device to start.

  @retval EFI_SUCCESS         This driver supports this device
  @retval EFI_ALREADY_STARTED This driver is already running on this device
  @retval other               This driver does not support this device

**/
EFI_STATUS
EFIAPI
DiskIoDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS             Status;
  EFI_BLOCK_IO_PROTOCOL  *BlockIo;

  //
  // Open the IO Abstraction(s) needed to perform the supported test.
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiBlockIoProtocolGuid,
                  (VOID **)&BlockIo,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Close the I/O Abstraction(s) used to perform the supported test.
  //
  gBS->CloseProtocol (
         ControllerHandle,
         &gEfiBlockIoProtocolGuid,
         This->DriverBindingHandle,
         ControllerHandle
         );
  return EFI_SUCCESS;
}

/**
  Start this driver on ControllerHandle by opening a Block IO protocol and
  installing a Disk IO protocol on ControllerHandle.

  @param  This                 Protocol instance pointer.
  @param  ControllerHandle     Handle of device to bind driver to
  @param  RemainingDevicePath  Optional parameter use to pick a specific child
                               device to start.

  @retval EFI_SUCCESS          This driver is added to ControllerHandle
  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
  @retval other                This driver does not support this device

**/
EFI_STATUS
EFIAPI
DiskIoDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS            Status;
  DISK_IO_PRIVATE_DATA  *Instance;
  EFI_TPL               OldTpl;

  Instance = NULL;

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  //
  // Connect to the Block IO and Block IO2 interface on ControllerHandle.
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiBlockIoProtocolGuid,
                  (VOID **)&gDiskIoPrivateDataTemplate.BlockIo,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto ErrorExit1;
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiBlockIo2ProtocolGuid,
                  (VOID **)&gDiskIoPrivateDataTemplate.BlockIo2,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    gDiskIoPrivateDataTemplate.BlockIo2 = NULL;
  }

  //
  // Initialize the Disk IO device instance.
  //
  Instance = AllocateCopyPool (sizeof (DISK_IO_PRIVATE_DATA), &gDiskIoPrivateDataTemplate);
  if (Instance == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }

  //
  // The BlockSize and IoAlign of BlockIo and BlockIo2 should equal.
  //
  ASSERT (
    (Instance->BlockIo2 == NULL) ||
    ((Instance->BlockIo->Media->IoAlign == Instance->BlockIo2->Media->IoAlign) &&
     (Instance->BlockIo->Media->BlockSize == Instance->BlockIo2->Media->BlockSize)
    )
    );

  InitializeListHead (&Instance->TaskQueue);
  EfiInitializeLock (&Instance->TaskQueueLock, TPL_NOTIFY);
  Instance->SharedWorkingBuffer = AllocateAlignedPages (
                                    EFI_SIZE_TO_PAGES (PcdGet32 (PcdDiskIoDataBufferBlockNum) * Instance->BlockIo->Media->BlockSize),
                                    Instance->BlockIo->Media->IoAlign
                                    );
  if (Instance->SharedWorkingBuffer == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto ErrorExit;
  }

  //
  // Install protocol interfaces for the Disk IO device.
  //
  if (Instance->BlockIo2 != NULL) {
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &ControllerHandle,
                    &gEfiDiskIoProtocolGuid,
                    &Instance->DiskIo,
                    &gEfiDiskIo2ProtocolGuid,
                    &Instance->DiskIo2,
                    NULL
                    );
  } else {
    Status = gBS->InstallMultipleProtocolInterfaces (
                    &ControllerHandle,
                    &gEfiDiskIoProtocolGuid,
                    &Instance->DiskIo,
                    NULL
                    );
  }

ErrorExit:
  if (EFI_ERROR (Status)) {
    if ((Instance != NULL) && (Instance->SharedWorkingBuffer != NULL)) {
      FreeAlignedPages (
        Instance->SharedWorkingBuffer,
        EFI_SIZE_TO_PAGES (PcdGet32 (PcdDiskIoDataBufferBlockNum) * Instance->BlockIo->Media->BlockSize)
        );
    }

    if (Instance != NULL) {
      FreePool (Instance);
    }

    gBS->CloseProtocol (
           ControllerHandle,
           &gEfiBlockIoProtocolGuid,
           This->DriverBindingHandle,
           ControllerHandle
           );
  }

ErrorExit1:
  gBS->RestoreTPL (OldTpl);
  return Status;
}

/**
  Stop this driver on ControllerHandle by removing Disk IO protocol and closing
  the Block IO protocol on ControllerHandle.

  @param  This              Protocol instance pointer.
  @param  ControllerHandle  Handle of device to stop driver on
  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
                            children is zero stop the entire bus driver.
  @param  ChildHandleBuffer List of Child Handles to Stop.

  @retval EFI_SUCCESS       This driver is removed ControllerHandle
  @retval other             This driver was not removed from this device

**/
EFI_STATUS
EFIAPI
DiskIoDriverBindingStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  UINTN                        NumberOfChildren,
  IN  EFI_HANDLE                   *ChildHandleBuffer
  )
{
  EFI_STATUS             Status;
  EFI_DISK_IO_PROTOCOL   *DiskIo;
  EFI_DISK_IO2_PROTOCOL  *DiskIo2;
  DISK_IO_PRIVATE_DATA   *Instance;
  BOOLEAN                AllTaskDone;

  //
  // Get our context back.
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDiskIoProtocolGuid,
                  (VOID **)&DiskIo,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDiskIo2ProtocolGuid,
                  (VOID **)&DiskIo2,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    DiskIo2 = NULL;
  }

  Instance = DISK_IO_PRIVATE_DATA_FROM_DISK_IO (DiskIo);

  if (DiskIo2 != NULL) {
    //
    // Call BlockIo2::Reset() to terminate any in-flight non-blocking I/O requests
    //
    ASSERT (Instance->BlockIo2 != NULL);
    Status = Instance->BlockIo2->Reset (Instance->BlockIo2, FALSE);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = gBS->UninstallMultipleProtocolInterfaces (
                    ControllerHandle,
                    &gEfiDiskIoProtocolGuid,
                    &Instance->DiskIo,
                    &gEfiDiskIo2ProtocolGuid,
                    &Instance->DiskIo2,
                    NULL
                    );
  } else {
    Status = gBS->UninstallMultipleProtocolInterfaces (
                    ControllerHandle,
                    &gEfiDiskIoProtocolGuid,
                    &Instance->DiskIo,
                    NULL
                    );
  }

  if (!EFI_ERROR (Status)) {
    do {
      EfiAcquireLock (&Instance->TaskQueueLock);
      AllTaskDone = IsListEmpty (&Instance->TaskQueue);
      EfiReleaseLock (&Instance->TaskQueueLock);
    } while (!AllTaskDone);

    FreeAlignedPages (
      Instance->SharedWorkingBuffer,
      EFI_SIZE_TO_PAGES (PcdGet32 (PcdDiskIoDataBufferBlockNum) * Instance->BlockIo->Media->BlockSize)
      );

    Status = gBS->CloseProtocol (
                    ControllerHandle,
                    &gEfiBlockIoProtocolGuid,
                    This->DriverBindingHandle,
                    ControllerHandle
                    );
    ASSERT_EFI_ERROR (Status);
    if (DiskIo2 != NULL) {
      Status = gBS->CloseProtocol (
                      ControllerHandle,
                      &gEfiBlockIo2ProtocolGuid,
                      This->DriverBindingHandle,
                      ControllerHandle
                      );
      ASSERT_EFI_ERROR (Status);
    }

    FreePool (Instance);
  }

  return Status;
}

/**
  Destroy the sub task.

  @param Instance     Pointer to the DISK_IO_PRIVATE_DATA.
  @param Subtask      Subtask.

  @return LIST_ENTRY *  Pointer to the next link of subtask.
**/
LIST_ENTRY *
DiskIoDestroySubtask (
  IN DISK_IO_PRIVATE_DATA  *Instance,
  IN DISK_IO_SUBTASK       *Subtask
  )
{
  LIST_ENTRY  *Link;

  if (Subtask->Task != NULL) {
    EfiAcquireLock (&Subtask->Task->SubtasksLock);
  }

  Link = RemoveEntryList (&Subtask->Link);
  if (Subtask->Task != NULL) {
    EfiReleaseLock (&Subtask->Task->SubtasksLock);
  }

  if (!Subtask->Blocking) {
    if (Subtask->WorkingBuffer != NULL) {
      FreeAlignedPages (
        Subtask->WorkingBuffer,
        Subtask->Length < Instance->BlockIo->Media->BlockSize
        ? EFI_SIZE_TO_PAGES (Instance->BlockIo->Media->BlockSize)
        : EFI_SIZE_TO_PAGES (Subtask->Length)
        );
    }

    if (Subtask->BlockIo2Token.Event != NULL) {
      gBS->CloseEvent (Subtask->BlockIo2Token.Event);
    }
  }

  FreePool (Subtask);

  return Link;
}

/**
  The callback for the BlockIo2 ReadBlocksEx/WriteBlocksEx.
  @param  Event                 Event whose notification function is being invoked.
  @param  Context               The pointer to the notification function's context,
                                which points to the DISK_IO_SUBTASK instance.
**/
VOID
EFIAPI
DiskIo2OnReadWriteComplete (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  DISK_IO_SUBTASK       *Subtask;
  DISK_IO2_TASK         *Task;
  EFI_STATUS            TransactionStatus;
  DISK_IO_PRIVATE_DATA  *Instance;

  Subtask           = (DISK_IO_SUBTASK *)Context;
  TransactionStatus = Subtask->BlockIo2Token.TransactionStatus;
  Task              = Subtask->Task;
  Instance          = Task->Instance;

  ASSERT (Subtask->Signature  == DISK_IO_SUBTASK_SIGNATURE);
  ASSERT (Instance->Signature == DISK_IO_PRIVATE_DATA_SIGNATURE);
  ASSERT (Task->Signature     == DISK_IO2_TASK_SIGNATURE);

  if ((Subtask->WorkingBuffer != NULL) && !EFI_ERROR (TransactionStatus) &&
      (Task->Token != NULL) && !Subtask->Write
      )
  {
    CopyMem (Subtask->Buffer, Subtask->WorkingBuffer + Subtask->Offset, Subtask->Length);
  }

  DiskIoDestroySubtask (Instance, Subtask);

  if (EFI_ERROR (TransactionStatus) || IsListEmpty (&Task->Subtasks)) {
    if (Task->Token != NULL) {
      //
      // Signal error status once the subtask is failed.
      // Or signal the last status once the last subtask is finished.
      //
      Task->Token->TransactionStatus = TransactionStatus;
      gBS->SignalEvent (Task->Token->Event);

      //
      // Mark token to NULL indicating the Task is a dead task.
      //
      Task->Token = NULL;
    }
  }
}

/**
  Create the subtask.

  @param Write         TRUE: Write request; FALSE: Read request.
  @param Lba           The starting logical block address to read from on the device.
  @param Offset        The starting byte offset to read from the LBA.
  @param Length        The number of bytes to read from the device.
  @param WorkingBuffer The aligned buffer to hold the data for reading or writing.
  @param Buffer        The buffer to hold the data for reading or writing.
  @param Blocking      TRUE: Blocking request; FALSE: Non-blocking request.

  @return A pointer to the created subtask.
**/
DISK_IO_SUBTASK *
DiskIoCreateSubtask (
  IN BOOLEAN  Write,
  IN UINT64   Lba,
  IN UINT32   Offset,
  IN UINTN    Length,
  IN VOID     *WorkingBuffer   OPTIONAL,
  IN VOID     *Buffer,
  IN BOOLEAN  Blocking
  )
{
  DISK_IO_SUBTASK  *Subtask;
  EFI_STATUS       Status;

  Subtask = AllocateZeroPool (sizeof (DISK_IO_SUBTASK));
  if (Subtask == NULL) {
    return NULL;
  }

  Subtask->Signature     = DISK_IO_SUBTASK_SIGNATURE;
  Subtask->Write         = Write;
  Subtask->Lba           = Lba;
  Subtask->Offset        = Offset;
  Subtask->Length        = Length;
  Subtask->WorkingBuffer = WorkingBuffer;
  Subtask->Buffer        = Buffer;
  Subtask->Blocking      = Blocking;
  if (!Blocking) {
    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    DiskIo2OnReadWriteComplete,
                    Subtask,
                    &Subtask->BlockIo2Token.Event
                    );
    if (EFI_ERROR (Status)) {
      FreePool (Subtask);
      return NULL;
    }
  }

  DEBUG ((
    DEBUG_BLKIO,
    "  %c:Lba/Offset/Length/WorkingBuffer/Buffer = %016lx/%08x/%08x/%08x/%08x\n",
    Write ? 'W' : 'R',
    Lba,
    Offset,
    Length,
    WorkingBuffer,
    Buffer
    ));

  return Subtask;
}

/**
  Create the subtask list.

  @param Instance            Pointer to the DISK_IO_PRIVATE_DATA.
  @param Write               TRUE: Write request; FALSE: Read request.
  @param Offset              The starting byte offset to read from the device.
  @param BufferSize          The size in bytes of Buffer. The number of bytes to read from the device.
  @param Buffer              A pointer to the buffer for the data.
  @param Blocking            TRUE: Blocking request; FALSE: Non-blocking request.
  @param SharedWorkingBuffer The aligned buffer to hold the data for reading or writing.
  @param Subtasks            The subtask list header.

  @retval TRUE  The subtask list is created successfully.
  @retval FALSE The subtask list is not created.
**/
BOOLEAN
DiskIoCreateSubtaskList (
  IN DISK_IO_PRIVATE_DATA  *Instance,
  IN BOOLEAN               Write,
  IN UINT64                Offset,
  IN UINTN                 BufferSize,
  IN VOID                  *Buffer,
  IN BOOLEAN               Blocking,
  IN VOID                  *SharedWorkingBuffer,
  IN OUT LIST_ENTRY        *Subtasks
  )
{
  UINT32           BlockSize;
  UINT32           IoAlign;
  UINT64           Lba;
  UINT64           OverRunLba;
  UINT32           UnderRun;
  UINT32           OverRun;
  UINT8            *BufferPtr;
  UINTN            Length;
  UINTN            DataBufferSize;
  DISK_IO_SUBTASK  *Subtask;
  VOID             *WorkingBuffer;
  LIST_ENTRY       *Link;

  DEBUG ((DEBUG_BLKIO, "DiskIo: Create subtasks for task: Offset/BufferSize/Buffer = %016lx/%08x/%08x\n", Offset, BufferSize, Buffer));

  BlockSize = Instance->BlockIo->Media->BlockSize;
  IoAlign   = Instance->BlockIo->Media->IoAlign;
  if (IoAlign == 0) {
    IoAlign = 1;
  }

  Lba       = DivU64x32Remainder (Offset, BlockSize, &UnderRun);
  BufferPtr = (UINT8 *)Buffer;

  //
  // Special handling for zero BufferSize
  //
  if (BufferSize == 0) {
    Subtask = DiskIoCreateSubtask (Write, Lba, UnderRun, 0, NULL, BufferPtr, Blocking);
    if (Subtask == NULL) {
      goto Done;
    }

    InsertTailList (Subtasks, &Subtask->Link);
    return TRUE;
  }

  if (UnderRun != 0) {
    Length = MIN (BlockSize - UnderRun, BufferSize);
    if (Blocking) {
      WorkingBuffer = SharedWorkingBuffer;
    } else {
      WorkingBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BlockSize), IoAlign);
      if (WorkingBuffer == NULL) {
        goto Done;
      }
    }

    if (Write) {
      //
      // A half write operation can be splitted to a blocking block-read and half write operation
      // This can simplify the sub task processing logic
      //
      Subtask = DiskIoCreateSubtask (FALSE, Lba, 0, BlockSize, NULL, WorkingBuffer, TRUE);
      if (Subtask == NULL) {
        goto Done;
      }

      InsertTailList (Subtasks, &Subtask->Link);
    }

    Subtask = DiskIoCreateSubtask (Write, Lba, UnderRun, Length, WorkingBuffer, BufferPtr, Blocking);
    if (Subtask == NULL) {
      goto Done;
    }

    InsertTailList (Subtasks, &Subtask->Link);

    BufferPtr  += Length;
    Offset     += Length;
    BufferSize -= Length;
    Lba++;
  }

  OverRunLba  = Lba + DivU64x32Remainder (BufferSize, BlockSize, &OverRun);
  BufferSize -= OverRun;

  if (OverRun != 0) {
    if (Blocking) {
      WorkingBuffer = SharedWorkingBuffer;
    } else {
      WorkingBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BlockSize), IoAlign);
      if (WorkingBuffer == NULL) {
        goto Done;
      }
    }

    if (Write) {
      //
      // A half write operation can be splitted to a blocking block-read and half write operation
      // This can simplify the sub task processing logic
      //
      Subtask = DiskIoCreateSubtask (FALSE, OverRunLba, 0, BlockSize, NULL, WorkingBuffer, TRUE);
      if (Subtask == NULL) {
        goto Done;
      }

      InsertTailList (Subtasks, &Subtask->Link);
    }

    Subtask = DiskIoCreateSubtask (Write, OverRunLba, 0, OverRun, WorkingBuffer, BufferPtr + BufferSize, Blocking);
    if (Subtask == NULL) {
      goto Done;
    }

    InsertTailList (Subtasks, &Subtask->Link);
  }

  if (OverRunLba > Lba) {
    //
    // If the DiskIo maps directly to a BlockIo device do the read.
    //
    if (ALIGN_POINTER (BufferPtr, IoAlign) == BufferPtr) {
      Subtask = DiskIoCreateSubtask (Write, Lba, 0, BufferSize, NULL, BufferPtr, Blocking);
      if (Subtask == NULL) {
        goto Done;
      }

      InsertTailList (Subtasks, &Subtask->Link);

      BufferPtr  += BufferSize;
      Offset     += BufferSize;
      BufferSize -= BufferSize;
    } else {
      if (Blocking) {
        //
        // Use the allocated buffer instead of the original buffer
        // to avoid alignment issue.
        //
        for ( ; Lba < OverRunLba; Lba += PcdGet32 (PcdDiskIoDataBufferBlockNum)) {
          DataBufferSize = MIN (BufferSize, PcdGet32 (PcdDiskIoDataBufferBlockNum) * BlockSize);

          Subtask = DiskIoCreateSubtask (Write, Lba, 0, DataBufferSize, SharedWorkingBuffer, BufferPtr, Blocking);
          if (Subtask == NULL) {
            goto Done;
          }

          InsertTailList (Subtasks, &Subtask->Link);

          BufferPtr  += DataBufferSize;
          Offset     += DataBufferSize;
          BufferSize -= DataBufferSize;
        }
      } else {
        WorkingBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (BufferSize), IoAlign);
        if (WorkingBuffer == NULL) {
          //
          // If there is not enough memory, downgrade to blocking access
          //
          DEBUG ((DEBUG_VERBOSE, "DiskIo: No enough memory so downgrade to blocking access\n"));
          if (!DiskIoCreateSubtaskList (Instance, Write, Offset, BufferSize, BufferPtr, TRUE, SharedWorkingBuffer, Subtasks)) {
            goto Done;
          }
        } else {
          Subtask = DiskIoCreateSubtask (Write, Lba, 0, BufferSize, WorkingBuffer, BufferPtr, Blocking);
          if (Subtask == NULL) {
            goto Done;
          }

          InsertTailList (Subtasks, &Subtask->Link);
        }

        BufferPtr  += BufferSize;
        Offset     += BufferSize;
        BufferSize -= BufferSize;
      }
    }
  }

  ASSERT (BufferSize == 0);

  return TRUE;

Done:
  //
  // Remove all the subtasks.
  //
  for (Link = GetFirstNode (Subtasks); !IsNull (Subtasks, Link); ) {
    Subtask = CR (Link, DISK_IO_SUBTASK, Link, DISK_IO_SUBTASK_SIGNATURE);
    Link    = DiskIoDestroySubtask (Instance, Subtask);
  }

  return FALSE;
}

/**
  Terminate outstanding asynchronous requests to a device.

  @param This                   Indicates a pointer to the calling context.

  @retval EFI_SUCCESS           All outstanding requests were successfully terminated.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the cancel
                                operation.
**/
EFI_STATUS
EFIAPI
DiskIo2Cancel (
  IN EFI_DISK_IO2_PROTOCOL  *This
  )
{
  DISK_IO_PRIVATE_DATA  *Instance;
  DISK_IO2_TASK         *Task;
  LIST_ENTRY            *Link;

  Instance = DISK_IO_PRIVATE_DATA_FROM_DISK_IO2 (This);

  EfiAcquireLock (&Instance->TaskQueueLock);

  for (Link = GetFirstNode (&Instance->TaskQueue)
       ; !IsNull (&Instance->TaskQueue, Link)
       ; Link = GetNextNode (&Instance->TaskQueue, Link)
       )
  {
    Task = CR (Link, DISK_IO2_TASK, Link, DISK_IO2_TASK_SIGNATURE);

    if (Task->Token != NULL) {
      Task->Token->TransactionStatus = EFI_ABORTED;
      gBS->SignalEvent (Task->Token->Event);
      //
      // Set Token to NULL so that the further BlockIo2 responses will be ignored
      //
      Task->Token = NULL;
    }
  }

  EfiReleaseLock (&Instance->TaskQueueLock);

  return EFI_SUCCESS;
}

/**
  Remove the completed tasks from Instance->TaskQueue. Completed tasks are those who don't have any subtasks.

  @param Instance    Pointer to the DISK_IO_PRIVATE_DATA.

  @retval TRUE       The Instance->TaskQueue is empty after the completed tasks are removed.
  @retval FALSE      The Instance->TaskQueue is not empty after the completed tasks are removed.
**/
BOOLEAN
DiskIo2RemoveCompletedTask (
  IN DISK_IO_PRIVATE_DATA  *Instance
  )
{
  BOOLEAN        QueueEmpty;
  LIST_ENTRY     *Link;
  DISK_IO2_TASK  *Task;

  QueueEmpty = TRUE;

  EfiAcquireLock (&Instance->TaskQueueLock);
  for (Link = GetFirstNode (&Instance->TaskQueue); !IsNull (&Instance->TaskQueue, Link); ) {
    Task = CR (Link, DISK_IO2_TASK, Link, DISK_IO2_TASK_SIGNATURE);
    if (IsListEmpty (&Task->Subtasks)) {
      Link = RemoveEntryList (&Task->Link);
      ASSERT (Task->Token == NULL);
      FreePool (Task);
    } else {
      Link       = GetNextNode (&Instance->TaskQueue, Link);
      QueueEmpty = FALSE;
    }
  }

  EfiReleaseLock (&Instance->TaskQueueLock);

  return QueueEmpty;
}

/**
  Common routine to access the disk.

  @param Instance    Pointer to the DISK_IO_PRIVATE_DATA.
  @param Write       TRUE: Write operation; FALSE: Read operation.
  @param MediaId     ID of the medium to access.
  @param Offset      The starting byte offset on the logical block I/O device to access.
  @param Token       A pointer to the token associated with the transaction.
                     If this field is NULL, synchronous/blocking IO is performed.
  @param  BufferSize            The size in bytes of Buffer. The number of bytes to read from the device.
  @param  Buffer                A pointer to the destination buffer for the data.
                                The caller is responsible either having implicit or explicit ownership of the buffer.
**/
EFI_STATUS
DiskIo2ReadWriteDisk (
  IN DISK_IO_PRIVATE_DATA  *Instance,
  IN BOOLEAN               Write,
  IN UINT32                MediaId,
  IN UINT64                Offset,
  IN EFI_DISK_IO2_TOKEN    *Token,
  IN UINTN                 BufferSize,
  IN UINT8                 *Buffer
  )
{
  EFI_STATUS              Status;
  EFI_BLOCK_IO_PROTOCOL   *BlockIo;
  EFI_BLOCK_IO2_PROTOCOL  *BlockIo2;
  EFI_BLOCK_IO_MEDIA      *Media;
  LIST_ENTRY              *Link;
  LIST_ENTRY              *NextLink;
  LIST_ENTRY              Subtasks;
  DISK_IO_SUBTASK         *Subtask;
  DISK_IO2_TASK           *Task;
  EFI_TPL                 SubtaskPerformTpl;
  EFI_TPL                 SubtaskLockTpl;
  BOOLEAN                 Blocking;
  BOOLEAN                 SubtaskBlocking;
  LIST_ENTRY              *SubtasksPtr;

  Task     = NULL;
  BlockIo  = Instance->BlockIo;
  BlockIo2 = Instance->BlockIo2;
  Media    = BlockIo->Media;
  Status   = EFI_SUCCESS;
  Blocking = (BOOLEAN)((Token == NULL) || (Token->Event == NULL));

  if (Blocking) {
    //
    // Wait till pending async task is completed.
    //
    while (!DiskIo2RemoveCompletedTask (Instance)) {
    }

    SubtasksPtr = &Subtasks;
  } else {
    DiskIo2RemoveCompletedTask (Instance);
    Task = AllocatePool (sizeof (DISK_IO2_TASK));
    if (Task == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    EfiAcquireLock (&Instance->TaskQueueLock);
    InsertTailList (&Instance->TaskQueue, &Task->Link);
    EfiReleaseLock (&Instance->TaskQueueLock);

    Task->Signature = DISK_IO2_TASK_SIGNATURE;
    Task->Instance  = Instance;
    Task->Token     = Token;
    EfiInitializeLock (&Task->SubtasksLock, TPL_NOTIFY);

    SubtasksPtr = &Task->Subtasks;
  }

  InitializeListHead (SubtasksPtr);
  if (!DiskIoCreateSubtaskList (Instance, Write, Offset, BufferSize, Buffer, Blocking, Instance->SharedWorkingBuffer, SubtasksPtr)) {
    if (Task != NULL) {
      FreePool (Task);
    }

    return EFI_OUT_OF_RESOURCES;
  }

  ASSERT (!IsListEmpty (SubtasksPtr));

  SubtaskPerformTpl = gBS->RaiseTPL (TPL_CALLBACK);
  for ( Link = GetFirstNode (SubtasksPtr), NextLink = GetNextNode (SubtasksPtr, Link)
        ; !IsNull (SubtasksPtr, Link)
        ; Link = NextLink, NextLink = GetNextNode (SubtasksPtr, NextLink)
        )
  {
    Subtask         = CR (Link, DISK_IO_SUBTASK, Link, DISK_IO_SUBTASK_SIGNATURE);
    Subtask->Task   = Task;
    SubtaskBlocking = Subtask->Blocking;

    ASSERT ((Subtask->Length % Media->BlockSize == 0) || (Subtask->Length < Media->BlockSize));

    if (Subtask->Write) {
      //
      // Write
      //
      if (Subtask->WorkingBuffer != NULL) {
        //
        // A sub task before this one should be a block read operation, causing the WorkingBuffer filled with the entire one block data.
        //
        CopyMem (Subtask->WorkingBuffer + Subtask->Offset, Subtask->Buffer, Subtask->Length);
      }

      if (SubtaskBlocking) {
        Status = BlockIo->WriteBlocks (
                            BlockIo,
                            MediaId,
                            Subtask->Lba,
                            (Subtask->Length % Media->BlockSize == 0) ? Subtask->Length : Media->BlockSize,
                            (Subtask->WorkingBuffer != NULL) ? Subtask->WorkingBuffer : Subtask->Buffer
                            );
      } else {
        Status = BlockIo2->WriteBlocksEx (
                             BlockIo2,
                             MediaId,
                             Subtask->Lba,
                             &Subtask->BlockIo2Token,
                             (Subtask->Length % Media->BlockSize == 0) ? Subtask->Length : Media->BlockSize,
                             (Subtask->WorkingBuffer != NULL) ? Subtask->WorkingBuffer : Subtask->Buffer
                             );
      }
    } else {
      //
      // Read
      //
      if (SubtaskBlocking) {
        Status = BlockIo->ReadBlocks (
                            BlockIo,
                            MediaId,
                            Subtask->Lba,
                            (Subtask->Length % Media->BlockSize == 0) ? Subtask->Length : Media->BlockSize,
                            (Subtask->WorkingBuffer != NULL) ? Subtask->WorkingBuffer : Subtask->Buffer
                            );
        if (!EFI_ERROR (Status) && (Subtask->WorkingBuffer != NULL)) {
          CopyMem (Subtask->Buffer, Subtask->WorkingBuffer + Subtask->Offset, Subtask->Length);
        }
      } else {
        Status = BlockIo2->ReadBlocksEx (
                             BlockIo2,
                             MediaId,
                             Subtask->Lba,
                             &Subtask->BlockIo2Token,
                             (Subtask->Length % Media->BlockSize == 0) ? Subtask->Length : Media->BlockSize,
                             (Subtask->WorkingBuffer != NULL) ? Subtask->WorkingBuffer : Subtask->Buffer
                             );
      }
    }

    if (SubtaskBlocking || EFI_ERROR (Status)) {
      //
      // Make sure the subtask list only contains non-blocking subtasks.
      // Remove failed non-blocking subtasks as well because the callback won't be called.
      //
      DiskIoDestroySubtask (Instance, Subtask);
    }

    if (EFI_ERROR (Status)) {
      break;
    }
  }

  SubtaskLockTpl = gBS->RaiseTPL (TPL_NOTIFY);

  //
  // Remove all the remaining subtasks when failure.
  // We shouldn't remove all the tasks because the non-blocking requests have been submitted and cannot be canceled.
  //
  if (EFI_ERROR (Status)) {
    while (!IsNull (SubtasksPtr, NextLink)) {
      Subtask  = CR (NextLink, DISK_IO_SUBTASK, Link, DISK_IO_SUBTASK_SIGNATURE);
      NextLink = DiskIoDestroySubtask (Instance, Subtask);
    }
  }

  //
  // It's possible that the non-blocking subtasks finish before raising TPL to NOTIFY,
  // so the subtasks list might be empty at this point.
  //
  if (!Blocking && IsListEmpty (SubtasksPtr)) {
    EfiAcquireLock (&Instance->TaskQueueLock);
    RemoveEntryList (&Task->Link);
    EfiReleaseLock (&Instance->TaskQueueLock);

    if (!EFI_ERROR (Status) && (Task->Token != NULL)) {
      //
      // Task->Token should be set to NULL by the DiskIo2OnReadWriteComplete
      // It it's not, that means the non-blocking request was downgraded to blocking request.
      //
      DEBUG ((DEBUG_VERBOSE, "DiskIo: Non-blocking request was downgraded to blocking request, signal event directly.\n"));
      Task->Token->TransactionStatus = Status;
      gBS->SignalEvent (Task->Token->Event);
    }

    FreePool (Task);
  }

  gBS->RestoreTPL (SubtaskLockTpl);
  gBS->RestoreTPL (SubtaskPerformTpl);

  return Status;
}

/**
  Reads a specified number of bytes from a device.

  @param This                   Indicates a pointer to the calling context.
  @param MediaId                ID of the medium to be read.
  @param Offset                 The starting byte offset on the logical block I/O device to read from.
  @param Token                  A pointer to the token associated with the transaction.
                                If this field is NULL, synchronous/blocking IO is performed.
  @param  BufferSize            The size in bytes of Buffer. The number of bytes to read from the device.
  @param  Buffer                A pointer to the destination buffer for the data.
                                The caller is responsible either having implicit or explicit ownership of the buffer.

  @retval EFI_SUCCESS           If Event is NULL (blocking I/O): The data was read correctly from the device.
                                If Event is not NULL (asynchronous I/O): The request was successfully queued for processing.
                                                                         Event will be signaled upon completion.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.
  @retval EFI_NO_MEDIA          There is no medium in the device.
  @retval EFI_MEDIA_CHNAGED     The MediaId is not for the current medium.
  @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not valid for the device.
  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

**/
EFI_STATUS
EFIAPI
DiskIo2ReadDiskEx (
  IN EFI_DISK_IO2_PROTOCOL   *This,
  IN UINT32                  MediaId,
  IN UINT64                  Offset,
  IN OUT EFI_DISK_IO2_TOKEN  *Token,
  IN UINTN                   BufferSize,
  OUT VOID                   *Buffer
  )
{
  return DiskIo2ReadWriteDisk (
           DISK_IO_PRIVATE_DATA_FROM_DISK_IO2 (This),
           FALSE,
           MediaId,
           Offset,
           Token,
           BufferSize,
           (UINT8 *)Buffer
           );
}

/**
  Writes a specified number of bytes to a device.

  @param This        Indicates a pointer to the calling context.
  @param MediaId     ID of the medium to be written.
  @param Offset      The starting byte offset on the logical block I/O device to write to.
  @param Token       A pointer to the token associated with the transaction.
                     If this field is NULL, synchronous/blocking IO is performed.
  @param BufferSize  The size in bytes of Buffer. The number of bytes to write to the device.
  @param Buffer      A pointer to the buffer containing the data to be written.

  @retval EFI_SUCCESS           If Event is NULL (blocking I/O): The data was written correctly to the device.
                                If Event is not NULL (asynchronous I/O): The request was successfully queued for processing.
                                                                         Event will be signaled upon completion.
  @retval EFI_WRITE_PROTECTED   The device cannot be written to.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write operation.
  @retval EFI_NO_MEDIA          There is no medium in the device.
  @retval EFI_MEDIA_CHNAGED     The MediaId is not for the current medium.
  @retval EFI_INVALID_PARAMETER The write request contains device addresses that are not valid for the device.
  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.

**/
EFI_STATUS
EFIAPI
DiskIo2WriteDiskEx (
  IN EFI_DISK_IO2_PROTOCOL   *This,
  IN UINT32                  MediaId,
  IN UINT64                  Offset,
  IN OUT EFI_DISK_IO2_TOKEN  *Token,
  IN UINTN                   BufferSize,
  IN VOID                    *Buffer
  )
{
  return DiskIo2ReadWriteDisk (
           DISK_IO_PRIVATE_DATA_FROM_DISK_IO2 (This),
           TRUE,
           MediaId,
           Offset,
           Token,
           BufferSize,
           (UINT8 *)Buffer
           );
}

/**
  The callback for the BlockIo2 FlushBlocksEx.
  @param  Event                 Event whose notification function is being invoked.
  @param  Context               The pointer to the notification function's context,
                                which points to the DISK_IO2_FLUSH_TASK instance.
**/
VOID
EFIAPI
DiskIo2OnFlushComplete (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  DISK_IO2_FLUSH_TASK  *Task;

  gBS->CloseEvent (Event);

  Task = (DISK_IO2_FLUSH_TASK *)Context;
  ASSERT (Task->Signature == DISK_IO2_FLUSH_TASK_SIGNATURE);
  Task->Token->TransactionStatus = Task->BlockIo2Token.TransactionStatus;
  gBS->SignalEvent (Task->Token->Event);

  FreePool (Task);
}

/**
  Flushes all modified data to the physical device.

  @param This        Indicates a pointer to the calling context.
  @param Token       A pointer to the token associated with the transaction.
                     If this field is NULL, synchronous/blocking IO is performed.

  @retval EFI_SUCCESS           If Event is NULL (blocking I/O): The data was flushed successfully to the device.
                                If Event is not NULL (asynchronous I/O): The request was successfully queued for processing.
                                                                         Event will be signaled upon completion.
  @retval EFI_WRITE_PROTECTED   The device cannot be written to.
  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write operation.
  @retval EFI_NO_MEDIA          There is no medium in the device.
  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.
**/
EFI_STATUS
EFIAPI
DiskIo2FlushDiskEx (
  IN EFI_DISK_IO2_PROTOCOL   *This,
  IN OUT EFI_DISK_IO2_TOKEN  *Token
  )
{
  EFI_STATUS            Status;
  DISK_IO2_FLUSH_TASK   *Task;
  DISK_IO_PRIVATE_DATA  *Private;

  Private = DISK_IO_PRIVATE_DATA_FROM_DISK_IO2 (This);

  if ((Token != NULL) && (Token->Event != NULL)) {
    Task = AllocatePool (sizeof (DISK_IO2_FLUSH_TASK));
    if (Task == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_CALLBACK,
                    DiskIo2OnFlushComplete,
                    Task,
                    &Task->BlockIo2Token.Event
                    );
    if (EFI_ERROR (Status)) {
      FreePool (Task);
      return Status;
    }

    Task->Signature = DISK_IO2_FLUSH_TASK_SIGNATURE;
    Task->Token     = Token;
    Status          = Private->BlockIo2->FlushBlocksEx (Private->BlockIo2, &Task->BlockIo2Token);
    if (EFI_ERROR (Status)) {
      gBS->CloseEvent (Task->BlockIo2Token.Event);
      FreePool (Task);
    }
  } else {
    Status = Private->BlockIo2->FlushBlocksEx (Private->BlockIo2, NULL);
  }

  return Status;
}

/**
  Read BufferSize bytes from Offset into Buffer.
  Reads may support reads that are not aligned on
  sector boundaries. There are three cases:
    UnderRun - The first byte is not on a sector boundary or the read request is
               less than a sector in length.
    Aligned  - A read of N contiguous sectors.
    OverRun  - The last byte is not on a sector boundary.

  @param  This                  Protocol instance pointer.
  @param  MediaId               Id of the media, changes every time the media is replaced.
  @param  Offset                The starting byte offset to read from
  @param  BufferSize            Size of Buffer
  @param  Buffer                Buffer containing read data

  @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_CHNAGED     The MediaId does not matched the current device.
  @retval EFI_INVALID_PARAMETER The read request contains device addresses that are not
                                valid for the device.

**/
EFI_STATUS
EFIAPI
DiskIoReadDisk (
  IN EFI_DISK_IO_PROTOCOL  *This,
  IN UINT32                MediaId,
  IN UINT64                Offset,
  IN UINTN                 BufferSize,
  OUT VOID                 *Buffer
  )
{
  return DiskIo2ReadWriteDisk (
           DISK_IO_PRIVATE_DATA_FROM_DISK_IO (This),
           FALSE,
           MediaId,
           Offset,
           NULL,
           BufferSize,
           (UINT8 *)Buffer
           );
}

/**
  Writes BufferSize bytes from Buffer into Offset.
  Writes may require a read modify write to support writes that are not
  aligned on sector boundaries. There are three cases:
    UnderRun - The first byte is not on a sector boundary or the write request
               is less than a sector in length. Read modify write is required.
    Aligned  - A write of N contiguous sectors.
    OverRun  - The last byte is not on a sector boundary. Read modified write
               required.

  @param  This       Protocol instance pointer.
  @param  MediaId    Id of the media, changes every time the media is replaced.
  @param  Offset     The starting byte offset to read from
  @param  BufferSize Size of Buffer
  @param  Buffer     Buffer containing read 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_CHNAGED     The MediaId does not matched the current device.
  @retval EFI_INVALID_PARAMETER The write request contains device addresses that are not
                                 valid for the device.

**/
EFI_STATUS
EFIAPI
DiskIoWriteDisk (
  IN EFI_DISK_IO_PROTOCOL  *This,
  IN UINT32                MediaId,
  IN UINT64                Offset,
  IN UINTN                 BufferSize,
  IN VOID                  *Buffer
  )
{
  return DiskIo2ReadWriteDisk (
           DISK_IO_PRIVATE_DATA_FROM_DISK_IO (This),
           TRUE,
           MediaId,
           Offset,
           NULL,
           BufferSize,
           (UINT8 *)Buffer
           );
}

/**
  The user Entry Point for module DiskIo. 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
InitializeDiskIo (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  //
  // Install driver model protocol(s).
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gDiskIoDriverBinding,
             ImageHandle,
             &gDiskIoComponentName,
             &gDiskIoComponentName2
             );
  ASSERT_EFI_ERROR (Status);

  return Status;
}
