void CParaNdisTX::CompleteOutstandingNBLChain(PNET_BUFFER_LIST NBL, ULONG Flags) { ULONG NBLNum = ParaNdis_CountNBLs(NBL); ParaNdis_CompleteNBLChain(m_Context->MiniportHandle, NBL, Flags); m_StateMachine.UnregisterOutstandingItems(NBLNum); }
/********************************************************** NDIS procedure of returning us buffer of previously indicated packets Parameters: context PNET_BUFFER_LIST pNBL - list of buffers to free returnFlags - is dpc The procedure frees: received buffer descriptors back to list of RX buffers all the allocated MDL structures all the received NBLs back to our pool ***********************************************************/ VOID ParaNdis6_ReturnNetBufferLists( NDIS_HANDLE miniportAdapterContext, PNET_BUFFER_LIST pNBL, ULONG returnFlags) { PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)miniportAdapterContext; auto NumNBLs = ParaNdis_CountNBLs(pNBL); UNREFERENCED_PARAMETER(returnFlags); DEBUG_ENTRY(5); ParaNdis_ReuseRxNBLs(pNBL); pContext->m_RxStateMachine.UnregisterOutstandingItems(NumNBLs); }
void CParaNdisTX::Send(PNET_BUFFER_LIST NBL) { PNET_BUFFER_LIST nextNBL = nullptr; NDIS_STATUS RejectionStatus = NDIS_STATUS_FAILURE; if (!m_StateMachine.RegisterOutstandingItems(ParaNdis_CountNBLs(NBL), &RejectionStatus)) { ParaNdis_CompleteNBLChainWithStatus(m_Context->MiniportHandle, NBL, RejectionStatus); return; } for(auto currNBL = NBL; currNBL != nullptr; currNBL = nextNBL) { nextNBL = NET_BUFFER_LIST_NEXT_NBL(currNBL); NET_BUFFER_LIST_NEXT_NBL(currNBL) = nullptr; auto NBLHolder = new (m_Context->MiniportHandle) CNBL(currNBL, m_Context, *this); if (NBLHolder == nullptr) { currNBL->Status = NDIS_STATUS_RESOURCES; CompleteOutstandingNBLChain(currNBL); DPrintf(0, ("ERROR: Failed to allocate CNBL instance\n")); continue; } if(NBLHolder->Prepare() && ParaNdis_IsSendPossible(m_Context)) { NBLHolder->StartMapping(); } else { NBLHolder->SetStatus(ParaNdis_ExactSendFailureStatus(m_Context)); NBLHolder->Release(); } } }