/** @file

  This driver produces Extended SCSI Pass Thru Protocol instances for
  virtio-scsi devices.

  The implementation is basic:

  - No hotplug / hot-unplug.

  - Although EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru() could be a good match
    for multiple in-flight virtio-scsi requests, we stick to synchronous
    requests for now.

  - Timeouts are not supported for EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru().

  - Only one channel is supported. (At the time of this writing, host-side
    virtio-scsi supports a single channel too.)

  - Only one request queue is used (for the one synchronous request).

  - The ResetChannel() and ResetTargetLun() functions of
    EFI_EXT_SCSI_PASS_THRU_PROTOCOL are not supported (which is allowed by the
    UEFI 2.3.1 Errata C specification), although
    VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET could be a good match. That would
    however require client code for the control queue, which is deemed
    unreasonable for now.

  Copyright (C) 2012, Red Hat, Inc.
  Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials are licensed and made available
  under the terms and conditions of the BSD License which accompanies this
  distribution. The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include <IndustryStandard/VirtioScsi.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/VirtioLib.h>

#include "VirtioScsi.h"

/**

  Convenience macros to read and write configuration elements of the
  virtio-scsi VirtIo device.

  The following macros make it possible to specify only the "core parameters"
  for such accesses and to derive the rest. By the time VIRTIO_CFG_WRITE()
  returns, the transaction will have been completed.

  @param[in] Dev       Pointer to the VSCSI_DEV structure.

  @param[in] Field     A field name from VSCSI_HDR, identifying the virtio-scsi
                       configuration item to access.

  @param[in] Value     (VIRTIO_CFG_WRITE() only.) The value to write to the
                       selected configuration item.

  @param[out] Pointer  (VIRTIO_CFG_READ() only.) The object to receive the
                       value read from the configuration item. Its type must be
                       one of UINT8, UINT16, UINT32, UINT64.


  @return  Status codes returned by Virtio->WriteDevice() / Virtio->ReadDevice().

**/

#define VIRTIO_CFG_WRITE(Dev, Field, Value)  ((Dev)->VirtIo->WriteDevice (  \
                                                (Dev)->VirtIo,              \
                                                OFFSET_OF_VSCSI (Field),    \
                                                SIZE_OF_VSCSI (Field),      \
                                                (Value)                     \
                                                ))

#define VIRTIO_CFG_READ(Dev, Field, Pointer) ((Dev)->VirtIo->ReadDevice (   \
                                                (Dev)->VirtIo,              \
                                                OFFSET_OF_VSCSI (Field),    \
                                                SIZE_OF_VSCSI (Field),      \
                                                sizeof *(Pointer),          \
                                                (Pointer)                   \
                                                ))


//
// UEFI Spec 2.3.1 + Errata C, 14.7 Extended SCSI Pass Thru Protocol specifies
// the PassThru() interface. Beside returning a status code, the function must
// set some fields in the EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET in/out
// parameter on return. The following is a full list of those fields, for
// easier validation of PopulateRequest(), ParseResponse(), and
// VirtioScsiPassThru() below.
//
// - InTransferLength
// - OutTransferLength
// - HostAdapterStatus
// - TargetStatus
// - SenseDataLength
// - SenseData
//
// On any return from the PassThru() interface, these fields must be set,
// except if the returned status code is explicitly exempt. (Actually the
// implementation here conservatively sets these fields even in case not all
// of them would be required by the specification.)
//

/**

  Populate a virtio-scsi request from the Extended SCSI Pass Thru Protocol
  packet.

  The caller is responsible for pre-zeroing the virtio-scsi request. The
  Extended SCSI Pass Thru Protocol packet is modified, to be forwarded outwards
  by VirtioScsiPassThru(), if invalid or unsupported parameters are detected.

  @param[in] Dev          The virtio-scsi host device the packet targets.

  @param[in] Target       The SCSI target controlled by the virtio-scsi host
                          device.

  @param[in] Lun          The Logical Unit Number under the SCSI target.

  @param[in out] Packet   The Extended SCSI Pass Thru Protocol packet the
                          function translates to a virtio-scsi request. On
                          failure this parameter relays error contents.

  @param[out]    Request  The pre-zeroed virtio-scsi request to populate. This
                          parameter is volatile-qualified because we expect the
                          caller to append it to a virtio ring, thus
                          assignments to Request must be visible when the
                          function returns.


  @retval EFI_SUCCESS  The Extended SCSI Pass Thru Protocol packet was valid,
                       Request has been populated.

  @return              Otherwise, invalid or unsupported parameters were
                       detected. Status codes are meant for direct forwarding
                       by the EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru()
                       implementation.

**/
STATIC
EFI_STATUS
EFIAPI
PopulateRequest (
  IN     CONST    VSCSI_DEV                                   *Dev,
  IN              UINT16                                      Target,
  IN              UINT64                                      Lun,
  IN OUT          EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET  *Packet,
  OUT    volatile VIRTIO_SCSI_REQ                             *Request
  )
{
  UINTN Idx;

  if (
      //
      // bidirectional transfer was requested, but the host doesn't support it
      //
      (Packet->InTransferLength > 0 && Packet->OutTransferLength > 0 &&
       !Dev->InOutSupported) ||

      //
      // a target / LUN was addressed that's impossible to encode for the host
      //
      Target > 0xFF || Lun >= 0x4000 ||

      //
      // Command Descriptor Block bigger than VIRTIO_SCSI_CDB_SIZE
      //
      Packet->CdbLength > VIRTIO_SCSI_CDB_SIZE ||

      //
      // From virtio-0.9.5, 2.3.2 Descriptor Table:
      // "no descriptor chain may be more than 2^32 bytes long in total".
      //
      (UINT64) Packet->InTransferLength + Packet->OutTransferLength > SIZE_1GB
      ) {

    //
    // this error code doesn't require updates to the Packet output fields
    //
    return EFI_UNSUPPORTED;
  }

  if (
      //
      // addressed invalid device
      //
      Target > 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;
  }

  //
  // Catch oversized requests eagerly. If this condition evaluates to false,
  // then the combined size of a bidirectional request will not exceed the
  // virtio-scsi device's transfer limit either.
  //
  if (ALIGN_VALUE (Packet->OutTransferLength, 512) / 512
        > Dev->MaxSectors / 2 ||
      ALIGN_VALUE (Packet->InTransferLength,  512) / 512
        > Dev->MaxSectors / 2) {
    Packet->InTransferLength  = (Dev->MaxSectors / 2) * 512;
    Packet->OutTransferLength = (Dev->MaxSectors / 2) * 512;
    Packet->HostAdapterStatus =
                        EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;
    Packet->TargetStatus      = EFI_EXT_SCSI_STATUS_TARGET_GOOD;
    Packet->SenseDataLength   = 0;
    return EFI_BAD_BUFFER_SIZE;
  }

  //
  // target & LUN encoding: see virtio-0.9.5, Appendix I: SCSI Host Device,
  // Device Operation: request queues
  //
  Request->Lun[0] = 1;
  Request->Lun[1] = (UINT8) Target;
  Request->Lun[2] = (UINT8) (((UINT32)Lun >> 8) | 0x40);
  Request->Lun[3] = (UINT8) Lun;

  //
  // CopyMem() would cast away the "volatile" qualifier before access, which is
  // undefined behavior (ISO C99 6.7.3p5)
  //
  for (Idx = 0; Idx < Packet->CdbLength; ++Idx) {
    Request->Cdb[Idx] = ((UINT8 *) Packet->Cdb)[Idx];
  }

  return EFI_SUCCESS;
}


/**

  Parse the virtio-scsi device's response, translate it to an EFI status code,
  and update the Extended SCSI Pass Thru Protocol packet, to be returned by
  the EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru() implementation.

  @param[in out] Packet  The Extended SCSI Pass Thru Protocol packet that has
                         been translated to a virtio-scsi request with
                         PopulateRequest(), and processed by the host. On
                         output this parameter is updated with response or
                         error contents.

  @param[in] Response    The virtio-scsi response structure to parse. We expect
                         it to come from a virtio ring, thus it is qualified
                         volatile.


  @return  PassThru() status codes mandated by UEFI Spec 2.3.1 + Errata C, 14.7
           Extended SCSI Pass Thru Protocol.

**/
STATIC
EFI_STATUS
EFIAPI
ParseResponse (
  IN OUT                EFI_EXT_SCSI_PASS_THRU_SCSI_REQUEST_PACKET *Packet,
  IN     CONST volatile VIRTIO_SCSI_RESP                           *Response
  )
{
  UINTN ResponseSenseLen;
  UINTN Idx;

  //
  // return sense data (length and contents) in all cases, truncated if needed
  //
  ResponseSenseLen = MIN (Response->SenseLen, VIRTIO_SCSI_SENSE_SIZE);
  if (Packet->SenseDataLength > ResponseSenseLen) {
    Packet->SenseDataLength = (UINT8) ResponseSenseLen;
  }
  for (Idx = 0; Idx < Packet->SenseDataLength; ++Idx) {
    ((UINT8 *) Packet->SenseData)[Idx] = Response->Sense[Idx];
  }

  //
  // Report actual transfer lengths. The logic below covers all three
  // DataDirections (read, write, bidirectional).
  //
  // -+- @ 0
  //  |
  //  | write                                       ^  @ Residual (unprocessed)
  //  |                                             |
  // -+- @ OutTransferLength                       -+- @ InTransferLength
  //  |                                             |
  //  | read                                        |
  //  |                                             |
  //  V  @ OutTransferLength + InTransferLength    -+- @ 0
  //
  if (Response->Residual <= Packet->InTransferLength) {
    Packet->InTransferLength  -= Response->Residual;
  }
  else {
    Packet->OutTransferLength -= Response->Residual - Packet->InTransferLength;
    Packet->InTransferLength   = 0;
  }

  //
  // report target status in all cases
  //
  Packet->TargetStatus = Response->Status;

  //
  // host adapter status and function return value depend on virtio-scsi
  // response code
  //
  switch (Response->Response) {
  case VIRTIO_SCSI_S_OK:
    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;
    return EFI_SUCCESS;

  case VIRTIO_SCSI_S_OVERRUN:
    Packet->HostAdapterStatus =
                        EFI_EXT_SCSI_STATUS_HOST_ADAPTER_DATA_OVERRUN_UNDERRUN;
    break;

  case VIRTIO_SCSI_S_BAD_TARGET:
    //
    // This is non-intuitive but explicitly required by the
    // EFI_EXT_SCSI_PASS_THRU_PROTOCOL.PassThru() specification for
    // disconnected (but otherwise valid) target / LUN addresses.
    //
    Packet->HostAdapterStatus =
                              EFI_EXT_SCSI_STATUS_HOST_ADAPTER_TIMEOUT_COMMAND;
    return EFI_TIMEOUT;

  case VIRTIO_SCSI_S_RESET:
    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_BUS_RESET;
    break;

  case VIRTIO_SCSI_S_BUSY:
    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OK;
    return EFI_NOT_READY;

  //
  // Lump together the rest. The mapping for VIRTIO_SCSI_S_ABORTED is
  // intentional as well, not an oversight.
  //
  case VIRTIO_SCSI_S_ABORTED:
  case VIRTIO_SCSI_S_TRANSPORT_FAILURE:
  case VIRTIO_SCSI_S_TARGET_FAILURE:
  case VIRTIO_SCSI_S_NEXUS_FAILURE:
  case VIRTIO_SCSI_S_FAILURE:
  default:
    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
  }

  return EFI_DEVICE_ERROR;
}


//
// The next seven functions implement EFI_EXT_SCSI_PASS_THRU_PROTOCOL
// for the virtio-scsi HBA. Refer to UEFI Spec 2.3.1 + Errata C, sections
// - 14.1 SCSI Driver Model Overview,
// - 14.7 Extended SCSI Pass Thru Protocol.
//

EFI_STATUS
EFIAPI
VirtioScsiPassThru (
  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
  )
{
  VSCSI_DEV                 *Dev;
  UINT16                    TargetValue;
  EFI_STATUS                Status;
  volatile VIRTIO_SCSI_REQ  Request;
  volatile VIRTIO_SCSI_RESP Response;
  DESC_INDICES              Indices;

  ZeroMem ((VOID*) &Request, sizeof (Request));
  ZeroMem ((VOID*) &Response, sizeof (Response));

  Dev = VIRTIO_SCSI_FROM_PASS_THRU (This);
  CopyMem (&TargetValue, Target, sizeof TargetValue);

  Status = PopulateRequest (Dev, TargetValue, Lun, Packet, &Request);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  VirtioPrepare (&Dev->Ring, &Indices);

  //
  // preset a host status for ourselves that we do not accept as success
  //
  Response.Response = VIRTIO_SCSI_S_FAILURE;

  //
  // ensured by VirtioScsiInit() -- this predicate, in combination with the
  // lock-step progress, ensures we don't have to track free descriptors.
  //
  ASSERT (Dev->Ring.QueueSize >= 4);

  //
  // enqueue Request
  //
  VirtioAppendDesc (&Dev->Ring, (UINTN) &Request, sizeof Request,
    VRING_DESC_F_NEXT, &Indices);

  //
  // enqueue "dataout" if any
  //
  if (Packet->OutTransferLength > 0) {
    VirtioAppendDesc (&Dev->Ring, (UINTN) Packet->OutDataBuffer,
      Packet->OutTransferLength, VRING_DESC_F_NEXT, &Indices);
  }

  //
  // enqueue Response, to be written by the host
  //
  VirtioAppendDesc (&Dev->Ring, (UINTN) &Response, sizeof Response,
    VRING_DESC_F_WRITE | (Packet->InTransferLength > 0 ?
                          VRING_DESC_F_NEXT : 0),
    &Indices);

  //
  // enqueue "datain" if any, to be written by the host
  //
  if (Packet->InTransferLength > 0) {
    VirtioAppendDesc (&Dev->Ring, (UINTN) Packet->InDataBuffer,
      Packet->InTransferLength, VRING_DESC_F_WRITE, &Indices);
  }

  // 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.
  //
  if (VirtioFlush (Dev->VirtIo, VIRTIO_SCSI_REQUEST_QUEUE, &Dev->Ring,
        &Indices) != EFI_SUCCESS) {
    Packet->InTransferLength  = 0;
    Packet->OutTransferLength = 0;
    Packet->HostAdapterStatus = EFI_EXT_SCSI_STATUS_HOST_ADAPTER_OTHER;
    Packet->TargetStatus      = EFI_EXT_SCSI_STATUS_TARGET_GOOD;
    Packet->SenseDataLength   = 0;
    return EFI_DEVICE_ERROR;
  }

  return ParseResponse (Packet, &Response);
}


EFI_STATUS
EFIAPI
VirtioScsiGetNextTargetLun (
  IN     EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
  IN OUT UINT8                           **TargetPointer,
  IN OUT UINT64                          *Lun
  )
{
  UINT8     *Target;
  UINTN     Idx;
  UINT16    LastTarget;
  VSCSI_DEV *Dev;

  //
  // the TargetPointer input parameter is unnecessarily a pointer-to-pointer
  //
  Target = *TargetPointer;

  //
  // Search for first non-0xFF byte. If not found, return first target & LUN.
  //
  for (Idx = 0; Idx < TARGET_MAX_BYTES && Target[Idx] == 0xFF; ++Idx)
    ;
  if (Idx == TARGET_MAX_BYTES) {
    SetMem (Target, TARGET_MAX_BYTES, 0x00);
    *Lun = 0;
    return EFI_SUCCESS;
  }

  //
  // see the TARGET_MAX_BYTES check in "VirtioScsi.h"
  //
  CopyMem (&LastTarget, Target, sizeof LastTarget);

  //
  // increment (target, LUN) pair if valid on input
  //
  Dev = VIRTIO_SCSI_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;
    CopyMem (Target, &LastTarget, sizeof LastTarget);
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}


