/** @file

  This driver produces Extended SCSI Pass Thru Protocol instances for
  LSI Fusion MPT SCSI devices.

  Copyright (C) 2020, Oracle and/or its affiliates.

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <IndustryStandard/FusionMptScsi.h>
#include <IndustryStandard/Pci.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Protocol/PciIo.h>
#include <Protocol/PciRootBridgeIo.h>
#include <Protocol/ScsiPassThruExt.h>
#include <Uefi/UefiSpec.h>

//
// Higher versions will be used before lower, 0x10-0xffffffef is the version
// range for IVH (Indie Hardware Vendors)
//
#define MPT_SCSI_BINDING_VERSION  0x10

//
// Runtime Structures
//

typedef struct {
  MPT_SCSI_REQUEST_ALIGNED     IoRequest;
  MPT_SCSI_IO_REPLY_ALIGNED    IoReply;
  //
  // As EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET.SenseDataLength is defined
  // as UINT8, defining here SenseData size to MAX_UINT8 will guarantee it
  // cannot overflow when passed to device.
  //
  UINT8                        Sense[MAX_UINT8];
  //
  // This size of the data is arbitrarily chosen.
  // It seems to be sufficient for all I/O requests sent through
  // EFI_SCSI_PASS_THRU_PROTOCOL.PassThru() for common boot scenarios.
  //
  UINT8                        Data[0x2000];
} MPT_SCSI_DMA_BUFFER;

#define MPT_SCSI_DEV_SIGNATURE  SIGNATURE_32 ('M','P','T','S')
typedef struct {
  UINT32                             Signature;
  EFI_EXT_SCSI_PASS_THRU_PROTOCOL    PassThru;
  EFI_EXT_SCSI_PASS_THRU_MODE        PassThruMode;
  UINT8                              MaxTarget;
  UINT32                             StallPerPollUsec;
  EFI_PCI_IO_PROTOCOL                *PciIo;
  UINT64                             OriginalPciAttributes;
  EFI_EVENT                          ExitBoot;
  MPT_SCSI_DMA_BUFFER                *Dma;
  EFI_PHYSICAL_ADDRESS               DmaPhysical;
  VOID                               *DmaMapping;
  BOOLEAN                            IoReplyEnqueued;
} MPT_SCSI_DEV;

#define MPT_SCSI_FROM_PASS_THRU(PassThruPtr) \
  CR (PassThruPtr, MPT_SCSI_DEV, PassThru, MPT_SCSI_DEV_SIGNATURE)

#define MPT_SCSI_DMA_ADDR(Dev, MemberName) \
  (Dev->DmaPhysical + OFFSET_OF (MPT_SCSI_DMA_BUFFER, MemberName))

#define MPT_SCSI_DMA_ADDR_HIGH(Dev, MemberName) \
  ((UINT32)RShiftU64 (MPT_SCSI_DMA_ADDR (Dev, MemberName), 32))

#define MPT_SCSI_DMA_ADDR_LOW(Dev, MemberName) \
  ((UINT32)MPT_SCSI_DMA_ADDR (Dev, MemberName))

//
// Hardware functions
//

STATIC
EFI_STATUS
Out32 (
  IN MPT_SCSI_DEV  *Dev,
  IN UINT32        Addr,
  IN UINT32        Data
  )
{
  return Dev->PciIo->Io.Write (
                          Dev->PciIo,
                          EfiPciIoWidthUint32,
                          PCI_BAR_IDX0,
                          Addr,
                          1,
                          &Data
                          );
}

STATIC
EFI_STATUS
In32 (
  IN  MPT_SCSI_DEV  *Dev,
  IN  UINT32        Addr,
  OUT UINT32        *Data
  )
{
  return Dev->PciIo->Io.Read (
                          Dev->PciIo,
                          EfiPciIoWidthUint32,
                          PCI_BAR_IDX0,
                          Addr,
                          1,
                          Data
                          );
}

STATIC
EFI_STATUS
MptDoorbell (
  IN MPT_SCSI_DEV  *Dev,
  IN UINT8         DoorbellFunc,
  IN UINT8         DoorbellArg
  )
{
  return Out32 (
           Dev,
           MPT_REG_DOORBELL,
           (((UINT32)DoorbellFunc) << 24) | (DoorbellArg << 16)
           );
}

STATIC
EFI_STATUS
MptScsiReset (
  IN MPT_SCSI_DEV  *Dev
  )
{
  EFI_STATUS  Status;

  //
  // Reset hardware
  //
  Status = MptDoorbell (Dev, MPT_DOORBELL_RESET, 0);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Mask interrupts
  //
  Status = Out32 (Dev, MPT_REG_IMASK, MPT_IMASK_DOORBELL | MPT_IMASK_REPLY);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Clear interrupt status
  //
  Status = Out32 (Dev, MPT_REG_ISTATUS, 0);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
MptScsiInit (
  IN MPT_SCSI_DEV  *Dev
  )
{
  EFI_STATUS  Status;

  union {
    MPT_IO_CONTROLLER_INIT_REQUEST    Data;
    UINT32                            Uint32;
  } AlignedReq;
  MPT_IO_CONTROLLER_INIT_REQUEST  *Req;
  MPT_IO_CONTROLLER_INIT_REPLY    Reply;
  UINT8                           *ReplyBytes;
  UINT32                          ReplyWord;

  Req = &AlignedReq.Data;

  Status = MptScsiReset (Dev);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  ZeroMem (Req, sizeof (*Req));
  ZeroMem (&Reply, sizeof (Reply));
  Req->WhoInit  = MPT_IOC_WHOINIT_ROM_BIOS;
  Req->Function = MPT_MESSAGE_HDR_FUNCTION_IOC_INIT;
  STATIC_ASSERT (
    FixedPcdGet8 (PcdMptScsiMaxTargetLimit) < 255,
    "Req supports 255 targets only (max target is 254)"
    );
  Req->MaxDevices          = Dev->MaxTarget + 1;
  Req->MaxBuses            = 1;
  Req->ReplyFrameSize      = sizeof Dev->Dma->IoReply.Data;
  Req->HostMfaHighAddr     = MPT_SCSI_DMA_ADDR_HIGH (Dev, IoRequest);
  Req->SenseBufferHighAddr = MPT_SCSI_DMA_ADDR_HIGH (Dev, Sense);

  //
  // Send controller init through doorbell
  //
  STATIC_ASSERT (
    sizeof (*Req) % sizeof (UINT32) == 0,
    "Req must be multiple of UINT32"
    );
  STATIC_ASSERT (
    sizeof (*Req) / sizeof (UINT32) <= MAX_UINT8,
    "Req must fit in MAX_UINT8 Dwords"
    );
  Status = MptDoorbell (
             Dev,
             MPT_DOORBELL_HANDSHAKE,
             (UINT8)(sizeof (*Req) / sizeof (UINT32))
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = Dev->PciIo->Io.Write (
                            Dev->PciIo,
                            EfiPciIoWidthFifoUint32,
                            PCI_BAR_IDX0,
                            MPT_REG_DOORBELL,
                            sizeof (*Req) / sizeof (UINT32),
                            Req
                            );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Read reply through doorbell
  // Each 32bit (Dword) read produces 16bit (Word) of data
  //
  // The reply is read back to complete the doorbell function but it
  // isn't useful because it doesn't contain relevant data or status
  // codes.
  //
  STATIC_ASSERT (
    sizeof (Reply) % sizeof (UINT16) == 0,
    "Reply must be multiple of UINT16"
    );
  ReplyBytes = (UINT8 *)&Reply;
  while (ReplyBytes != (UINT8 *)(&Reply + 1)) {
    Status = In32 (Dev, MPT_REG_DOORBELL, &ReplyWord);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    CopyMem (ReplyBytes, &ReplyWord, sizeof (UINT16));
    ReplyBytes += sizeof (UINT16);
  }

  //
  // Clear interrupts generated by doorbell reply
  //
  Status = Out32 (Dev, MPT_REG_ISTATUS, 0);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
ReportHostAdapterError (
  OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet
  )
{
  DEBUG ((DEBUG_ERROR, "%a: fatal error in scsi request\n", __func__));
  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_TASK_ABORTED;
  return EFI_DEVICE_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;
}

STATIC
EFI_STATUS
MptScsiPopulateRequest (
  IN MPT_SCSI_DEV                                    *Dev,
  IN UINT8                                           Target,
  IN UINT64                                          Lun,
  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet
  )
{
  MPT_SCSI_REQUEST_WITH_SG  *Request;

  Request = &Dev->Dma->IoRequest.Data;

  if ((Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_BIDIRECTIONAL) ||
      ((Packet->InTransferLength > 0) && (Packet->OutTransferLength > 0)) ||
      (Packet->CdbLength > sizeof (Request->Header.Cdb)))
  {
    return EFI_UNSUPPORTED;
  }

  if ((Target > Dev->MaxTarget) || (Lun > 0) ||
      (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)
       )
      )
      )
  {
    return EFI_INVALID_PARAMETER;
  }

  if (Packet->InTransferLength > sizeof (Dev->Dma->Data)) {
    Packet->InTransferLength = sizeof (Dev->Dma->Data);
    return ReportHostAdapterOverrunError (Packet);
  }

  if (Packet->OutTransferLength > sizeof (Dev->Dma->Data)) {
    Packet->OutTransferLength = sizeof (Dev->Dma->Data);
    return ReportHostAdapterOverrunError (Packet);
  }

  ZeroMem (Request, sizeof (*Request));
  Request->Header.TargetId = Target;
  //
  // Only LUN 0 is currently supported, hence the cast is safe
  //
  Request->Header.Lun[1]         = (UINT8)Lun;
  Request->Header.Function       = MPT_MESSAGE_HDR_FUNCTION_SCSI_IO_REQUEST;
  Request->Header.MessageContext = 1; // We handle one request at a time

  Request->Header.CdbLength = Packet->CdbLength;
  CopyMem (Request->Header.Cdb, Packet->Cdb, Packet->CdbLength);

  //
  // SenseDataLength is UINT8, Sense[] is MAX_UINT8, so we can't overflow
  //
  ZeroMem (Dev->Dma->Sense, Packet->SenseDataLength);
  Request->Header.SenseBufferLength     = Packet->SenseDataLength;
  Request->Header.SenseBufferLowAddress = MPT_SCSI_DMA_ADDR_LOW (Dev, Sense);

  Request->Sg.EndOfList         = 1;
  Request->Sg.EndOfBuffer       = 1;
  Request->Sg.LastElement       = 1;
  Request->Sg.ElementType       = MPT_SG_ENTRY_TYPE_SIMPLE;
  Request->Sg.Is64BitAddress    = 1;
  Request->Sg.DataBufferAddress = MPT_SCSI_DMA_ADDR (Dev, Data);

  //
  // "MPT_SG_ENTRY_SIMPLE.Length" is a 24-bit quantity.
  //
  STATIC_ASSERT (
    sizeof (Dev->Dma->Data) < SIZE_16MB,
    "MPT_SCSI_DMA_BUFFER.Data must be smaller than 16MB"
    );

  if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
    Request->Header.DataLength = Packet->InTransferLength;
    Request->Sg.Length         = Packet->InTransferLength;
    Request->Header.Control    = MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ;
  } else {
    Request->Header.DataLength = Packet->OutTransferLength;
    Request->Sg.Length         = Packet->OutTransferLength;
    Request->Header.Control    = MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE;

    CopyMem (Dev->Dma->Data, Packet->OutDataBuffer, Packet->OutTransferLength);
    Request->Sg.BufferContainsData = 1;
  }

  if (Request->Header.DataLength == 0) {
    Request->Header.Control = MPT_SCSIIO_REQUEST_CONTROL_TXDIR_NONE;
  }

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
MptScsiSendRequest (
  IN MPT_SCSI_DEV                                    *Dev,
  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet
  )
{
  EFI_STATUS  Status;

  if (!Dev->IoReplyEnqueued) {
    //
    // Put one free reply frame on the reply queue, the hardware may use it to
    // report an error to us.
    //
    Status = Out32 (Dev, MPT_REG_REP_Q, MPT_SCSI_DMA_ADDR_LOW (Dev, IoReply));
    if (EFI_ERROR (Status)) {
      return EFI_DEVICE_ERROR;
    }

    Dev->IoReplyEnqueued = TRUE;
  }

  Status = Out32 (Dev, MPT_REG_REQ_Q, MPT_SCSI_DMA_ADDR_LOW (Dev, IoRequest));
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
MptScsiGetReply (
  IN MPT_SCSI_DEV  *Dev,
  OUT UINT32       *Reply
  )
{
  EFI_STATUS  Status;
  UINT32      Istatus;
  UINT32      EmptyReply;

  //
  // Timeouts are not supported for
  // EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru() in this implementation.
  //
  for ( ; ;) {
    Status = In32 (Dev, MPT_REG_ISTATUS, &Istatus);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Interrupt raised
    //
    if (Istatus & MPT_IMASK_REPLY) {
      break;
    }

    gBS->Stall (Dev->StallPerPollUsec);
  }

  Status = In32 (Dev, MPT_REG_REP_Q, Reply);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // The driver is supposed to fetch replies until 0xffffffff is returned, which
  // will reset the interrupt status. We put only one request, so we expect the
  // next read reply to be the last.
  //
  Status = In32 (Dev, MPT_REG_REP_Q, &EmptyReply);
  if (EFI_ERROR (Status) || (EmptyReply != MAX_UINT32)) {
    return EFI_DEVICE_ERROR;
  }

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
MptScsiHandleReply (
  IN MPT_SCSI_DEV                                 *Dev,
  IN UINT32                                       Reply,
  OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet
  )
{
  if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
    CopyMem (Packet->InDataBuffer, Dev->Dma->Data, Packet->InTransferLength);
  }

  if (Reply == Dev->Dma->IoRequest.Data.Header.MessageContext) {
    //
    // This is a turbo reply, everything is good
    //
    Packet->SenseDataLength   = 0;
    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;
    Packet->TargetStatus      = EFI_EXT_SCSI_STATUS_TARGET_GOOD;
  } else if ((Reply & BIT31) != 0) {
    DEBUG ((DEBUG_INFO, "%a: Full reply returned\n", __func__));
    //
    // When reply MSB is set, we got a full reply. Since we submitted only one
    // reply frame, we know it's IoReply.
    //
    Dev->IoReplyEnqueued = FALSE;

    Packet->TargetStatus = Dev->Dma->IoReply.Data.ScsiStatus;
    //
    // Make sure device only lowers SenseDataLength before copying sense
    //
    ASSERT (Dev->Dma->IoReply.Data.SenseCount <= Packet->SenseDataLength);
    Packet->SenseDataLength =
      (UINT8)MIN (Dev->Dma->IoReply.Data.SenseCount, Packet->SenseDataLength);
    CopyMem (Packet->SenseData, Dev->Dma->Sense, Packet->SenseDataLength);

    if (Packet->DataDirection == EFI_EXT_SCSI_DATA_DIRECTION_READ) {
      Packet->InTransferLength = Dev->Dma->IoReply.Data.TransferCount;
    } else {
      Packet->OutTransferLength = Dev->Dma->IoReply.Data.TransferCount;
    }

    switch (Dev->Dma->IoReply.Data.IocStatus) {
      case MPT_SCSI_IOCSTATUS_SUCCESS:
        Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;
        break;
      case MPT_SCSI_IOCSTATUS_DEVICE_NOT_THERE:
        Packet->HostAdapterStatus =
          EFI_EXT_SCSI_STATUS_HOST_ADAPTER_SELECTION_TIMEOUT;
        return EFI_TIMEOUT;
      case MPT_SCSI_IOCSTATUS_DATA_UNDERRUN:
      case MPT_SCSI_IOCSTATUS_DATA_OVERRUN:
        Packet->HostAdapterStatus =
          EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;
        break;
      default:
        Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
        return EFI_DEVICE_ERROR;
    }
  } else {
    DEBUG ((DEBUG_ERROR, "%a: unexpected reply (%x)\n", __func__, Reply));
    return ReportHostAdapterError (Packet);
  }

  return EFI_SUCCESS;
}

//
// Ext SCSI Pass Thru
//

STATIC
EFI_STATUS
EFIAPI
MptScsiPassThru (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL                 *This,
  IN UINT8                                           *Target,
  IN UINT64                                          Lun,
  IN OUT EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet,
  IN EFI_EVENT                                       Event     OPTIONAL
  )
{
  EFI_STATUS    Status;
  MPT_SCSI_DEV  *Dev;
  UINT32        Reply;

  Dev = MPT_SCSI_FROM_PASS_THRU (This);
  //
  // We only use first byte of target identifer
  //
  Status = MptScsiPopulateRequest (Dev, *Target, Lun, Packet);
  if (EFI_ERROR (Status)) {
    //
    // MptScsiPopulateRequest modified packet according to the error
    //
    return Status;
  }

  Status = MptScsiSendRequest (Dev, Packet);
  if (EFI_ERROR (Status)) {
    return ReportHostAdapterError (Packet);
  }

  Status = MptScsiGetReply (Dev, &Reply);
  if (EFI_ERROR (Status)) {
    return ReportHostAdapterError (Packet);
  }

  return MptScsiHandleReply (Dev, Reply, Packet);
}

STATIC
BOOLEAN
IsTargetInitialized (
  IN UINT8  *Target
  )
{
  UINTN  Idx;

  for (Idx = 0; Idx < TARGET_MAX_BYTES; ++Idx) {
    if (Target[Idx] != 0xFF) {
      return TRUE;
    }
  }

  return FALSE;
}

STATIC
EFI_STATUS
EFIAPI
MptScsiGetNextTargetLun (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN OUT UINT8                        **Target,
  IN OUT UINT64                       *Lun
  )
{
  MPT_SCSI_DEV  *Dev;

  Dev = MPT_SCSI_FROM_PASS_THRU (This);
  //
  // Currently support only LUN 0, so hardcode it
  //
  if (!IsTargetInitialized (*Target)) {
    ZeroMem (*Target, TARGET_MAX_BYTES);
    *Lun = 0;
  } else if ((**Target > Dev->MaxTarget) || (*Lun > 0)) {
    return EFI_INVALID_PARAMETER;
  } else if (**Target < Dev->MaxTarget) {
    //
    // This device interface support 256 targets only, so it's enough to
    // increment the LSB of Target, as it will never overflow.
    //
    **Target += 1;
  } else {
    return EFI_NOT_FOUND;
  }

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
MptScsiGetNextTarget (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN OUT UINT8                        **Target
  )
{
  MPT_SCSI_DEV  *Dev;

  Dev = MPT_SCSI_FROM_PASS_THRU (This);
  if (!IsTargetInitialized (*Target)) {
    ZeroMem (*Target, TARGET_MAX_BYTES);
  } else if (**Target > Dev->MaxTarget) {
    return EFI_INVALID_PARAMETER;
  } else if (**Target < Dev->MaxTarget) {
    //
    // This device interface support 256 targets only, so it's enough to
    // increment the LSB of Target, as it will never overflow.
    //
    **Target += 1;
  } else {
    return EFI_NOT_FOUND;
  }

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
MptScsiBuildDevicePath (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN UINT8                            *Target,
  IN UINT64                           Lun,
  IN OUT EFI_DEVICE_PATH_PROTOCOL     **DevicePath
  )
{
  MPT_SCSI_DEV      *Dev;
  SCSI_DEVICE_PATH  *ScsiDevicePath;

  if (DevicePath == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // This device support 256 targets only, so it's enough to dereference
  // the LSB of Target.
  //
  Dev = MPT_SCSI_FROM_PASS_THRU (This);
  if ((*Target > Dev->MaxTarget) || (Lun > 0)) {
    return EFI_NOT_FOUND;
  }

  ScsiDevicePath = AllocateZeroPool (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              = *Target;
  ScsiDevicePath->Lun              = (UINT16)Lun;

  *DevicePath = &ScsiDevicePath->Header;
  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
MptScsiGetTargetLun (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN EFI_DEVICE_PATH_PROTOCOL         *DevicePath,
  OUT UINT8                           **Target,
  OUT UINT64                          *Lun
  )
{
  MPT_SCSI_DEV      *Dev;
  SCSI_DEVICE_PATH  *ScsiDevicePath;

  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;
  }

  Dev            = MPT_SCSI_FROM_PASS_THRU (This);
  ScsiDevicePath = (SCSI_DEVICE_PATH *)DevicePath;
  if ((ScsiDevicePath->Pun > Dev->MaxTarget) ||
      (ScsiDevicePath->Lun > 0))
  {
    return EFI_NOT_FOUND;
  }

  ZeroMem (*Target, TARGET_MAX_BYTES);
  //
  // This device support 256 targets only, so it's enough to set the LSB
  // of Target.
  //
  **Target = (UINT8)ScsiDevicePath->Pun;
  *Lun     = ScsiDevicePath->Lun;

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
EFIAPI
MptScsiResetChannel (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This
  )
{
  return EFI_UNSUPPORTED;
}

STATIC
VOID
EFIAPI
MptScsiExitBoot (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  MPT_SCSI_DEV  *Dev;

  Dev = Context;
  DEBUG ((DEBUG_VERBOSE, "%a: Context=0x%p\n", __func__, Context));
  MptScsiReset (Dev);
}

STATIC
EFI_STATUS
EFIAPI
MptScsiResetTargetLun (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL  *This,
  IN UINT8                            *Target,
  IN UINT64                           Lun
  )
{
  return EFI_UNSUPPORTED;
}

//
// Driver Binding
//

STATIC
EFI_STATUS
EFIAPI
MptScsiControllerSupported (
  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 == LSI_LOGIC_PCI_VENDOR_ID) &&
      ((Pci.Hdr.DeviceId == LSI_53C1030_PCI_DEVICE_ID) ||
       (Pci.Hdr.DeviceId == LSI_SAS1068_PCI_DEVICE_ID) ||
       (Pci.Hdr.DeviceId == LSI_SAS1068E_PCI_DEVICE_ID)))
  {
    Status = EFI_SUCCESS;
  } else {
    Status = EFI_UNSUPPORTED;
  }

Done:
  gBS->CloseProtocol (
         ControllerHandle,
         &gEfiPciIoProtocolGuid,
         This->DriverBindingHandle,
         ControllerHandle
         );
  return Status;
}

STATIC
EFI_STATUS
EFIAPI
MptScsiControllerStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS    Status;
  MPT_SCSI_DEV  *Dev;
  UINTN         Pages;
  UINTN         BytesMapped;

  Dev = AllocateZeroPool (sizeof (*Dev));
  if (Dev == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Dev->Signature = MPT_SCSI_DEV_SIGNATURE;

  Dev->MaxTarget        = PcdGet8 (PcdMptScsiMaxTargetLimit);
  Dev->StallPerPollUsec = PcdGet32 (PcdMptScsiStallPerPollUsec);

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiPciIoProtocolGuid,
                  (VOID **)&Dev->PciIo,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    goto FreePool;
  }

  Status = Dev->PciIo->Attributes (
                         Dev->PciIo,
                         EfiPciIoAttributeOperationGet,
                         0,
                         &Dev->OriginalPciAttributes
                         );
  if (EFI_ERROR (Status)) {
    goto CloseProtocol;
  }

  //
  // Enable I/O Space & Bus-Mastering
  //
  Status = Dev->PciIo->Attributes (
                         Dev->PciIo,
                         EfiPciIoAttributeOperationEnable,
                         (EFI_PCI_IO_ATTRIBUTE_IO |
                          EFI_PCI_IO_ATTRIBUTE_BUS_MASTER),
                         NULL
                         );
  if (EFI_ERROR (Status)) {
    goto CloseProtocol;
  }

  //
  // 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__
      ));
  }

  //
  // Create buffers for data transfer
  //
  Pages  = EFI_SIZE_TO_PAGES (sizeof (*Dev->Dma));
  Status = Dev->PciIo->AllocateBuffer (
                         Dev->PciIo,
                         AllocateAnyPages,
                         EfiBootServicesData,
                         Pages,
                         (VOID **)&Dev->Dma,
                         EFI_PCI_ATTRIBUTE_MEMORY_CACHED
                         );
  if (EFI_ERROR (Status)) {
    goto RestoreAttributes;
  }

  BytesMapped = EFI_PAGES_TO_SIZE (Pages);
  Status      = Dev->PciIo->Map (
                              Dev->PciIo,
                              EfiPciIoOperationBusMasterCommonBuffer,
                              Dev->Dma,
                              &BytesMapped,
                              &Dev->DmaPhysical,
                              &Dev->DmaMapping
                              );
  if (EFI_ERROR (Status)) {
    goto FreeBuffer;
  }

  if (BytesMapped != EFI_PAGES_TO_SIZE (Pages)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Unmap;
  }

  Status = MptScsiInit (Dev);
  if (EFI_ERROR (Status)) {
    goto Unmap;
  }

  Status = gBS->CreateEvent (
                  EVT_SIGNAL_EXIT_BOOT_SERVICES,
                  TPL_CALLBACK,
                  &MptScsiExitBoot,
                  Dev,
                  &Dev->ExitBoot
                  );
  if (EFI_ERROR (Status)) {
    goto UninitDev;
  }

  //
  // Host adapter channel, doesn't exist
  //
  Dev->PassThruMode.AdapterId  = MAX_UINT32;
  Dev->PassThruMode.Attributes =
    EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL |
    EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;

  Dev->PassThru.Mode             = &Dev->PassThruMode;
  Dev->PassThru.PassThru         = &MptScsiPassThru;
  Dev->PassThru.GetNextTargetLun = &MptScsiGetNextTargetLun;
  Dev->PassThru.BuildDevicePath  = &MptScsiBuildDevicePath;
  Dev->PassThru.GetTargetLun     = &MptScsiGetTargetLun;
  Dev->PassThru.ResetChannel     = &MptScsiResetChannel;
  Dev->PassThru.ResetTargetLun   = &MptScsiResetTargetLun;
  Dev->PassThru.GetNextTarget    = &MptScsiGetNextTarget;

  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:
  MptScsiReset (Dev);

Unmap:
  Dev->PciIo->Unmap (
                Dev->PciIo,
                Dev->DmaMapping
                );

FreeBuffer:
  Dev->PciIo->FreeBuffer (
                Dev->PciIo,
                Pages,
                Dev->Dma
                );

RestoreAttributes:
  Dev->PciIo->Attributes (
                Dev->PciIo,
                EfiPciIoAttributeOperationSet,
                Dev->OriginalPciAttributes,
                NULL
                );

CloseProtocol:
  gBS->CloseProtocol (
         ControllerHandle,
         &gEfiPciIoProtocolGuid,
         This->DriverBindingHandle,
         ControllerHandle
         );

FreePool:
  FreePool (Dev);

  return Status;
}

STATIC
EFI_STATUS
EFIAPI
MptScsiControllerStop (
  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;
  MPT_SCSI_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 = MPT_SCSI_FROM_PASS_THRU (PassThru);

  Status = gBS->UninstallProtocolInterface (
                  ControllerHandle,
                  &gEfiExtScsiPassThruProtocolGuid,
                  &Dev->PassThru
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  gBS->CloseEvent (Dev->ExitBoot);

  MptScsiReset (Dev);

  Dev->PciIo->Unmap (
                Dev->PciIo,
                Dev->DmaMapping
                );

  Dev->PciIo->FreeBuffer (
                Dev->PciIo,
                EFI_SIZE_TO_PAGES (sizeof (*Dev->Dma)),
                Dev->Dma
                );

  Dev->PciIo->Attributes (
                Dev->PciIo,
                EfiPciIoAttributeOperationSet,
                Dev->OriginalPciAttributes,
                NULL
                );

  gBS->CloseProtocol (
         ControllerHandle,
         &gEfiPciIoProtocolGuid,
         This->DriverBindingHandle,
         ControllerHandle
         );

  FreePool (Dev);

  return Status;
}

STATIC
EFI_DRIVER_BINDING_PROTOCOL  mMptScsiDriverBinding = {
  &MptScsiControllerSupported,
  &MptScsiControllerStart,
  &MptScsiControllerStop,
  MPT_SCSI_BINDING_VERSION,
  NULL, // ImageHandle, filled by EfiLibInstallDriverBindingComponentName2
  NULL, // DriverBindingHandle, filled as well
};

//
// Component Name
//

STATIC
EFI_UNICODE_STRING_TABLE  mDriverNameTable[] = {
  { "eng;en", L"LSI Fusion MPT SCSI Driver" },
  { NULL,     NULL                          }
};

STATIC
EFI_COMPONENT_NAME_PROTOCOL  mComponentName;

EFI_STATUS
EFIAPI
MptScsiGetDriverName (
  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
  IN  CHAR8                        *Language,
  OUT CHAR16                       **DriverName
  )
{
  return LookupUnicodeString2 (
           Language,
           This->SupportedLanguages,
           mDriverNameTable,
           DriverName,
           (BOOLEAN)(This == &mComponentName) // Iso639Language
           );
}

EFI_STATUS
EFIAPI
MptScsiGetDeviceName (
  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 = {
  &MptScsiGetDriverName,
  &MptScsiGetDeviceName,
  "eng" // SupportedLanguages, ISO 639-2 language codes
};

STATIC
EFI_COMPONENT_NAME2_PROTOCOL  mComponentName2 = {
  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)&MptScsiGetDriverName,
  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)&MptScsiGetDeviceName,
  "en" // SupportedLanguages, RFC 4646 language codes
};

//
// Entry Point
//

EFI_STATUS
EFIAPI
MptScsiEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  return EfiLibInstallDriverBindingComponentName2 (
           ImageHandle,
           SystemTable,
           &mMptScsiDriverBinding,
           ImageHandle, // The handle to install onto
           &mComponentName,
           &mComponentName2
           );
}
