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; }