/** @file
  Minimal block driver for Mini-OS.

  Copyright (c) 2007-2008 Samuel Thibault.
  Copyright (C) 2014, Citrix Ltd.
  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:
  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in the
     documentation and/or other materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  SUCH DAMAGE.
**/

#include <Library/PrintLib.h>
#include <Library/DebugLib.h>

#include "BlockFront.h"

#include <IndustryStandard/Xen/io/protocols.h>
#include <IndustryStandard/Xen/io/xenbus.h>

/**
  Helper to read an integer from XenStore.

  If the number overflows according to the range defined by UINT64,
  then ASSERT().

  @param This         A pointer to a XENBUS_PROTOCOL instance.
  @param Node         The XenStore node to read from.
  @param FromBackend  Read frontend or backend value.
  @param ValuePtr     Where to put the value.

  @retval XENSTORE_STATUS_SUCCESS  If succefull, will update ValuePtr.
  @return                          Any other return value indicate the error,
                                   ValuePtr is not updated in this case.
**/
STATIC
XENSTORE_STATUS
XenBusReadUint64 (
  IN  XENBUS_PROTOCOL *This,
  IN  CONST CHAR8     *Node,
  IN  BOOLEAN         FromBackend,
  OUT UINT64          *ValuePtr
  )
{
  XENSTORE_STATUS Status;
  CHAR8 *Ptr;

  if (!FromBackend) {
    Status = This->XsRead (This, XST_NIL, Node, (VOID**)&Ptr);
  } else {
    Status = This->XsBackendRead (This, XST_NIL, Node, (VOID**)&Ptr);
  }
  if (Status != XENSTORE_STATUS_SUCCESS) {
    return Status;
  }
  // AsciiStrDecimalToUint64 will ASSERT if Ptr overflow UINT64.
  *ValuePtr = AsciiStrDecimalToUint64 (Ptr);
  FreePool (Ptr);
  return Status;
}

/**
  Free an instance of XEN_BLOCK_FRONT_DEVICE.

  @param Dev  The instance to free.
**/
STATIC
VOID
XenPvBlockFree (
  IN XEN_BLOCK_FRONT_DEVICE *Dev
  )
{
  XENBUS_PROTOCOL *XenBusIo = Dev->XenBusIo;

  if (Dev->RingRef != 0) {
    XenBusIo->GrantEndAccess (XenBusIo, Dev->RingRef);
  }
  if (Dev->Ring.sring != NULL) {
    FreePages (Dev->Ring.sring, 1);
  }
  if (Dev->EventChannel != 0) {
    XenBusIo->EventChannelClose (XenBusIo, Dev->EventChannel);
  }
  FreePool (Dev);
}

/**
  Wait until until the backend has reached the ExpectedState.

  @param Dev            A XEN_BLOCK_FRONT_DEVICE instance.
  @param ExpectedState  The backend state expected.
  @param LastStatePtr   An optional pointer where to right the final state.

  @return Return XENSTORE_STATUS_SUCCESS if the new backend state is ExpectedState
          or return an error otherwise.
**/
STATIC
XENSTORE_STATUS
XenPvBlkWaitForBackendState (
  IN  XEN_BLOCK_FRONT_DEVICE *Dev,
  IN  XenbusState            ExpectedState,
  OUT XenbusState            *LastStatePtr OPTIONAL
  )
{
  XENBUS_PROTOCOL *XenBusIo = Dev->XenBusIo;
  XenbusState State;
  UINT64 Value;
  XENSTORE_STATUS Status = XENSTORE_STATUS_SUCCESS;

  while (TRUE) {
    Status = XenBusReadUint64 (XenBusIo, "state", TRUE, &Value);
    if (Status != XENSTORE_STATUS_SUCCESS) {
      return Status;
    }
    if (Value > XenbusStateReconfigured) {
      //
      // Value is not a State value.
      //
      return XENSTORE_STATUS_EIO;
    }
    State = Value;
    if (State == ExpectedState) {
      break;
    } else if (State > ExpectedState) {
      Status = XENSTORE_STATUS_FAIL;
      break;
    }
    DEBUG ((EFI_D_INFO,
            "XenPvBlk: waiting backend state %d, current: %d\n",
            ExpectedState, State));
    XenBusIo->WaitForWatch (XenBusIo, Dev->StateWatchToken);
  }

  if (LastStatePtr != NULL) {
    *LastStatePtr = State;
  }

  return Status;
}

