⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 recvlist.cpp

📁 收集到的orion_ep93xx_wince_bsp_1-3-507红外收发驱动源码,未作测试
💻 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 + -