diff options
Diffstat (limited to '')
-rw-r--r-- | private/ntos/ndis/testprot/tpdrvr/strfunc.c | 1858 |
1 files changed, 1858 insertions, 0 deletions
diff --git a/private/ntos/ndis/testprot/tpdrvr/strfunc.c b/private/ntos/ndis/testprot/tpdrvr/strfunc.c new file mode 100644 index 000000000..c9721cc42 --- /dev/null +++ b/private/ntos/ndis/testprot/tpdrvr/strfunc.c @@ -0,0 +1,1858 @@ +// ********************** +// +// Copyright (c) 1990 Microsoft Corporation +// +// Module Name: +// +// strfunc. +// +// Abstract: +// +// Tests to drive the NDIS wrapper and NDIS 3.0 MACs. +// +// Author: +// +// Tom Adams (tomad) 26-Nov-1990 +// +// Environment: +// +// Kernel mode, FSD +// +// Revision History: +// +// Sanjeev Katariya(sanjeevk) +// 3-16-1993 Change TpStressResetComplete() to accomodate for bug #2874 +// 4-14-1993 Changed error count check for Fddi also within TpStressSendComplete since +// both 802.5 and Fddi work on tokens and hence the FS bits are the same +// 5-10-1993 Fixed TpStressTransferDataComplete to not check the data in the event +// that the transfer data failed. Bug#9244 +// +// Tim Wynsma (timothyw) +// 5-18-1994 Fixed warnings, improved debug, cleanup +// +// ****************** + +#include <ndis.h> + +#include <string.h> + +#include "tpdefs.h" +#include "media.h" +#include "tpprocs.h" + +// +// Forward references +// +extern VOID +TpStressFreePostResetResources( + IN POPEN_BLOCK OpenP + ); + + + +NDIS_STATUS +TpStressAddMulticastAddress( + IN POPEN_BLOCK OpenP, + IN PUCHAR MulticastAddress, + IN BOOLEAN SetZeroTableSize + ) + +// ----- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// ---- + +{ + NDIS_STATUS Status; + PNDIS_REQUEST Request; + PTP_REQUEST_HANDLE ReqHndl; + ULONG OidIndex; + PUCHAR InformationBuffer; + + + Status = NdisAllocateMemory((PVOID *)&ReqHndl, + sizeof( TP_REQUEST_HANDLE ), + 0, + HighestAddress ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG (TP_DEBUG_RESOURCES) + { + TpPrint0("TpStressAddMulticastAddress: unable to allocate ReqHndl.\n"); + } + return NDIS_STATUS_RESOURCES; + } + else + { + NdisZeroMemory( ReqHndl,sizeof( TP_REQUEST_HANDLE )); + } + + ReqHndl->Signature = STRESS_REQUEST_HANDLE_SIGNATURE; + ReqHndl->Open = OpenP; + ReqHndl->RequestPended = TRUE; + ReqHndl->u.STRESS_REQ.NextReqHndl = NULL; + + Status = NdisAllocateMemory((PVOID *)&Request, + sizeof( NDIS_REQUEST ), + 0, + HighestAddress ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG (TP_DEBUG_RESOURCES) + { + TpPrint0("TpStressAddMulticastAddress: unable to allocate Request.\n"); + } + return NDIS_STATUS_RESOURCES; + } + else + { + NdisZeroMemory( Request,sizeof( NDIS_REQUEST )); + } + + Request->RequestType = NdisRequestSetInformation; + + OidIndex = TpLookUpOidInfo( OID_802_3_MULTICAST_LIST ); + + Status = NdisAllocateMemory((PVOID *)&InformationBuffer, + OidArray[OidIndex].Length, + 0, + HighestAddress ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG (TP_DEBUG_RESOURCES) + { + TpPrint0("TpStressAddMulticastAddress: unable to allocate Information Buffer.\n"); + } + return NDIS_STATUS_RESOURCES; + } + else + { + NdisZeroMemory( InformationBuffer,OidArray[OidIndex].Length ); + } + + Request->DATA.SET_INFORMATION.Oid = OID_802_3_MULTICAST_LIST; + Request->DATA.SET_INFORMATION.InformationBuffer = InformationBuffer; + if ( SetZeroTableSize ) + { + Request->DATA.SET_INFORMATION.InformationBufferLength = 0; + } + else + { + Request->DATA.SET_INFORMATION.InformationBufferLength = OidArray[OidIndex].Length; + } + + RtlMoveMemory( InformationBuffer,MulticastAddress,ADDRESS_LENGTH ); + + ReqHndl->u.STRESS_REQ.Request = Request; + + NdisAcquireSpinLock( &OpenP->SpinLock ); + + ReqHndl->u.STRESS_REQ.NextReqHndl = OpenP->StressReqHndl; + OpenP->StressReqHndl = ReqHndl; + + NdisReleaseSpinLock( &OpenP->SpinLock ); + + NdisAcquireSpinLock( &OpenP->Stress->Pend->SpinLock ); + ++OpenP->Stress->Pend->PendingRequests; + NdisReleaseSpinLock( &OpenP->Stress->Pend->SpinLock ); + + NdisRequest( &Status,OpenP->NdisBindingHandle,Request ); + + if ( Status == NDIS_STATUS_SUCCESS ) + { + TP_ASSERT( Request->DATA.SET_INFORMATION.BytesRead <= + Request->DATA.SET_INFORMATION.InformationBufferLength ); + } + + // + // If the request did not pend, then free up the memory now. + // + + if ( Status != NDIS_STATUS_PENDING ) + { + TpStressRequestComplete( OpenP,Request,Status ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG ( TP_DEBUG_NDIS_CALLS ) + { + TpPrint1("TpStressAddMulticastAddress: NdisRequest returned %s\n", + TpGetStatus(Status)); + } + } + } + + return Status; +} + + + +NDIS_STATUS +TpStressAddLongMulticastAddress( + IN POPEN_BLOCK OpenP, + IN PUCHAR MulticastAddress, + IN BOOLEAN SetZeroTableSize + ) + +// ------- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// ------ + +{ + NDIS_STATUS Status; + PNDIS_REQUEST Request; + PTP_REQUEST_HANDLE ReqHndl; + ULONG OidIndex; + PUCHAR InformationBuffer; + + + Status = NdisAllocateMemory((PVOID *)&ReqHndl, + sizeof( TP_REQUEST_HANDLE ), + 0, + HighestAddress ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG (TP_DEBUG_RESOURCES) + { + TpPrint0("TpStressAddMulticastAddress: unable to allocate ReqHndl.\n"); + } + return NDIS_STATUS_RESOURCES; + } + else + { + NdisZeroMemory( ReqHndl,sizeof( TP_REQUEST_HANDLE )); + } + + ReqHndl->Signature = STRESS_REQUEST_HANDLE_SIGNATURE; + ReqHndl->Open = OpenP; + ReqHndl->RequestPended = TRUE; + ReqHndl->u.STRESS_REQ.NextReqHndl = NULL; + + Status = NdisAllocateMemory((PVOID *)&Request, + sizeof( NDIS_REQUEST ), + 0, + HighestAddress ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG (TP_DEBUG_RESOURCES) + { + TpPrint0("TpStressAddMulticastAddress: unable to allocate Request.\n"); + } + return NDIS_STATUS_RESOURCES; + } + else + { + NdisZeroMemory( Request,sizeof( NDIS_REQUEST )); + } + + Request->RequestType = NdisRequestSetInformation; + + OidIndex = TpLookUpOidInfo( OID_FDDI_LONG_MULTICAST_LIST ); + + Status = NdisAllocateMemory((PVOID *)&InformationBuffer, + OidArray[OidIndex].Length, + 0, + HighestAddress ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG (TP_DEBUG_RESOURCES) + { + TpPrint0("TpStressAddMulticastAddress: unable to allocate Information Buffer.\n"); + } + return NDIS_STATUS_RESOURCES; + } + else + { + NdisZeroMemory( InformationBuffer,OidArray[OidIndex].Length ); + } + + Request->DATA.SET_INFORMATION.Oid = OID_FDDI_LONG_MULTICAST_LIST; + Request->DATA.SET_INFORMATION.InformationBuffer = InformationBuffer; + + if ( SetZeroTableSize ) + { + Request->DATA.SET_INFORMATION.InformationBufferLength = 0; + } + else + { + Request->DATA.SET_INFORMATION.InformationBufferLength = OidArray[OidIndex].Length; + } + + RtlMoveMemory( InformationBuffer,MulticastAddress,ADDRESS_LENGTH ); + + ReqHndl->u.STRESS_REQ.Request = Request; + + NdisAcquireSpinLock( &OpenP->SpinLock ); + + ReqHndl->u.STRESS_REQ.NextReqHndl = OpenP->StressReqHndl; + OpenP->StressReqHndl = ReqHndl; + + NdisReleaseSpinLock( &OpenP->SpinLock ); + + NdisAcquireSpinLock( &OpenP->Stress->Pend->SpinLock ); + ++OpenP->Stress->Pend->PendingRequests; + NdisReleaseSpinLock( &OpenP->Stress->Pend->SpinLock ); + + NdisRequest( &Status,OpenP->NdisBindingHandle,Request ); + + if ( Status == NDIS_STATUS_SUCCESS ) + { + TP_ASSERT( Request->DATA.SET_INFORMATION.BytesRead <= + Request->DATA.SET_INFORMATION.InformationBufferLength ); + } + + // + // If the request did not pend, then free up the memory now. + // + + if ( Status != NDIS_STATUS_PENDING ) + { + TpStressRequestComplete( OpenP,Request,Status ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG ( TP_DEBUG_NDIS_CALLS ) + { + TpPrint1("TpStressAddMulticastAddress: NdisRequest returned %s\n", + TpGetStatus(Status)); + } + } + } + + return Status; +} + + + +NDIS_STATUS +TpStressSetFunctionalAddress( + IN POPEN_BLOCK OpenP, + IN PUCHAR FunctionalAddress, + IN BOOLEAN SetZeroTableSize + ) + +// ------ +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// ------ + +{ + NDIS_STATUS Status; + PTP_REQUEST_HANDLE ReqHndl; + PNDIS_REQUEST Request; + ULONG OidIndex; + PUCHAR InformationBuffer; + + + Status = NdisAllocateMemory((PVOID *)&ReqHndl, + sizeof( TP_REQUEST_HANDLE ), + 0, + HighestAddress ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG (TP_DEBUG_RESOURCES) + { + TpPrint0("TpStressSetFunctionalAddress: unable to allocate ReqHndl.\n"); + } + return NDIS_STATUS_RESOURCES; + } + else + { + NdisZeroMemory( ReqHndl,sizeof( TP_REQUEST_HANDLE )); + } + + ReqHndl->Signature = STRESS_REQUEST_HANDLE_SIGNATURE; + ReqHndl->Open = OpenP; + ReqHndl->RequestPended = TRUE; + ReqHndl->u.STRESS_REQ.NextReqHndl = NULL; + + + Status = NdisAllocateMemory((PVOID *)&Request, + sizeof( NDIS_REQUEST ), + 0, + HighestAddress ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG (TP_DEBUG_RESOURCES) + { + TpPrint0("TpStressSetFunctionalAddress: unable to allocate Request.\n"); + } + return NDIS_STATUS_RESOURCES; + } + else + { + NdisZeroMemory( Request,sizeof( NDIS_REQUEST )); + } + + Request->RequestType = NdisRequestSetInformation; + + OidIndex = TpLookUpOidInfo( OID_802_5_CURRENT_FUNCTIONAL ); + + Status = NdisAllocateMemory((PVOID *)&InformationBuffer, + OidArray[OidIndex].Length, + 0, + HighestAddress ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG (TP_DEBUG_RESOURCES) + { + TpPrint0("TpStressSetFunctionalAddress: unable to allocate Information Buffer.\n"); + } + return NDIS_STATUS_RESOURCES; + } + else + { + NdisZeroMemory( InformationBuffer,OidArray[OidIndex].Length); + } + + Request->DATA.SET_INFORMATION.Oid = OID_802_5_CURRENT_FUNCTIONAL; + Request->DATA.SET_INFORMATION.InformationBuffer = InformationBuffer; + +// Wrapper requires information buffer length to be 4 here--zero is not allowed + +// if ( SetZeroTableSize ) +// { +// Request->DATA.SET_INFORMATION.InformationBufferLength = 0; +// } +// else +// { + Request->DATA.SET_INFORMATION.InformationBufferLength = OidArray[OidIndex].Length; +// } + + RtlMoveMemory( InformationBuffer, + FunctionalAddress, + FUNCTIONAL_ADDRESS_LENGTH ); + + ReqHndl->u.STRESS_REQ.Request = Request; + + NdisAcquireSpinLock( &OpenP->SpinLock ); + + ReqHndl->u.STRESS_REQ.NextReqHndl = OpenP->StressReqHndl; + OpenP->StressReqHndl = ReqHndl; + + NdisReleaseSpinLock( &OpenP->SpinLock ); + + NdisAcquireSpinLock( &OpenP->Stress->Pend->SpinLock ); + ++OpenP->Stress->Pend->PendingRequests; + NdisReleaseSpinLock( &OpenP->Stress->Pend->SpinLock ); + + NdisRequest( &Status,OpenP->NdisBindingHandle,Request ); + + // + // If the request did not pend, then free up the memory now. + // + + if ( Status != NDIS_STATUS_PENDING ) + { + TpStressRequestComplete( OpenP,Request,Status ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG ( TP_DEBUG_NDIS_CALLS ) + { + TpPrint1("TpStressSetFunctionalAddress: NdisRequest returned %s\n", + TpGetStatus(Status)); + } + } + } + return Status; +} + + + +NDIS_STATUS +TpStressSetPacketFilter( + IN POPEN_BLOCK OpenP, + IN UINT PacketFilter + ) + +// ------ +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// ------ + +{ + NDIS_STATUS Status; + PTP_REQUEST_HANDLE ReqHndl; + PNDIS_REQUEST Request; + ULONG OidIndex; + PUCHAR InformationBuffer; + + + Status = NdisAllocateMemory((PVOID *)&ReqHndl, + sizeof( TP_REQUEST_HANDLE ), + 0, + HighestAddress ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG (TP_DEBUG_RESOURCES) + { + TpPrint0("TpStressSetPacketFilter: unable to allocate ReqHndl.\n"); + } + return NDIS_STATUS_RESOURCES; + } + else + { + NdisZeroMemory( ReqHndl,sizeof( TP_REQUEST_HANDLE )); + } + + ReqHndl->Signature = STRESS_REQUEST_HANDLE_SIGNATURE; + ReqHndl->Open = OpenP; + ReqHndl->RequestPended = TRUE; + ReqHndl->u.STRESS_REQ.NextReqHndl = NULL; + + Status = NdisAllocateMemory((PVOID *)&Request, + sizeof( NDIS_REQUEST ), + 0, + HighestAddress ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG (TP_DEBUG_RESOURCES) + { + TpPrint0("TpStressSetPacketFilter: unable to allocate Request.\n"); + } + return NDIS_STATUS_RESOURCES; + } + else + { + NdisZeroMemory( Request,sizeof( NDIS_REQUEST )); + } + + Request->RequestType = NdisRequestSetInformation; + + OidIndex = TpLookUpOidInfo( OID_GEN_CURRENT_PACKET_FILTER ); + + Status = NdisAllocateMemory((PVOID *)&InformationBuffer, + OidArray[OidIndex].Length, + 0, + HighestAddress ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG (TP_DEBUG_RESOURCES) + { + TpPrint0("TpStressSetPacketFilter: unable to allocate Information Buffer.\n"); + } + return NDIS_STATUS_RESOURCES; + } + else + { + NdisZeroMemory( InformationBuffer,OidArray[OidIndex].Length); + } + + Request->DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER; + Request->DATA.SET_INFORMATION.InformationBuffer = InformationBuffer; + Request->DATA.SET_INFORMATION.InformationBufferLength = + OidArray[OidIndex].Length; + + *((PULONG)InformationBuffer) = (ULONG)PacketFilter; + + ReqHndl->u.STRESS_REQ.Request = Request; + + NdisAcquireSpinLock( &OpenP->SpinLock ); + + ReqHndl->u.STRESS_REQ.NextReqHndl = OpenP->StressReqHndl; + OpenP->StressReqHndl = ReqHndl; + + NdisReleaseSpinLock( &OpenP->SpinLock ); + + NdisAcquireSpinLock( &OpenP->Stress->Pend->SpinLock ); + ++OpenP->Stress->Pend->PendingRequests; + NdisReleaseSpinLock( &OpenP->Stress->Pend->SpinLock ); + + NdisRequest( &Status,OpenP->NdisBindingHandle,Request ); + + // + // If the request did not pend, then free up the memory now. + // + + if ( Status != NDIS_STATUS_PENDING ) + { + TpStressRequestComplete( OpenP,Request,Status ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG ( TP_DEBUG_NDIS_CALLS ) + { + TpPrint1("TpStressSetPacketFilter: NdisRequest returned %s\n", + TpGetStatus(Status)); + } + } + } + + return Status; +} + + + +VOID +TpStressRequestComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_REQUEST NdisRequest, + IN NDIS_STATUS Status + ) + +// --------- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// --------- + +{ + POPEN_BLOCK OpenP = ((POPEN_BLOCK)ProtocolBindingContext); + PTP_REQUEST_HANDLE CorrectReqHndl = NULL; + PTP_REQUEST_HANDLE RH; + + NdisAcquireSpinLock( &OpenP->SpinLock ); + + TP_ASSERT( OpenP->StressReqHndl != NULL ); + + if ( OpenP->StressReqHndl->u.STRESS_REQ.Request == NdisRequest ) + { + CorrectReqHndl = OpenP->StressReqHndl; + OpenP->StressReqHndl = OpenP->StressReqHndl->u.STRESS_REQ.NextReqHndl; + } + else + { + RH = OpenP->StressReqHndl; + + do + { + if ( RH->u.STRESS_REQ.NextReqHndl->u.STRESS_REQ.Request == NdisRequest ) + { + CorrectReqHndl = RH->u.STRESS_REQ.NextReqHndl; + + RH->u.STRESS_REQ.NextReqHndl = + RH->u.STRESS_REQ.NextReqHndl->u.STRESS_REQ.NextReqHndl; + + break; + } + else + { + RH = RH->u.STRESS_REQ.NextReqHndl; + } + } while ( RH->u.STRESS_REQ.NextReqHndl != NULL ); + } + + NdisReleaseSpinLock( &OpenP->SpinLock ); + + TP_ASSERT( CorrectReqHndl != NULL ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG( TP_DEBUG_NDIS_ERROR ) + { + TpPrint2("TpStressRequestComplete returned %s, request type %d\n", + TpGetStatus( Status ), NdisRequest->RequestType); + } + } + + if ( NdisRequest->RequestType == NdisRequestSetInformation ) + { + NdisFreeMemory( NdisRequest->DATA.SET_INFORMATION.InformationBuffer,0,0 ); + + } + else // NdisRequestQueryInformation + { + NdisFreeMemory( NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,0,0 ); + } + + NdisFreeMemory( NdisRequest,0,0 ); + NdisFreeMemory( CorrectReqHndl,0,0 ); + + // + // Decrement the Pending Requests and set the stressing flag to + // stop all stressing if the time is right counter. + // + + NdisAcquireSpinLock( &OpenP->Stress->Pend->SpinLock ); + --OpenP->Stress->Pend->PendingRequests; + + if (((( OpenP->Stress->StopStressing == TRUE ) && + ( OpenP->Stress->StressFinal == TRUE )) && + ( OpenP->Stress->Pend->PendingRequests == 0 )) && + ( OpenP->Stress->Pend->PendingPackets == 0 )) + { + OpenP->Stress->Stressing = FALSE; + NdisReleaseSpinLock( &OpenP->Stress->Pend->SpinLock ); + TpStressFreeResources( OpenP ); + } + else + { + NdisReleaseSpinLock( &OpenP->Stress->Pend->SpinLock ); + } + + return; +} + + + +NDIS_STATUS +TpStressReset( + POPEN_BLOCK OpenP + ) + +// ------- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// ------- + +{ + NDIS_STATUS Status; + + NdisReset( &Status,OpenP->NdisBindingHandle ); + + if (( Status != NDIS_STATUS_SUCCESS ) && ( Status != NDIS_STATUS_PENDING )) + { + IF_TPDBG ( TP_DEBUG_NDIS_CALLS ) + { + TpPrint1("TpStressReset: NdisReset returned %s\n", + TpGetStatus(Status)); + } + } + return Status; +} + + + +VOID +TpStressResetComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN NDIS_STATUS Status + ) + +// -------- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// -------- + +{ + POPEN_BLOCK OpenP = ((POPEN_BLOCK)ProtocolBindingContext); + ULONG NextEvent; + + // + // Indicate RESET is over + // + OpenP->Stress->Resetting = FALSE; + + + // Sanjeevk : STARTCHANGE + + if (( OpenP->ResetReqHndl != NULL ) && + (( OpenP->ResetReqHndl->Signature == FUNC_REQUEST_HANDLE_SIGNATURE ) && + ( OpenP->ResetReqHndl->Open == OpenP ))) + { + IF_TPDBG(TP_DEBUG_DISPATCH) + { + TpPrint1("TpStressResetComplete Status = %s\n", TpGetStatus( Status )); + } + + // + // Check if any stress cleanup is required + // + if ( OpenP->ResetReqHndl->u.RESET_REQ.PostResetStressCleanup ) + { + OpenP->ResetReqHndl->u.RESET_REQ.PostResetStressCleanup = FALSE; + + // + // Free up the resources associated with this instance of the stress test + // + TpStressFreePostResetResources( OpenP ); + + // + // Decrement the reference count on the OpenBlock stating this + // instance of an async test is no longer running, and the adapter + // may be closed if requested. + // + TpRemoveReference( OpenP ); + } + + NdisAcquireSpinLock( &OpenP->SpinLock ); + + if ( OpenP->Stress->StressIrp != NULL ) + { + OpenP->Stress->StressIrp->IoStatus.Status = NDIS_STATUS_SUCCESS; + + IoAcquireCancelSpinLock( &OpenP->Stress->StressIrp->CancelIrql ); + IoSetCancelRoutine( OpenP->Stress->StressIrp,NULL ); + IoReleaseCancelSpinLock( OpenP->Stress->StressIrp->CancelIrql ); + + if ( OpenP->Stress->StressStarted == TRUE ) + { + IoCompleteRequest( OpenP->Stress->StressIrp,IO_NETWORK_INCREMENT ); + } + + OpenP->Stress->StressIrp = NULL; + } + + NdisReleaseSpinLock( &OpenP->SpinLock ); + + // + // Free up the request handle block + // + NdisFreeMemory( OpenP->ResetReqHndl,0,0 ); + OpenP->ResetReqHndl = NULL; + } + else + { + // + // We are not expecting any requests to complete at this + // point, so stick this on the Event Queue. + // + + NdisAcquireSpinLock( &OpenP->EventQueue->SpinLock ); + + NextEvent = OpenP->EventQueue->Head + 1; + if ( NextEvent == MAX_EVENT ) + { + NextEvent = 0; + } + + if ( NextEvent != OpenP->EventQueue->Tail ) + { + // + // There is room to add another event to the event queue. + // + + OpenP->EventQueue->Events[NextEvent].TpEventType = CompleteReset; + + OpenP->EventQueue->Head = NextEvent; + + // we should also stick some interesting info like requesttype. + } + else + { + // + // The event queue is full, and this would have overflowed it, so + // mark the Head event overflow flag to show this. + // + + OpenP->EventQueue->Events[OpenP->EventQueue->Head].Overflow = TRUE; + } + + NdisReleaseSpinLock( &OpenP->EventQueue->SpinLock ); + } + + // Sanjeevk : STOPCHANGE +} + + + +NDIS_STATUS +TpStressClientSend( + POPEN_BLOCK OpenP, + NDIS_HANDLE PacketHandle, + PTP_TRANSMIT_POOL TpTransmitPool, + PUCHAR DestAddr, + UCHAR SrcInstance, + UCHAR DestInstance, + UCHAR PacketProtocol, + ULONG SequenceNumber, + ULONG MaxSequenceNumber, + UCHAR ClientReference, + UCHAR ServerReference, + INT PacketSize, + INT BufferSize + ) + +// --------- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// --------- + +{ + PNDIS_PACKET Packet; + PSTRESS_ARGUMENTS Args; + PINSTANCE_COUNTERS Counters; + + Args = OpenP->Stress->Arguments; + Counters = OpenP->Stress->Client->Servers[ServerReference].Counters; + + if ( Args->PacketsFromPool == TRUE ) + { + Packet = TpStressAllocatePoolPacket(TpTransmitPool, + Counters ); + + if ( Packet != NULL ) + { + TpStressSetPoolPacketInfo( OpenP, + Packet, + DestAddr, + DestInstance, + SrcInstance, + SequenceNumber, + MaxSequenceNumber, + ClientReference, + ServerReference ); + } + else + { + return NDIS_STATUS_RESOURCES; + } + } + else + { + if ( Args->PacketType == RANDOMSIZE ) + { + PacketSize = TpGetRandom( sizeof( STRESS_PACKET ), + Args->PacketSize ); + } + else if (Args->PacketType == FIXEDSIZE) + { + PacketSize = Args->PacketSize; + } // else Args->PacketType == CYCLICAL + + Packet = TpStressCreatePacket( OpenP, + PacketHandle, + Args->PacketMakeUp, + DestInstance, + SrcInstance, + PacketProtocol, + Args->ResponseType, + DestAddr, + PacketSize, + BufferSize, + SequenceNumber, + MaxSequenceNumber, + ClientReference, + ServerReference, + Args->DataChecking ); + + if ( Packet != NULL ) + { + TpInitProtocolReserved( Packet,Counters ); + } + else + { + return NDIS_STATUS_RESOURCES; + } + } + + TpStressSend( OpenP,Packet,Counters ); + + return NDIS_STATUS_SUCCESS; +} + + + +VOID +TpStressServerSend( + POPEN_BLOCK OpenP, + PTP_TRANSMIT_POOL TpTransmitPool, + PUCHAR DestAddr, + UCHAR DestInstance, + UCHAR SrcInstance, + ULONG SequenceNumber, + ULONG MaxSequenceNumber, + UCHAR ClientReference, + UCHAR ServerReference, + INT PacketSize, + ULONG DataBufferOffset + ) + +// -------- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// -------- + +{ + PNDIS_PACKET Packet; + PINSTANCE_COUNTERS Counters; + + Counters = OpenP->Stress->Server->Clients[ClientReference].Counters; + +// ------- +// This does not work correctly if you are under severe stress +// because we run out of packets and loop forever. However, there +// needs to be done some work to handle the less severe case of +// lower stress say for instance when the window is enabled, or +// there is a large inter packet delay, giving the sends time to +// complete and put the used packets back in the transmitpool. +// Maybe if this fails here it should be handled in the completion +// routine where it is allowed to loop continuously. +// +// do +// { +// Packet = TpStressAllocatePoolPacket( TpTransmitPool,Counters ); +// } while ( Packet == NULL ); +// +// ------- + + Packet = TpStressAllocatePoolPacket( TpTransmitPool,Counters ); + + if ( Packet == NULL ) + { + return; + } + + + TpStressSetTruncatedPacketInfo( OpenP, + Packet, + DestAddr, + PacketSize, + DestInstance, + SrcInstance, + SequenceNumber, + MaxSequenceNumber, + ClientReference, + ServerReference, + DataBufferOffset & 0x07FF ); + + TpStressSend( OpenP,Packet,Counters ); +} + + + +VOID +TpStressSend( + POPEN_BLOCK OpenP, + PNDIS_PACKET Packet, + PINSTANCE_COUNTERS Counters OPTIONAL + ) + +// ----- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// ----- + +{ + NDIS_STATUS Status; + PPROTOCOL_RESERVED ProtRes; + PPENDING PPend; + PSTRESS_ARGUMENTS Args; + ULONG TmpPendNumber; + + Args = OpenP->Stress->Arguments; + ProtRes = PROT_RES( Packet ); + + // + // First allocate the Request Handle. + // + + Status = NdisAllocateMemory((PVOID *)&ProtRes->RequestHandle, + sizeof( TP_REQUEST_HANDLE ), + 0, + HighestAddress ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + // + // If we can't allocate the memory, then fail the send. + // + + IF_TPDBG (TP_DEBUG_RESOURCES) + { + TpPrint0("TpStressSend: unable to allocate RequestHandle\n"); + } + Status = NDIS_STATUS_RESOURCES; + } + else + { + // + // Otherwise zero the memory, and fill in the fields + // + + NdisZeroMemory( ProtRes->RequestHandle,sizeof( TP_REQUEST_HANDLE )); + + ProtRes->RequestHandle->Signature = STRESS_REQUEST_HANDLE_SIGNATURE; + ProtRes->RequestHandle->Open = OpenP; + ProtRes->RequestHandle->RequestPended = TRUE; + ProtRes->RequestHandle->u.SEND_REQ.Packet = Packet; + + // + // Then Set the CheckSum in the Protocol Reserved section of the + // packet header. + // + + ProtRes->CheckSum = TpSetCheckSum( (PUCHAR)ProtRes, + sizeof( PROTOCOL_RESERVED ) - sizeof( ULONG ) ); + + // + // and put the packet in the pending queue. + // + + PPend = OpenP->Stress->Pend; + + NdisAcquireSpinLock( &PPend->SpinLock ); + + // + // If the windowing mechanism is enabled, then add the packet + // to the pend queue. We don't add the packet to the pend queue + // when we are not windowing because a fast machine can quickly + // overrun the queue, and we don't support dynamically increasing + // the size of the queue yet. + // + if ( Args->WindowEnabled == TRUE ) + { + TmpPendNumber = PPend->PacketPendNumber; + + while ( PPend->Packets[TmpPendNumber] != NULL ) + { + NdisReleaseSpinLock( &PPend->SpinLock ); + +// IF_TPDBG ( TP_DEBUG_DPC ) +// { +// TpPrint2("TpStressSend: Found packet 0x%lX at slot %d of Pendbuffer\n", +// PPend->Packets[TmpPendNumber], +// TmpPendNumber); +// TpBreakPoint(); +// } + ++TmpPendNumber; + TmpPendNumber &= (NUM_PACKET_PENDS-1); // 2**n - 1 + + if (TmpPendNumber == PPend->PacketPendNumber) + { + TpPrint0("PPend buffer full -- no empty slots!\n"); + TpBreakPoint(); + } + NdisAcquireSpinLock( &PPend->SpinLock ); + } + + PPend->Packets[TmpPendNumber] = Packet; + + PPend->PacketPendNumber = (TmpPendNumber + 1) & (NUM_PACKET_PENDS - 1); // 2**n - 1 + } + + // + // We will also increment the Pending Packets counter now in + // case the packet pends and completes before the actual call + // to ndis send returns. if the send does not pend, the counter + // will be decremented later. + // + + ++PPend->PendingPackets; + + NdisReleaseSpinLock( &PPend->SpinLock ); + + // + // Then send then packet + // + + NdisSend( &Status,OpenP->NdisBindingHandle,Packet ); + + // + // and count the send. + // + + if ( ARGUMENT_PRESENT( Counters )) + { + NdisAcquireSpinLock( &OpenP->SpinLock ); + ++Counters->Sends; + NdisReleaseSpinLock( &OpenP->SpinLock ); + } + + if ( Status != NDIS_STATUS_PENDING ) + { + TpStressSendComplete(OpenP, Packet, Status); + } + else // ( Status == NDIS_STATUS_PENDING ) + { + // + // Otherwise the SEND pended so all of the clean up + // will be done in the Send Completion routine. Simply + // count the pend here. + // + + if ( ARGUMENT_PRESENT( Counters )) + { + NdisAcquireSpinLock( &OpenP->SpinLock ); + ++Counters->SendPends; + NdisReleaseSpinLock( &OpenP->SpinLock ); + } + } + } +} + + + +VOID +TpStressSendComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET Packet, + IN NDIS_STATUS Status + ) + +// ------- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// ------- + +{ + POPEN_BLOCK OpenP = ((POPEN_BLOCK)ProtocolBindingContext); + PPROTOCOL_RESERVED ProtRes; + PTP_REQUEST_HANDLE SendReqHndl; + ULONG TmpCompleteNumber; + ULONG MaxCompleteNumber; + BOOLEAN CompletePacketCleared; + PPENDING PPend; + PSTRESS_ARGUMENTS Args; + + TP_ASSERT( Packet != NULL ); + + Args = OpenP->Stress->Arguments; + ProtRes = PROT_RES( Packet ); + SendReqHndl = ProtRes->RequestHandle; + + TP_ASSERT( SendReqHndl->Signature == STRESS_REQUEST_HANDLE_SIGNATURE ); + TP_ASSERT( SendReqHndl->Open == OpenP ); + TP_ASSERT( SendReqHndl->RequestPended == TRUE ); + TP_ASSERT( Packet == SendReqHndl->u.SEND_REQ.Packet ); + + // + // Now check the PROTOCOL_RESERVED section of the Packet header + // to ensure that it was not corrupted while in the hands of + // the MAC. + // + + if ( !TpCheckSum( (PUCHAR)ProtRes, + sizeof( PROTOCOL_RESERVED ) - sizeof( ULONG ), + &ProtRes->CheckSum )) + { + // + // This could cause an access violation because we have + // just found that the PROTOCOL_RESERVED section of this + // packet header has been corrupted, and we are about to + // attempt to dereference a pointer stored in it. This + // should be changed to a try except. + // + + if ( ARGUMENT_PRESENT( ProtRes->InstanceCounters )) + { + NdisAcquireSpinLock( &OpenP->SpinLock ); + ++ProtRes->InstanceCounters->SendFails; + NdisReleaseSpinLock( &OpenP->SpinLock ); + } + } + + PPend = OpenP->Stress->Pend; + + NdisAcquireSpinLock( &PPend->SpinLock ); + + // + // If the windowing mechinism is enabled, then find the packet in the + // pend queue and remove it. + // + + if ( Args->WindowEnabled == TRUE ) + { + TmpCompleteNumber = PPend->PacketCompleteNumber; + MaxCompleteNumber = TmpCompleteNumber; + CompletePacketCleared = FALSE; + + do + { + if (CompletePacketCleared) + { + if (PPend->Packets[TmpCompleteNumber] != NULL) + { + break; + } + } + else + { + if ( Packet == PPend->Packets[TmpCompleteNumber] ) + { + PPend->Packets[TmpCompleteNumber] = NULL; + CompletePacketCleared = TRUE; + TmpCompleteNumber = PPend->PacketCompleteNumber; + MaxCompleteNumber = PPend->PacketPendNumber; + continue; + } + } + + ++TmpCompleteNumber; + TmpCompleteNumber &= (NUM_PACKET_PENDS - 1); // 2**n - 1 + } + while ( TmpCompleteNumber != MaxCompleteNumber ); + + if (CompletePacketCleared) + { + PPend->PacketCompleteNumber = TmpCompleteNumber; + } + else + { + IF_TPDBG( TP_DEBUG_DPC ) + { + TpPrint0("TpStressSendComplete: Pending Packet not found!!\n"); + TpPrint2("Packet: 0x%lX, list: 0x%lX\n",Packet,PPend->Packets ); + TpBreakPoint(); + } + } + } + + NdisReleaseSpinLock( &PPend->SpinLock ); + + if ( ARGUMENT_PRESENT( ProtRes->InstanceCounters )) + { + NdisAcquireSpinLock( &OpenP->SpinLock ); + + ++ProtRes->InstanceCounters->SendComps; + + if ( Status != NDIS_STATUS_SUCCESS ) + { + // + // If we are running on TokenRing the following to "failures" + // are not considered failures NDIS_STATUS_NOT_RECOGNIZED - + // no one on the ring recognized the address as theirs, or + // NDIS_STATUS_NOT_COPIED - no one on the ring copied the + // packet, so we need to special case this and not count + // these as failures. + // + + // + // STARTCHANGE: Added FDDI problem catching + // + if ( ( NdisMediumArray[OpenP->MediumIndex] == NdisMedium802_5 ) || + ( NdisMediumArray[OpenP->MediumIndex] == NdisMediumFddi ) || + ( NdisMediumArray[OpenP->MediumIndex] == NdisMediumArcnet878_2) ) + { + if (( Status != NDIS_STATUS_NOT_RECOGNIZED ) && + ( Status != NDIS_STATUS_NOT_COPIED )) + { + ++ProtRes->InstanceCounters->SendFails; + } + } + else + { + ++ProtRes->InstanceCounters->SendFails; + } + // + // STOPCHANGE + // + + } + NdisReleaseSpinLock( &OpenP->SpinLock ); + } + + if ( ProtRes->Pool.TransmitPool != NULL ) + { + TpStressFreePoolPacket( (PNDIS_PACKET)Packet ); + } + else + { + TpStressFreePacket( (PNDIS_PACKET)Packet ); + } + + // + // Decrement the counter representing the number of packets pending + // on this open instance. + // + + NdisAcquireSpinLock( &PPend->SpinLock ); + --PPend->PendingPackets; + + if (((( OpenP->Stress->StopStressing == TRUE ) && + ( OpenP->Stress->StressFinal == TRUE )) && + ( OpenP->Stress->Pend->PendingRequests == 0 )) && + ( OpenP->Stress->Pend->PendingPackets == 0 )) + { + OpenP->Stress->Stressing = FALSE; + NdisReleaseSpinLock( &PPend->SpinLock ); + TpStressFreeResources( OpenP ); + } + else + { + NdisReleaseSpinLock( &PPend->SpinLock ); + } + + // + // And free the Request Handle memory + // + + NdisFreeMemory( SendReqHndl,0,0 ); +} + + + +VOID +TpStressCheckPacketData( + POPEN_BLOCK OpenP, + NDIS_HANDLE MacReceiveContext, + ULONG DataOffset, + UINT PacketSize, + PINSTANCE_COUNTERS Counters + ) + +// ------------ +// +// Routine Description: +// +// TpStressCheckPacketData is used to verify the data of a stress packet. +// It calls NdisTransferData to copy the packet into a NDIS_PACKET structure +// and then verifies the data in the packet's buffer. +// +// Arguments: +// +// OpenP - The Open Instance that received this packet. We will use this +// open instances resources. +// +// MacReceiveContext - Passed to NdisTransferData, the MAC way of +// recognizing this Open Instance. +// +// DataOffset - the offset into the DataBuffer where the packet's data +// should begin. +// +// PacketSize - The size of data of this packet to be verified. +// +// Counters - The specific client or server's counters used to track the +// results of the data checking. +// +// Return Value: +// +// None. +// +// ------------ + +{ + NDIS_STATUS Status; + PNDIS_PACKET TransferPacket; + PNDIS_BUFFER TransferBuffer; + PUCHAR Memory; + PPROTOCOL_RESERVED ProtRes; + UINT BytesTransferred; + UINT DataStart; + UINT DataSize; + UINT i, j; + + // + // Allocate a packet, and a buffer to use in the call to transfer + // the packet into. + // + + NdisAllocatePacket( &Status,&TransferPacket,OpenP->Stress->PacketHandle ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG( TP_DEBUG_NDIS_CALLS ) + { + TpPrint1("TpStressCheckPacketData: NdisAllocatePacket failed: %s\n", + TpGetStatus(Status)); + } + return; + } + + // + // STARTCHANGE + // + + // + // We are only going to transfer the data portion of the packet. + // NOTE: + // The PacketSize being used here is the COMPLETE packet size + // = HEADER + DATA + // + DataSize = PacketSize - sizeof(STRESS_PACKET); + DataStart = (UINT)sizeof( STRESS_PACKET ) - OpenP->Media->HeaderSize; + + // + // STOPCHANGE + // + + Status = NdisAllocateMemory((PVOID *)&Memory,DataSize,0,HighestAddress ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG( TP_DEBUG_RESOURCES ) + { + TpPrint0("TpStressCheckPacketData: failed to allocate TransferBuffer\n"); + } + NdisFreePacket( TransferPacket ); + return; + } + else + { + NdisZeroMemory( Memory,DataSize ); + } + + TransferBuffer = IoAllocateMdl( Memory,DataSize,TRUE,FALSE,NULL ); + + if ( TransferBuffer == NULL ) + { + IF_TPDBG( TP_DEBUG_RESOURCES ) + { + TpPrint0("TpStressCheckPacketData: failed to allocate TransferBuffer Mdl\n"); + } + NdisFreeMemory( Memory,0,0 ); + NdisFreePacket( TransferPacket ); + return; + } + + MmBuildMdlForNonPagedPool((PMDL)TransferBuffer ); + + NdisChainBufferAtFront( TransferPacket,TransferBuffer ); + + // + // Now allocate a request handle structure and reference it in + // the packets protocol reserved section to pass info to the + // completion routine. + // + + ProtRes = PROT_RES( TransferPacket ); + + Status = NdisAllocateMemory((PVOID *)&ProtRes->RequestHandle, + sizeof( TP_REQUEST_HANDLE ), + 0, + HighestAddress ); + + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG ( TP_DEBUG_RESOURCES ) + { + TpPrint0("TpStressCheckPacketData: unable to allocate RequestHandle\n"); + } + IoFreeMdl( TransferBuffer ); + NdisFreeMemory( Memory,0,0 ); + NdisFreePacket( TransferPacket ); + return; + } + else + { + NdisZeroMemory( ProtRes->RequestHandle,sizeof( TP_REQUEST_HANDLE )); + } + + // + // and initialize the information in the request handle. + // + + ProtRes->RequestHandle->Signature = STRESS_REQUEST_HANDLE_SIGNATURE; + ProtRes->RequestHandle->u.TRANS_REQ.Packet = TransferPacket; + ProtRes->RequestHandle->u.TRANS_REQ.DataOffset = DataOffset; + ProtRes->RequestHandle->u.TRANS_REQ.DataSize = DataSize; + ProtRes->RequestHandle->u.TRANS_REQ.InstanceCounters = Counters; + + // + // Increment the transfer data counter, and make the call. + // + + NdisAcquireSpinLock( &OpenP->SpinLock ); + ++Counters->XferData; + NdisReleaseSpinLock( &OpenP->SpinLock ); + + NdisAcquireSpinLock( &OpenP->Stress->Pend->SpinLock ); + ++OpenP->Stress->Pend->PendingRequests; + NdisReleaseSpinLock( &OpenP->Stress->Pend->SpinLock ); + + NdisTransferData( &Status, + OpenP->NdisBindingHandle, + MacReceiveContext, + DataStart, + DataSize, + TransferPacket, + &BytesTransferred ); + + if ( Status == NDIS_STATUS_SUCCESS ) + { + // + // if the call succeeded, then verify the data now. + // + + TP_ASSERT( BytesTransferred == DataSize ); + + i = 0; + j = DataOffset; + + while ( i < DataSize ) + { + if ( Memory[i++] != (UCHAR)(j++ % 256) ) + { + NdisAcquireSpinLock( &OpenP->SpinLock ); + ++Counters->CorruptRecs; + NdisReleaseSpinLock( &OpenP->SpinLock ); + + IF_TPDBG ( TP_DEBUG_DATA ) + { + TpPrint1("TpStressCheckPacketData1: Data Error at offset %d in packet data\n", + i-1); + TpPrint2(" Found %02x, Expected %02x\n\n", + Memory[i-1],(( j - 1 ) % 256 )); + TpBreakPoint(); + } + break; + } + } + } + else if ( Status != NDIS_STATUS_PENDING ) + { + IF_TPDBG( TP_DEBUG_NDIS_CALLS ) + { + TpPrint1("TpStressCheckPacketData: NdisTransferData returned %s\n",TpGetStatus(Status)); + } + + NdisAcquireSpinLock( &OpenP->SpinLock ); + ++Counters->XferDataFails; + NdisReleaseSpinLock( &OpenP->SpinLock ); + } + else // (Status == NDIS_STATUS_PENDING) + { + // + // The call to NdisTransferData pended, the completion routine will + // verify the data. + // + + NdisAcquireSpinLock( &OpenP->SpinLock ); + ++Counters->XferDataPends; + NdisReleaseSpinLock( &OpenP->SpinLock ); + } + + if ( Status != NDIS_STATUS_PENDING ) + { + NdisAcquireSpinLock( &OpenP->Stress->Pend->SpinLock ); + + --OpenP->Stress->Pend->PendingRequests; + + if (((( OpenP->Stress->StopStressing == TRUE ) && + ( OpenP->Stress->StressFinal == TRUE )) && + ( OpenP->Stress->Pend->PendingRequests == 0 )) && + ( OpenP->Stress->Pend->PendingPackets == 0 )) + { + OpenP->Stress->Stressing = FALSE; + NdisReleaseSpinLock( &OpenP->Stress->Pend->SpinLock ); + TpStressFreeResources( OpenP ); + } + else + { + NdisReleaseSpinLock( &OpenP->Stress->Pend->SpinLock ); + } + + // + // If the routine did not pend, then deallocate the various resources, + // otherwise the completion routine will do this later. + // + IoFreeMdl( TransferBuffer ); + NdisFreeMemory( Memory,0,0 ); + NdisFreeMemory( ProtRes->RequestHandle,0,0 ); + NdisFreePacket( TransferPacket ); + } +} + + + +VOID +TpStressTransferDataComplete( + IN NDIS_HANDLE ProtocolBindingContext, + IN PNDIS_PACKET Packet, + IN NDIS_STATUS Status, + IN UINT BytesTransferred + ) + +// ----- +// +// Routine Description: +// +// Arguments: +// +// Return Value: +// +// ----- + +{ + POPEN_BLOCK OpenP = ((POPEN_BLOCK)ProtocolBindingContext); + PPROTOCOL_RESERVED ProtRes; + PTP_REQUEST_HANDLE XferReqHndl; + PNDIS_BUFFER TransferBuffer; + PUCHAR Memory; + UINT i = 0; + + TP_ASSERT( Packet != NULL ); + + ProtRes = PROT_RES( Packet ); + XferReqHndl = ProtRes->RequestHandle; + + TP_ASSERT( XferReqHndl->Signature == STRESS_REQUEST_HANDLE_SIGNATURE ); + TP_ASSERT( Packet == XferReqHndl->u.SEND_REQ.Packet ); + + // + // Increment the NdisTransferData completion counter. + // + // + + NdisAcquireSpinLock( &OpenP->SpinLock ); + ++XferReqHndl->u.TRANS_REQ.InstanceCounters->XferDataComps; + NdisReleaseSpinLock( &OpenP->SpinLock ); + + // + // Now unchain the buffer from the packet... + // + + NdisUnchainBufferAtFront( Packet,&TransferBuffer ); + + // + // get the actual packet data from the buffer... + // + + Memory = MmGetMdlVirtualAddress( TransferBuffer ); + + + // + // SanjeevK + // + // Fix for Bug# 9244 + // + + if ( ( Status != NDIS_STATUS_SUCCESS ) || + ( BytesTransferred != XferReqHndl->u.TRANS_REQ.DataSize ) ) + { + if ( Status != NDIS_STATUS_SUCCESS ) + { + IF_TPDBG( TP_DEBUG_NDIS_CALLS ) + { + TpPrint1("TpStressTransferDataComplete: NdisTransferData failed: Returned %s\n", + TpGetStatus(Status)); + } + } + else + { + IF_TPDBG ( TP_DEBUG_DATA ) + { + TpPrint0("TpStressCheckPacketData: Data bytes transfered were incorrect: "); + TpPrint2("Expected: %ld\tTransfered:%ld\n", + XferReqHndl->u.TRANS_REQ.DataSize, BytesTransferred ); + } + } + NdisAcquireSpinLock( &OpenP->SpinLock ); + ++XferReqHndl->u.TRANS_REQ.InstanceCounters->XferDataFails; + NdisReleaseSpinLock( &OpenP->SpinLock ); + } + else + { + // + // NdisTransferData completed successfully and thus proceed with + // checking the received data and see if it was corrupted. + // + + while ( i < XferReqHndl->u.TRANS_REQ.DataSize ) + { + if ( Memory[i++] != (UCHAR)( XferReqHndl->u.TRANS_REQ.DataOffset++ % 256 )) + { + NdisAcquireSpinLock( &OpenP->SpinLock ); + ++XferReqHndl->u.TRANS_REQ.InstanceCounters->CorruptRecs; + NdisReleaseSpinLock( &OpenP->SpinLock ); + + IF_TPDBG ( TP_DEBUG_DATA ) + { + TpPrint1("TpStressCheckPacketData2: Data Error at offset %d in packet data\n", + i-1); + TpPrint2(" Found %02x, Expected %02x\n\n", + Memory[i-1],(( XferReqHndl->u.TRANS_REQ.DataOffset - 1 ) % 256 )); + TpBreakPoint(); + } + break; + } // End of the if + } // End of the while + } // End of the if-else + + // + // Finally Free up the packet, buffer memory and finally the RequestHandle. + // + + NdisFreeMemory( Memory,0,0 ); + IoFreeMdl( TransferBuffer ); + NdisFreePacket( Packet ); + NdisFreeMemory( XferReqHndl,0,0 ); + + // + // Decrement the Pending Requests and set the stressing flag to + // stop all stressing if the time is right counter. + // + + NdisAcquireSpinLock( &OpenP->Stress->Pend->SpinLock ); + --OpenP->Stress->Pend->PendingRequests; + + if (((( OpenP->Stress->StopStressing == TRUE ) && + ( OpenP->Stress->StressFinal == TRUE )) && + ( OpenP->Stress->Pend->PendingRequests == 0 )) && + ( OpenP->Stress->Pend->PendingPackets == 0 )) + { + OpenP->Stress->Stressing = FALSE; + NdisReleaseSpinLock( &OpenP->Stress->Pend->SpinLock ); + TpStressFreeResources( OpenP ); + } + else + { + NdisReleaseSpinLock( &OpenP->Stress->Pend->SpinLock ); + } +} + + + +VOID +TpStressDoNothing( + VOID + ) +{ +// +// This function is used to ensure that busy loops don't +// get completely optimized out by the compiler. +// + + return; +} + + + |