コード例 #1
0
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;
}
コード例 #2
0
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);
	}
	
}