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

📄 receive.c

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

Copyright (c) 2000 Microsoft Corporation. All rights reserved.

   File:       receive.c
 
               Developed for Toshiba by Elisa Research Inc., CA
               http://www.elisaresearch.com
               (510) 770-4920



Abstract:

   This routine contains all of receive related handlers.

Author:

	A. Wang

Environment:

	Kernel mode

Revision History:

	09/23/96		kyleb		Added support for NdisAllocateMemoryWithTag
	10/01/96		kyleb		Added async receive buffer allocation.
	10/18/96		kyleb		Added async receive indication.
	01/07/97		awang		Initial of Toshiba ATM 155 Device Driver.
    02/16/99        hhan        Use synchronize mode to allocate xmit buffer.

--*/

#include "precomp.h"
#pragma hdrstop

#define MODULE_NUMBER   MODULE_RECEIVE

NDIS_STATUS
tbAtm155FreeReceiveBufferInfo(
   IN  PADAPTER_BLOCK      pAdapter,
   IN  PRECV_BUFFER_INFO   pRecvInfo
   )
/*++

Routine Description:

   This routine will attempt to free the receive buffer information.

Arguments:

   pAdapter    -   Poitner to the ADAPTER_BLOCK.
   pRecvInfo   -   Pointer to the RECV_BUFFER_INFO structure that
                   describes one or more receive pools to free up.

Return Value:

   NDIS_STATUS_SUCCESS if the data structures were correctly free'd up.

--*/
{

   UNREFERENCED_PARAMETER(pAdapter);

   ASSERT(RECV_BUFFER_INFO_SIG == pRecvInfo->Signature);

   //
   //	Free up the receive information buffer.
   //
   NdisFreeSpinLock(&pRecvInfo->lock);
   FREE_MEMORY(pRecvInfo, sizeof(RECV_BUFFER_INFO));
   return(NDIS_STATUS_SUCCESS);

}



NDIS_STATUS
tbAtm155AllocateReceiveBufferInfo(
   OUT PRECV_BUFFER_INFO   *pRecvInfo,
   IN  PVC_BLOCK           pVc
   )
/*++

Routine Description:

   This routine will allocate receive buffer information.

Arguments:

   pRecvInfo   -   Pointer to storage for the receive buffer
                   information structure.
   pVc         -   Pointer to the VC block that this receive information
                   is for.

Return Value:

   NDIS_STATUS_SUCCESS     if we successfully allocated storage.
   NDIS_STATUS_RESOURCES   if the allocation failed.

--*/
{
   PRECV_BUFFER_INFO   ptmpRecvInfo;
   NDIS_STATUS         Status;

   DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
       ("==>tbAtm155AllocateReceiveBufferInfo\n"));

   //
   //	Allocate memory for the receive buffer information structure.
   //
   ALLOCATE_MEMORY(
       &Status,
       &ptmpRecvInfo,
       sizeof(RECV_BUFFER_INFO),
       '60DA');
   if (NDIS_STATUS_SUCCESS != Status)
   {
       DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
           ("Unable to allocate RECV_BUFFER_INFO\n"));

       return(Status);
   }

   //
   //	This will initialize the list's heads and counts...
   //
   ZERO_MEMORY(ptmpRecvInfo, sizeof(RECV_BUFFER_INFO));

   //
   //	Allocate the spin lock that will protect this structure.
   //
   NdisAllocateSpinLock(&ptmpRecvInfo->lock);

#if DBG
   //
   // Set the signature for the receive buffer information structure.
   //
   ptmpRecvInfo->Signature = RECV_BUFFER_INFO_SIG;

#endif


   //
   //	Save the VC_BLOCK with the receive information.
   //
   ptmpRecvInfo->pVc = pVc;

   //
   //	Return the buffer information structure back to the caller.
   //
   *pRecvInfo = ptmpRecvInfo;

   DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
       ("<==tbAtm155AllocateReceiveBufferInfo\n"));

   return(NDIS_STATUS_SUCCESS);
}



VOID
tbAtm155FreeReceiveBufferPool(
   IN  PADAPTER_BLOCK      pAdapter,
   IN  PRECV_BUFFER_POOL   pRecvPool
   )
/*++

Routine Description:

   This routine will free up a receive buffer pool and it's resources.
   If the VC that these resources belong to is deactivating then we also
   need to check to see if we can complete the deactivation.

Arguments:

   pAdapter    -   Pointer to the adapter block.
   pRecvPool   -   Pointer to the receive buffer pool that we are freeing.

Return Value:

   None.

Note:

   The receive buffer information spin lock is already held.

--*/
{
   PRECV_BUFFER_HEADER	ptmpRecvHeader;
   PRECV_BUFFER_HEADER	pNextRecvHeader;

   DBGPRINT(DBG_COMP_RECV, DBG_LEVEL_INFO,
       ("==>tbAtm155FreeReceiveBufferPool\n"));

   ASSERT(RECV_BUFFER_POOL_SIG == pRecvPool->Signature);

   //
   //	Walk through the free buffer list and free the NDIS buffers and
   //  packets for each.  Also if the buffers were individually
   //  allocated then we need to free the shared memory for them also.
   //
   ptmpRecvHeader = pRecvPool->FreeBuffersHead;

   for (ptmpRecvHeader = pRecvPool->FreeBuffersHead;
        ptmpRecvHeader != NULL;
        ptmpRecvHeader = pNextRecvHeader)
   {
       //
       //	Save the pointer to the next receive header.
       //
       pNextRecvHeader = ptmpRecvHeader->Next;

       //
       //	Free the flush buffer.
       //
       if (NULL != ptmpRecvHeader->FlushBuffer)
       {
           NdisFreeBuffer(ptmpRecvHeader->FlushBuffer);
       }

       //
       //	Free the NDIS buffer.
       //
       if (NULL != ptmpRecvHeader->NdisBuffer)
       {
           NdisFreeBuffer(ptmpRecvHeader->NdisBuffer);
       }

       //
       //	Free the NDIS packet.
       //
       if (NULL != ptmpRecvHeader->Packet)
       {
           NdisFreePacket(ptmpRecvHeader->Packet);
       }

       //
       //	Was this buffer individually allocated?
       //
       if (!RECV_POOL_TEST_FLAG(pRecvPool, fRECV_POOL_BLOCK_ALLOC))
       {
           NdisMFreeSharedMemory(
               pAdapter->MiniportAdapterHandle,
               ptmpRecvHeader->Alloc[RECV_BUFFER_ORIGINAL].Size,
               TRUE,
               ptmpRecvHeader->Alloc[RECV_BUFFER_ORIGINAL].VirtualAddress,
               ptmpRecvHeader->Alloc[RECV_BUFFER_ORIGINAL].PhysicalAddress);
       }
   }

   //
   //	Were the receive buffers allocated in one big chunk?
   //
   if ((RECV_POOL_TEST_FLAG(pRecvPool, fRECV_POOL_BLOCK_ALLOC)) &&
       (NULL != pRecvPool->VirtualAddress))
   {
       NdisMFreeSharedMemory(
           pAdapter->MiniportAdapterHandle,
           pRecvPool->Size,
           TRUE,
           pRecvPool->VirtualAddress,
           pRecvPool->PhysicalAddress);
   }

   //
   //	Free the buffer pools and packet pools.
   //
   if (NULL != pRecvPool->hFlushBufferPool)
   {
       NdisFreeBufferPool(pRecvPool->hFlushBufferPool);
   }

   if (NULL != pRecvPool->hNdisBufferPool)
   {
       NdisFreeBufferPool(pRecvPool->hNdisBufferPool);
   }

   if (NULL != pRecvPool->hNdisPacketPool)
   {
       NdisFreePacketPool(pRecvPool->hNdisPacketPool);
   }

   //
   //	Free the memory used for the RECV_BUFFER_POOL structure.
   //
   FREE_MEMORY(pRecvPool, sizeof(RECV_BUFFER_POOL));

   DBGPRINT(DBG_COMP_RECV, DBG_LEVEL_INFO,
       ("<==tbAtm155FreeReceiveBufferPool\n"));
}



NDIS_STATUS
tbAtm155InitializeReceiveBuffer(
   IN  PRECV_BUFFER_POOL       pRecvPool,
   IN  PRECV_BUFFER_HEADER     pRecvHeader,
   IN  PVOID                   VirtualAddress,
   IN  NDIS_PHYSICAL_ADDRESS   PhysicalAddress,
   IN  ULONG                   SizeOfReceiveBuffer
   )