EFI_STATUS
EFIAPI
VirtioScsiBuildDevicePath (
  IN     EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
  IN     UINT8                           *Target,
  IN     UINT64                          Lun,
  IN OUT EFI_DEVICE_PATH_PROTOCOL        **DevicePath
  )
{
  UINT16           TargetValue;
  VSCSI_DEV        *Dev;
  SCSI_DEVICE_PATH *ScsiDevicePath;

  if (DevicePath == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  CopyMem (&TargetValue, Target, sizeof TargetValue);
  Dev = VIRTIO_SCSI_FROM_PASS_THRU (This);
  if (TargetValue > Dev->MaxTarget || Lun > Dev->MaxLun || Lun > 0xFFFF) {
    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;
}


EFI_STATUS
EFIAPI
VirtioScsiGetTargetLun (
  IN  EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
  IN  EFI_DEVICE_PATH_PROTOCOL        *DevicePath,
  OUT UINT8                           **TargetPointer,
  OUT UINT64                          *Lun
  )
{
  SCSI_DEVICE_PATH *ScsiDevicePath;
  VSCSI_DEV        *Dev;
  UINT8            *Target;

  if (DevicePath == NULL || TargetPointer == NULL || *TargetPointer == 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 = VIRTIO_SCSI_FROM_PASS_THRU (This);
  if (ScsiDevicePath->Pun > Dev->MaxTarget ||
      ScsiDevicePath->Lun > Dev->MaxLun) {
    return EFI_NOT_FOUND;
  }

  //
  // a) the TargetPointer input parameter is unnecessarily a pointer-to-pointer
  // b) see the TARGET_MAX_BYTES check in "VirtioScsi.h"
  // c) ScsiDevicePath->Pun is an UINT16
  //
  Target = *TargetPointer;
  CopyMem (Target, &ScsiDevicePath->Pun, 2);
  SetMem (Target + 2, TARGET_MAX_BYTES - 2, 0x00);

  *Lun = ScsiDevicePath->Lun;
  return EFI_SUCCESS;
}


EFI_STATUS
EFIAPI
VirtioScsiResetChannel (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This
  )
{
  return EFI_UNSUPPORTED;
}


EFI_STATUS
EFIAPI
VirtioScsiResetTargetLun (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
  IN UINT8                           *Target,
  IN UINT64                          Lun
  )
{
  return EFI_UNSUPPORTED;
}


EFI_STATUS
EFIAPI
VirtioScsiGetNextTarget (
  IN EFI_EXT_SCSI_PASS_THRU_PROTOCOL *This,
  IN OUT UINT8                       **TargetPointer
  )
{
  UINT8     *Target;
  UINTN     Idx;
  UINT16    LastTarget;
  VSCSI_DEV *Dev;

  //
  // the TargetPointer input parameter is unnecessarily a pointer-to-pointer
  //
  Target = *TargetPointer;

  //
  // Search for first non-0xFF byte. If not found, return first target.
  //
  for (Idx = 0; Idx < TARGET_MAX_BYTES && Target[Idx] == 0xFF; ++Idx)
    ;
  if (Idx == TARGET_MAX_BYTES) {
    SetMem (Target, TARGET_MAX_BYTES, 0x00);
    return EFI_SUCCESS;
  }

  //
  // see the TARGET_MAX_BYTES check in "VirtioScsi.h"
  //
  CopyMem (&LastTarget, Target, sizeof LastTarget);

  //
  // increment target if valid on input
  //
  Dev = VIRTIO_SCSI_FROM_PASS_THRU (This);
  if (LastTarget > Dev->MaxTarget) {
    return EFI_INVALID_PARAMETER;
  }

  if (LastTarget < Dev->MaxTarget) {
    ++LastTarget;
    CopyMem (Target, &LastTarget, sizeof LastTarget);
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}


STATIC
EFI_STATUS
EFIAPI
VirtioScsiInit (
  IN OUT VSCSI_DEV *Dev
  )
{
  UINT8      NextDevStat;
  EFI_STATUS Status;

  UINT32     Features;
  UINT16     MaxChannel; // for validation only
  UINT32     NumQueues;  // for validation only
  UINT16     QueueSize;

  //
  // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
  //
  NextDevStat = 0;             // step 1 -- reset device
  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
  if (EFI_ERROR (Status)) {
    goto Failed;
  }

  NextDevStat |= VSTAT_ACK;    // step 2 -- acknowledge device presence
  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
  if (EFI_ERROR (Status)) {
    goto Failed;
  }

  NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
  if (EFI_ERROR (Status)) {
    goto Failed;
  }

  //
  // Set Page Size - MMIO VirtIo Specific
  //
  Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE);
  if (EFI_ERROR (Status)) {
    goto Failed;
  }

  //
  // step 4a -- retrieve and validate features
  //
  Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features);
  if (EFI_ERROR (Status)) {
    goto Failed;
  }
  Dev->InOutSupported = (BOOLEAN) ((Features & VIRTIO_SCSI_F_INOUT) != 0);

  Status = VIRTIO_CFG_READ (Dev, MaxChannel, &MaxChannel);
  if (EFI_ERROR (Status)) {
    goto Failed;
  }
  if (MaxChannel != 0) {
    //
    // this driver is for a single-channel virtio-scsi HBA
    //
    Status = EFI_UNSUPPORTED;
    goto Failed;
  }

  Status = VIRTIO_CFG_READ (Dev, NumQueues, &NumQueues);
  if (EFI_ERROR (Status)) {
    goto Failed;
  }
  if (NumQueues < 1) {
    Status = EFI_UNSUPPORTED;
    goto Failed;
  }

  Status = VIRTIO_CFG_READ (Dev, MaxTarget, &Dev->MaxTarget);
  if (EFI_ERROR (Status)) {
    goto Failed;
  }
  if (Dev->MaxTarget > PcdGet16 (PcdVirtioScsiMaxTargetLimit)) {
    Dev->MaxTarget = PcdGet16 (PcdVirtioScsiMaxTargetLimit);
  }

  Status = VIRTIO_CFG_READ (Dev, MaxLun, &Dev->MaxLun);
  if (EFI_ERROR (Status)) {
    goto Failed;
  }
  if (Dev->MaxLun > PcdGet32 (PcdVirtioScsiMaxLunLimit)) {
    Dev->MaxLun = PcdGet32 (PcdVirtioScsiMaxLunLimit);
  }

  Status = VIRTIO_CFG_READ (Dev, MaxSectors, &Dev->MaxSectors);
  if (EFI_ERROR (Status)) {
    goto Failed;
  }
  if (Dev->MaxSectors < 2) {
    //
    // We must be able to halve it for bidirectional transfers
    // (see EFI_BAD_BUFFER_SIZE in PopulateRequest()).
    //
    Status = EFI_UNSUPPORTED;
    goto Failed;
  }

  //
  // step 4b -- allocate request virtqueue
  //
  Status = Dev->VirtIo->SetQueueSel (Dev->VirtIo, VIRTIO_SCSI_REQUEST_QUEUE);
  if (EFI_ERROR (Status)) {
    goto Failed;
  }
  Status = Dev->VirtIo->GetQueueNumMax (Dev->VirtIo, &QueueSize);
  if (EFI_ERROR (Status)) {
    goto Failed;
  }
  //
  // VirtioScsiPassThru() uses at most four descriptors
  //
  if (QueueSize < 4) {
    Status = EFI_UNSUPPORTED;
    goto Failed;
  }

  Status = VirtioRingInit (QueueSize, &Dev->Ring);
  if (EFI_ERROR (Status)) {
    goto Failed;
  }

  //
  // Additional steps for MMIO: align the queue appropriately, and set the
  // size. If anything fails from here on, we must release the ring resources.
  //
  Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
  if (EFI_ERROR (Status)) {
    goto ReleaseQueue;
  }

  Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
  if (EFI_ERROR (Status)) {
    goto ReleaseQueue;
  }

  //
  // step 4c -- Report GPFN (guest-physical frame number) of queue.
  //
  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,
      (UINT32) ((UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT));
  if (EFI_ERROR (Status)) {
    goto ReleaseQueue;
  }

  //
  // step 5 -- Report understood features and guest-tuneables. We want none of
  // the known (or unknown) VIRTIO_SCSI_F_* or VIRTIO_F_* capabilities (see
  // virtio-0.9.5, Appendices B and I), except bidirectional transfers.
  //
  Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo,
      Features & VIRTIO_SCSI_F_INOUT);
  if (EFI_ERROR (Status)) {
    goto ReleaseQueue;
  }

  //
  // We expect these maximum sizes from the host. Since they are
  // guest-negotiable, ask for them rather than just checking them.
  //
  Status = VIRTIO_CFG_WRITE (Dev, CdbSize, VIRTIO_SCSI_CDB_SIZE);
  if (EFI_ERROR (Status)) {
    goto ReleaseQueue;
  }
  Status = VIRTIO_CFG_WRITE (Dev, SenseSize, VIRTIO_SCSI_SENSE_SIZE);
  if (EFI_ERROR (Status)) {
    goto ReleaseQueue;
  }

  //
  // step 6 -- initialization complete
  //
  NextDevStat |= VSTAT_DRIVER_OK;
  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
  if (EFI_ERROR (Status)) {
    goto ReleaseQueue;
  }

  //
  // populate the exported interface's attributes
  //
  Dev->PassThru.Mode             = &Dev->PassThruMode;
  Dev->PassThru.PassThru         = &VirtioScsiPassThru;
  Dev->PassThru.GetNextTargetLun = &VirtioScsiGetNextTargetLun;
  Dev->PassThru.BuildDevicePath  = &VirtioScsiBuildDevicePath;
  Dev->PassThru.GetTargetLun     = &VirtioScsiGetTargetLun;
  Dev->PassThru.ResetChannel     = &VirtioScsiResetChannel;
  Dev->PassThru.ResetTargetLun   = &VirtioScsiResetTargetLun;
  Dev->PassThru.GetNextTarget    = &VirtioScsiGetNextTarget;

  //
  // AdapterId is a target for which no handle will be created during bus scan.
  // Prevent any conflict with real devices.
  //
  Dev->PassThruMode.AdapterId = 0xFFFFFFFF;

  //
  // Set both physical and logical attributes for non-RAID SCSI channel. See
  // Driver Writer's Guide for UEFI 2.3.1 v1.01, 20.1.5 Implementing Extended
  // SCSI Pass Thru Protocol.
  //
  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;

ReleaseQueue:
  VirtioRingUninit (&Dev->Ring);

Failed:
  //
  // Notify the host about our failure to setup: virtio-0.9.5, 2.2.2.1 Device
  // Status. VirtIo access failure here should not mask the original error.
  //
  NextDevStat |= VSTAT_FAILED;
  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);

  Dev->InOutSupported = FALSE;
  Dev->MaxTarget      = 0;
  Dev->MaxLun         = 0;
  Dev->MaxSectors     = 0;

  return Status; // reached only via Failed above
}



STATIC
VOID
EFIAPI
VirtioScsiUninit (
  IN OUT VSCSI_DEV *Dev
  )
{
  //
  // Reset the virtual device -- see virtio-0.9.5, 2.2.2.1 Device Status. When
  // VIRTIO_CFG_WRITE() returns, the host will have learned to stay away from
  // the old comms area.
  //
  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);

  Dev->InOutSupported = FALSE;
  Dev->MaxTarget      = 0;
  Dev->MaxLun         = 0;
  Dev->MaxSectors     = 0;

  VirtioRingUninit (&Dev->Ring);

  SetMem (&Dev->PassThru,     sizeof Dev->PassThru,     0x00);
  SetMem (&Dev->PassThruMode, sizeof Dev->PassThruMode, 0x00);
}


//
// Probe, start and stop functions of this driver, called by the DXE core for
// specific devices.
//
// The following specifications document these interfaces:
// - Driver Writer's Guide for UEFI 2.3.1 v1.01, 9 Driver Binding Protocol
// - UEFI Spec 2.3.1 + Errata C, 10.1 EFI Driver Binding Protocol
//
// The implementation follows:
// - Driver Writer's Guide for UEFI 2.3.1 v1.01
//   - 5.1.3.4 OpenProtocol() and CloseProtocol()
// - UEFI Spec 2.3.1 + Errata C
//   -  6.3 Protocol Handler Services
//

