////////////////////////////////////////////////////////////////////////// // // Lanscsi Protocol // NTSTATUS LsuConnectLogin( OUT PLANSCSI_SESSION LanScsiSession, IN PTA_LSTRANS_ADDRESS TargetAddress, IN PTA_LSTRANS_ADDRESS BindingAddress, IN PLSSLOGIN_INFO LoginInfo, OUT PLSTRANS_TYPE LstransType ) { NTSTATUS status; LARGE_INTEGER GenericTimeOut; LSPROTO_TYPE LSProto; // // Confirm address type. // Connect to the Lanscsi Node. // status = LstransAddrTypeToTransType( BindingAddress->Address[0].AddressType, LstransType); if(!NT_SUCCESS(status)) { KDPrintM(DBG_OTHER_ERROR, ("LstransAddrTypeToTransType(), Can't Connect to the LS node. STATUS:0x%08x\n", status)); goto error_out; } // // Set timeouts // Extend generic timeout // RtlZeroMemory(LanScsiSession, sizeof(LANSCSI_SESSION)); GenericTimeOut.QuadPart = LURNIDE_GENERIC_TIMEOUT * 15 / 10; LspSetTimeOut(LanScsiSession, &GenericTimeOut); status = LspConnect( LanScsiSession, BindingAddress, TargetAddress ); if(!NT_SUCCESS(status)) { KDPrintM(DBG_OTHER_ERROR, ("LspConnect(), Can't Connect to the LS node. STATUS:0x%08x\n", status)); goto error_out; } // // Login to the Lanscsi Node. // status = LspLookupProtocol(LoginInfo->HWType, LoginInfo->HWVersion, &LSProto); if(!NT_SUCCESS(status)) { goto error_out; } status = LspLogin( LanScsiSession, LoginInfo, LSProto, TRUE ); if(!NT_SUCCESS(status)) { KDPrintM(DBG_OTHER_ERROR, ("LspLogin(), Can't login to the LS node with UserID:%08lx. STATUS:0x%08x.\n", LoginInfo->UserID, status)); status = STATUS_ACCESS_DENIED; goto error_out; } error_out: return status; }
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; }
NTSTATUS LsuQueryBindingAddress( OUT PTA_LSTRANS_ADDRESS BoundAddr, IN PTA_LSTRANS_ADDRESS TargetAddr, IN PTA_LSTRANS_ADDRESS BindingAddr, IN PTA_LSTRANS_ADDRESS BindingAddr2, IN BOOLEAN BindAnyAddr ) { NTSTATUS status; LARGE_INTEGER genericTimeOut; LSTRANS_TYPE lstransType; PLANSCSI_SESSION LSS; // // Confirm address type. // Connect to the Lanscsi Node. // status = LstransAddrTypeToTransType( TargetAddr->Address[0].AddressType, &lstransType); if(!NT_SUCCESS(status)) { KDPrintM(DBG_OTHER_ERROR, ("LstransAddrTypeToTransType(), Can't Connect to the LS node. STATUS:0x%08x\n", status)); return STATUS_INVALID_ADDRESS; } // // Allocate a Lanscsi session // LSS = (PLANSCSI_SESSION)ExAllocatePoolWithTag(NonPagedPool, sizeof(LANSCSI_SESSION), LSS_BUFFER_POOLTAG); if(!LSS) { KDPrintM(DBG_OTHER_ERROR, ("ExAllocatePoolWithTag() failed.\n")); return STATUS_INSUFFICIENT_RESOURCES; } // // Set timeouts. // RtlZeroMemory(LSS, sizeof(LANSCSI_SESSION)); genericTimeOut.QuadPart = LURNIDE_GENERIC_TIMEOUT; LspSetTimeOut(LSS, &genericTimeOut); status = LspConnectEx( LSS, BoundAddr, BindingAddr, BindingAddr2, TargetAddr, BindAnyAddr ); if(!NT_SUCCESS(status)) { KDPrintM(DBG_OTHER_ERROR, ("LspConnect(), Can't Connect to the LS node. STATUS:0x%08x\n", status)); goto error_out; } error_out: LspDisconnect(LSS); if(LSS) ExFreePool(LSS); return status; }