예제 #1
0
NTSTATUS
LspReleaseLock(
	IN PLANSCSI_SESSION	LSS,
	IN ULONG			LockNo,
	IN PBYTE			LockData,
	IN PLARGE_INTEGER	TimeOut
){
	NTSTATUS		status;
	LANSCSI_PDUDESC	pduDesc;
	BYTE			pduResponse;

	if(LSS->HWProtoVersion <= LSIDEPROTO_VERSION_1_0) {
		NDAS_ASSERT( FALSE );
		return STATUS_NOT_SUPPORTED;
	}

	pduResponse = LANSCSI_RESPONSE_SUCCESS;

	RtlZeroMemory(&pduDesc, sizeof(LANSCSI_PDUDESC));
	pduDesc.Command = VENDOR_OP_FREE_MUTEX;
	pduDesc.Param8[3] = (UCHAR)LockNo;
	pduDesc.TimeOut = IF_NULL_TIMEOUT_THEN_DEFAULT(LSS, TimeOut);
	status = LspVendorRequest(
							LSS,
							&pduDesc,
							&pduResponse
						);

	if(NT_SUCCESS(status)) {

		if(pduResponse != LANSCSI_RESPONSE_SUCCESS) {
			KDPrintM(DBG_LURN_ERROR,	("Releasing lock #%u denied by NDAS device\n", LockNo));
			status = STATUS_LOCK_NOT_GRANTED;
		} else {
			KDPrintM(DBG_LURN_TRACE,	("Released lock #%u\n", LockNo));
		}

		//
		// Convert Network endian to the host endian here.
		//

		if(LockData) {
			UINT32	lockData = NTOHL(pduDesc.Param32[1]);


			//
			// NDAS chip 1.1 returns the increased lock counter.
			// Decrease it for the chip version abstraction.
			//
			if(LSS->HWVersion == LANSCSIIDE_VERSION_1_1) {
				lockData --;
			}
			if(LSS->HWProtoVersion == LSIDEPROTO_VERSION_1_1) {
				*(PUINT32)LockData = lockData;
			}
		}
	}

	return status;
}
예제 #2
0
//////////////////////////////////////////////////////////////////////////
//
//	NDAS device lock control
//
NTSTATUS
LspAcquireLock(
	IN PLANSCSI_SESSION	LSS,
	IN ULONG			LockNo,
	OUT PBYTE			LockData,
	IN PLARGE_INTEGER	TimeOut
){
	NTSTATUS		status;
	LANSCSI_PDUDESC	pduDesc;
	BYTE			pduResponse;

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

	if(LSS->HWProtoVersion <= LSIDEPROTO_VERSION_1_0) {
		return STATUS_NOT_SUPPORTED;
	}

	pduResponse = LANSCSI_RESPONSE_SUCCESS;

	RtlZeroMemory(&pduDesc, sizeof(LANSCSI_PDUDESC));
	pduDesc.Command = VENDOR_OP_SET_MUTEX;
	pduDesc.Param8[3] = (UCHAR)LockNo;
	
	pduDesc.TimeOut = IF_NULL_TIMEOUT_THEN_DEFAULT(LSS, TimeOut);

	if (pduDesc.TimeOut && pduDesc.TimeOut->QuadPart == 0) {

		pduDesc.TimeOut = IF_NULL_TIMEOUT_THEN_DEFAULT(LSS, NULL);
	};

	status = LspVendorRequest(
							LSS,
							&pduDesc,
							&pduResponse
						);
	if(NT_SUCCESS(status)) {

		if(pduResponse != LANSCSI_RESPONSE_SUCCESS) {
			KDPrintM(DBG_LURN_TRACE,	("Acquiring lock #%u denied by NDAS device\n", LockNo));
			status = STATUS_LOCK_NOT_GRANTED;
		} else {
			KDPrintM(DBG_LURN_TRACE,	("Acquired lock #%u\n", LockNo));
		}

		//
		// Convert Network endian to the host endian here.
		//

		if(LockData) {
			if(LSS->HWProtoVersion == LSIDEPROTO_VERSION_1_1) {
				*(PUINT32)LockData = NTOHL(pduDesc.Param32[1]);
			}
		}
	}

	return status;
}
예제 #3
0
NTSTATUS
LspGetLockData(
	IN PLANSCSI_SESSION	LSS,
	IN ULONG			LockNo,
	IN PBYTE			LockData,
	IN PLARGE_INTEGER	TimeOut
){
	NTSTATUS		status;
	LANSCSI_PDUDESC	pduDesc;
	BYTE			pduResponse;

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

	if(LSS->HWProtoVersion <= LSIDEPROTO_VERSION_1_0) {
		return STATUS_NOT_SUPPORTED;
	}

	pduResponse = LANSCSI_RESPONSE_SUCCESS;

	RtlZeroMemory(&pduDesc, sizeof(LANSCSI_PDUDESC));
	pduDesc.Command = VENDOR_OP_FREE_SEMA;
	pduDesc.Param64 = ((UINT64)(LockNo & 0x3)) << 32;	// Lock number: 32~33 bit.
	pduDesc.TimeOut = IF_NULL_TIMEOUT_THEN_DEFAULT(LSS, TimeOut);
	status = LspVendorRequest(
							LSS,
							&pduDesc,
							&pduResponse
						);

	if(NT_SUCCESS(status)) {

		if(pduResponse != LANSCSI_RESPONSE_SUCCESS) {
			KDPrintM(DBG_LURN_ERROR,	("Releasing lock #%u denied by NDAS device\n", LockNo));
			status = STATUS_LOCK_NOT_GRANTED;
		} else {
			KDPrintM(DBG_LURN_TRACE,	("Lock data of lock #%u\n", LockNo));
		}

		//
		// Convert Network endian to the host endian here.
		//

		if(LockData) {
			if(LSS->HWProtoVersion == LSIDEPROTO_VERSION_1_1) {
				*(PUINT32)LockData = NTOHL(pduDesc.Param32[1]);
			}
		}
	}

	return status;
}
예제 #4
0
NTSTATUS
LspGetLockOwner(
	IN PLANSCSI_SESSION	LSS,
	IN ULONG			LockNo,
	IN PBYTE			LockOwner,
	IN PLARGE_INTEGER	TimeOut
){
	NTSTATUS		status;
	LANSCSI_PDUDESC	pduDesc;
	BYTE			pduResponse;

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

	if(LSS->HWProtoVersion <= LSIDEPROTO_VERSION_1_0) {
		return STATUS_NOT_SUPPORTED;
	}

	pduResponse = LANSCSI_RESPONSE_SUCCESS;

	RtlZeroMemory(&pduDesc, sizeof(LANSCSI_PDUDESC));
	pduDesc.Command = VENDOR_OP_OWNER_SEMA;
	pduDesc.Param64 = ((UINT64)(LockNo & 0x3)) << 32;	// Lock number: 32~33 bit.
	pduDesc.TimeOut = IF_NULL_TIMEOUT_THEN_DEFAULT(LSS, TimeOut);
	status = LspVendorRequest(
							LSS,
							&pduDesc,
							&pduResponse
						);

	if(NT_SUCCESS(status)) {

		if(pduResponse != LANSCSI_RESPONSE_SUCCESS) {
			KDPrintM(DBG_LURN_ERROR,	("Get owner of lock #%u denied by NDAS device\n", LockNo));
			status = STATUS_LOCK_NOT_GRANTED;
		} else {
			KDPrintM(DBG_LURN_TRACE,	("owner #%u\n", LockNo));
		}

		RtlCopyMemory(LockOwner, &pduDesc.Param64, 8);
	}

	return status;
}
예제 #5
0
NTSTATUS
LspReleaseLock(
	PLANSCSI_SESSION		LSS,
	UCHAR					LockNo,
	PUINT32					LockCount
){
	NTSTATUS		status;
	LANSCSI_PDUDESC	pduDesc;
	BYTE			pduResponse;

	if(LSS->HWProtoVersion <= LSIDEPROTO_VERSION_1_0) {
		return STATUS_NOT_SUPPORTED;
	}

	pduResponse = LANSCSI_RESPONSE_SUCCESS;

	RtlZeroMemory(&pduDesc, sizeof(LANSCSI_PDUDESC));
	pduDesc.Command = VENDOR_OP_FREE_SEMA;
	pduDesc.Param64 = ((UINT64)(LockNo & 0x3)) << 32;	// Lock number: 32~33 bit.
	status = LspVendorRequest(
							LSS,
							&pduDesc,
							&pduResponse
						);

	if(NT_SUCCESS(status)) {
		KDPrintM(DBG_LURN_TRACE,	("Released lock #%u\n", LockNo));

		if(pduResponse != LANSCSI_RESPONSE_SUCCESS) {
			KDPrintM(DBG_LURN_ERROR,	("Releasing lock #%u denied by NDAS device\n", LockNo));
			status = STATUS_WAS_LOCKED;
		}

		if(LockCount)
			*LockCount = NTOHL(pduDesc.Param32[1]);
	}

	return status;
}
예제 #6
0
//////////////////////////////////////////////////////////////////////////
//
//	NDAS device lock control
//
NTSTATUS
LspAcquireLock(
	PLANSCSI_SESSION		LSS,
	UCHAR					LockNo,
	PUINT32					LockCount

){
	NTSTATUS		status;
	LANSCSI_PDUDESC	pduDesc;
	BYTE			pduResponse;

	if(LSS->HWProtoVersion <= LSIDEPROTO_VERSION_1_0) {
		return STATUS_NOT_SUPPORTED;
	}

	pduResponse = LANSCSI_RESPONSE_SUCCESS;

	RtlZeroMemory(&pduDesc, sizeof(LANSCSI_PDUDESC));
	pduDesc.Command = VENDOR_OP_SET_MUTEX;
	pduDesc.Param8[3] = (UCHAR)LockNo;
	status = LspVendorRequest(
							LSS,
							&pduDesc,
							&pduResponse
						);
	if(NT_SUCCESS(status)) {
		KDPrintM(DBG_LURN_TRACE,	("Acquired lock #%u\n", LockNo));

		if(pduResponse != LANSCSI_RESPONSE_SUCCESS) {
			KDPrintM(DBG_LURN_ERROR,	("Acquiring lock #%u denied by NDAS device\n", LockNo));
			status = STATUS_WAS_LOCKED;
		}

		if(LockCount)
			*LockCount = NTOHL(pduDesc.Param32[1]);
	}

	return status;
}
예제 #7
0
NTSTATUS
LspWorkaroundCleanupLock(
   PLANSCSI_SESSION	LSS,
   ULONG			LockNo,
   PLARGE_INTEGER	TimeOut
){
	NTSTATUS		status;
	LONG			i;
	LANSCSI_PDUDESC	pduDesc;
	BYTE			pduResponse;
	PLANSCSI_SESSION	tempLSS;
	LONG			maxConn;
	UCHAR			bindingBuffer[(FIELD_OFFSET(TA_ADDRESS, Address) + TDI_ADDRESS_LENGTH_LPX)];
	UCHAR			targetBuffer[(FIELD_OFFSET(TA_ADDRESS, Address) + TDI_ADDRESS_LENGTH_LPX)];
	PTA_ADDRESS		BindingAddress = (PTA_ADDRESS)bindingBuffer;
	PTA_ADDRESS  	TargetAddress = (PTA_ADDRESS)targetBuffer;
	LSSLOGIN_INFO	loginInfo;
	LSPROTO_TYPE	LSProto;
	ULONG			cleaned;

	//
	//	Parameter check
	//
	// Perform clean-up only for NDAS 2.0 rev 0.
	//

	if((LSS->HWVersion == LANSCSIIDE_VERSION_2_0 &&
		 LSS->HWRevision == LANSCSIIDE_VER20_REV_1G_ORIGINAL)) {

		// Get maximum connections excluding the current session/connection.
		maxConn = LANSCSIIDE_MAX_CONNECTION_VER11 - 1;
	} else {
		return STATUS_SUCCESS;
	}

	tempLSS = ExAllocatePoolWithTag(
							NonPagedPool,
							maxConn * sizeof(LANSCSI_SESSION),
							LSS_POOLTAG);
	if(tempLSS == NULL)
		return STATUS_INSUFFICIENT_RESOURCES;
	RtlZeroMemory(tempLSS, maxConn * sizeof(LANSCSI_SESSION));

	//
	//	Init variables
	//

	status = STATUS_SUCCESS;
	RtlZeroMemory(&pduDesc, sizeof(LANSCSI_PDUDESC));
	pduDesc.Param8[3] = (UCHAR)LockNo;
	pduDesc.TimeOut = IF_NULL_TIMEOUT_THEN_DEFAULT(LSS, TimeOut);
	LspGetAddresses(LSS, BindingAddress, TargetAddress);
	cleaned = 0;


	//
	//	Try to make connections to fill up connection pool of the NDAS device.
	//	So, we can clear invalid acquisition of the locks.
	//
	KDPrintM(DBG_LURN_ERROR,("Try to clean up lock\n"));
	for (i=0 ; i < maxConn; i++) {

		tempLSS[i].DefaultTimeOut.QuadPart = IF_NULL_TIMEOUT_THEN_DEFAULT(LSS, TimeOut)->QuadPart;

		//
		//	Connect and log in with read-only access.
		//

		//	connect
		status = LspConnect(
					&tempLSS[i],
					BindingAddress,
					TargetAddress,
					NULL,
					NULL,
					NULL,
					NULL
					);
		if(!NT_SUCCESS(status)) {
			KDPrintM(DBG_LURN_ERROR, ("LspConnect(), Can't Connect to the LS node. STATUS:0x%08x\n", status));
			break;
		}
	}


	for (i=0; i < maxConn; i++) {

		if(!LspIsConnected(&tempLSS[i])) {
			continue;
		}

		KDPrintM(DBG_LURN_TRACE, ("Con#%u\n", i));
		cleaned++;

		//	extract login information from the existing LSS.
		LspBuildLoginInfo(LSS, &loginInfo);
		status = LspLookupProtocol(loginInfo.HWType, loginInfo.HWVersion, &LSProto);
		if(!NT_SUCCESS(status)) {
			LspDisconnect(&tempLSS[i]);
			KDPrintM(DBG_LURN_ERROR, ("Wrong hardware version.\n"));
			continue;
		}

		//	Log in with read-only access.
		loginInfo.UserID &= 0x0000ffff;
		status = LspLogin(
						&tempLSS[i],
						&loginInfo,
						LSProto,
						NULL,
						FALSE
					);
		if(!NT_SUCCESS(status)) {
			KDPrintM(DBG_LURN_ERROR, ("LspLogin() failed. STATUS:0x%08x\n", status));
			LspDisconnect(&tempLSS[i]);
			continue;
		}

		// Do need to acquire the lock to release.
		// NDAS chip 2.0 original allow to release the lock 
		// regardless of the ownership if the connection number
		// in the lock information of NDAS chip 2.0
		// is same.
#if 0
		//
		//	Acquire the lock on the NDAS device.
		//

		pduDesc.Command = VENDOR_OP_SET_MUTEX;
		status = LspVendorRequest(
						&tempLSS[i],
						&pduDesc,
						&pduResponse
						);
		if(pduResponse != LANSCSI_RESPONSE_SUCCESS) {
			KDPrintM(DBG_LURN_ERROR,	("Acquiring lock #%u denied by NDAS device\n", LockNo));
		}
		if(!NT_SUCCESS(status)) {
			LspDisconnect(&tempLSS[i]);
			KDPrintM(DBG_LURN_ERROR, ("LspVendorRequest() failed. STATUS=%08lx\n", status));
			continue;
		}
#endif
		//
		//	Release the lock on the NDAS device.
		//

		pduDesc.Command = VENDOR_OP_FREE_MUTEX;
		status = LspVendorRequest(
						&tempLSS[i],
						&pduDesc,
						&pduResponse
						);
		if(pduResponse != LANSCSI_RESPONSE_SUCCESS) {
			KDPrintM(DBG_LURN_ERROR,	("Releasing lock #%u denied by NDAS device\n", LockNo));
		}
		if(!NT_SUCCESS(status)) {
			LspDisconnect(&tempLSS[i]);
			KDPrintM(DBG_LURN_ERROR, ("LspVendorRequest() failed. STATUS=%08lx\n", status));
			continue;
		}


		//
		//	Log out and disconnect.
		//

		LspLogout(
			&tempLSS[i],
			NULL
			);

		LspDisconnect(
			&tempLSS[i]
			);

		//
		// Init PDU
		//
		pduDesc.Retransmits = 0;
		pduDesc.PacketLoss = 0;
	}

	KDPrintM(DBG_LURN_INFO, ("Cleaned #%u\n", cleaned));

	ExFreePool(tempLSS);

	return status;
}
예제 #8
0
NTSTATUS
LspCleanupLock(
   PLANSCSI_SESSION	LSS,
   UCHAR			LockNo
){
	NTSTATUS		status;
	LONG			i;
	LANSCSI_PDUDESC	pduDesc;
	BYTE			pduResponse;
	PLANSCSI_SESSION	tempLSS;
	LONG			maxConn;
	LARGE_INTEGER	GenericTimeOut;
	TA_LSTRANS_ADDRESS	BindingAddress, TargetAddress;
	LSSLOGIN_INFO	loginInfo;
	LSPROTO_TYPE	LSProto;
	ULONG			cleaned;

	//
	//	Parameter check
	//

	if(LSS->HWProtoVersion <= LSIDEPROTO_VERSION_1_0) {
		return STATUS_NOT_SUPPORTED;
	}

	if(LSS->HWVersion >= 1) {
		maxConn = LANSCSIIDE_MAX_CONNECTION_VER11 - 1;
	} else {
		return STATUS_NOT_SUPPORTED;
	}

	tempLSS = ExAllocatePoolWithTag(
							NonPagedPool,
							maxConn * sizeof(LANSCSI_SESSION),
							LSS_POOLTAG);
	RtlZeroMemory(tempLSS, maxConn * sizeof(LANSCSI_SESSION));

	//
	//	Init variables
	//

	status = STATUS_SUCCESS;
	RtlZeroMemory(&pduDesc, sizeof(LANSCSI_PDUDESC));
	pduDesc.Param64 = ((UINT64)(LockNo & 0x3)) << 32;	// Lock number: 32~33 bit.
	LspGetAddresses(LSS, &BindingAddress, &TargetAddress);
	GenericTimeOut.QuadPart = NANO100_PER_SEC * 5;
	cleaned = 0;


	//
	//	Try to make connections to fill up connection pool of the NDAS device.
	//	So, we can clear invalid acquisition of the locks.
	//
	KDPrintM(DBG_LURN_ERROR,("Try to clean up lock\n"));
	for (i=0 ; i < maxConn; i++) {


		//
		//	Connect and log in with read-only access.
		//

		//	connect
		LspSetTimeOut(&tempLSS[i], &GenericTimeOut);
		status = LspConnect(
					&tempLSS[i],
					&BindingAddress,
					&TargetAddress
					);
		if(!NT_SUCCESS(status)) {
			KDPrintM(DBG_LURN_ERROR, ("LspConnect(), Can't Connect to the LS node. STATUS:0x%08x\n", status));
			break;
		}
	}


	for (i=0; i < maxConn; i++) {

		if(!LspIsConnected(&tempLSS[i])) {
			continue;
		}

		KDPrintM(DBG_LURN_TRACE, ("Con#%u\n", i));
		cleaned++;

		//	extract login information from the existing LSS.
		LspBuildLoginInfo(LSS, &loginInfo);
		status = LspLookupProtocol(loginInfo.HWType, loginInfo.HWVersion, &LSProto);
		if(!NT_SUCCESS(status)) {
			LspDisconnect(&tempLSS[i]);
			KDPrintM(DBG_LURN_ERROR, ("Wrong hardware version.\n"));
			continue;
		}

		//	Log in with read-only access.
		loginInfo.UserID &= 0x0000ffff;
		status = LspLogin(
						&tempLSS[i],
						&loginInfo,
						LSProto,
						FALSE
					);
		if(!NT_SUCCESS(status)) {
			KDPrintM(DBG_LURN_ERROR, ("LspLogin() failed. STATUS:0x%08x\n", status));
			LspDisconnect(&tempLSS[i]);
			ASSERT(FALSE);
			continue;
		}


		//
		//	Acquire the lock on the NDAS device.
		//

		pduDesc.Command = VENDOR_OP_SET_SEMA;
		status = LspVendorRequest(
						&tempLSS[i],
						&pduDesc,
						&pduResponse
						);
		if(pduResponse != LANSCSI_RESPONSE_SUCCESS) {
			KDPrintM(DBG_LURN_ERROR,	("Acquiring lock #%u denied by NDAS device\n", LockNo));
		}
		if(!NT_SUCCESS(status)) {
			LspDisconnect(&tempLSS[i]);
			KDPrintM(DBG_LURN_ERROR, ("LspVendorRequest() failed. STATUS=%08lx\n", status));
			continue;
		}

		//
		//	Release the lock on the NDAS device.
		//

		pduDesc.Command = VENDOR_OP_FREE_SEMA;
		status = LspVendorRequest(
						&tempLSS[i],
						&pduDesc,
						&pduResponse
						);
		if(pduResponse != LANSCSI_RESPONSE_SUCCESS) {
			KDPrintM(DBG_LURN_ERROR,	("Releasing lock #%u denied by NDAS device\n", LockNo));
		}
		if(!NT_SUCCESS(status)) {
			LspDisconnect(&tempLSS[i]);
			KDPrintM(DBG_LURN_ERROR, ("LspVendorRequest() failed. STATUS=%08lx\n", status));
			continue;
		}


		//
		//	Log out and disconnect.
		//

		LspLogout(
			&tempLSS[i]
			);

		LspDisconnect(
			&tempLSS[i]
			);
	}

	KDPrintM(DBG_LURN_INFO, ("Cleaned #%u\n", cleaned));

	ExFreePool(tempLSS);

	return status;
}