📄 recvlist.cpp
字号:
//**********************************************************************
//
// Filename: recvlist.cpp
//
// Description: Recieve Packet list.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// Copyright(c) Cirrus Logic Corporation 2001, All Rights Reserved
//
//**********************************************************************
#include <windows.h>
extern "C"
{
#include <ndis.h>
#include <ntddndis.h>
}
#include <linklist.h>
#include <ceddk.h>
#include "settings.h"
#include "debugzone.h"
#include "recvlist.h"
#include "sirstate.h"
#include "irdahw.h"
//#include "miniport.h"
//****************************************************************************
// ReceiveList::ReceiveList
//****************************************************************************
// Constructor to Initialize the ReceiveList.
//
//
ReceiveList::ReceiveList(NDIS_HANDLE hNdisAdapter):
m_hPacketPool(0),
m_hBufferPool(0),
m_hNdisAdapter(hNdisAdapter)
{
}
//****************************************************************************
// ReceiveList::Initialize
//****************************************************************************
// Initialize the recieve list.
//
//
NDIS_STATUS ReceiveList::Initialize()
{
NDIS_STATUS status;
ULONG i;
//
// Initialize the list head.
//
InitializeListHead(&m_FreeList);
InitializeListHead(&m_PendingList);
//
// Initialize the Critical Section to protect the recieve list.
//
InitializeCriticalSection(&m_CritSection);
//
// Allocate memory for the Recieve Packets.
// I am not exactly clear why we have to allocate this memory.
//
NdisAllocatePacketPool
(
&status,
&m_hPacketPool,
NUM_RX_BUFFERS,
16
);
//
// Allocate the Ndis buffer pool.
//
if (status == NDIS_STATUS_SUCCESS)
{
NdisAllocateBufferPool
(
&status,
&m_hBufferPool,
NUM_RX_BUFFERS
);
}
//
// Allocate each packet from the pool allocated above.
//
if(status == NDIS_STATUS_SUCCESS)
{
for (i = 0; i < NUM_RX_BUFFERS; i++)
{
PRX_BUFFER pRxBuf;
PNDIS_BUFFER pNdisBuffer;
//
// Allocate memory for each recieve structure.
//
pRxBuf = (PRX_BUFFER) LocalAlloc
(
LMEM_FIXED | LMEM_ZEROINIT,
MAX_IRDA_DATA_SIZE
);
//
// Break out of the loop if we can't allocate the memory.
//
if(pRxBuf == 0 )
{
status = NDIS_STATUS_RESOURCES;
break;
}
//
// Initialize the recieve buffers structure.
//
pRxBuf->pbBuffer = (LPBYTE)pRxBuf + sizeof(RX_BUFFER);
pRxBuf->cbBuffer = RX_BUFFER_SIZE;
pRxBuf->cbData = 0;
//
// Allocate a Recieve Packet.
//
NdisAllocatePacket
(
&status,
&pRxBuf->pPacket,
m_hPacketPool
);
if (status != NDIS_STATUS_SUCCESS)
{
NdisFreePacket(pRxBuf->pPacket);
break;
}
//
// Allocate a DMA buffer that is non paged.
// Probably could use the normal memory allocation functions.
//
NdisAllocateBuffer
(
&status,
&pNdisBuffer,
m_hBufferPool,
pRxBuf->pbBuffer,
pRxBuf->cbBuffer
);
if (status != NDIS_STATUS_SUCCESS)
{
NdisFreeBuffer(pNdisBuffer);
break;
}
//
// Chain buffer to packet.
//
NdisChainBufferAtFront(pRxBuf->pPacket, pNdisBuffer);
//
// Put on free list.
//
InsertTailList( &m_FreeList, (LIST_ENTRY *)pRxBuf);
}
}
return status;
}
//****************************************************************************
// ReceiveList::~ReceiveList
//****************************************************************************
// Delete the lists
//
//
ReceiveList::~ReceiveList()
{
PRX_BUFFER pRxBuf;
//
// Delete the list
//
while(!IsListEmpty(&m_FreeList))
{
pRxBuf = (RX_BUFFER *)RemoveTailList(&m_FreeList);
LocalFree(pRxBuf);
}
//
// Free the buffer pool.
//
NdisFreeBufferPool(m_hBufferPool);
NdisFreePacketPool(m_hPacketPool);
}
//****************************************************************************
// ReceiveList::GetFree
//****************************************************************************
// Get the first NDIS Packet on the free list.
//
//
PRX_BUFFER ReceiveList::GetFree()
{
PNDIS_PACKET_OOB_DATA pOobData;
PNDIS_BUFFER pNdisBuffer;
PRX_BUFFER pRxBuf;
//
// Get the first item in the list.
//
EnterCriticalSection(&m_CritSection);
pRxBuf = (PRX_BUFFER)RemoveHeadList (&m_FreeList);
LeaveCriticalSection(&m_CritSection);
if (pRxBuf != NULL)
{
//
// Zero data buffer.
//
ZeroMemory(pRxBuf->pbBuffer, pRxBuf->cbBuffer);
//
// Zero OOB data in packet.
//
pOobData = NDIS_OOB_DATA_FROM_PACKET(pRxBuf->pPacket);
ASSERT(pOobData);
ZeroMemory(pOobData, sizeof(NDIS_PACKET_OOB_DATA));
//
// Reset packet/buffer size.
//
NdisQueryPacket(pRxBuf->pPacket, NULL, NULL, &pNdisBuffer, NULL);
NdisAdjustBufferLength(pNdisBuffer, pRxBuf->cbBuffer);
pRxBuf->cbData = 0;
//
// This forces NdisQueryPacket to recalculate #packets and #bytes.
//
pRxBuf->pPacket->Private.ValidCounts = FALSE;
}
return (pRxBuf);
}
//****************************************************************************
// ReceiveList::ReturnBuffer
//****************************************************************************
// Returns a Recieve Buffer to the Free list.
//
//
void ReceiveList::ReturnBuffer
(
PRX_BUFFER pRxBuf
)
{
EnterCriticalSection(&m_CritSection);
InsertTailList ( &m_FreeList, pRxBuf);
LeaveCriticalSection(&m_CritSection);
}
//****************************************************************************
// ReceiveList::AddPendingBuffer
//****************************************************************************
// Add a receive buffer to the pending queue.
//
//
void ReceiveList::AddPendingBuffer
(
PRX_BUFFER pRxBuf
)
{
EnterCriticalSection(&m_CritSection);
InsertTailList(&m_PendingList, pRxBuf );
LeaveCriticalSection(&m_CritSection);
}
//****************************************************************************
// ReceiveList::RemovePendingBuffer
//****************************************************************************
// Removes a receive buffer from the pending queue, based
// on the associated NDIS_PACKET address.
//
PRX_BUFFER ReceiveList::RemovePendingBuffer
(
PNDIS_PACKET pNdisPacket
)
{
PRX_BUFFER pRxBuf;
PLIST_ENTRY pEntry;
//
// Protect the list.
//
EnterCriticalSection(&m_CritSection);
for (pEntry = m_PendingList.Flink;
pEntry != &m_PendingList;
pEntry = pEntry->Flink
)
{
pRxBuf = (PRX_BUFFER)pEntry;
if (pRxBuf->pPacket == pNdisPacket)
{
RemoveEntryList(pEntry);
break;
}
}
LeaveCriticalSection(&m_CritSection);
return (pRxBuf);
}
//****************************************************************************
// ReceiveList::ProcessFrame
//****************************************************************************
// Performs the necessary processing after a frame has been processed.
//
//
NDIS_STATUS ReceiveList::ProcessFrame
(
PRX_BUFFER pRxBuf
)
{
NDIS_HANDLE hSwitchToMiniport = 0;
PNDIS_BUFFER pNdisBuffer;
BOOL fSwitchSuccessful;
NDIS_STATUS status;
//
// Adjust buffer size to actual size of data and not size of the
// buffer.
//
NdisQueryPacket(pRxBuf->pPacket, NULL, NULL, &pNdisBuffer, NULL);
NdisAdjustBufferLength(pNdisBuffer, pRxBuf->cbData);
//
// This forces NdisQueryPacket to recalculate #packets and #bytes.
//
pRxBuf->pPacket->Private.ValidCounts = FALSE;
//
// Put receive buffer on pending queue before we indicate to the
// protocol, just in case the protocol can somehow call
// NdisReturnPacket before we queue it. If the protocol returns
// the packet immediately, we will just dequeue.
//
EnterCriticalSection(&m_CritSection);
InsertTailList( &m_PendingList, pRxBuf );
LeaveCriticalSection(&m_CritSection);
//
// Since this is an intermediate miniport, we must call
// NdisIMSwitchToMiniport to grab the miniport lock.
//
fSwitchSuccessful = NdisIMSwitchToMiniport
(
m_hNdisAdapter,
&hSwitchToMiniport
);
if (fSwitchSuccessful == FALSE)
{
// WinCE's NdisIMSwitchToMiniport should not fail.
ASSERT(FALSE);
}
NdisMIndicateReceivePacket
(
m_hNdisAdapter,
&pRxBuf->pPacket,
1
);
status = NDIS_GET_PACKET_STATUS(pRxBuf->pPacket);
if (status != NDIS_STATUS_PENDING)
{
//
// Remove the item from the pending list.
//
RemoveEntryList(pRxBuf);
DEBUGMSG(ZONE_RECV,
(TEXT(" Removing packet from pending queue.\r\n")));
//
// Add the item back into the free list.
//
EnterCriticalSection(&m_CritSection);
InsertTailList(&m_FreeList, pRxBuf);
LeaveCriticalSection(&m_CritSection);
pRxBuf = NULL;
}
else
{
// Protocol has retained ownership of packet. The miniport
// will regain ownership when IrsirReturnPacket is called.
DEBUGMSG(ZONE_RECV,
(TEXT(" Protocol has retained ownership of packet 0x%.8X.\r\n"),
pRxBuf->pPacket)
);
pRxBuf = NULL;
}
//
// Undo the call to NdisIMSwitchToMiniport.
//
if(hSwitchToMiniport)
{
NdisIMRevertBack(m_hNdisAdapter, hSwitchToMiniport);
}
return(status);
}
//****************************************************************************
// ReceiveList::Reset
//****************************************************************************
// Moves all pending buffers and moves them to the free list.
// Occurs when MiniportReset is called.
//
//
void ReceiveList::Reset()
{
PRX_BUFFER pBuffer;
EnterCriticalSection(&m_CritSection);
for(;;)
{
pBuffer = (PRX_BUFFER) RemoveHeadList(&m_PendingList);
if(!pBuffer)
break;
InsertTailList(&m_FreeList, pBuffer);
}
LeaveCriticalSection(&m_CritSection);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -