BOOLEAN
VirtIoInterrupt(
    IN PVOID DeviceExtension
    )
{
    pblk_req            vbr;
    unsigned int        len;
    PADAPTER_EXTENSION  adaptExt;
    BOOLEAN             isInterruptServiced = FALSE;
    PSCSI_REQUEST_BLOCK Srb;
    ULONG               intReason = 0;
    adaptExt = (PADAPTER_EXTENSION)DeviceExtension;

    RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s (%d)\n", __FUNCTION__, KeGetCurrentIrql()));
    intReason = VirtIODeviceISR((VirtIODevice*)DeviceExtension);
    if ( intReason == 1) {
        isInterruptServiced = TRUE;
        while((vbr = (pblk_req)adaptExt->vq->vq_ops->get_buf(adaptExt->vq, &len)) != NULL) {
           Srb = (PSCSI_REQUEST_BLOCK)vbr->req;
           if (Srb) {
              switch (vbr->status) {
              case VIRTIO_BLK_S_OK:
                 Srb->SrbStatus = SRB_STATUS_SUCCESS;
                 break;
              case VIRTIO_BLK_S_UNSUPP:
                 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
                 break;
              default:
                 Srb->SrbStatus = SRB_STATUS_ERROR;
                 RhelDbgPrint(TRACE_LEVEL_ERROR, ("SRB_STATUS_ERROR\n"));
                 break;
              }
           }
           if (vbr->out_hdr.type == VIRTIO_BLK_T_FLUSH) {
#ifdef USE_STORPORT
              --adaptExt->in_fly;
#endif
              CompleteSRB(DeviceExtension, Srb);
           } else if (vbr->out_hdr.type == VIRTIO_BLK_T_GET_ID) {
              adaptExt->sn_ok = TRUE;
           } else if (Srb) {
#ifdef USE_STORPORT
              --adaptExt->in_fly;
#endif
              CompleteDPC(DeviceExtension, vbr, 0);
           }
        }
    } else if (intReason == 3) {
        adaptExt->rescan_geometry = TRUE;
        ScsiPortNotification( BusChangeDetected, DeviceExtension, 0);
        isInterruptServiced = TRUE;
    }
#ifdef USE_STORPORT
    if (adaptExt->in_fly > 0) {
        adaptExt->vq->vq_ops->kick(adaptExt->vq);
    }
#endif
    RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s isInterruptServiced = %d\n", __FUNCTION__, isInterruptServiced));
    return isInterruptServiced;
}
BOOLEAN
VirtIoMSInterruptRoutine (
    IN PVOID  DeviceExtension,
    IN ULONG  MessageID
    )
{
    pblk_req            vbr;
    unsigned int        len;
    PADAPTER_EXTENSION  adaptExt;
    PSCSI_REQUEST_BLOCK Srb;
    BOOLEAN             isInterruptServiced = FALSE;

    adaptExt = (PADAPTER_EXTENSION)DeviceExtension;

    RhelDbgPrint(TRACE_LEVEL_VERBOSE,
                 ("<--->%s : MessageID 0x%x\n", __FUNCTION__, MessageID));

    if (MessageID == 0) {
       adaptExt->rescan_geometry = TRUE;
       StorPortNotification( BusChangeDetected, DeviceExtension, 0);
       return TRUE;
    }

    while((vbr = (pblk_req)adaptExt->vq->vq_ops->get_buf(adaptExt->vq, &len)) != NULL) {
        Srb = (PSCSI_REQUEST_BLOCK)vbr->req;
        if (Srb) {
           switch (vbr->status) {
           case VIRTIO_BLK_S_OK:
              Srb->SrbStatus = SRB_STATUS_SUCCESS;
              break;
           case VIRTIO_BLK_S_UNSUPP:
              Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
              break;
           default:
              Srb->SrbStatus = SRB_STATUS_ERROR;
              RhelDbgPrint(TRACE_LEVEL_ERROR, ("SRB_STATUS_ERROR\n"));
              break;
           }
        }
        if (vbr->out_hdr.type == VIRTIO_BLK_T_FLUSH) {
            --adaptExt->in_fly;
            CompleteSRB(DeviceExtension, Srb);
        } else if (vbr->out_hdr.type == VIRTIO_BLK_T_GET_ID) {
            adaptExt->sn_ok = TRUE;
        } else if (Srb) {
            --adaptExt->in_fly;
            CompleteDPC(DeviceExtension, vbr, MessageID);
        }
        isInterruptServiced = TRUE;
    }
    if (adaptExt->in_fly > 0) {
        adaptExt->vq->vq_ops->kick(adaptExt->vq);
    }
    return isInterruptServiced;
}
BOOLEAN
VirtIoMSInterruptRoutine (
    IN PVOID  DeviceExtension,
    IN ULONG  MessageID
    )
{
    pblk_req            vbr;
    unsigned int        len;
    PADAPTER_EXTENSION  adaptExt;
    PSCSI_REQUEST_BLOCK Srb;
    BOOLEAN             isInterruptServiced = FALSE;
    PRHEL_SRB_EXTENSION srbExt;

    adaptExt = (PADAPTER_EXTENSION)DeviceExtension;

    RhelDbgPrint(TRACE_LEVEL_VERBOSE,
                 ("<--->%s : MessageID 0x%x\n", __FUNCTION__, MessageID));

    if (MessageID == 0) {
        RhelGetDiskGeometry(DeviceExtension);
        return TRUE;
    }

    while((vbr = (pblk_req)adaptExt->vq->vq_ops->get_buf(adaptExt->vq, &len)) != NULL) {
        Srb = (PSCSI_REQUEST_BLOCK)vbr->req;
        if (Srb) {
           switch (vbr->status) {
           case VIRTIO_BLK_S_OK:
              Srb->SrbStatus = SRB_STATUS_SUCCESS;
              break;
           case VIRTIO_BLK_S_UNSUPP:
              Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
              break;
           default:
              Srb->SrbStatus = SRB_STATUS_ERROR;
              RhelDbgPrint(TRACE_LEVEL_ERROR, ("SRB_STATUS_ERROR\n"));
              break;
           }
        }
        if (vbr->out_hdr.type == VIRTIO_BLK_T_FLUSH) {
            --adaptExt->in_fly;
            CompleteSRB(DeviceExtension, Srb);
        } else if (vbr->out_hdr.type == VIRTIO_BLK_T_GET_ID) {
            adaptExt->sn_ok = TRUE;
        } else if (Srb) {
            --adaptExt->in_fly;

            srbExt   = (PRHEL_SRB_EXTENSION)Srb->SrbExtension;
            if (srbExt->fua == TRUE) {
               RemoveEntryList(&vbr->list_entry);
               Srb->SrbStatus = SRB_STATUS_PENDING;
               Srb->ScsiStatus = SCSISTAT_GOOD;
               if (!RhelDoFlush(DeviceExtension, Srb, FALSE)) {
                    Srb->SrbStatus = SRB_STATUS_ERROR;
                    CompleteSRB(DeviceExtension, Srb);
                } else {
                    srbExt->fua = FALSE;
                }
            } else {
                CompleteDPC(DeviceExtension, vbr, MessageID);
            }
        }
        isInterruptServiced = TRUE;
    }
    if (adaptExt->in_fly > 0) {
        adaptExt->vq->vq_ops->kick(adaptExt->vq);
    }
    return isInterruptServiced;
}
BOOLEAN
VirtIoInterrupt(
    IN PVOID DeviceExtension
    )
{
    pblk_req            vbr;
    unsigned int        len;
    PADAPTER_EXTENSION  adaptExt;
    BOOLEAN             isInterruptServiced = FALSE;
    PSCSI_REQUEST_BLOCK Srb;
    ULONG               intReason = 0;
    PRHEL_SRB_EXTENSION srbExt;

    adaptExt = (PADAPTER_EXTENSION)DeviceExtension;

    RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s (%d)\n", __FUNCTION__, KeGetCurrentIrql()));
    intReason = VirtIODeviceISR((VirtIODevice*)DeviceExtension);
    if ( intReason == 1) {
        isInterruptServiced = TRUE;
        while((vbr = (pblk_req)adaptExt->vq->vq_ops->get_buf(adaptExt->vq, &len)) != NULL) {
           Srb = (PSCSI_REQUEST_BLOCK)vbr->req;
           if (Srb) {
              switch (vbr->status) {
              case VIRTIO_BLK_S_OK:
                 Srb->SrbStatus = SRB_STATUS_SUCCESS;
                 break;
              case VIRTIO_BLK_S_UNSUPP:
                 Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
                 break;
              default:
                 Srb->SrbStatus = SRB_STATUS_ERROR;
                 RhelDbgPrint(TRACE_LEVEL_ERROR, ("SRB_STATUS_ERROR\n"));
                 break;
              }
           }
           if (vbr->out_hdr.type == VIRTIO_BLK_T_FLUSH) {
#ifdef USE_STORPORT
              --adaptExt->in_fly;
#endif
              CompleteSRB(DeviceExtension, Srb);
           } else if (vbr->out_hdr.type == VIRTIO_BLK_T_GET_ID) {
              adaptExt->sn_ok = TRUE;
           } else if (Srb) {
#ifdef USE_STORPORT
              --adaptExt->in_fly;
#endif
              srbExt = (PRHEL_SRB_EXTENSION)Srb->SrbExtension;
              if (srbExt->fua) {
                  RemoveEntryList(&vbr->list_entry);
                  Srb->SrbStatus = SRB_STATUS_PENDING;
                  Srb->ScsiStatus = SCSISTAT_GOOD;
                  if (!RhelDoFlush(DeviceExtension, Srb, FALSE)) {
                      Srb->SrbStatus = SRB_STATUS_ERROR;
                      CompleteSRB(DeviceExtension, Srb);
                  } else {
                      srbExt->fua = FALSE;
                  }
              } else {
                  CompleteDPC(DeviceExtension, vbr, 0);
              }
           }
        }
    } else if (intReason == 3) {
        RhelGetDiskGeometry(DeviceExtension);
        isInterruptServiced = TRUE;
    }
#ifdef USE_STORPORT
    if (adaptExt->in_fly > 0) {
        adaptExt->vq->vq_ops->kick(adaptExt->vq);
    }
#endif
    RhelDbgPrint(TRACE_LEVEL_VERBOSE, ("%s isInterruptServiced = %d\n", __FUNCTION__, isInterruptServiced));
    return isInterruptServiced;
}