EFI_STATUS
EFIAPI
VirtioScsiDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                  DeviceHandle,
  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
  )
{
  EFI_STATUS             Status;
  VIRTIO_DEVICE_PROTOCOL *VirtIo;

  //
  // Attempt to open the device with the VirtIo set of interfaces. On success,
  // the protocol is "instantiated" for the VirtIo device. Covers duplicate open
  // attempts (EFI_ALREADY_STARTED).
  //
  Status = gBS->OpenProtocol (
                  DeviceHandle,               // candidate device
                  &gVirtioDeviceProtocolGuid, // for generic VirtIo access
                  (VOID **)&VirtIo,           // handle to instantiate
                  This->DriverBindingHandle,  // requestor driver identity
                  DeviceHandle,               // ControllerHandle, according to
                                              // the UEFI Driver Model
                  EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive VirtIo access to
                                              // the device; to be released
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_SCSI_HOST) {
    Status = EFI_UNSUPPORTED;
  }

  //
  // We needed VirtIo access only transitorily, to see whether we support the
  // device or not.
  //
  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
         This->DriverBindingHandle, DeviceHandle);
  return Status;
}


EFI_STATUS
EFIAPI
VirtioScsiDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                  DeviceHandle,
  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
  )
{
  VSCSI_DEV  *Dev;
  EFI_STATUS Status;

  Dev = (VSCSI_DEV *) AllocateZeroPool (sizeof *Dev);
  if (Dev == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Status = gBS->OpenProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
                  (VOID **)&Dev->VirtIo, This->DriverBindingHandle,
                  DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
  if (EFI_ERROR (Status)) {
    goto FreeVirtioScsi;
  }

  //
  // VirtIo access granted, configure virtio-scsi device.
  //
  Status = VirtioScsiInit (Dev);
  if (EFI_ERROR (Status)) {
    goto CloseVirtIo;
  }

  //
  // Setup complete, attempt to export the driver instance's PassThru
  // interface.
  //
  Dev->Signature = VSCSI_SIG;
  Status = gBS->InstallProtocolInterface (&DeviceHandle,
                  &gEfiExtScsiPassThruProtocolGuid, EFI_NATIVE_INTERFACE,
                  &Dev->PassThru);
  if (EFI_ERROR (Status)) {
    goto UninitDev;
  }

  return EFI_SUCCESS;

UninitDev:
  VirtioScsiUninit (Dev);

CloseVirtIo:
  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
         This->DriverBindingHandle, DeviceHandle);

FreeVirtioScsi:
  FreePool (Dev);

  return Status;
}


