Beispiel #1
0
NTSTATUS
LspLogin(
		PLANSCSI_SESSION	LSS,
		PLSSLOGIN_INFO		LoginInfo,
		LSPROTO_TYPE		LSProto,
		BOOLEAN				LockCleanup
	) {
	NTSTATUS	status;

	ASSERT(LSS);
	ASSERT(LoginInfo);

	if(LSS->LanscsiProtocol) {
		return STATUS_INVALID_PARAMETER;
	}

	if(LSProto < 0 || LSProto >= LsprotoCnt ) {
		return STATUS_INVALID_PARAMETER;
	}

	LSS->LanscsiProtocol = LsprotoList[LSProto];

	if(!LSS->LanscsiProtocol->LsprotoFunc.LsprotoLogin) {
		return STATUS_NOT_IMPLEMENTED;
	}

	//
	//	initialize LanscsiSession
	//
	LSS->LoginType				= LoginInfo->LoginType;
	RtlCopyMemory(&LSS->UserID, &LoginInfo->UserID, LSPROTO_USERID_LENGTH);
	RtlCopyMemory(&LSS->Password, &LoginInfo->Password, LSPROTO_PASSWORD_LENGTH);
	LSS->MaxBlocksPerRequest	= LoginInfo->MaxBlocksPerRequest;
	LSS->LanscsiTargetID		= LoginInfo->LanscsiTargetID;
	LSS->LanscsiLU				= LoginInfo->LanscsiLU;
	LSS->HWType					= LoginInfo->HWType;
	LSS->HWVersion				= LoginInfo->HWVersion;
	LSS->BlockInBytes			= LoginInfo->BlockInBytes;
	LSS->HWProtoType			= HARDWARETYPE_TO_PROTOCOLTYPE(LoginInfo->HWType);
	LSS->HWProtoVersion			= (BYTE)LSProto;
	LSS->HPID					= 0;
	LSS->RPID					= 0;
	LSS->CommandTag				= 0;
	LSS->WriteSplitSize			= 8; // Start with small value. LSS->MaxBlocks is not yet initialized.
	LSS->ReadSplitSize			= 8;
	
	status = LSS->LanscsiProtocol->LsprotoFunc.LsprotoLogin(
					LSS,
					LoginInfo
				);

	if(NT_SUCCESS(status)) {
		LONG	lockMax;
		LONG	lockIdx;

		LSS->WriteSplitSize	= LSS->MaxBlocksPerRequest; // Start with max possible blocks.
		LSS->ReadSplitSize	= LSS->MaxBlocksPerRequest;
		ASSERT(LSS->WriteSplitSize <=128);
		ASSERT(LSS->WriteSplitSize >0);

		if(LoginInfo->IsEncryptBuffer) {
			ULONG	encBuffSize;

			encBuffSize = LSS->MaxBlocksPerRequest * LSS->BlockInBytes;
			KDPrintM(DBG_PROTO_TRACE, ("Allocating a encryption buffer. BufferSize:%lu\n", encBuffSize));

			LSS->EncryptBuffer = ExAllocatePoolWithTag( NonPagedPool, encBuffSize, LSS_ENCRYPTBUFFER_POOLTAG);
			if(!LSS->EncryptBuffer) {
				LSS->EncryptBufferLength = 0;
				KDPrintM(DBG_PROTO_ERROR, ("Error! Could not allocate the encrypt buffer! Performace may slow down.\n"));
			} else {
				LSS->EncryptBufferLength = encBuffSize;
			}
		}

		LSS->WriteCheckBuffer = ExAllocatePoolWithTag( NonPagedPool, LSS->MaxBlocksPerRequest * LSS->BlockInBytes, LSS_WRITECHECK_BUFFER_POOLTAG);
		if(!LSS->WriteCheckBuffer) {
			KDPrintM(DBG_PROTO_ERROR, ("Error! Could not allocate the write-check buffer!\n"));
		}

		//
		//	Clean up locks
		//

		if(LockCleanup) {
			if(LSS->HWProtoVersion >= LSIDEPROTO_VERSION_1_1) {
				lockMax = LANSCSIIDE_MAX_LOCK_VER11;
			} else {
				lockMax = 0;
			}

			KDPrintM(DBG_PROTO_TRACE, ("Clean up locks of %u\n", lockMax));

			for(lockIdx = 0; lockIdx < lockMax; lockIdx ++) {
				LspAcquireLock(LSS, (UCHAR)lockIdx, NULL);
				LspReleaseLock(LSS, (UCHAR)lockIdx, NULL);
			}
		}


	} else {
		LSS->LanscsiProtocol = NULL;
	}

	return status;
}
Beispiel #2
0
static
NTSTATUS
OpAcquireDevLock(
	IN PLANSCSI_SESSION	LSS,
	IN ULONG			LockIndex,
	OUT PBYTE			LockData,
	IN PLARGE_INTEGER	TimeOut,
	IN BOOLEAN			RetryWhenFailure
){
	NTSTATUS		status;
	ULONG			lockContention;
	LARGE_INTEGER	startTime;
	LARGE_INTEGER	maximumWaitTime;

	NDAS_ASSERT( TimeOut == NULL || TimeOut->QuadPart <= 0 );

	lockContention = 0;
	status = STATUS_IO_TIMEOUT;
	startTime = LMCurrentTime();
	if(TimeOut && TimeOut->QuadPart) {
		maximumWaitTime.QuadPart = -TimeOut->QuadPart;
	} else {
		maximumWaitTime.QuadPart = 2 * NANO100_PER_SEC;
	}

	while(LMCurrentTime().QuadPart <= startTime.QuadPart + maximumWaitTime.QuadPart) {

		status = LspAcquireLock(
			LSS,
			LockIndex,
			LockData,
			TimeOut);

		if(status == STATUS_LOCK_NOT_GRANTED) {
			KDPrintM(DBG_OTHER_INFO, ("LockIndex%u: Lock contention #%u!!!\n", LockIndex, lockContention));
		} else if(NT_SUCCESS(status)) {
			break;
		} else {
			break;
		}
		lockContention ++;


		//
		//	Clean up the lock on the NDAS device.
		//

		if(lockContention != 0 && (lockContention % 10000 == 0)) {

			LspWorkaroundCleanupLock(LSS,
				LockIndex, NULL);
		}

		if(RetryWhenFailure == FALSE) {
			break;
		}
	}
	if(status == STATUS_LOCK_NOT_GRANTED) {
		KDPrintM(DBG_OTHER_INFO, ("Lock denied. idx=%u lock contention=%u\n", LockIndex, lockContention));
	} else if(!NT_SUCCESS(status)) {
		KDPrintM(DBG_OTHER_INFO, ("Failed to acquire lock idx=%u lock contention=%u\n", LockIndex, lockContention));
	}

	return status;
}
Beispiel #3
0
NTSTATUS
LspLogin(
		PLANSCSI_SESSION	LSS,
		PLSSLOGIN_INFO		LoginInfo,
		LSPROTO_TYPE		LSProto,
		PLARGE_INTEGER		TimeOut,
		BOOLEAN				LockCleanup
	) {
	NTSTATUS	status;

	ASSERT(LSS);
	ASSERT(LoginInfo);

	if(LSS->LanscsiProtocol) {
		return STATUS_INVALID_PARAMETER;
	}

	if(LSProto >= LsprotoCnt) {
		return STATUS_INVALID_PARAMETER;
	}

	LSS->LanscsiProtocol = LsprotoList[LSProto];

	if(!LSS->LanscsiProtocol->LsprotoFunc.LsprotoLogin) {
		return STATUS_NOT_IMPLEMENTED;
	}

	//
	//	initialize LanscsiSession
	//
	LSS->LoginType				= LoginInfo->LoginType;
	RtlCopyMemory(&LSS->UserID, &LoginInfo->UserID, LSPROTO_USERID_LENGTH);
	RtlCopyMemory(&LSS->Password, &LoginInfo->Password, LSPROTO_PASSWORD_LENGTH);
	LSS->MaxDataTransferLength	= LoginInfo->MaxDataTransferLength;
	LSS->LanscsiTargetID		= LoginInfo->LanscsiTargetID;
	LSS->LanscsiLU				= LoginInfo->LanscsiLU;
	LSS->HWType				= LoginInfo->HWType;
	LSS->HWVersion				= LoginInfo->HWVersion;
	LSS->HWRevision				= LoginInfo->HWRevision;	
	LSS->HWProtoType			= HARDWARETYPE_TO_PROTOCOLTYPE(LoginInfo->HWType);
	LSS->HWProtoVersion			= (BYTE)LSProto;
	LSS->HPID					= 0;
	LSS->RPID					= 0;
	LSS->CommandTag			= 0;
	
	status = LSS->LanscsiProtocol->LsprotoFunc.LsprotoLogin(
					LSS,
					LoginInfo,
					IF_NULL_TIMEOUT_THEN_DEFAULT(LSS, TimeOut)
				);
	if(NT_SUCCESS(status)) {
		LONG	lockMax;
		LONG	lockIdx;
		ULONG	buffSize;

		buffSize = LSS->MaxDataTransferLength;
		if(LoginInfo->IsEncryptBuffer) {
			KDPrintM(DBG_PROTO_TRACE, ("Allocating a encryption buffer. BufferSize:%lu\n", buffSize));
			LSS->EncryptBuffer = ExAllocatePoolWithTag( NonPagedPool, buffSize, LSS_ENCRYPTBUFFER_POOLTAG);
			if(!LSS->EncryptBuffer) {
				LSS->EncryptBufferLength = 0;
				KDPrintM(DBG_PROTO_ERROR, ("Error! Could not allocate the encrypt buffer! Performace may slow down.\n"));
			} else {
				LSS->EncryptBufferLength = buffSize;
			}
		}


#if 0	// for 2.5
		LSS->DigestPatchBuffer = ExAllocatePoolWithTag( NonPagedPool,  LSS->MaxBlocksPerRequest * LSS->BlockInBytes + 16, LSS_DIGEST_PATCH_POOLTAG);
		if(!LSS->DigestPatchBuffer) {
			KDPrintM(DBG_PROTO_ERROR, ("Error! Could not allocate the digest patch buffer! Performace may slow down.\n"));
		}
#endif
		//
		//	Clean up locks
		//

		if(LockCleanup) {
			if(LSS->HWProtoVersion >= LSIDEPROTO_VERSION_1_1) {
				lockMax = LANSCSIIDE_MAX_LOCK_VER11;
			} else {
				lockMax = 0;
			}

			KDPrintM(DBG_PROTO_TRACE, ("Clean up locks of %u\n", lockMax));

			for(lockIdx = 0; lockIdx < lockMax; lockIdx ++) {
				LspAcquireLock(LSS, (UCHAR)lockIdx, NULL, IF_NULL_TIMEOUT_THEN_DEFAULT(LSS, TimeOut));
				LspReleaseLock(LSS, (UCHAR)lockIdx, NULL, IF_NULL_TIMEOUT_THEN_DEFAULT(LSS, TimeOut));
			}
		}


	} else {
		LSS->LanscsiProtocol = NULL;
	}

	return status;
}