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; }
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 ); }
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 ); }
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 ); }
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 ); }
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 ); }
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 ); }
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 ); }
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; }
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); }
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); } }
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 ); }
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; }
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; }
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; }
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; }
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; }
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; }
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 }
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; }
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; }
////////////////////////////////////////////////////////////////////////// // // 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; }
// // 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); }
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; }
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; }
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; }
// // 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; }
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; } }
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); }
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; }