/*++

Routine Description:

   This routine will initialize the receive header with the allocation info,
   (tempVa, tempPa and size of receive buffer).  It will also allocate
   resources from the receive pool (buffers and packets) for use by the
   receive buffer.

Arguments:

   pRecvPool           -   Pointer to the receive pool that this receive
							header belongs to.
   pRecvHeader         -   Pointer to the receive header that we are
                           initializing.
   VirtualAddress      -   This is the virtual address for the receive buffer.
   PhysicalAddress     -   This is the physical address for the receive
                           buffer.
   SizeOfReceiveBuffer -   Size of the receive buffer in bytes.

Return Value:

   NDIS_STATUS_SUCCESS     if the initialization is successful.


--*/
{
   NDIS_STATUS                     Status;
   PMEDIA_SPECIFIC_INFORMATION     pMediaSpecificInfo;

   DBGPRINT(DBG_COMP_RECV, DBG_LEVEL_INFO,
       ("==>tbAtm155InitializeReceiveBuffer\n"));

   ASSERT(RECV_BUFFER_POOL_SIG == pRecvPool->Signature);

   //
   //	Determine the pointers to where the data will start.
   //
   pRecvHeader->Alloc[RECV_BUFFER_ALIGNED].VirtualAddress =
               (PUCHAR)VirtualAddress + pRecvPool->ReceiveHeaderSize;

   NdisSetPhysicalAddressLow(
       pRecvHeader->Alloc[RECV_BUFFER_ALIGNED].PhysicalAddress,
       NdisGetPhysicalAddressLow(PhysicalAddress) + pRecvPool->ReceiveHeaderSize);

   pRecvHeader->Alloc[RECV_BUFFER_ALIGNED].Size = SizeOfReceiveBuffer;
   DBGPRINT(DBG_COMP_RECV, DBG_LEVEL_INFO,
       ("pRecvBuf[ALIGNED]: Va(%lx), Pa(%lx)\n", 
         pRecvHeader->Alloc[RECV_BUFFER_ALIGNED].VirtualAddress,
         pRecvHeader->Alloc[RECV_BUFFER_ALIGNED].PhysicalAddress));

   DBGPRINT(DBG_COMP_RECV, DBG_LEVEL_INFO,
       ("pRecvBuf[ALIGNED]: Size(%lx)\n", 
         pRecvHeader->Alloc[RECV_BUFFER_ALIGNED].Size));

   do
   {
       //
       //	Allocate a flush buffer.
       //
       NdisAllocateBuffer(
           &Status,
           &pRecvHeader->FlushBuffer,
           pRecvPool->hFlushBufferPool,
           pRecvHeader->Alloc[RECV_BUFFER_ALIGNED].VirtualAddress,
           pRecvHeader->Alloc[RECV_BUFFER_ALIGNED].Size);
       if (Status != NDIS_STATUS_SUCCESS)
       {
           DBGPRINT(DBG_COMP_RECV, DBG_LEVEL_ERR,
               ("Unable to allocate an NDIS_BUFFER for the flush buffer\n"));

           break;
       }

       //
       //	Allocate a buffer to describe the data to be indicated.
       //
       NdisAllocateBuffer(
           &Status,
           &pRecvHeader->NdisBuffer,
           pRecvPool->hNdisBufferPool,
           (PUCHAR)pRecvHeader->Alloc[RECV_BUFFER_ALIGNED].VirtualAddress,
           pRecvHeader->Alloc[RECV_BUFFER_ALIGNED].Size);
       if (Status != NDIS_STATUS_SUCCESS)
       {
           DBGPRINT(DBG_COMP_RECV, DBG_LEVEL_ERR,
               ("Unabled to allocate an NDIS_BUFFER for the receive buffer\n"));

           break;
       }
	
       //
       //	Allocate a packet from the pool for the receive buffer.
       //
       NdisAllocatePacket(
           &Status,
           &pRecvHeader->Packet,
           pRecvPool->hNdisPacketPool);
       if (Status != NDIS_STATUS_SUCCESS)
       {
           DBGPRINT(DBG_COMP_RECV, DBG_LEVEL_ERR,
               ("Unable to allocate an NDIS_PACKET for the receive packet\n"));

           break;
       }
   } while (FALSE);

   if (NDIS_STATUS_SUCCESS == Status)
   {
		//
		//	Initialize the media specific information.
		//	Our media specific storage is right after the protocol's
		//	reserved area.
		//
		pMediaSpecificInfo = (PMEDIA_SPECIFIC_INFORMATION)((PUCHAR)pRecvHeader->Packet +
								FIELD_OFFSET(NDIS_PACKET, ProtocolReserved) +
								PROTOCOL_RESERVED_SIZE_IN_PACKET +
								sizeof(RECV_PACKET_RESERVED));
       pMediaSpecificInfo->NextEntryOffset = 0;
       pMediaSpecificInfo->ClassId = NdisClassAtmAALInfo;
       pMediaSpecificInfo->Size = sizeof(ATM_AAL_OOB_INFO);

⌨️ 快捷键说明

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