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

📄 init.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) Microsoft Corporation.  All rights reserved.

    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.

Module Name:

   INIT.C

Abstract:

    This module contains initialization helper routines called during
    MiniportInitialize.

Revision History:

Notes:

--*/
#include "miniport.h"

#pragma NDIS_PAGEABLE_FUNCTION(NICAllocAdapter)
#pragma NDIS_PAGEABLE_FUNCTION(NICFreeAdapter)
#pragma NDIS_PAGEABLE_FUNCTION(NICInitializeAdapter)
#pragma NDIS_PAGEABLE_FUNCTION(NICReadRegParameters)

NDIS_STATUS NICAllocAdapter(
    PMP_ADAPTER *pAdapter)
{
    PMP_ADAPTER Adapter = NULL;
    PNDIS_PACKET Packet;
    PNDIS_BUFFER Buffer;
    PUCHAR pTCBMem;
    PTCB  pTCB;
    NDIS_STATUS Status;

    LONG index;

    DEBUGP(MP_TRACE, ("--> NICAllocAdapter\n"));

    *pAdapter = NULL;

    do
    {
        //
        // Allocate memory for adapter context
        //
        Status = NdisAllocateMemoryWithTag(
            &Adapter, 
            sizeof(MP_ADAPTER), 
            NIC_TAG);
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("Failed to allocate memory for adapter context\n"));
            break;
        }
        //
        // Zero the memory block
        //
        NdisZeroMemory(Adapter, sizeof(MP_ADAPTER));
        NdisInitializeListHead(&Adapter->List);

        //
        // Initialize Send & Recv listheads and corresponding 
        // spinlocks.
        //
        NdisInitializeListHead(&Adapter->RecvWaitList);
        NdisInitializeListHead(&Adapter->SendWaitList);
        NdisInitializeListHead(&Adapter->SendFreeList);
        NdisAllocateSpinLock(&Adapter->SendLock);                                                  

        NdisInitializeListHead(&Adapter->RecvFreeList);
        NdisAllocateSpinLock(&Adapter->RecvLock);  

        //
        // Allocate lookside list for Receive Control blocks.
        //
        NdisInitializeNPagedLookasideList(
                    &Adapter->RecvLookaside,
                    NULL, // No Allocate function
                    NULL, // No Free function
                    0,    // Reserved for system use
                    sizeof(RCB),
                    NIC_TAG, 
                    0); // Reserved for system use
                    
        MP_SET_FLAG(Adapter, fMP_ADAPTER_RECV_LOOKASIDE); 
        
        //
        // Allocate packet pool for receive indications
        //
        NdisAllocatePacketPool(
            &Status,
            &Adapter->RecvPacketPoolHandle,
            NIC_MAX_BUSY_RECVS,
            PROTOCOL_RESERVED_SIZE_IN_PACKET);
        
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("NdisAllocatePacketPool failed\n"));
            break;
        }
        //
        // Initialize receive packets
        //
        for(index=0; index < NIC_MAX_BUSY_RECVS; index++)
        {
            //
            // Allocate a packet descriptor for receive packets
            // from a preallocated pool.
            //
            NdisAllocatePacket(
                &Status,
                &Packet,
                Adapter->RecvPacketPoolHandle);
            if(Status != NDIS_STATUS_SUCCESS)
            {
                DEBUGP(MP_ERROR, ("NdisAllocatePacket failed\n"));
                break;
            }
            
            NDIS_SET_PACKET_HEADER_SIZE(Packet, ETH_HEADER_SIZE);

            //
            // Insert it into the list of free receive packets.
            //
            NdisInterlockedInsertTailList(
                &Adapter->RecvFreeList, 
                (PLIST_ENTRY)&Packet->MiniportReserved[0], 
                &Adapter->RecvLock);
        }
        
        //
        // Allocate a huge block of memory for all TCB's
        //
        Status = NdisAllocateMemoryWithTag(
            &pTCBMem, 
            sizeof(TCB) * NIC_MAX_BUSY_SENDS, 
            NIC_TAG);
        
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("Failed to allocate memory for TCB's\n"));
            break;
        }
        NdisZeroMemory(pTCBMem, sizeof(TCB) * NIC_MAX_BUSY_SENDS);
        Adapter->TCBMem = pTCBMem;

        //
        // Allocate a buffer pool for send buffers.
        //

        NdisAllocateBufferPool(
            &Status,
            &Adapter->SendBufferPoolHandle,
            NIC_MAX_BUSY_SENDS);
        if(Status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(MP_ERROR, ("NdisAllocateBufferPool for send buffer failed\n"));
            break;
        }

        //
        // Divide the TCBMem blob into TCBs and create a buffer
        // descriptor for the Data portion of the TCBs.
        //
        for(index=0; index < NIC_MAX_BUSY_SENDS; index++)
        {
            pTCB = (PTCB) pTCBMem;
            //
            // Create a buffer descriptor for the Data portion of the TCBs.
            // Buffer descriptors are nothing but MDLs on NT systems.
            //
            NdisAllocateBuffer(
                &Status,
                &Buffer,
                Adapter->SendBufferPoolHandle,
                (PVOID)&pTCB->Data[0],
                NIC_BUFFER_SIZE);
            if(Status != NDIS_STATUS_SUCCESS)
            {
                DEBUGP(MP_ERROR, ("NdisAllocateBuffer failed\n"));
                break;
            }

            //
            // Initialize the TCB structure.
            // 
            pTCB->Buffer = Buffer;
            pTCB->pData = (PUCHAR) &pTCB->Data[0];       
            pTCB->Adapter = Adapter;

            NdisInterlockedInsertTailList(
                &Adapter->SendFreeList, 
                &pTCB->List, 
                &Adapter->SendLock);

            pTCBMem = pTCBMem + sizeof(TCB);
        }

    } while(FALSE);


    *pAdapter = Adapter;

    //
    // In the failure case, the caller of this routine will end up
    // calling NICFreeAdapter to free all the successfully allocated
    // resources.
    //
    DEBUGP(MP_TRACE, ("<-- NICAllocAdapter\n"));

    return(Status);

}

