📄 init.c
字号:
/*++
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 + -