EFI_STATUS
XenPvBlockFrontInitialization (
  IN  XENBUS_PROTOCOL         *XenBusIo,
  IN  CONST CHAR8             *NodeName,
  OUT XEN_BLOCK_FRONT_DEVICE  **DevPtr
  )
{
  XENSTORE_TRANSACTION Transaction;
  CHAR8 *DeviceType;
  blkif_sring_t *SharedRing;
  XENSTORE_STATUS Status;
  XEN_BLOCK_FRONT_DEVICE *Dev;
  XenbusState State;
  UINT64 Value;

  ASSERT (NodeName != NULL);

  Dev = AllocateZeroPool (sizeof (XEN_BLOCK_FRONT_DEVICE));
  Dev->Signature = XEN_BLOCK_FRONT_SIGNATURE;
  Dev->NodeName = NodeName;
  Dev->XenBusIo = XenBusIo;
  Dev->DeviceId = XenBusIo->DeviceId;

  XenBusIo->XsRead (XenBusIo, XST_NIL, "device-type", (VOID**)&DeviceType);
  if (AsciiStrCmp (DeviceType, "cdrom") == 0) {
    Dev->MediaInfo.CdRom = TRUE;
  } else {
    Dev->MediaInfo.CdRom = FALSE;
  }
  FreePool (DeviceType);

  Status = XenBusReadUint64 (XenBusIo, "backend-id", FALSE, &Value);
  if (Status != XENSTORE_STATUS_SUCCESS || Value > MAX_UINT16) {
    DEBUG ((EFI_D_ERROR, "XenPvBlk: Failed to get backend-id (%d)\n",
            Status));
    goto Error;
  }
  Dev->DomainId = (domid_t)Value;
  XenBusIo->EventChannelAllocate (XenBusIo, Dev->DomainId, &Dev->EventChannel);

  SharedRing = (blkif_sring_t*) AllocatePages (1);
  SHARED_RING_INIT (SharedRing);
  FRONT_RING_INIT (&Dev->Ring, SharedRing, EFI_PAGE_SIZE);
  XenBusIo->GrantAccess (XenBusIo,
                         Dev->DomainId,
                         (INTN) SharedRing >> EFI_PAGE_SHIFT,
                         FALSE,
                         &Dev->RingRef);

Again:
  Status = XenBusIo->XsTransactionStart (XenBusIo, &Transaction);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    DEBUG ((EFI_D_WARN, "XenPvBlk: Failed to start transaction, %d\n", Status));
    goto Error;
  }

  Status = XenBusIo->XsPrintf (XenBusIo, &Transaction, NodeName, "ring-ref", "%d",
                               Dev->RingRef);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    DEBUG ((EFI_D_ERROR, "XenPvBlk: Failed to write ring-ref.\n"));
    goto AbortTransaction;
  }
  Status = XenBusIo->XsPrintf (XenBusIo, &Transaction, NodeName,
                               "event-channel", "%d", Dev->EventChannel);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    DEBUG ((EFI_D_ERROR, "XenPvBlk: Failed to write event-channel.\n"));
    goto AbortTransaction;
  }
  Status = XenBusIo->XsPrintf (XenBusIo, &Transaction, NodeName,
                               "protocol", "%a", XEN_IO_PROTO_ABI_NATIVE);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    DEBUG ((EFI_D_ERROR, "XenPvBlk: Failed to write protocol.\n"));
    goto AbortTransaction;
  }

  Status = XenBusIo->SetState (XenBusIo, &Transaction, XenbusStateConnected);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    DEBUG ((EFI_D_ERROR, "XenPvBlk: Failed to switch state.\n"));
    goto AbortTransaction;
  }

  Status = XenBusIo->XsTransactionEnd (XenBusIo, &Transaction, FALSE);
  if (Status == XENSTORE_STATUS_EAGAIN) {
    goto Again;
  }

  XenBusIo->RegisterWatchBackend (XenBusIo, "state", &Dev->StateWatchToken);

  //
  // Waiting for backend
  //
  Status = XenPvBlkWaitForBackendState (Dev, XenbusStateConnected, &State);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    DEBUG ((EFI_D_ERROR,
            "XenPvBlk: backend for %a/%d not available, rc=%d state=%d\n",
            XenBusIo->Type, XenBusIo->DeviceId, Status, State));
    goto Error2;
  }

  Status = XenBusReadUint64 (XenBusIo, "info", TRUE, &Value);
  if (Status != XENSTORE_STATUS_SUCCESS || Value > MAX_UINT32) {
    goto Error2;
  }
  Dev->MediaInfo.VDiskInfo = (UINT32)Value;
  if (Dev->MediaInfo.VDiskInfo & VDISK_READONLY) {
    Dev->MediaInfo.ReadWrite = FALSE;
  } else {
    Dev->MediaInfo.ReadWrite = TRUE;
  }

  Status = XenBusReadUint64 (XenBusIo, "sectors", TRUE, &Dev->MediaInfo.Sectors);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    goto Error2;
  }

  Status = XenBusReadUint64 (XenBusIo, "sector-size", TRUE, &Value);
  if (Status != XENSTORE_STATUS_SUCCESS || Value > MAX_UINT32) {
    goto Error2;
  }
  if ((UINT32)Value % 512 != 0) {
    //
    // This is not supported by the driver.
    //
    DEBUG ((EFI_D_ERROR, "XenPvBlk: Unsupported sector-size value %d, "
            "it must be a multiple of 512\n", Value));
    goto Error2;
  }
  Dev->MediaInfo.SectorSize = (UINT32)Value;

  // Default value
  Value = 0;
  XenBusReadUint64 (XenBusIo, "feature-barrier", TRUE, &Value);
  if (Value == 1) {
    Dev->MediaInfo.FeatureBarrier = TRUE;
  } else {
    Dev->MediaInfo.FeatureBarrier = FALSE;
  }

  // Default value
  Value = 0;
  XenBusReadUint64 (XenBusIo, "feature-flush-cache", TRUE, &Value);
  if (Value == 1) {
    Dev->MediaInfo.FeatureFlushCache = TRUE;
  } else {
    Dev->MediaInfo.FeatureFlushCache = FALSE;
  }

  DEBUG ((EFI_D_INFO, "XenPvBlk: New disk with %ld sectors of %d bytes\n",
          Dev->MediaInfo.Sectors, Dev->MediaInfo.SectorSize));

  *DevPtr = Dev;
  return EFI_SUCCESS;

