/** @file

  This driver produces Extended SCSI Pass Thru Protocol instances for
  pvscsi devices.

  Copyright (C) 2020, Oracle and/or its affiliates.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <IndustryStandard/Pci.h>
#include <IndustryStandard/PvScsi.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Protocol/PciIo.h>
#include <Protocol/PciRootBridgeIo.h>
#include <Uefi/UefiSpec.h>

#include "PvScsi.h"

//
// Higher versions will be used before lower, 0x10-0xffffffef is the version
// range for IHV (Indie Hardware Vendors)
//
#define PVSCSI_BINDING_VERSION  0x10

//
// Ext SCSI Pass Thru utilities
//

/**
  Reads a 32-bit value into BAR0 using MMIO
**/
STATIC
EFI_STATUS
PvScsiMmioRead32 (
  IN CONST PVSCSI_DEV  *Dev,
  IN UINT64            Offset,
  OUT UINT32           *Value
  )
{
  return Dev->PciIo->Mem.Read (
                           Dev->PciIo,
                           EfiPciIoWidthUint32,
                           PCI_BAR_IDX0,
                           Offset,
                           1,   // Count
                           Value
                           );
}

/**
  Writes a 32-bit value into BAR0 using MMIO
**/
STATIC
EFI_STATUS
PvScsiMmioWrite32 (
  IN CONST PVSCSI_DEV  *Dev,
  IN UINT64            Offset,
  IN UINT32            Value
  )
{
  return Dev->PciIo->Mem.Write (
                           Dev->PciIo,
                           EfiPciIoWidthUint32,
                           PCI_BAR_IDX0,
                           Offset,
                           1,   // Count
                           &Value
                           );
}

/**
  Writes multiple words of data into BAR0 using MMIO
**/
STATIC
EFI_STATUS
PvScsiMmioWrite32Multiple (
  IN CONST PVSCSI_DEV  *Dev,
  IN UINT64            Offset,
  IN UINTN             Count,
  IN UINT32            *Words
  )
{
  return Dev->PciIo->Mem.Write (
                           Dev->PciIo,
                           EfiPciIoWidthFifoUint32,
                           PCI_BAR_IDX0,
                           Offset,
                           Count,
                           Words
                           );
}