EFI_STATUS
EFIAPI
VirtioScsiDriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                  DeviceHandle,
  IN UINTN                       NumberOfChildren,
  IN EFI_HANDLE                  *ChildHandleBuffer
  )
{
  EFI_STATUS                      Status;
  EFI_EXT_SCSI_PASS_THRU_PROTOCOL *PassThru;
  VSCSI_DEV                       *Dev;

  Status = gBS->OpenProtocol (
                  DeviceHandle,                     // candidate device
                  &gEfiExtScsiPassThruProtocolGuid, // retrieve the SCSI iface
                  (VOID **)&PassThru,               // target pointer
                  This->DriverBindingHandle,        // requestor driver ident.
                  DeviceHandle,                     // lookup req. for dev.
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL    // lookup only, no new ref.
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Dev = VIRTIO_SCSI_FROM_PASS_THRU (PassThru);

  //
  // Handle Stop() requests for in-use driver instances gracefully.
  //
  Status = gBS->UninstallProtocolInterface (DeviceHandle,
                  &gEfiExtScsiPassThruProtocolGuid, &Dev->PassThru);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  VirtioScsiUninit (Dev);

  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
         This->DriverBindingHandle, DeviceHandle);

  FreePool (Dev);

  return EFI_SUCCESS;
}


//
// The static object that groups the Supported() (ie. probe), Start() and
// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
// C, 10.1 EFI Driver Binding Protocol.
//
STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
  &VirtioScsiDriverBindingSupported,
  &VirtioScsiDriverBindingStart,
  &VirtioScsiDriverBindingStop,
  0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
  NULL, // ImageHandle, to be overwritten by
        // EfiLibInstallDriverBindingComponentName2() in VirtioScsiEntryPoint()
  NULL  // DriverBindingHandle, ditto
};


//
// The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and
// EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name
// in English, for display on standard console devices. This is recommended for
// UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's
// Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.
//
// Device type names ("Virtio SCSI Host Device") are not formatted because the
// driver supports only that device type. Therefore the driver name suffices
// for unambiguous identification.
//

STATIC
EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
  { "eng;en", L"Virtio SCSI Host Driver" },
  { NULL,     NULL                   }
};

STATIC
EFI_COMPONENT_NAME_PROTOCOL gComponentName;

EFI_STATUS
EFIAPI
VirtioScsiGetDriverName (
  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
  IN  CHAR8                       *Language,
  OUT CHAR16                      **DriverName
  )
{
  return LookupUnicodeString2 (
           Language,
           This->SupportedLanguages,
           mDriverNameTable,
           DriverName,
           (BOOLEAN)(This == &gComponentName) // Iso639Language
           );
}

EFI_STATUS
EFIAPI
VirtioScsiGetDeviceName (
  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 gComponentName = {
  &VirtioScsiGetDriverName,
  &VirtioScsiGetDeviceName,
  "eng" // SupportedLanguages, ISO 639-2 language codes
};

STATIC
EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)     &VirtioScsiGetDriverName,
  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &VirtioScsiGetDeviceName,
  "en" // SupportedLanguages, RFC 4646 language codes
};


//
// Entry point of this driver.
//
EFI_STATUS
EFIAPI
VirtioScsiEntryPoint (
  IN EFI_HANDLE       ImageHandle,
  IN EFI_SYSTEM_TABLE *SystemTable
  )
{
  return EfiLibInstallDriverBindingComponentName2 (
           ImageHandle,
           SystemTable,
           &gDriverBinding,
           ImageHandle,
           &gComponentName,
           &gComponentName2
           );
}
