예제 #1
0
static
NTSTATUS
GetBufferLockPendingRequests(
	IN PBUFFLOCK_CONTROL	BuffLockCtl,
	IN PLANSCSI_SESSION		LSS,
	IN PLU_HWDATA			LuHwData,
	OUT PULONG				PendingRequests,
	IN PLARGE_INTEGER		TimeOut
){
	NTSTATUS	status;
	TARGET_DATA	targetData;
	ULONG		requestCount;

	status = LspTextTartgetData(
		LSS,
		FALSE,
		LuHwData->LanscsiTargetID,
		&targetData,
		TimeOut);
	if(!NT_SUCCESS(status)) {
		KDPrintM(DBG_OTHER_ERROR, ("LspTextTartgetData() failed.\n", status));
		return status;
	}

	KDPrintM(DBG_OTHER_TRACE, ("TargetData:%u\n", targetData));
	//
	// Match the signature.
	// If not match, it might be interference by anonymous application.
	//
	requestCount = (ULONG)(targetData & TARGETDATA_REQUEST_COUNT_MASK);
	UpdateRequestCount(BuffLockCtl, requestCount, PendingRequests);

	return status;
}
예제 #2
0
NTSTATUS
LstransReceive(
		IN PLSTRANS_CONNECTION_FILE	ConnectionFile,
		IN	PUCHAR					RecvBuffer,
		IN 	ULONG					RecvLength,
		IN	ULONG					Flags,
		OUT	PLONG					Result,
		IN OUT PVOID				CompletionContext,
		IN PLARGE_INTEGER			TimeOut
	) {
	ASSERT(ConnectionFile);

	KDPrintM(DBG_TRANS_TRACE, ("entered.\n"));

	if(!ConnectionFile->Protocol) {
		KDPrintM(DBG_TRANS_TRACE, ("No protocol.\n"));
		return STATUS_INVALID_PARAMETER;
	}
	if(!ConnectionFile->Protocol->LstransFunc.LstransReceive) {
		return STATUS_NOT_IMPLEMENTED;
	}

	return ConnectionFile->Protocol->LstransFunc.LstransReceive(
					ConnectionFile->ConnectionFileObject,
					RecvBuffer,
					RecvLength,
					Flags,
					Result,
					CompletionContext,
					TimeOut
				);
}
예제 #3
0
NTSTATUS
LstransRegisterDisconnectHandler(
		IN	PLSTRANS_ADDRESS_FILE	AddressFile,
		IN	PVOID					EventHandler,
		IN	PVOID					EventContext
	) {
	ASSERT(AddressFile);

	KDPrintM(DBG_TRANS_TRACE, ("entered.\n"));

	if(!AddressFile->Protocol) {
		KDPrintM(DBG_TRANS_TRACE, ("AddressFile No protocol.\n"));
		return STATUS_INVALID_PARAMETER;
	}

	if(!AddressFile->Protocol->LstransFunc.LstransDisconnect) {
		return STATUS_NOT_IMPLEMENTED;
	}

	return AddressFile->Protocol->LstransFunc.LstransRegisterDisconHandler(
					AddressFile->AddressFileObject,
					EventHandler,
					EventContext
				);
}
예제 #4
0
NTSTATUS
LstransReceive(
		IN PLSTRANS_CONNECTION_FILE	ConnectionFile,
		IN	PUCHAR					RecvBuffer,
		IN 	ULONG					RecvLength,
		IN	ULONG					Flags,
		IN PLARGE_INTEGER			TimeOut,
		OUT	PLONG					Result,
		IN PLSTRANS_OVERLAPPED		OverlappedData
	) {
	ASSERT(ConnectionFile);

	KDPrintM(DBG_TRANS_TRACE, ("entered.\n"));

	if(!ConnectionFile->Protocol) {
		KDPrintM(DBG_TRANS_TRACE, ("No protocol.\n"));
		return STATUS_INVALID_PARAMETER;
	}
	if(!ConnectionFile->Protocol->LstransFunc.LstransReceive) {
		return STATUS_NOT_IMPLEMENTED;
	}

	return ConnectionFile->Protocol->LstransFunc.LstransReceive( // call to LpxTdiRecv_LSTrans
					ConnectionFile->ConnectionFileObject,
					RecvBuffer,
					RecvLength,
					Flags,
					TimeOut,
					Result,
					OverlappedData
				);
}
예제 #5
0
NTSTATUS
LstransSendDatagram(
		IN	PLSTRANS_ADDRESS_FILE	AddressFile,
		IN	PTA_LSTRANS_ADDRESS		RemoteAddress,
		IN	PUCHAR					SendBuffer,
		IN 	ULONG					SendLength,
		IN	ULONG					Flags,
		OUT	PLONG					Result,
		IN PLSTRANS_OVERLAPPED		OverlappedData
	) {
	ASSERT(AddressFile);

	KDPrintM(DBG_TRANS_TRACE, ("entered.\n"));

	if(!AddressFile->Protocol) {
		KDPrintM(DBG_TRANS_TRACE, ("No protocol.\n"));
		return STATUS_INVALID_PARAMETER;
	}
	if(!AddressFile->Protocol->LstransFunc.LstransSendDatagram) {
		return STATUS_NOT_IMPLEMENTED;
	}

	return AddressFile->Protocol->LstransFunc.LstransSendDatagram(
					AddressFile->AddressFileObject,
					RemoteAddress,
					SendBuffer,
					SendLength,
					Flags,
					Result,
					OverlappedData
				);
}
예제 #6
0
NTSTATUS
LstransConnect(
		IN PLSTRANS_CONNECTION_FILE	ConnectionFile,
		IN PTA_LSTRANS_ADDRESS		RemoteAddress,
		IN PLARGE_INTEGER			TimeOut,
		IN PLSTRANS_OVERLAPPED		OverlappedData
	) {
	ASSERT(ConnectionFile);
	ASSERT(RemoteAddress);

	KDPrintM(DBG_TRANS_TRACE, ("entered.\n"));

	if(!ConnectionFile->Protocol) {
		KDPrintM(DBG_TRANS_TRACE, ("ConnectionFile No protocol.\n"));
		return STATUS_INVALID_PARAMETER;
	}

	if(!ConnectionFile->Protocol->LstransFunc.LstransConnect) {
		return STATUS_NOT_IMPLEMENTED;
	}

	return ConnectionFile->Protocol->LstransFunc.LstransConnect(
					ConnectionFile->ConnectionFileObject,
					RemoteAddress,
					TimeOut,
					OverlappedData
				);

}
예제 #7
0
NTSTATUS
LstransListen(
		IN PLSTRANS_CONNECTION_FILE	ConnectionFile,
		IN PVOID					CompletionContext,
		IN PULONG					Flags,
		IN PLARGE_INTEGER			TimeOut
	) {
	ASSERT(ConnectionFile);

	KDPrintM(DBG_TRANS_TRACE, ("entered.\n"));

	if(!ConnectionFile->Protocol) {
		KDPrintM(DBG_TRANS_TRACE, ("ConnectionFile No protocol.\n"));
		return STATUS_INVALID_PARAMETER;
	}

	if(!ConnectionFile->Protocol->LstransFunc.LstransListen) {
		return STATUS_NOT_IMPLEMENTED;
	}

	return ConnectionFile->Protocol->LstransFunc.LstransListen(
					ConnectionFile->ConnectionFileObject,
					CompletionContext,
					Flags,
					TimeOut
				);
}
예제 #8
0
NTSTATUS
LstransAssociate(
		IN	PLSTRANS_ADDRESS_FILE		AddressFile,
		IN	PLSTRANS_CONNECTION_FILE	ConnectionFile
) {
	ASSERT(AddressFile);
	ASSERT(ConnectionFile);

	KDPrintM(DBG_TRANS_TRACE, ("entered.\n"));

	if(!AddressFile->Protocol) {
		KDPrintM(DBG_TRANS_TRACE, ("AddressFile No protocol.\n"));
		return STATUS_INVALID_PARAMETER;
	}

	if(!ConnectionFile->Protocol) {
		KDPrintM(DBG_TRANS_TRACE, ("ConnectionFile No protocol.\n"));
		return STATUS_INVALID_PARAMETER;
	}

	if(ConnectionFile->Protocol != AddressFile->Protocol) {
		return STATUS_INVALID_PARAMETER;
	}

	if(!ConnectionFile->Protocol->LstransFunc.LstransAssociate) {
		return STATUS_NOT_IMPLEMENTED;
	}

	return ConnectionFile->Protocol->LstransFunc.LstransAssociate(
					ConnectionFile->ConnectionFileObject,
					AddressFile->AddressFileHandle
				);
}
예제 #9
0
NTSTATUS
LstransCloseAddress(
		IN PLSTRANS_ADDRESS_FILE	AddressFile
	) {
	NTSTATUS	status;
	ASSERT(AddressFile);

	KDPrintM(DBG_TRANS_TRACE, ("entered.\n"));

	if(!AddressFile->Protocol) {
//		KDPrintM(DBG_TRANS_ERROR, ("Protocol NULL!\n"));
		// Maybe this addressfile is already closed.
		return STATUS_INVALID_PARAMETER;
	}

	if(!AddressFile->Protocol->LstransFunc.LstransCloseAddress) {
		KDPrintM(DBG_TRANS_ERROR, ("LstransCloseAddress not implemented.\n"));
		return STATUS_NOT_IMPLEMENTED;
	}

	status = AddressFile->Protocol->LstransFunc.LstransCloseAddress(
					AddressFile->AddressFileHandle,
					AddressFile->AddressFileObject
				);

	AddressFile->AddressFileHandle = NULL;
	AddressFile->AddressFileObject = NULL;
	AddressFile->Protocol = NULL;

	return status;
}
예제 #10
0
VOID
DraidListnerDelAddress(
	PTDI_ADDRESS_LPX Addr
) {
	PDRAID_GLOBALS DraidGlobals;
	PLIST_ENTRY listEntry;
	KIRQL oldIrql;
	PDRAID_LISTEN_CONTEXT ListenContext;
	
	if (!g_DraidGlobals) {
		KDPrintM(DBG_LURN_INFO, ("DRAID is not running\n"));
		return;
	}

	DraidGlobals = g_DraidGlobals;
	
	// Find matching address and just mark active flag false because Wait event may be in use.	
	ACQUIRE_SPIN_LOCK(&DraidGlobals->ListenContextSpinlock, &oldIrql);
	for (listEntry = DraidGlobals->ListenContextList.Flink;
		listEntry != &DraidGlobals->ListenContextList;
		listEntry = listEntry->Flink) 
	{
		ListenContext = CONTAINING_RECORD (listEntry, DRAID_LISTEN_CONTEXT, Link);
		if (RtlCompareMemory(ListenContext->Addr.Node, 
			Addr->Node, 6) == 6) {
			KDPrintM(DBG_LURN_INFO, ("Found matching address\n"));
			ListenContext->Destroy = TRUE;
			KeSetEvent(&DraidGlobals->NetChangedEvent, IO_NO_INCREMENT, FALSE);
			break;
		}
	}
	RELEASE_SPIN_LOCK(&DraidGlobals->ListenContextSpinlock, oldIrql);
}
예제 #11
0
VOID
LsuWriteLogErrorEntry(
	IN PDEVICE_OBJECT		DeviceObject,
    IN PLSU_ERROR_LOG_ENTRY ErrorLogEntry
){


	if(KeGetCurrentIrql() > PASSIVE_LEVEL) {
		PIO_WORKITEM	workitem;
		PLSU_ERRORLOGCTX	context;

		context = ExAllocatePoolWithTag(NonPagedPool, sizeof(LSU_ERRORLOGCTX), LSU_POOLTAG_ERRORLOGWORKER);
		if(context == NULL) {
			KDPrintM(DBG_OTHER_ERROR, ("Allocating context failed.\n"));
			return;
		}

		RtlCopyMemory(&context->ErrorLogEntry, ErrorLogEntry, sizeof(LSU_ERROR_LOG_ENTRY));


		workitem = IoAllocateWorkItem(DeviceObject);
		if(workitem == NULL) {
			KDPrintM(DBG_OTHER_ERROR, ("IoAllocateWorkItem() failed.\n"));
			return;
		}

		context->IoWorkItem = workitem;

		IoQueueWorkItem(workitem, WriteErrorLogWorker, DelayedWorkQueue, context);

	} else {
		_WriteLogErrorEntry(DeviceObject, ErrorLogEntry);
	}
}
예제 #12
0
NTSTATUS
LstransSetInformation(
		IN PLSTRANS_CONNECTION_FILE	ConnectionFile,
		IN ULONG				SetType,
		IN PVOID				Buffer,
		IN ULONG				BufferLen
	){
	ASSERT(ConnectionFile);

	KDPrintM(DBG_TRANS_TRACE, ("entered.\n"));

	if(!ConnectionFile->Protocol) {
		KDPrintM(DBG_TRANS_TRACE, ("No protocol.\n"));
		return STATUS_INVALID_PARAMETER;
	}
	if(!ConnectionFile->Protocol->LstransFunc.LstransSetInformation) {
		return STATUS_NOT_IMPLEMENTED;
	}

	return ConnectionFile->Protocol->LstransFunc.LstransSetInformation( // call to LpxTdiSetInformation_LSTrans
					ConnectionFile->ConnectionFileObject,
					SetType,
					Buffer,
					BufferLen
				);
}
예제 #13
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;
}
예제 #14
0
NTSTATUS
LsuWriteBlocks(
	IN PLANSCSI_SESSION	LSS,
	IN PBYTE			Buffer,
	IN UINT64			LogicalBlockAddress,
	IN ULONG			TransferBlocks,
	IN ULONG			BlockBytes,
	IN ULONG			PduFlags
) {
	NTSTATUS		status;
	LANSCSI_PDUDESC	PduDesc;
	BYTE			PduResponse;

	LSS_INITIALIZE_PDUDESC(LSS, &PduDesc, IDE_COMMAND, WIN_WRITE, PduFlags, LogicalBlockAddress, TransferBlocks, TransferBlocks * BlockBytes, Buffer, NULL);
	status = LspRequest(
					LSS,
					&PduDesc,
					&PduResponse
				);

	if(!NT_SUCCESS(status)) {
		KDPrintM(DBG_OTHER_ERROR, 
			("Error: logicalBlockAddress = %I64x, transferBlocks = %x\n", 
			LogicalBlockAddress, TransferBlocks));

	} else if(PduResponse != LANSCSI_RESPONSE_SUCCESS) {
		KDPrintM(DBG_OTHER_ERROR, 
			("Error: logicalBlockAddress = %I64x, transferBlocks = %x PduResponse:%x\n", 
			LogicalBlockAddress, TransferBlocks, PduResponse));

		status = STATUS_REQUEST_NOT_ACCEPTED;
	}

	return status;
}
예제 #15
0
파일: lslurn.c 프로젝트: yzx65/ndas4windows
NTSTATUS
LurnDestroy(
		PLURELATION_NODE Lurn
	) {
	NTSTATUS ntStatus;

	KDPrintM(DBG_LURN_ERROR, ("In. Lurn %p\n", Lurn));

	ASSERT(Lurn);
	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

	if(!Lurn->LurnInterface) {
		KDPrintM(DBG_LURN_ERROR, ("LURN->LurnInterface NULL!\n"));
		return STATUS_INVALID_PARAMETER;
	}
	if(!Lurn->LurnInterface->LurnFunc.LurnDestroy) {
		return STATUS_NOT_IMPLEMENTED;
	}

	ntStatus = Lurn->LurnInterface->LurnFunc.LurnDestroy(
					Lurn
				);
	ASSERT(NT_SUCCESS(ntStatus));
	Lurn->LurnStatus =  LURN_STATUS_DESTROYING;

	return ntStatus;
}
예제 #16
0
NTSTATUS
EnterBufferLockIoIdle(
	IN PBUFFLOCK_CONTROL BuffLockCtl,
	IN PLANSCSI_SESSION	LSS,
	IN PLU_HWDATA		LuHwData
){
	NTSTATUS	status;

	KDPrintM(DBG_OTHER_INFO, (
		"Enter buffer lock IO idle.\n"));

	if(BuffLockCtl->BufferLockConrol == FALSE) {
		return STATUS_SUCCESS;
	}

	// Release the buffer lock
	status = NdasReleaseBufferLock(BuffLockCtl, LSS, LuHwData
		, NULL, NULL, TRUE, 0);
	if(!NT_SUCCESS(status)) {
		KDPrintM(DBG_OTHER_ERROR, (
			" ReleaseNdasBufferLock() failed. STATUS=%08lx.\n",
			status));
	}

	// Indicate IO idle state.
	BuffLockCtl->IoIdle = TRUE;

	return status;
}
예제 #17
0
파일: lslurn.c 프로젝트: yzx65/ndas4windows
NTSTATUS
LurnInitialize(
		PLURELATION_NODE		Lurn,
		PLURELATION				Lur,
		PLURELATION_NODE_DESC	LurnDesc
	) {
	NTSTATUS			status;

	KDPrintM(DBG_LURN_ERROR, ("In. Lurn : %p, Lur : %p, LurnDesc : %p\n", Lurn, Lur, LurnDesc));

	ASSERT(Lurn);
	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

	if(Lur && LurnDesc)
	{
		// normal initialize

		if(LurnDesc->LurnType < 0 || LurnDesc->LurnType >= LurnInterfaceCnt ) {
			KDPrintM(DBG_LURN_ERROR, ("Error in Lurn Type %x\n", LurnDesc->LurnType));
			return STATUS_INVALID_PARAMETER;
		}

		//
		//	set default values.
		//	Do not zero pointers to children.
		//
		KeInitializeSpinLock(&Lurn->LurnSpinLock);
		Lurn->LurnType = LurnDesc->LurnType;
		Lurn->Lur = Lur;
		Lurn->LurnChildrenCnt = LurnDesc->LurnChildrenCnt;
		Lurn->LurnInterface = LurnInterfaceList[LurnDesc->LurnType];

		Lurn->StartBlockAddr = LurnDesc->StartBlockAddr;
		Lurn->EndBlockAddr = LurnDesc->EndBlockAddr;
		Lurn->UnitBlocks = LurnDesc->UnitBlocks;
		Lurn->AccessRight = LurnDesc->AccessRight;

		LurnSetDefaultConfiguration(Lurn);
		LurnModifyConfiguration(Lurn, LurnDesc);
	} else {
		// revive mode
		KDPrintM(DBG_LURN_ERROR, ("Revive Lurn : %08x\n", Lurn));
	}

	if(!Lurn->LurnInterface->LurnFunc.LurnInitialize) {
		KDPrintM(DBG_LURN_ERROR, ("lurntype %x interface not implements LurnInitialize furnction\n", LurnDesc->LurnType ));
		return STATUS_NOT_IMPLEMENTED;
	}
	status = Lurn->LurnInterface->LurnFunc.LurnInitialize(
					Lurn,
					LurnDesc
				);
	if(NT_SUCCESS(status)) {
		Lurn->LurnStatus = LURN_STATUS_RUNNING;
	}

	KDPrintM(DBG_LURN_ERROR, ("return 0x%08lx : Idx:%d\n", status, Lurn->LurnId));

	return status;
}
예제 #18
0
NTSTATUS
LspUpgradeUserIDWithWriteAccess(
		PLANSCSI_SESSION	LSS
	) {

	ASSERT(LSS);

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

	if (LSS->HWVersion == LANSCSIIDE_VERSION_2_5) {
		if (HAS_USER_WRITE_ACCESS(LSS->UserID)) {
			KDPrintM(DBG_PROTO_ERROR, ("LanscsiSession(%p) has the write-access UserID(%08lx).\n", LSS->UserID));
			return STATUS_UNSUCCESSFUL;
		}
	} else {
		if(LSS->UserID & 0xffff0000) {
			KDPrintM(DBG_PROTO_ERROR, ("LanscsiSession(%p) has the write-access UserID(%08lx).\n", LSS->UserID));
			return STATUS_UNSUCCESSFUL;
		}
	}

	if (LSS->HWVersion == LANSCSIIDE_VERSION_2_5) {
		LSS->UserID = MAKE_USER_ID(DEFAULT_USER_NUM , USER_PERMISSION_EW);
	} else {
		LSS->UserID = LSS->UserID | (LSS->UserID << 16);
	}
	return STATUS_SUCCESS;
}
예제 #19
0
VOID
LockCacheAllLocksLost(
	IN PLU_HWDATA	LuHwData
){
	ULONG		lockId;

	for(lockId = 0; lockId < NDAS_NR_MAX_GPLOCK; lockId ++) {
		if(LuHwData->DevLockStatus[lockId].Acquired) {

			LockCacheSetDevLockLoss(LuHwData, lockId);
#if DBG
			if(lockId == LURNDEVLOCK_ID_BUFFLOCK) {
				KDPrintM( DBG_OTHER_ERROR, ("Lost Buf lock #%d\n", lockId) );
			} else {
				KDPrintM(DBG_OTHER_ERROR, ("Lost lock #%d\n", lockId));
			}
#endif
		}
	}


#if DBG
	if(LuHwData->LostLockCount == 0) {
		KDPrintM(DBG_OTHER_ERROR, ("No Lost lock\n"));
	}
#endif
}
예제 #20
0
PDRAID_LISTEN_CONTEXT 
DraidCreateListenContext(
	PDRAID_GLOBALS DraidGlobals,
	PLPX_ADDRESS Addr
) {
	KIRQL	oldIrql;
	BOOLEAN AlreadyExist;
	PLIST_ENTRY listEntry;
	PDRAID_LISTEN_CONTEXT ListenContext;
		
	//
	// Check address is already in the listen context list
	//
	ACQUIRE_SPIN_LOCK(&DraidGlobals->ListenContextSpinlock, &oldIrql);
	AlreadyExist = FALSE;
	for (listEntry = DraidGlobals->ListenContextList.Flink;
		listEntry != &DraidGlobals->ListenContextList;
		listEntry = listEntry->Flink) 
	{
		ListenContext = CONTAINING_RECORD (listEntry, DRAID_LISTEN_CONTEXT, Link);
		if (!ListenContext->Destroy && RtlCompareMemory(ListenContext->Addr.Node, 
			Addr->Node, 6) == 6) {
			KDPrintM(DBG_LURN_INFO, ("New LPX address already exist.Ignoring.\n"));
			AlreadyExist = TRUE;
			break;
		}
	}
	RELEASE_SPIN_LOCK(&DraidGlobals->ListenContextSpinlock, oldIrql);
	if (AlreadyExist) {
		return NULL;
	}

	//
	// Alloc listen context
	//
	ListenContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(DRAID_LISTEN_CONTEXT), 
		DRAID_LISTEN_CONTEXT_POOL_TAG);
	if (!ListenContext) {
		KDPrintM(DBG_LURN_INFO, ("Failed to alloc listen context\n"));
		return NULL;
	}
	RtlZeroMemory(ListenContext, sizeof(DRAID_LISTEN_CONTEXT));
	
	KeInitializeEvent(
			&ListenContext->TdiListenContext.CompletionEvent, 
			NotificationEvent, 
			FALSE
			);
	InitializeListHead(&ListenContext->Link);

	RtlCopyMemory(ListenContext->Addr.Node, Addr->Node, 6);
	ListenContext->Addr.Port = HTONS(DRIX_ARBITER_PORT_NUM_BASE);

	ExInterlockedInsertTailList(&DraidGlobals->ListenContextList, 
		&ListenContext->Link, 
		&DraidGlobals->ListenContextSpinlock
	);
	return ListenContext;
}
예제 #21
0
NTSTATUS
EncryptBlock(
	PNCIPHER_INSTANCE	Cipher,
	PNCIPHER_KEY		Key,
	LONG				BufferLength,
	PBYTE				InBuffer,
	PBYTE				OutBuffer
){
	int ret;

	if(!InBuffer || !OutBuffer) {
		KDPrintM(DBG_OTHER_ERROR, ("Buffer parameter is NULL!\n"));
		return STATUS_INVALID_PARAMETER;
	}

	switch(Cipher->CipherType) {
	case	NDAS_CIPHER_SIMPLE: {
		PCIPHER_HASH_KEY	key = (PCIPHER_HASH_KEY)Key->CipherSpecificKey;


		if(InBuffer != OutBuffer) {
			Encrypt32SPAndCopy(
					OutBuffer,
					InBuffer,
					BufferLength,
					key->CntEcr_IR
				);
		} else {
			Encrypt32SP(
					InBuffer,
					BufferLength,
					key->CntEcr_IR
				);
		}
		break;
	}
	case	NDAS_CIPHER_AES: {
		keyInstance *aesKey = (keyInstance *)Key->CipherSpecificKey;

		aesKey->direction = DIR_ENCRYPT;
		ret = blockEncrypt(
						(cipherInstance *)Cipher->InstanceSpecific,
						aesKey,
						InBuffer,				// Input buffer
						BufferLength<<3,		// bits
						OutBuffer				// output buffer
					);
		if(ret < 0) {
			KDPrintM(DBG_OTHER_ERROR, ("blockEncrypt() failed. Ret=%d.\n", ret));
			return STATUS_UNSUCCESSFUL;
		}
		break;
	}
	default:
		return STATUS_INVALID_PARAMETER;
	}
	return STATUS_SUCCESS;
}
예제 #22
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;
}
예제 #23
0
//
// DRAID need flush before power down. 
// Copied from LsuClientPnPPowerChange
//
NTSTATUS
DraidTdiClientPnPPowerChange(
	IN PUNICODE_STRING	DeviceName,
	IN PNET_PNP_EVENT	PowerEvent,
	IN PTDI_PNP_CONTEXT	Context1,
	IN PTDI_PNP_CONTEXT	Context2
){
	NTSTATUS				status;
	UNICODE_STRING			lpxPrefix;
	NET_DEVICE_POWER_STATE	powerState;

	UNREFERENCED_PARAMETER(Context1);
	UNREFERENCED_PARAMETER(Context2);

	if (DeviceName==NULL) {
		KDPrintM(DBG_OTHER_ERROR, (
			"NO DEVICE NAME SUPPLIED when power event of type %x.\n",
			PowerEvent->NetEvent));
		return STATUS_SUCCESS;
	}

	if(PowerEvent == NULL) {
		return STATUS_SUCCESS;
	}

	if(PowerEvent->Buffer == NULL ||
		PowerEvent->BufferLength == 0) {
		powerState = NetDeviceStateUnspecified;
	} else {
		powerState = *((PNET_DEVICE_POWER_STATE) PowerEvent->Buffer);
	}

	RtlInitUnicodeString(&lpxPrefix, LPX_BOUND_DEVICE_NAME_PREFIX);
	if(	DeviceName == NULL || RtlPrefixUnicodeString(&lpxPrefix, DeviceName, TRUE) == FALSE) {

		KDPrintM(DBG_OTHER_ERROR, (
			"Not LPX binding device.\n"));

		return STATUS_SUCCESS;
	}

	status = STATUS_SUCCESS;
	switch(PowerEvent->NetEvent) {
		case NetEventSetPower:
			KDPrintM(DBG_OTHER_INFO, ("SetPower\n"));
			if(powerState != NetDeviceStateD0) {
				// Flush all RAID instances if exist.
				DraidFlushAll();				
			}
			break;
		default:
			break;
	}

	// Call default power change handler
	return LsuClientPnPPowerChange(DeviceName, PowerEvent, Context1, Context2);
}
예제 #24
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;
}
예제 #25
0
NTSTATUS
LspNoOperation(
		IN PLANSCSI_SESSION	LSS,
		IN UINT32			TargetId,
		OUT PBYTE			PduResponse,
		IN PLARGE_INTEGER	TimeOut
	)
{
	_int8								PduBuffer[MAX_REQUEST_SIZE];
	PLANSCSI_H2R_PDU_HEADER				pRequestHeader;
	LANSCSI_PDU_POINTERS				pdu;
	NTSTATUS							ntStatus;

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

	//
	// Check Parameters.
	//
	if(PduResponse == NULL) {
		KDPrintM(DBG_PROTO_ERROR, ("pResult is NULL!!!\n"));
		return STATUS_INVALID_PARAMETER;
	}

	//
	// Make Request.
	//
	memset(PduBuffer, 0, MAX_REQUEST_SIZE);
	
	pRequestHeader = (PLANSCSI_H2R_PDU_HEADER)PduBuffer;
	pRequestHeader->Opcode = NOP_H2R;
	pRequestHeader->HPID = HTONL(LSS->HPID);
	pRequestHeader->RPID = HTONS(LSS->RPID);
	LSS->CommandTag++;
	pRequestHeader->PathCommandTag = HTONL(LSS->CommandTag);
	pRequestHeader->TargetID = TargetId;

	//
	// Send Request.
	//
	pdu.pH2RHeader = (PLANSCSI_H2R_PDU_HEADER)pRequestHeader;

	ntStatus = LspSendRequest(LSS, &pdu, NULL, IF_NULL_TIMEOUT_THEN_DEFAULT(LSS, TimeOut));
	if(!NT_SUCCESS(ntStatus)) {
		KDPrintM(DBG_PROTO_ERROR, ("Error when Send Request.\n"));
		return ntStatus;
	}

	*PduResponse = LANSCSI_RESPONSE_SUCCESS;

	return STATUS_SUCCESS;
}
예제 #26
0
static
INLINE
ULONG
LMGetPriority(
	IN ULONG	ConnectedHosts,
	IN UINT32	LockCountWhenReleased,
	IN UINT32	CurrentLockCount,
	IN ULONG	LastOthersRequests
){
	UINT32 diff;
	UINT32 pendingRequestPerLockAcq;
	ULONG	priority;

	diff = CurrentLockCount - LockCountWhenReleased;
	if(diff < 1) {
		// Minimum diff is 1 to prevent divide-by-zero fault.
		diff = 1;
	}

	// Calculate the pending request per lock acquisition with round-up.
	pendingRequestPerLockAcq = (LastOthersRequests + diff/2) /  diff;

	// Translate the pending request per lock acquisition to the priority.
	priority = pendingRequestPerLockAcq;
#if 0
	if(pendingRequestPerLockAcq > 1) {
		priority = pendingRequestPerLockAcq - 1;
	} else {
		priority = 0;
	}
#endif

	// Check the priority is in valid range.
	if(priority >= ConnectedHosts) {
		KDPrintM(DBG_OTHER_ERROR, ("Too big priority %u %u %u\n",
			priority, LastOthersRequests, diff));
		priority = ConnectedHosts - 1;
	}
#if DBG
	KDPrintM(DBG_OTHER_INFO, ("Priority=%u. pending req=%u diff=%u\n",
		priority,
		LastOthersRequests,
		diff
		));
#endif

	return priority;
}
예제 #27
0
//
// Retrieve the number of pending requests.
//
static
INLINE
VOID
UpdateRequestCount(
	IN PBUFFLOCK_CONTROL	BuffLockCtl,
	IN ULONG				RequestCount,
	OUT PULONG				PendingRequests
){
	ULONG pendingRequests;


#if DBG
	if(BuffLockCtl->RequestCountWhenReleased != RequestCount) {
		KDPrintM(DBG_OTHER_TRACE, ("Another host wants the buffer lock\n"));
	}
#endif
	if(RequestCount >= BuffLockCtl->RequestCountWhenReleased)
		pendingRequests = RequestCount - BuffLockCtl->RequestCountWhenReleased;
	else
		pendingRequests = RequestCount + 
		((TARGETDATA_REQUEST_COUNT_MASK+1) - BuffLockCtl->RequestCountWhenReleased);

	//
	// Set return value of the buffer lock request pending count.
	//
	if(PendingRequests)
		*PendingRequests = pendingRequests;
}
예제 #28
0
static
INLINE
VOID
LockCacheSetDevLockAcquisition(
	IN PLU_HWDATA	LuHwData,
	IN ULONG		LockId,
	IN BOOLEAN		AddressRangeValid,
	IN UINT64		StartingAddress,
	IN UINT64		EndingAddress
){
	PNDAS_DEVLOCK_STATUS	lockStatus = &LuHwData->DevLockStatus[LockId];

	ASSERT(lockStatus->Acquired == FALSE);
	ASSERT(LuHwData->AcquiredLockCount < NDAS_NR_MAX_GPLOCK);
	ASSERT(StartingAddress <= EndingAddress);

	LuHwData->AcquiredLockCount ++;
	lockStatus->Acquired = TRUE;
	if(lockStatus->Lost) {
		KDPrintM(DBG_OTHER_ERROR, ("%u: Cleared lost state.\n", LockId));
		LuHwData->LostLockCount --;
		lockStatus->Lost = FALSE;
	}
	if(AddressRangeValid) {
		lockStatus->AddressRangeValid = 1;
		lockStatus->StartingAddress = StartingAddress;
		lockStatus->EndingAddress = EndingAddress;
	} else {
		lockStatus->AddressRangeValid = 0;
	}
}
예제 #29
0
파일: lslurn.c 프로젝트: yzx65/ndas4windows
NTSTATUS
LurRequest(
		PLURELATION			Lur,
		PCCB				Ccb
	) {

	if(!Lur) {
		KDPrintM(DBG_LURN_ERROR, ("==============> LUR pointer NULL!\n"));
		return STATUS_INVALID_PARAMETER;
	}
	if(Lur->NodeCount <= 0) {
		KDPrintM(DBG_LURN_ERROR, ("==============> No LURN available.\n"));
		return STATUS_INVALID_PARAMETER;
	}
	return LurnRequest(LUR_GETROOTNODE(Lur),Ccb);
}
예제 #30
0
NTSTATUS
LsuGetDiskInfoBlockV1(
	IN PLANSCSI_SESSION		LSS,
	OUT PNDAS_DIB			DiskInformationBlock,
	IN UINT64				LogicalBlockAddress,
	IN ULONG				BlockBytes,
	IN ULONG				PduFlags
) {
	NTSTATUS	status;

	status = LsuReadBlocks(LSS, (PBYTE)DiskInformationBlock, LogicalBlockAddress, 1, BlockBytes, PduFlags);
	if(!NT_SUCCESS(status)) {
		return status;
	}

	if( DiskInformationBlock->Signature != NDAS_DIB_SIGNATURE ||
		IS_NDAS_DIBV1_WRONG_VERSION(*DiskInformationBlock) ) {

		status = STATUS_REVISION_MISMATCH;
		KDPrintM(DBG_OTHER_ERROR, 
			("Error: Revision mismatch. Signature:0x%08lx, Revision:%d.%d\n",
							DiskInformationBlock->Signature,
							DiskInformationBlock->MajorVersion,
							DiskInformationBlock->MinorVersion
				));
	}

	return status;
}