/**
  Send a PVSCSI command to device.

  @param[in] Dev                    The pvscsi host device.
  @param[in] Cmd                    The command to send to device.
  @param[in] OPTIONAL DescWords     An optional command descriptor (If command
                                    have a descriptor). The descriptor is
                                    provided as an array of UINT32 words and
                                    is must be 32-bit aligned.
  @param[in] DescWordsCount         The number of words in command descriptor.
                                    Caller must specify here 0 if DescWords
                                    is not supplied (It is optional). In that
                                    case, DescWords is ignored.

  @return   Status codes returned by Dev->PciIo->Mem.Write().

**/
STATIC
EFI_STATUS
PvScsiWriteCmdDesc (
  IN CONST PVSCSI_DEV  *Dev,
  IN UINT32            Cmd,
  IN UINT32            *DescWords      OPTIONAL,
  IN UINTN             DescWordsCount
  )
{
  EFI_STATUS  Status;

  if (DescWordsCount > PVSCSI_MAX_CMD_DATA_WORDS) {
    return EFI_INVALID_PARAMETER;
  }

  Status = PvScsiMmioWrite32 (Dev, PvScsiRegOffsetCommand, Cmd);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (DescWordsCount > 0) {
    return PvScsiMmioWrite32Multiple (
             Dev,
             PvScsiRegOffsetCommandData,
             DescWordsCount,
             DescWords
             );
  }

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
PvScsiResetAdapter (
  IN CONST PVSCSI_DEV  *Dev
  )
{
  return PvScsiWriteCmdDesc (Dev, PvScsiCmdAdapterReset, NULL, 0);
}

/**
  Returns if PVSCSI request ring is full
**/
STATIC
BOOLEAN
PvScsiIsReqRingFull (
  IN CONST PVSCSI_DEV  *Dev
  )
{
  PVSCSI_RINGS_STATE  *RingsState;
  UINT32              ReqNumEntries;

  RingsState    = Dev->RingDesc.RingState;
  ReqNumEntries = 1U << RingsState->ReqNumEntriesLog2;
  return (RingsState->ReqProdIdx - RingsState->CmpConsIdx) >= ReqNumEntries;
}

/**
  Returns pointer to current request descriptor to produce
**/
STATIC
PVSCSI_RING_REQ_DESC *
PvScsiGetCurrentRequest (
  IN CONST PVSCSI_DEV  *Dev
  )
{
  PVSCSI_RINGS_STATE  *RingState;
  UINT32              ReqNumEntries;

  RingState     = Dev->RingDesc.RingState;
  ReqNumEntries = 1U << RingState->ReqNumEntriesLog2;
  return Dev->RingDesc.RingReqs +
         (RingState->ReqProdIdx & (ReqNumEntries - 1));
}

/**
  Returns pointer to current completion descriptor to consume
**/
STATIC
PVSCSI_RING_CMP_DESC *
PvScsiGetCurrentResponse (
  IN CONST PVSCSI_DEV  *Dev
  )
{
  PVSCSI_RINGS_STATE  *RingState;
  UINT32              CmpNumEntries;

  RingState     = Dev->RingDesc.RingState;
  CmpNumEntries = 1U << RingState->CmpNumEntriesLog2;
  return Dev->RingDesc.RingCmps +
         (RingState->CmpConsIdx & (CmpNumEntries - 1));
}

/**
  Wait for device to signal completion of submitted requests
**/
STATIC
EFI_STATUS
PvScsiWaitForRequestCompletion (
  IN CONST PVSCSI_DEV  *Dev
  )
{
  EFI_STATUS  Status;
  UINT32      IntrStatus;

  //
  // Note: We don't yet support Timeout according to
  // EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET.Timeout.
  //
  // This is consistent with some other Scsi PassThru drivers
  // such as VirtioScsi.
  //
  for ( ; ;) {
    Status = PvScsiMmioRead32 (Dev, PvScsiRegOffsetIntrStatus, &IntrStatus);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // PVSCSI_INTR_CMPL_MASK is set if device completed submitted requests
    //
    if ((IntrStatus & PVSCSI_INTR_CMPL_MASK) != 0) {
      break;
    }

    gBS->Stall (Dev->WaitForCmpStallInUsecs);
  }

  //
  // Acknowledge PVSCSI_INTR_CMPL_MASK in device interrupt-status register
  //
  return PvScsiMmioWrite32 (
           Dev,
           PvScsiRegOffsetIntrStatus,
           PVSCSI_INTR_CMPL_MASK
           );
}

/**
  Create a fake host adapter error
**/
STATIC
EFI_STATUS
ReportHostAdapterError (
  OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet
  )
{
  Packet->InTransferLength  = 0;
  Packet->OutTransferLength = 0;
  Packet->SenseDataLength   = 0;
  Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
  Packet->TargetStatus      = EFI_EXT_SCSI_STATUS_TARGET_GOOD;
  return EFI_DEVICE_ERROR;
}

/**
  Create a fake host adapter overrun error
**/
STATIC
EFI_STATUS
ReportHostAdapterOverrunError (
  OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet
  )
{
  Packet->SenseDataLength   = 0;
  Packet->HostAdapterStatus =
    EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;
  Packet->TargetStatus = EFI_EXT_SCSI_STATUS_TARGET_GOOD;
  return EFI_BAD_BUFFER_SIZE;
}

/**
  Populate a PVSCSI request descriptor from the Extended SCSI Pass Thru
  Protocol packet.
**/
STATIC
EFI_STATUS
PopulateRequest (
  IN CONST PVSCSI_DEV                                *Dev,
  IN UINT8                                           *Target,
  IN UINT64                                          Lun,
  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet,
  OUT PVSCSI_RING_REQ_DESC                           *Request
  )
{
  UINT8  TargetValue;

  //
  // We only use first byte of target identifer
  //
  TargetValue = *Target;

  //
  // Check for unsupported requests
  //
  if (
      //
      // Bidirectional transfer was requested
      //
      ((Packet->InTransferLength > 0) && (Packet->OutTransferLength > 0)) ||
      (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL) ||
      //
      // Command Descriptor Block bigger than this constant should be considered
      // out-of-band. We currently don't support these CDBs.
      //
      (Packet->CdbLength > PVSCSI_CDB_MAX_SIZE)
      )
  {
    //
    // This error code doesn't require updates to the Packet output fields
    //
    return EFI_UNSUPPORTED;
  }

  //
  // Check for invalid parameters
  //
  if (
      //
      // Addressed invalid device
      //
      (TargetValue > Dev->MaxTarget) || (Lun > Dev->MaxLun) ||
      //
      // Invalid direction (there doesn't seem to be a macro for the "no data
      // transferred" "direction", eg. for TEST UNIT READY)
      //
      (Packet->DataDirection > EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL) ||
      //
      // Trying to receive, but destination pointer is NULL, or contradicting
      // transfer direction
      //
      ((Packet->InTransferLength > 0) &&
       ((Packet->InDataBuffer == NULL) ||
        (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_WRITE)
       )
      ) ||
      //
      // Trying to send, but source pointer is NULL, or contradicting
      // transfer direction
      //
      ((Packet->OutTransferLength > 0) &&
       ((Packet->OutDataBuffer == NULL) ||
        (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ)
       )
      )
      )
  {
    //
    // This error code doesn't require updates to the Packet output fields
    //
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check for input/output buffer too large for DMA communication buffer
  //
  if (Packet->InTransferLength > sizeof (Dev->DmaBuf->Data)) {
    Packet->InTransferLength = sizeof (Dev->DmaBuf->Data);
    return ReportHostAdapterOverrunError (Packet);
  }

  if (Packet->OutTransferLength > sizeof (Dev->DmaBuf->Data)) {
    Packet->OutTransferLength = sizeof (Dev->DmaBuf->Data);
    return ReportHostAdapterOverrunError (Packet);
  }

  //
  // Encode PVSCSI request
  //
  ZeroMem (Request, sizeof (*Request));

  Request->Bus    = 0;
  Request->Target = TargetValue;
  //
  // This cast is safe as PVSCSI_DEV.MaxLun is defined as UINT8
  //
  Request->Lun[1]   = (UINT8)Lun;
  Request->SenseLen = Packet->SenseDataLength;
  //
  // DMA communication buffer SenseData overflow is not possible
  // due to Packet->SenseDataLength defined as UINT8
  //
  Request->SenseAddr = PVSCSI_DMA_BUF_DEV_ADDR (Dev, SenseData);
  Request->CdbLen    = Packet->CdbLength;
  CopyMem (Request->Cdb, Packet->Cdb, Packet->CdbLength);
  Request->VcpuHint = 0;
  Request->Tag      = PVSCSI_SIMPLE_QUEUE_TAG;
  if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
    Request->Flags   = PVSCSI_FLAG_CMD_DIR_TOHOST;
    Request->DataLen = Packet->InTransferLength;
  } else {
    Request->Flags   = PVSCSI_FLAG_CMD_DIR_TODEVICE;
    Request->DataLen = Packet->OutTransferLength;
    CopyMem (
      Dev->DmaBuf->Data,
      Packet->OutDataBuffer,
      Packet->OutTransferLength
      );
  }

  Request->DataAddr = PVSCSI_DMA_BUF_DEV_ADDR (Dev, Data);

  return EFI_SUCCESS;
}

/**
  Handle the PVSCSI device response:
  - Copy returned data from DMA communication buffer.
  - Update fields in Extended SCSI Pass Thru Protocol packet as required.
  - Translate response code to EFI status code and host adapter status.
**/
STATIC
EFI_STATUS
HandleResponse (
  IN PVSCSI_DEV                                      *Dev,
  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet,
  IN CONST PVSCSI_RING_CMP_DESC                      *Response
  )
{
  //
  // Fix SenseDataLength to amount of data returned
  //
  if (Packet->SenseDataLength > Response->SenseLen) {
    Packet->SenseDataLength = (UINT8)Response->SenseLen;
  }

  //
  // Copy sense data from DMA communication buffer
  //
  CopyMem (
    Packet->SenseData,
    Dev->DmaBuf->SenseData,
    Packet->SenseDataLength
    );

  //
  // Copy device output from DMA communication buffer
  //
  if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
    CopyMem (Packet->InDataBuffer, Dev->DmaBuf->Data, Packet->InTransferLength);
  }

  //
  // Report target status
  // (Strangely, PVSCSI interface defines Response->ScsiStatus as UINT16.
  // But it should de-facto always have a value that fits UINT8. To avoid
  // unexpected behavior, verify value is in UINT8 bounds before casting)
  //
  ASSERT (Response->ScsiStatus <= MAX_UINT8);
  Packet->TargetStatus = (UINT8)Response->ScsiStatus;

  //
  // Host adapter status and function return value depend on
  // device response's host status
  //
  switch (Response->HostStatus) {
    case PvScsiBtStatSuccess:
    case PvScsiBtStatLinkedCommandCompleted:
    case PvScsiBtStatLinkedCommandCompletedWithFlag:
      Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;
      return EFI_SUCCESS;

    case PvScsiBtStatDataUnderrun:
      //
      // Report transferred amount in underrun
      //
      if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
        Packet->InTransferLength = (UINT32)Response->DataLen;
      } else {
        Packet->OutTransferLength = (UINT32)Response->DataLen;
      }

      Packet->HostAdapterStatus =
        EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;
      return EFI_SUCCESS;

    case PvScsiBtStatDatarun:
      Packet->HostAdapterStatus =
        EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;
      return EFI_SUCCESS;

    case PvScsiBtStatSelTimeout:
      Packet->HostAdapterStatus =
        EFI_EXT_SCSI_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT;
      return EFI_TIMEOUT;

    case PvScsiBtStatBusFree:
      Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_FREE;
      break;

    case PvScsiBtStatInvPhase:
      Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PHASE_ERROR;
      break;

    case PvScsiBtStatSensFailed:
      Packet->HostAdapterStatus =
        EFI_EXT_SCSI_STATUS_HOST_ADAPTER_REQUEST_SENSE_FAILED;
      break;

    case PvScsiBtStatTagReject:
    case PvScsiBtStatBadMsg:
      Packet->HostAdapterStatus =
        EFI_EXT_SCSI_STATUS_HOST_ADAPTER_MESSAGE_REJECT;
      break;

    case PvScsiBtStatBusReset:
      Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_RESET;
      break;

    case PvScsiBtStatHaTimeout:
      Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT;
      return EFI_TIMEOUT;

    case PvScsiBtStatScsiParity:
      Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_PARITY_ERROR;
      break;

    default:
      Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
      break;
  }

  return EFI_DEVICE_ERROR;
}