Error2:
  XenBusIo->UnregisterWatch (XenBusIo, Dev->StateWatchToken);
  XenBusIo->XsRemove (XenBusIo, XST_NIL, "ring-ref");
  XenBusIo->XsRemove (XenBusIo, XST_NIL, "event-channel");
  XenBusIo->XsRemove (XenBusIo, XST_NIL, "protocol");
  goto Error;
AbortTransaction:
  XenBusIo->XsTransactionEnd (XenBusIo, &Transaction, TRUE);
Error:
  XenPvBlockFree (Dev);
  return EFI_DEVICE_ERROR;
}

VOID
XenPvBlockFrontShutdown (
  IN XEN_BLOCK_FRONT_DEVICE *Dev
  )
{
  XENBUS_PROTOCOL *XenBusIo = Dev->XenBusIo;
  XENSTORE_STATUS Status;
  UINT64 Value;

  XenPvBlockSync (Dev);

  Status = XenBusIo->SetState (XenBusIo, XST_NIL, XenbusStateClosing);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    DEBUG ((EFI_D_ERROR,
            "XenPvBlk: error while changing state to Closing: %d\n",
            Status));
    goto Close;
  }

  Status = XenPvBlkWaitForBackendState (Dev, XenbusStateClosing, NULL);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    DEBUG ((EFI_D_ERROR,
            "XenPvBlk: error while waiting for closing backend state: %d\n",
            Status));
    goto Close;
  }

  Status = XenBusIo->SetState (XenBusIo, XST_NIL, XenbusStateClosed);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    DEBUG ((EFI_D_ERROR,
            "XenPvBlk: error while changing state to Closed: %d\n",
            Status));
    goto Close;
  }

  Status = XenPvBlkWaitForBackendState (Dev, XenbusStateClosed, NULL);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    DEBUG ((EFI_D_ERROR,
            "XenPvBlk: error while waiting for closed backend state: %d\n",
            Status));
    goto Close;
  }

  Status = XenBusIo->SetState (XenBusIo, XST_NIL, XenbusStateInitialising);
  if (Status != XENSTORE_STATUS_SUCCESS) {
    DEBUG ((EFI_D_ERROR,
            "XenPvBlk: error while changing state to initialising: %d\n",
            Status));
    goto Close;
  }

  while (TRUE) {
    Status = XenBusReadUint64 (XenBusIo, "state", TRUE, &Value);
    if (Status != XENSTORE_STATUS_SUCCESS) {
      DEBUG ((EFI_D_ERROR,
              "XenPvBlk: error while waiting for new backend state: %d\n",
              Status));
      goto Close;
    }
    if (Value <= XenbusStateInitWait || Value >= XenbusStateClosed) {
      break;
    }
    DEBUG ((EFI_D_INFO,
            "XenPvBlk: waiting backend state %d, current: %d\n",
            XenbusStateInitWait, Value));
    XenBusIo->WaitForWatch (XenBusIo, Dev->StateWatchToken);
  }

Close:
  XenBusIo->UnregisterWatch (XenBusIo, Dev->StateWatchToken);
  XenBusIo->XsRemove (XenBusIo, XST_NIL, "ring-ref");
  XenBusIo->XsRemove (XenBusIo, XST_NIL, "event-channel");
  XenBusIo->XsRemove (XenBusIo, XST_NIL, "protocol");

  XenPvBlockFree (Dev);
}

STATIC
VOID
XenPvBlockWaitSlot (
  IN XEN_BLOCK_FRONT_DEVICE *Dev
  )
{
  /* Wait for a slot */
  if (RING_FULL (&Dev->Ring)) {
    while (TRUE) {
      XenPvBlockAsyncIoPoll (Dev);
      if (!RING_FULL (&Dev->Ring)) {
        break;
      }
      /* Really no slot, could wait for an event on Dev->EventChannel. */
    }
  }
}

VOID
XenPvBlockAsyncIo (
  IN OUT XEN_BLOCK_FRONT_IO *IoData,
  IN     BOOLEAN            IsWrite
  )
{
  XEN_BLOCK_FRONT_DEVICE *Dev = IoData->Dev;
  XENBUS_PROTOCOL *XenBusIo = Dev->XenBusIo;
  blkif_request_t *Request;
  RING_IDX RingIndex;
  BOOLEAN Notify;
  INT32 NumSegments, Index;
  UINTN Start, End;

  // Can't io at non-sector-aligned location
  ASSERT(!(IoData->Sector & ((Dev->MediaInfo.SectorSize / 512) - 1)));
  // Can't io non-sector-sized amounts
  ASSERT(!(IoData->Size & (Dev->MediaInfo.SectorSize - 1)));
  // Can't io non-sector-aligned buffer
  ASSERT(!((UINTN) IoData->Buffer & (Dev->MediaInfo.SectorSize - 1)));

  Start = (UINTN) IoData->Buffer & ~EFI_PAGE_MASK;
  End = ((UINTN) IoData->Buffer + IoData->Size + EFI_PAGE_SIZE - 1) & ~EFI_PAGE_MASK;
  IoData->NumRef = NumSegments = (INT32)((End - Start) / EFI_PAGE_SIZE);

  ASSERT (NumSegments <= BLKIF_MAX_SEGMENTS_PER_REQUEST);

  XenPvBlockWaitSlot (Dev);
  RingIndex = Dev->Ring.req_prod_pvt;
  Request = RING_GET_REQUEST (&Dev->Ring, RingIndex);

  Request->operation = IsWrite ? BLKIF_OP_WRITE : BLKIF_OP_READ;
  Request->nr_segments = (UINT8)NumSegments;
  Request->handle = Dev->DeviceId;
  Request->id = (UINTN) IoData;
  Request->sector_number = IoData->Sector;

  for (Index = 0; Index < NumSegments; Index++) {
    Request->seg[Index].first_sect = 0;
    Request->seg[Index].last_sect = EFI_PAGE_SIZE / 512 - 1;
  }
  Request->seg[0].first_sect = (UINT8)(((UINTN) IoData->Buffer & EFI_PAGE_MASK) / 512);
  Request->seg[NumSegments - 1].last_sect =
      (UINT8)((((UINTN) IoData->Buffer + IoData->Size - 1) & EFI_PAGE_MASK) / 512);
  for (Index = 0; Index < NumSegments; Index++) {
    UINTN Data = Start + Index * EFI_PAGE_SIZE;
    XenBusIo->GrantAccess (XenBusIo, Dev->DomainId,
                           Data >> EFI_PAGE_SHIFT, IsWrite,
                           &Request->seg[Index].gref);
    IoData->GrantRef[Index] = Request->seg[Index].gref;
  }

  Dev->Ring.req_prod_pvt = RingIndex + 1;

  MemoryFence ();
  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY (&Dev->Ring, Notify);

  if (Notify) {
    UINT32 ReturnCode;
    ReturnCode = XenBusIo->EventChannelNotify (XenBusIo, Dev->EventChannel);
    if (ReturnCode != 0) {
      DEBUG ((EFI_D_ERROR,
              "XenPvBlk: Unexpected return value from EventChannelNotify: %d\n",
              ReturnCode));
    }
  }
}

