void com_ximeta_driver_NDASProtocolTransport::CompleteSCSITask ( com_ximeta_driver_NDASCommand *NDCmd_ptr ) { SCSITaskIdentifier scsiTask = NULL; SCSIServiceResponse serviceResponse = kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE; SCSITaskStatus taskStatus = kSCSITaskStatus_No_Status; IOByteCount bytesTransfered = 0; PSCSICommand scsiCommand_Ptr = NULL; DbgIOLog(DEBUG_MASK_DISK_TRACE, ("CompleteSCSITask: Entered. 0x%x\n", NDCmd_ptr)); scsiCommand_Ptr = NDCmd_ptr->scsiCommand(); if ( scsiCommand_Ptr->CmdData.taskStatus == kSCSITaskStatus_GOOD ) { bytesTransfered = scsiCommand_Ptr->CmdData.xferCount; } DbgIOLog(DEBUG_MASK_DISK_INFO, ("CompleteSCSITask: task 0x%x xferCount %u result 0x%x\n", scsiCommand_Ptr->scsiTask, bytesTransfered, scsiCommand_Ptr->CmdData.results)); SetRealizedDataTransferCount ( scsiCommand_Ptr->scsiTask, bytesTransfered ); // re-entrancy protection scsiTask = scsiCommand_Ptr->scsiTask; if(scsiCommand_Ptr->CmdData.results == kIOReturnSuccess) { serviceResponse = kSCSIServiceResponse_TASK_COMPLETE; } else { serviceResponse = kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE; } taskStatus = scsiCommand_Ptr->CmdData.taskStatus; scsiCommand_Ptr->scsiTask = NULL; // fProvider->clearCommand(); CommandCompleted ( scsiTask, serviceResponse, taskStatus ); scsiTask->release(); DbgIOLog(DEBUG_MASK_DISK_INFO, ("CompleteSCSITask: End task 0x%x task status 0x%x\n", scsiTask, taskStatus)); NDCmd_ptr->release(); /* if ( true == bTerminating ) { DebugPrint(1, false, "%s: CompleteSCSITask call didTerminate\n", getName () ); bool defer = false; IOService::didTerminate(TerminationProvider, TerminationOptions, &defer); } */ return; }
void com_apple_dts_SCSIEmulatorAdapter::CompleteTaskOnWorkloopThread ( SCSIParallelTaskIdentifier parallelRequest, bool transportSuccessful, SCSITaskStatus scsiStatus, UInt64 actuallyTransferred, UInt8* senseBuffer, int senseLength) { // SCSITargetIdentifier target = GetTargetIdentifier(parallelRequest); UInt8 transferDir = GetDataTransferDirection(parallelRequest); UInt64 transferSizeMax = GetRequestedDataTransferCount(parallelRequest); // IOMemoryDescriptor * transferMemDesc = GetDataBuffer(parallelRequest); SCSIEmulatorRequestBlock * srb = ( SCSIEmulatorRequestBlock * ) GetHBADataPointer ( parallelRequest ); if (transportSuccessful && (scsiStatus != kSCSITaskStatus_TASK_SET_FULL)) { // set the realized transfer counts switch (transferDir) { case kSCSIDataTransfer_FromTargetToInitiator: { if (actuallyTransferred > transferSizeMax) { actuallyTransferred = transferSizeMax; } if (!SetRealizedDataTransferCount(parallelRequest, actuallyTransferred)) { IOLog("CompleteTaskOnWorkloopThread: SetRealizedDataTransferCount (%d bytes) returned FAIL\n", actuallyTransferred); } break; } case kSCSIDataTransfer_FromInitiatorToTarget: { if (actuallyTransferred > transferSizeMax) { actuallyTransferred = transferSizeMax; } if (!SetRealizedDataTransferCount(parallelRequest, actuallyTransferred)) { IOLog("CompleteTaskOnWorkloopThread: SetRealizedDataTransferCount (%d bytes) returned FAIL\n", actuallyTransferred); } break; } case kSCSIDataTransfer_NoDataTransfer: default: { break; } } } // Now, add the completion to the queue to be checked by the workloop thread. The completion needs // to be done on the workloop to allow the stack to unwind itself or you risk running into a panic. // The addItemToQueue method in the event source signals the workloop to check the queue after the task // is added. if (!transportSuccessful) { IOLog("CompleteTaskOnWorkloopThread: Failed transport - task = %p, transferDir = %d, transferSize = %lld, scsiStatus = 0x%X\n", parallelRequest, transferDir, transferSizeMax, scsiStatus); queue_init(&srb->fQueueChain); srb->fTask = parallelRequest; srb->fTaskStatus = scsiStatus; srb->fServiceResponse = kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE; mResponderEventSource->addItemToQueue(srb); } else { // handle sense data in common fashion and complete the task if (senseLength > 0) { if (!SetAutoSenseData(parallelRequest, (SCSI_Sense_Data*) senseBuffer, senseLength)) { IOLog("CompleteTaskOnWorkloopThread: Could not set sense data in parallel task\n"); } } queue_init(&srb->fQueueChain); srb->fTask = parallelRequest; srb->fTaskStatus = scsiStatus; srb->fServiceResponse = kSCSIServiceResponse_TASK_COMPLETE; mResponderEventSource->addItemToQueue(srb); } }