/**
  Check if Target argument to EXT_SCSI_PASS_THRU.GetNextTarget() and
  EXT_SCSI_PASS_THRU.GetNextTargetLun() is initialized
**/
STATIC
BOOLEAN
IsTargetInitialized (
  IN UINT8  *Target
  )
{
  UINTN  Idx;

  for (Idx = 0; Idx < TARGET_MAX_BYTES; ++Idx) {
    if (Target[Idx] != 0xFF) {
      return TRUE;
    }
  }

  return FALSE;
}

//
// Ext SCSI Pass Thru
//

STATIC
EFI_STATUS
EFIAPI
PvScsiPassThru (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL                 *This,
  IN UINT8                                           *Target,
  IN UINT64                                          Lun,
  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet,
  IN EFI_EVENT                                       Event    OPTIONAL
  )
{
  PVSCSI_DEV            *Dev;
  EFI_STATUS            Status;
  PVSCSI_RING_REQ_DESC  *Request;
  PVSCSI_RING_CMP_DESC  *Response;

  Dev = PVSCSI_FROM_PASS_THRU (This);

  if (PvScsiIsReqRingFull (Dev)) {
    return EFI_NOT_READY;
  }

  Request = PvScsiGetCurrentRequest (Dev);

  Status = PopulateRequest (Dev, Target, Lun, Packet, Request);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Writes to Request must be globally visible before making request
  // available to device
  //
  MemoryFence ();
  Dev->RingDesc.RingState->ReqProdIdx++;

  Status = PvScsiMmioWrite32 (Dev, PvScsiRegOffsetKickRwIo, 0);
  if (EFI_ERROR (Status)) {
    //
    // If kicking the host fails, we must fake a host adapter error.
    // EFI_NOT_READY would save us the effort, but it would also suggest that
    // the caller retry.
    //
    return ReportHostAdapterError (Packet);
  }

  Status = PvScsiWaitForRequestCompletion (Dev);
  if (EFI_ERROR (Status)) {
    //
    // If waiting for request completion fails, we must fake a host adapter
    // error. EFI_NOT_READY would save us the effort, but it would also suggest
    // that the caller retry.
    //
    return ReportHostAdapterError (Packet);
  }

  Response = PvScsiGetCurrentResponse (Dev);
  Status   = HandleResponse (Dev, Packet, Response);

  //
  // Reads from response must complete before releasing completion entry
  // to device
  //
  MemoryFence ();
  Dev->RingDesc.RingState->CmpConsIdx++;

  return Status;
}

STATIC
EFI_STATUS
EFIAPI
PvScsiGetNextTargetLun (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN OUT UINT8                        **Target,
  IN OUT UINT64                       *Lun
  )
{
  UINT8       *TargetPtr;
  UINT8       LastTarget;
  PVSCSI_DEV  *Dev;

  if (Target == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // The Target input parameter is unnecessarily a pointer-to-pointer
  //
  TargetPtr = *Target;

  //
  // If target not initialized, return first target & LUN
  //
  if (!IsTargetInitialized (TargetPtr)) {
    ZeroMem (TargetPtr, TARGET_MAX_BYTES);
    *Lun = 0;
    return EFI_SUCCESS;
  }

  //
  // We only use first byte of target identifer
  //
  LastTarget = *TargetPtr;

  //
  // Increment (target, LUN) pair if valid on input
  //
  Dev = PVSCSI_FROM_PASS_THRU (This);
  if ((LastTarget > Dev->MaxTarget) || (*Lun > Dev->MaxLun)) {
    return EFI_INVALID_PARAMETER;
  }

  if (*Lun < Dev->MaxLun) {
    ++*Lun;
    return EFI_SUCCESS;
  }

  if (LastTarget < Dev->MaxTarget) {
    *Lun = 0;
    ++LastTarget;
    *TargetPtr = LastTarget;
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}

STATIC
EFI_STATUS
EFIAPI
PvScsiBuildDevicePath (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN UINT8                            *Target,
  IN UINT64                           Lun,
  IN OUT EFI_DEVICE_PATH_PROTOCOL     **DevicePath
  )
{
  UINT8             TargetValue;
  PVSCSI_DEV        *Dev;
  SCSI_DEVICE_PATH  *ScsiDevicePath;

  if (DevicePath == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // We only use first byte of target identifer
  //
  TargetValue = *Target;

  Dev = PVSCSI_FROM_PASS_THRU (This);
  if ((TargetValue > Dev->MaxTarget) || (Lun > Dev->MaxLun)) {
    return EFI_NOT_FOUND;
  }

  ScsiDevicePath = AllocatePool (sizeof (*ScsiDevicePath));
  if (ScsiDevicePath == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  ScsiDevicePath->Header.Type      = MESSAGING_DEVICE_PATH;
  ScsiDevicePath->Header.SubType   = MSG_SCSI_DP;
  ScsiDevicePath->Header.Length[0] = (UINT8)sizeof (*ScsiDevicePath);
  ScsiDevicePath->Header.Length[1] = (UINT8)(sizeof (*ScsiDevicePath) >> 8);
  ScsiDevicePath->Pun              = TargetValue;
  ScsiDevicePath->Lun              = (UINT16)Lun;

  *DevicePath = &ScsiDevicePath->Header;
  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
PvScsiGetTargetLun (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN EFI_DEVICE_PATH_PROTOCOL         *DevicePath,
  OUT UINT8                           **Target,
  OUT UINT64                          *Lun
  )
{
  SCSI_DEVICE_PATH  *ScsiDevicePath;
  PVSCSI_DEV        *Dev;

  if ((DevicePath == NULL) || (Target == NULL) || (*Target == NULL) || (Lun == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((DevicePath->Type    != MESSAGING_DEVICE_PATH) ||
      (DevicePath->SubType != MSG_SCSI_DP))
  {
    return EFI_UNSUPPORTED;
  }

  ScsiDevicePath = (SCSI_DEVICE_PATH *)DevicePath;
  Dev            = PVSCSI_FROM_PASS_THRU (This);
  if ((ScsiDevicePath->Pun > Dev->MaxTarget) ||
      (ScsiDevicePath->Lun > Dev->MaxLun))
  {
    return EFI_NOT_FOUND;
  }

  //
  // We only use first byte of target identifer
  //
  **Target = (UINT8)ScsiDevicePath->Pun;
  ZeroMem (*Target + 1, TARGET_MAX_BYTES - 1);
  *Lun = ScsiDevicePath->Lun;

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
PvScsiResetChannel (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This
  )
{
  return EFI_UNSUPPORTED;
}

STATIC
EFI_STATUS
EFIAPI
PvScsiResetTargetLun (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN UINT8                            *Target,
  IN UINT64                           Lun
  )
{
  return EFI_UNSUPPORTED;
}

STATIC
EFI_STATUS
EFIAPI
PvScsiGetNextTarget (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN OUT UINT8                        **Target
  )
{
  UINT8       *TargetPtr;
  UINT8       LastTarget;
  PVSCSI_DEV  *Dev;

  if (Target == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // The Target input parameter is unnecessarily a pointer-to-pointer
  //
  TargetPtr = *Target;

  //
  // If target not initialized, return first target
  //
  if (!IsTargetInitialized (TargetPtr)) {
    ZeroMem (TargetPtr, TARGET_MAX_BYTES);
    return EFI_SUCCESS;
  }

  //
  // We only use first byte of target identifer
  //
  LastTarget = *TargetPtr;

  //
  // Increment target if valid on input
  //
  Dev = PVSCSI_FROM_PASS_THRU (This);
  if (LastTarget > Dev->MaxTarget) {
    return EFI_INVALID_PARAMETER;
  }

  if (LastTarget < Dev->MaxTarget) {
    ++LastTarget;
    *TargetPtr = LastTarget;
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}

STATIC
EFI_STATUS
PvScsiSetPciAttributes (
  IN OUT PVSCSI_DEV  *Dev
  )
{
  EFI_STATUS  Status;

  //
  // Backup original PCI Attributes
  //
  Status = Dev->PciIo->Attributes (
                         Dev->PciIo,
                         EfiPciIoAttributeOperationGet,
                         0,
                         &Dev->OriginalPciAttributes
                         );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Enable MMIO-Space & Bus-Mastering
  //
  Status = Dev->PciIo->Attributes (
                         Dev->PciIo,
                         EfiPciIoAttributeOperationEnable,
                         (EFI_PCI_IO_ATTRIBUTE_MEMORY |
                          EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),
                         NULL
                         );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Signal device supports 64-bit DMA addresses
  //
  Status = Dev->PciIo->Attributes (
                         Dev->PciIo,
                         EfiPciIoAttributeOperationEnable,
                         EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE,
                         NULL
                         );
  if (EFI_ERROR (Status)) {
    //
    // Warn user that device will only be using 32-bit DMA addresses.
    //
    // Note that this does not prevent the device/driver from working
    // and therefore we only warn and continue as usual.
    //
    DEBUG ((
      DEBUG_WARN,
      "%a: failed to enable 64-bit DMA addresses\n",
      __func__
      ));
  }

  return EFI_SUCCESS;
}

STATIC
VOID
PvScsiRestorePciAttributes (
  IN PVSCSI_DEV  *Dev
  )
{
  Dev->PciIo->Attributes (
                Dev->PciIo,
                EfiPciIoAttributeOperationSet,
                Dev->OriginalPciAttributes,
                NULL
                );
}

STATIC
EFI_STATUS
PvScsiAllocateSharedPages (
  IN PVSCSI_DEV        *Dev,
  IN UINTN             Pages,
  OUT VOID             **HostAddress,
  OUT PVSCSI_DMA_DESC  *DmaDesc
  )
{
  EFI_STATUS  Status;
  UINTN       NumberOfBytes;

  Status = Dev->PciIo->AllocateBuffer (
                         Dev->PciIo,
                         AllocateAnyPages,
                         EfiBootServicesData,
                         Pages,
                         HostAddress,
                         EFI_PCI_ATTRIBUTE_MEMORY_CACHED
                         );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  NumberOfBytes = EFI_PAGES_TO_SIZE (Pages);
  Status        = Dev->PciIo->Map (
                                Dev->PciIo,
                                EfiPciIoOperationBusMasterCommonBuffer,
                                *HostAddress,
                                &NumberOfBytes,
                                &DmaDesc->DeviceAddress,
                                &DmaDesc->Mapping
                                );
  if (EFI_ERROR (Status)) {
    goto FreeBuffer;
  }

  if (NumberOfBytes != EFI_PAGES_TO_SIZE (Pages)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Unmap;
  }

  return EFI_SUCCESS;

Unmap:
  Dev->PciIo->Unmap (Dev->PciIo, DmaDesc->Mapping);

FreeBuffer:
  Dev->PciIo->FreeBuffer (Dev->PciIo, Pages, *HostAddress);

  return Status;
}

STATIC
VOID
PvScsiFreeSharedPages (
  IN PVSCSI_DEV       *Dev,
  IN UINTN            Pages,
  IN VOID             *HostAddress,
  IN PVSCSI_DMA_DESC  *DmaDesc
  )
{
  Dev->PciIo->Unmap (Dev->PciIo, DmaDesc->Mapping);
  Dev->PciIo->FreeBuffer (Dev->PciIo, Pages, HostAddress);
}

STATIC
EFI_STATUS
PvScsiInitRings (
  IN OUT PVSCSI_DEV  *Dev
  )
{
  EFI_STATUS  Status;

  Status = PvScsiAllocateSharedPages (
             Dev,
             1,
             (VOID **)&Dev->RingDesc.RingState,
             &Dev->RingDesc.RingStateDmaDesc
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  ZeroMem (Dev->RingDesc.RingState, EFI_PAGE_SIZE);

  Status = PvScsiAllocateSharedPages (
             Dev,
             1,
             (VOID **)&Dev->RingDesc.RingReqs,
             &Dev->RingDesc.RingReqsDmaDesc
             );
  if (EFI_ERROR (Status)) {
    goto FreeRingState;
  }

  ZeroMem (Dev->RingDesc.RingReqs, EFI_PAGE_SIZE);

  Status = PvScsiAllocateSharedPages (
             Dev,
             1,
             (VOID **)&Dev->RingDesc.RingCmps,
             &Dev->RingDesc.RingCmpsDmaDesc
             );
  if (EFI_ERROR (Status)) {
    goto FreeRingReqs;
  }

  ZeroMem (Dev->RingDesc.RingCmps, EFI_PAGE_SIZE);

  return EFI_SUCCESS;

FreeRingReqs:
  PvScsiFreeSharedPages (
    Dev,
    1,
    Dev->RingDesc.RingReqs,
    &Dev->RingDesc.RingReqsDmaDesc
    );

FreeRingState:
  PvScsiFreeSharedPages (
    Dev,
    1,
    Dev->RingDesc.RingState,
    &Dev->RingDesc.RingStateDmaDesc
    );

  return Status;
}

STATIC
VOID
PvScsiFreeRings (
  IN OUT PVSCSI_DEV  *Dev
  )
{
  PvScsiFreeSharedPages (
    Dev,
    1,
    Dev->RingDesc.RingCmps,
    &Dev->RingDesc.RingCmpsDmaDesc
    );

  PvScsiFreeSharedPages (
    Dev,
    1,
    Dev->RingDesc.RingReqs,
    &Dev->RingDesc.RingReqsDmaDesc
    );

  PvScsiFreeSharedPages (
    Dev,
    1,
    Dev->RingDesc.RingState,
    &Dev->RingDesc.RingStateDmaDesc
    );
}

STATIC
EFI_STATUS
PvScsiSetupRings (
  IN OUT PVSCSI_DEV  *Dev
  )
{
  union {
    PVSCSI_CMD_DESC_SETUP_RINGS    Cmd;
    UINT32                         Uint32;
  } AlignedCmd;
  PVSCSI_CMD_DESC_SETUP_RINGS  *Cmd;

  Cmd = &AlignedCmd.Cmd;

  ZeroMem (Cmd, sizeof (*Cmd));
  Cmd->ReqRingNumPages = 1;
  Cmd->CmpRingNumPages = 1;
  Cmd->RingsStatePPN   = RShiftU64 (
                           Dev->RingDesc.RingStateDmaDesc.DeviceAddress,
                           EFI_PAGE_SHIFT
                           );
  Cmd->ReqRingPPNs[0] = RShiftU64 (
                          Dev->RingDesc.RingReqsDmaDesc.DeviceAddress,
                          EFI_PAGE_SHIFT
                          );
  Cmd->CmpRingPPNs[0] = RShiftU64 (
                          Dev->RingDesc.RingCmpsDmaDesc.DeviceAddress,
                          EFI_PAGE_SHIFT
                          );

  STATIC_ASSERT (
    sizeof (*Cmd) % sizeof (UINT32) == 0,
    "Cmd must be multiple of 32-bit words"
    );
  return PvScsiWriteCmdDesc (
           Dev,
           PvScsiCmdSetupRings,
           (UINT32 *)Cmd,
           sizeof (*Cmd) / sizeof (UINT32)
           );
}

STATIC
EFI_STATUS
PvScsiInit (
  IN OUT PVSCSI_DEV  *Dev
  )
{
  EFI_STATUS  Status;

  //
  // Init configuration
  //
  Dev->MaxTarget              = PcdGet8 (PcdPvScsiMaxTargetLimit);
  Dev->MaxLun                 = PcdGet8 (PcdPvScsiMaxLunLimit);
  Dev->WaitForCmpStallInUsecs = PcdGet32 (PcdPvScsiWaitForCmpStallInUsecs);

  //
  // Set PCI Attributes
  //
  Status = PvScsiSetPciAttributes (Dev);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Reset adapter
  //
  Status = PvScsiResetAdapter (Dev);
  if (EFI_ERROR (Status)) {
    goto RestorePciAttributes;
  }

  //
  // Init PVSCSI rings
  //
  Status = PvScsiInitRings (Dev);
  if (EFI_ERROR (Status)) {
    goto RestorePciAttributes;
  }

  //
  // Allocate DMA communication buffer
  //
  Status = PvScsiAllocateSharedPages (
             Dev,
             EFI_SIZE_TO_PAGES (sizeof (*Dev->DmaBuf)),
             (VOID **)&Dev->DmaBuf,
             &Dev->DmaBufDmaDesc
             );
  if (EFI_ERROR (Status)) {
    goto FreeRings;
  }

  //
  // Setup rings against device
  //
  Status = PvScsiSetupRings (Dev);
  if (EFI_ERROR (Status)) {
    goto FreeDmaCommBuffer;
  }

  //
  // Populate the exported interface's attributes
  //
  Dev->PassThru.Mode             = &Dev->PassThruMode;
  Dev->PassThru.PassThru         = &PvScsiPassThru;
  Dev->PassThru.GetNextTargetLun = &PvScsiGetNextTargetLun;
  Dev->PassThru.BuildDevicePath  = &PvScsiBuildDevicePath;
  Dev->PassThru.GetTargetLun     = &PvScsiGetTargetLun;
  Dev->PassThru.ResetChannel     = &PvScsiResetChannel;
  Dev->PassThru.ResetTargetLun   = &PvScsiResetTargetLun;
  Dev->PassThru.GetNextTarget    = &PvScsiGetNextTarget;

  //
  // AdapterId is a target for which no handle will be created during bus scan.
  // Prevent any conflict with real devices.
  //
  Dev->PassThruMode.AdapterId = MAX_UINT32;

  //
  // Set both physical and logical attributes for non-RAID SCSI channel
  //
  Dev->PassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL |
                                 EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;

  //
  // No restriction on transfer buffer alignment
  //
  Dev->PassThruMode.IoAlign = 0;

  return EFI_SUCCESS;

FreeDmaCommBuffer:
  PvScsiFreeSharedPages (
    Dev,
    EFI_SIZE_TO_PAGES (sizeof (*Dev->DmaBuf)),
    Dev->DmaBuf,
    &Dev->DmaBufDmaDesc
    );

FreeRings:
  PvScsiFreeRings (Dev);

RestorePciAttributes:
  PvScsiRestorePciAttributes (Dev);

  return Status;
}

STATIC
VOID
PvScsiUninit (
  IN OUT PVSCSI_DEV  *Dev
  )
{
  //
  // Reset device to:
  // - Make device stop processing all requests.
  // - Stop device usage of the rings.
  //
  // This is required to safely free the DMA communication buffer
  // and the rings.
  //
  PvScsiResetAdapter (Dev);

  //
  // Free DMA communication buffer
  //
  PvScsiFreeSharedPages (
    Dev,
    EFI_SIZE_TO_PAGES (sizeof (*Dev->DmaBuf)),
    Dev->DmaBuf,
    &Dev->DmaBufDmaDesc
    );

  PvScsiFreeRings (Dev);

  PvScsiRestorePciAttributes (Dev);
}

/**
  Event notification called by ExitBootServices()
**/
STATIC
VOID
EFIAPI
PvScsiExitBoot (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  PVSCSI_DEV  *Dev;

  Dev = Context;
  DEBUG ((DEBUG_VERBOSE, "%a: Context=0x%p\n", __func__, Context));

  //
  // Reset the device to stop device usage of the rings.
  //
  // We allocated said rings in EfiBootServicesData type memory, and code
  // executing after ExitBootServices() is permitted to overwrite it.
  //
  PvScsiResetAdapter (Dev);
}

//
// Driver Binding
//

STATIC
EFI_STATUS
EFIAPI
PvScsiDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS           Status;
  EFI_PCI_IO_PROTOCOL  *PciIo;
  PCI_TYPE00           Pci;

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiPciIoProtocolGuid,
                  (VOID **)&PciIo,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = PciIo->Pci.Read (
                        PciIo,
                        EfiPciIoWidthUint32,
                        0,
                        sizeof (Pci) / sizeof (UINT32),
                        &Pci
                        );
  if (EFI_ERROR (Status)) {
    goto Done;
  }

  if ((Pci.Hdr.VendorId != PCI_VENDOR_ID_VMWARE) ||
      (Pci.Hdr.DeviceId != PCI_DEVICE_ID_VMWARE_PVSCSI))
  {
    Status = EFI_UNSUPPORTED;
    goto Done;
  }

  Status = EFI_SUCCESS;

Done:
  gBS->CloseProtocol (
         ControllerHandle,
         &gEfiPciIoProtocolGuid,
         This->DriverBindingHandle,
         ControllerHandle
         );

  return Status;
}

STATIC
EFI_STATUS
EFIAPI
PvScsiDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  PVSCSI_DEV  *Dev;
  EFI_STATUS  Status;

  Dev = (PVSCSI_DEV *)AllocateZeroPool (sizeof (*Dev));
  if (Dev == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiPciIoProtocolGuid,
                  (VOID **)&Dev->PciIo,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto FreePvScsi;
  }

  Status = PvScsiInit (Dev);
  if (EFI_ERROR (Status)) {
    goto ClosePciIo;
  }

  Status = gBS->CreateEvent (
                  EVT_SIGNAL_EXIT_BOOT_SERVICES,
                  TPL_CALLBACK,
                  &PvScsiExitBoot,
                  Dev,
                  &Dev->ExitBoot
                  );
  if (EFI_ERROR (Status)) {
    goto UninitDev;
  }

  //
  // Setup complete, attempt to export the driver instance's PassThru interface
  //
  Dev->Signature = PVSCSI_SIG;
  Status         = gBS->InstallProtocolInterface (
                          &ControllerHandle,
                          &gEfiExtScsiPassThruProtocolGuid,
                          EFI_NATIVE_INTERFACE,
                          &Dev->PassThru
                          );
  if (EFI_ERROR (Status)) {
    goto CloseExitBoot;
  }

  return EFI_SUCCESS;

CloseExitBoot:
  gBS->CloseEvent (Dev->ExitBoot);

UninitDev:
  PvScsiUninit (Dev);

ClosePciIo:
  gBS->CloseProtocol (
         ControllerHandle,
         &gEfiPciIoProtocolGuid,
         This->DriverBindingHandle,
         ControllerHandle
         );

FreePvScsi:
  FreePool (Dev);

  return Status;
}

STATIC
EFI_STATUS
EFIAPI
PvScsiDriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN UINTN                        NumberOfChildren,
  IN EFI_HANDLE                   *ChildHandleBuffer
  )
{
  EFI_STATUS                       Status;
  EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *PassThru;
  PVSCSI_DEV                       *Dev;

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiExtScsiPassThruProtocolGuid,
                  (VOID **)&PassThru,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL // Lookup only
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Dev = PVSCSI_FROM_PASS_THRU (PassThru);

  Status = gBS->UninstallProtocolInterface (
                  ControllerHandle,
                  &gEfiExtScsiPassThruProtocolGuid,
                  &Dev->PassThru
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  gBS->CloseEvent (Dev->ExitBoot);

  PvScsiUninit (Dev);

  gBS->CloseProtocol (
         ControllerHandle,
         &gEfiPciIoProtocolGuid,
         This->DriverBindingHandle,
         ControllerHandle
         );

  FreePool (Dev);

  return EFI_SUCCESS;
}

STATIC EFI_DRIVER_BINDING_PROTOCOL  mPvScsiDriverBinding = {
  &PvScsiDriverBindingSupported,
  &PvScsiDriverBindingStart,
  &PvScsiDriverBindingStop,
  PVSCSI_BINDING_VERSION,
  NULL, // ImageHandle, filled by EfiLibInstallDriverBindingComponentName2()
  NULL  // DriverBindingHandle, filled as well
};

//
// Component Name
//

STATIC EFI_UNICODE_STRING_TABLE  mDriverNameTable[] = {
  { "eng;en", L"PVSCSI Host Driver" },
  { NULL,     NULL                  }
};

STATIC EFI_COMPONENT_NAME_PROTOCOL  mComponentName;

STATIC
EFI_STATUS
EFIAPI
PvScsiGetDriverName (
  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
  IN  CHAR8                        *Language,
  OUT CHAR16                       **DriverName
  )
{
  return LookupUnicodeString2 (
           Language,
           This->SupportedLanguages,
           mDriverNameTable,
           DriverName,
           (BOOLEAN)(This == &mComponentName) // Iso639Language
           );
}

STATIC
EFI_STATUS
EFIAPI
PvScsiGetDeviceName (
  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
  IN  EFI_HANDLE                   DeviceHandle,
  IN  EFI_HANDLE                   ChildHandle,
  IN  CHAR8                        *Language,
  OUT CHAR16                       **ControllerName
  )
{
  return EFI_UNSUPPORTED;
}

STATIC EFI_COMPONENT_NAME_PROTOCOL  mComponentName = {
  &PvScsiGetDriverName,
  &PvScsiGetDeviceName,
  "eng" // SupportedLanguages, ISO 639-2 language codes
};

STATIC EFI_COMPONENT_NAME2_PROTOCOL  mComponentName2 = {
  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)&PvScsiGetDriverName,
  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)&PvScsiGetDeviceName,
  "en" // SupportedLanguages, RFC 4646 language codes
};

//
// Entry Point
//

EFI_STATUS
EFIAPI
PvScsiEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  return EfiLibInstallDriverBindingComponentName2 (
           ImageHandle,
           SystemTable,
           &mPvScsiDriverBinding,
           ImageHandle,
           &mComponentName,
           &mComponentName2
           );
}