EFI_STATUS
XenPvBlockIo (
  IN OUT XEN_BLOCK_FRONT_IO *IoData,
  IN     BOOLEAN            IsWrite
  )
{
  //
  // Status value that correspond to an IO in progress.
  //
  IoData->Status = EFI_ALREADY_STARTED;
  XenPvBlockAsyncIo (IoData, IsWrite);

  while (IoData->Status == EFI_ALREADY_STARTED) {
    XenPvBlockAsyncIoPoll (IoData->Dev);
  }

  return IoData->Status;
}

STATIC
VOID
XenPvBlockPushOperation (
  IN XEN_BLOCK_FRONT_DEVICE *Dev,
  IN UINT8                  Operation,
  IN UINT64                 Id
  )
{
  INT32 Index;
  blkif_request_t *Request;
  BOOLEAN Notify;

  XenPvBlockWaitSlot (Dev);
  Index = Dev->Ring.req_prod_pvt;
  Request = RING_GET_REQUEST(&Dev->Ring, Index);
  Request->operation = Operation;
  Request->nr_segments = 0;
  Request->handle = Dev->DeviceId;
  Request->id = Id;
  /* Not needed anyway, but the backend will check it */
  Request->sector_number = 0;
  Dev->Ring.req_prod_pvt = Index + 1;
  MemoryFence ();
  RING_PUSH_REQUESTS_AND_CHECK_NOTIFY (&Dev->Ring, Notify);
  if (Notify) {
    XENBUS_PROTOCOL *XenBusIo = Dev->XenBusIo;
    UINT32 ReturnCode;
    ReturnCode = XenBusIo->EventChannelNotify (XenBusIo, Dev->EventChannel);
    if (ReturnCode != 0) {
      DEBUG ((EFI_D_ERROR,
              "XenPvBlk: Unexpected return value from EventChannelNotify: %d\n",
              ReturnCode));
    }
  }
}