void NICFreeAdapter(
    PMP_ADAPTER Adapter)
{
    NDIS_STATUS    Status;
    PNDIS_PACKET   Packet;
    PNDIS_BUFFER   Buffer;
    PUCHAR         pMem;
    PTCB           pTCB;
    PLIST_ENTRY    pEntry;

    DEBUGP(MP_TRACE, ("--> NICFreeAdapter\n"));

    ASSERT(Adapter);
    ASSERT(!Adapter->RefCount);
    
    //
    // Free all the resources we allocated for send.
    //
    while(!IsListEmpty(&Adapter->SendFreeList))
    {
        pTCB = (PTCB) NdisInterlockedRemoveHeadList(
                     &Adapter->SendFreeList, 
                     &Adapter->SendLock);
        if(!pTCB)
        {
            break;
        }

        if(pTCB->Buffer)
        {
            NdisFreeBuffer(pTCB->Buffer);
        }
    }

    if(Adapter->SendBufferPoolHandle)
    {
        NdisFreeBufferPool(Adapter->SendBufferPoolHandle);
    }

    NdisFreeMemory(Adapter->TCBMem, sizeof(TCB) * NIC_MAX_BUSY_SENDS, 0);
    ASSERT(IsListEmpty(&Adapter->SendFreeList));                  
    ASSERT(IsListEmpty(&Adapter->RecvWaitList));                  
    ASSERT(IsListEmpty(&Adapter->SendWaitList));                  
    NdisFreeSpinLock(&Adapter->SendLock);

    //
    // Free all the resources we allocated for receive.
    //
    
    if (MP_TEST_FLAG(Adapter, fMP_ADAPTER_RECV_LOOKASIDE))
    {
        NdisDeleteNPagedLookasideList(&Adapter->RecvLookaside);
        MP_CLEAR_FLAG(Adapter, fMP_ADAPTER_RECV_LOOKASIDE);
    }
  
    while(!IsListEmpty(&Adapter->RecvFreeList))
    {
        pEntry = (PLIST_ENTRY) NdisInterlockedRemoveHeadList(
                        &Adapter->RecvFreeList, 
                        &Adapter->RecvLock);
        if(pEntry)
        {
            Packet = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReserved);
            NdisFreePacket(Packet);
        }
    }

    if(Adapter->RecvPacketPoolHandle)
    {
        NdisFreePacketPool(Adapter->RecvPacketPoolHandle);
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -