Ejemplo n.º 1
0
//
//	Completion routine for IRP carrying SRB.
//
NTSTATUS
CompletionIrpCompletionRoutine(
		IN PDEVICE_OBJECT		DeviceObject,
		IN PIRP					Irp,
		IN PCOMPLETION_DATA		Context
	)
{
    PMINIPORT_DEVICE_EXTENSION	HwDeviceExtension = Context->HwDeviceExtension;

	PSCSI_REQUEST_BLOCK			completionSrb = Context->CompletionSrb;
	PCCB						shippedCcb = Context->ShippedCcb;


	KDPrint(3,("Entered\n"));
	UNREFERENCED_PARAMETER(DeviceObject);

	if(completionSrb->DataBuffer) 

	{
		PSCSI_REQUEST_BLOCK	shippedSrb = (PSCSI_REQUEST_BLOCK)(completionSrb->DataBuffer);

		KDPrint(1, ("Unexpected IRP completion!!!\n"));
		ASSERT(shippedCcb);

		InterlockedDecrement(&HwDeviceExtension->RequestExecuting);
		InitializeListHead(&shippedCcb->ListEntry);
		LSCcbSetStatusFlag(shippedCcb, CCBSTATUS_FLAG_TIMER_COMPLETE);
		ExInterlockedInsertTailList(
				&HwDeviceExtension->CcbCompletionList,
				&shippedCcb->ListEntry,
				&HwDeviceExtension->CcbCompletionListSpinLock
				);

		completionSrb->DataBuffer = NULL;
	} else {
		//
		//	Free the CCB if it is not going to the timer completion routine
		//	and allocated from the system pool by lanscsiminiport.
		//
		if(Context->ShippedCcbAllocatedFromPool)
			LSCcbPostCompleteCcb(shippedCcb);
	}

	// Free resources
	ExFreePoolWithTag(completionSrb, LSMP_PTAG_SRB);
	ExFreePoolWithTag(Context, LSMP_PTAG_CMPDATA);
	IoFreeIrp(Irp);

	return STATUS_MORE_PROCESSING_REQUIRED;
}
Ejemplo n.º 2
0
//
//	Complete a Ccb
//
VOID
LSCcbCompleteCcb(
		IN PCCB Ccb
	) {
	LONG		idx_sl;
	NTSTATUS	status;

	ASSERT(Ccb->Type == LSSTRUC_TYPE_CCB);
	ASSERT(Ccb->Length == sizeof(CCB));
	ASSERT(!LSCcbIsFlagOn(Ccb,CCB_FLAG_COMPLETED));
	ASSERT(Ccb->AssociateCount == 0);
	ASSERT(Ccb->CcbCurrentStackLocationIndex < NR_MAX_CCB_STACKLOCATION);
	ASSERT(Ccb->CcbCurrentStackLocation == &Ccb->CcbStackLocation[Ccb->CcbCurrentStackLocationIndex]);

	KDPrintM(DBG_CCB_TRACE, ("entered with Ccb:%p\n", Ccb));

	LSCcbSetFlag(Ccb, CCB_FLAG_COMPLETED);
	LSCcbResetFlag(Ccb, CCB_FLAG_PENDING);


	Ccb->CcbCurrentStackLocationIndex++;
	Ccb->CcbCurrentStackLocation++;

	//
	//	Call completion routines in order.
	//
	for(	idx_sl = Ccb->CcbCurrentStackLocationIndex;
			idx_sl < NR_MAX_CCB_STACKLOCATION;
			idx_sl++, Ccb->CcbCurrentStackLocation++, Ccb->CcbCurrentStackLocationIndex++ ) {

		ASSERT(Ccb->CcbCurrentStackLocation <= &Ccb->CcbStackLocation[NR_MAX_CCB_STACKLOCATION - 1]);

		if(Ccb->CcbCurrentStackLocation->CcbCompletionRoutine) {
			status = Ccb->CcbCurrentStackLocation->CcbCompletionRoutine(Ccb, Ccb->CcbCurrentStackLocation->CcbCompletionContext);
			if(status == STATUS_MORE_PROCESSING_REQUIRED) {
				KDPrintM(DBG_CCB_TRACE, ("Ccb=%p, more processing required.\n", Ccb));
				return;
			}
		}
	}

	//
	//	Do post operation
	//
	LSCcbPostCompleteCcb(Ccb);
}
Ejemplo n.º 3
0
VOID
MiniTimer(
    IN PMINIPORT_DEVICE_EXTENSION HwDeviceExtension
    )
{
	BOOLEAN	BusChanged;

	MiniCounter ++;
	BusChanged = FALSE;

	do {
		PLIST_ENTRY			listEntry;
		PCCB				ccb;
		PSCSI_REQUEST_BLOCK	srb;

		// Get Completed CCB
		listEntry = ExInterlockedRemoveHeadList(
							&HwDeviceExtension->CcbCompletionList,
							&HwDeviceExtension->CcbCompletionListSpinLock
						);

		if(listEntry == NULL)
			break;

		ccb = CONTAINING_RECORD(listEntry, CCB, ListEntry);
		srb = ccb->Srb;
		ASSERT(srb);
		ASSERT(LSCcbIsStatusFlagOn(ccb, CCBSTATUS_FLAG_TIMER_COMPLETE));
		KDPrint(1,("completed SRB:%p SCSIOP:%x\n", srb, srb->Cdb[0]));

		if(LSCcbIsStatusFlagOn(ccb, CCBSTATUS_FLAG_BUSRESET_REQUIRED)) {
			BusChanged = TRUE;
		}
		//
		//	Free a CCB
		//
		LSCcbPostCompleteCcb(ccb);

		ScsiPortNotification(
			RequestComplete,
			HwDeviceExtension,
			srb
			);

		InterlockedDecrement(&HwDeviceExtension->RequestExecuting);

	} while(1);


	if(BusChanged) {
		KDPrint(1,("Bus change detected. RequestExecuting = %d\n", HwDeviceExtension->RequestExecuting));
		ScsiPortNotification(
			BusChangeDetected,
			HwDeviceExtension,
			NULL
			);
	}

	if((MiniCounter % 1000) == 0)
		KDPrint(4,("RequestExecuting = %d\n", HwDeviceExtension->RequestExecuting));

	if(HwDeviceExtension->RequestExecuting != 0) {
		ScsiPortNotification(
			RequestTimerCall,
			HwDeviceExtension,
			MiniTimer,
			1
			);
	} else {
		HwDeviceExtension->TimerOn = FALSE;

		if(ADAPTER_ISSTATUS(HwDeviceExtension,ADAPTER_STATUS_RUNNING))
			ScsiPortNotification(
				RequestTimerCall,
				HwDeviceExtension,
				MiniTimer,
				1 //1000
				);
		
	}

	ScsiPortNotification(
		NextRequest,
		HwDeviceExtension,
		NULL
		);

	return;
}