VOID
XenPvBlockSync (
  IN XEN_BLOCK_FRONT_DEVICE *Dev
  )
{
  if (Dev->MediaInfo.ReadWrite) {
    if (Dev->MediaInfo.FeatureBarrier) {
      XenPvBlockPushOperation (Dev, BLKIF_OP_WRITE_BARRIER, 0);
    }

    if (Dev->MediaInfo.FeatureFlushCache) {
      XenPvBlockPushOperation (Dev, BLKIF_OP_FLUSH_DISKCACHE, 0);
    }
  }

  /* Note: This won't finish if another thread enqueues requests.  */
  while (TRUE) {
    XenPvBlockAsyncIoPoll (Dev);
    if (RING_FREE_REQUESTS (&Dev->Ring) == RING_SIZE (&Dev->Ring)) {
      break;
    }
  }
}

VOID
XenPvBlockAsyncIoPoll (
  IN XEN_BLOCK_FRONT_DEVICE *Dev
  )
{
  RING_IDX ProducerIndex, ConsumerIndex;
  blkif_response_t *Response;
  INT32 More;

  do {
    ProducerIndex = Dev->Ring.sring->rsp_prod;
    /* Ensure we see queued responses up to 'ProducerIndex'. */
    MemoryFence ();
    ConsumerIndex = Dev->Ring.rsp_cons;

    while (ConsumerIndex != ProducerIndex) {
      XEN_BLOCK_FRONT_IO *IoData = NULL;
      INT16 Status;

      Response = RING_GET_RESPONSE (&Dev->Ring, ConsumerIndex);

      IoData = (VOID *) (UINTN) Response->id;
      Status = Response->status;

      switch (Response->operation) {
      case BLKIF_OP_READ:
      case BLKIF_OP_WRITE:
        {
          INT32 Index;

          if (Status != BLKIF_RSP_OKAY) {
            DEBUG ((EFI_D_ERROR,
                    "XenPvBlk: "
                    "%a error %d on %a at sector %p, num bytes %p\n",
                    Response->operation == BLKIF_OP_READ ? "read" : "write",
                    Status, IoData->Dev->NodeName,
                    IoData->Sector,
                    IoData->Size));
          }

          for (Index = 0; Index < IoData->NumRef; Index++) {
            Dev->XenBusIo->GrantEndAccess (Dev->XenBusIo, IoData->GrantRef[Index]);
          }

          break;
        }

      case BLKIF_OP_WRITE_BARRIER:
        if (Status != BLKIF_RSP_OKAY) {
          DEBUG ((EFI_D_ERROR, "XenPvBlk: write barrier error %d\n", Status));
        }
        break;
      case BLKIF_OP_FLUSH_DISKCACHE:
        if (Status != BLKIF_RSP_OKAY) {
          DEBUG ((EFI_D_ERROR, "XenPvBlk: flush error %d\n", Status));
        }
        break;

      default:
        DEBUG ((EFI_D_ERROR,
                "XenPvBlk: unrecognized block operation %d response (status %d)\n",
                Response->operation, Status));
        break;
      }

      Dev->Ring.rsp_cons = ++ConsumerIndex;
      if (IoData != NULL) {
        IoData->Status = Status ? EFI_DEVICE_ERROR : EFI_SUCCESS;
      }
      if (Dev->Ring.rsp_cons != ConsumerIndex) {
        /* We reentered, we must not continue here */
        break;
      }
    }

    RING_FINAL_CHECK_FOR_RESPONSES (&Dev->Ring, More);
  } while (More != 0);
}
