📄 d100.c
字号:
Adapter->ResetInProgress = FALSE;
DEBUGSTR(("D100Reset: Calling StartReceiveUnit\n"));
// Start the receive unit and indicate any pending receives that we
// had left in our queue.
if (StartReceiveUnit(Adapter))
{
TRACE2(Adapter, ("Indicating Receive complete\n"));
DEBUGCHAR(Adapter,'^');
NdisMEthIndicateReceiveComplete(Adapter->D100AdapterHandle);
}
D100EnableInterrupt(Adapter);
return;
}
//-----------------------------------------------------------------------------
// Procedure: D100AllocateComplete
//
// Description: This function handles initialization of new receive memory
// when the os returns some shared memory to us because we
// called NdisMAllocateSharedMemoryAsync when we ran low on
// receive buffers.
//
// Arguments: MiniportAdapterContext - a pointer to our adapter structure
// VirtualAddress - The virtual address of the new memory
// PhysicalAddress - _pointer to_ The physical address of the
// new memory
// Length - The length of the new memory
// Context - The offset into our MemoryDescriptor array to
// initialize (zero-based)
//
// Returns: Nothing
//
//-----------------------------------------------------------------------------
VOID
D100AllocateComplete(NDIS_HANDLE MiniportAdapterContext,
IN PVOID VirtualAddress,
IN PNDIS_PHYSICAL_ADDRESS PhysicalAddress,
IN ULONG Length,
IN PVOID Context)
{
PD100_ADAPTER Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
NDIS_STATUS AllocationStatus;
NDIS_STATUS Status;
UINT RfdCount;
UINT OldNumRfds = Adapter->NumRfd;
D100SwRfd *SwRfdPtr, *SwRfdNext; // cached RFD list logical pointers
ULONG HwRfdPhys; // uncached RFD list physical pointer
ReceiveMemoryDescriptor *current;
DEBUGFUNC("D100AllocateComplete");
current = &Adapter->ReceiveMemoryDescArray[PtrToUint(Context)];
INITSTR(("\n"));
// check if any of the three variables that indicate failure are zero,
// indicating that a part of the allocation failed
if ((VirtualAddress == 0)
|| (NdisGetPhysicalAddressLow(*PhysicalAddress) == 0)
|| (Length == 0))
{
// ndismfreesharedmemory?
Adapter->AsynchronousAllocationPending = FALSE;
return;
}
// catch the case where we have waaaay too many receive buffers.
if((Adapter->NumRfd + packet_count[PtrToUint(Context)]) >= MAX_RECEIVE_DESCRIPTORS)
{
NdisMFreeSharedMemory(Adapter->D100AdapterHandle,
Length,
FALSE,
(PVOID) VirtualAddress,
*PhysicalAddress);
Adapter->AsynchronousAllocationPending = FALSE;
return;
}
NdisAcquireSpinLock(&Adapter->Lock);
// allocate and setup some cached memory
// also initialize the uncached areas of the RMD
// (receive memory descriptor)
Status = AllocateRMD(current,
packet_count[PtrToUint(Context)],
(ULONG_PTR) VirtualAddress,
*PhysicalAddress,
Length);
if (Status != NDIS_STATUS_SUCCESS)
{
D100LogError(Adapter, EVENT_20, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 0);
INITSTR(("Could not allocate %d bytes for ExtraRecvCached mem\n", current->CachedMem.Size));
NdisReleaseSpinLock(&Adapter->Lock);
NdisMFreeSharedMemory(Adapter->D100AdapterHandle,
Length,
FALSE,
(PVOID) VirtualAddress,
*PhysicalAddress);
Adapter->AsynchronousAllocationPending = FALSE;
return;
}
// increment our RMD counter
++(Adapter->Last_RMD_used);
// update the number of Rfds we have
Adapter->NumRfd += packet_count[PtrToUint(Context)];
// SwRfdNext = (D100SwRfd *)current->CachedMem.VirtualAddress;// cached RFDs logical
// HwRfdNext = (RFD_STRUC *)xtraRecvUnCached; // uncached RFDs logical
for (RfdCount = 0;
RfdCount < (Adapter->NumRfd - OldNumRfds);
++RfdCount)
{
SwRfdPtr = BuildSwRfd(Adapter,current, RfdCount);
// if something goes wrong with packet pool (should be impossible)
if (SwRfdPtr == NULL)
break;
// call init and chain packet to put the packet on our available list
InitAndChainPacket(Adapter,SwRfdPtr);
}
Adapter->AsynchronousAllocationPending = FALSE;
NdisReleaseSpinLock(&Adapter->Lock);
return;
}
//-----------------------------------------------------------------------------
// Procedure: AllocateRMD
//
// Description: This function allocates and initializes a
// ReceiveMemoryDescriptor (RMD) for use in maintaining pointers
// when asyncronously allocating receive memory.
// this includes allocating cached memory for software structures
// and initializing the uncached memory associated with it.
//
// Arguments: new - the pointer to the structure/memory to init
// count - how many receive frames will be in this cached/uncached mem
// Virt - The virtual address of the uncached memory
// Phys - the physical address of the uncached memory
// Len - the length of the uncached memory
//
// Returns: a modified new pointer and an NDIS_STATUS of the success or failure
// to allocate cached memory
//
//-----------------------------------------------------------------------------
NDIS_STATUS
AllocateRMD(ReceiveMemoryDescriptor *new,
UINT count,
ULONG_PTR Virt,
NDIS_PHYSICAL_ADDRESS Phys,
UINT Len)
{
NDIS_STATUS status;
DEBUGFUNC("AllocateRMD");
// first take care of the Cached Memory needs for our
// SwRfds
new->CachedMem.Size = (count * sizeof(D100SwRfd));
status = D100_ALLOC_MEM(&new->CachedMem.VirtualAddress, new->CachedMem.Size);
if (status == NDIS_STATUS_SUCCESS)
{
INITSTR(("Allocated %08x %8d bytes for ExtraRecvCached mem\n",new->CachedMem.VirtualAddress,new->CachedMem.Size));
NdisZeroMemory((PVOID) new->CachedMem.VirtualAddress, new->CachedMem.Size);
// now set up the uncached memory
new->UnCachedMem.VirtualAddress = (ULONG)(Virt);
new->UnCachedMem.PhysicalAddress = Phys;
new->UnCachedMem.Size = Len;
}
return(status);
}
//-----------------------------------------------------------------------------
// Procedure: BuildSwRfd
//
// Description: Initializes a single SwRfd structure
//
// Arguments: Adapter - the adapter structure
// newmem - a pointer to the RMD structure that this RFD will
// be allocated from
// startpoint - the number of the RFD in this RMD
//
// Returns: a pointer to the SwRfd initialized
//
//-----------------------------------------------------------------------------
PD100SwRfd
BuildSwRfd(PD100_ADAPTER Adapter,
ReceiveMemoryDescriptor *newmem,
UINT startpoint)
{
D100SwRfd *rfdptr; // the new SwRfd we are creating
RFD_STRUC *hwptr; // uncached RFD list logical pointer
ULONG hwphys;
NDIS_STATUS AllocationStatus;
D100SwRfd **TempPtr;
D100SwRfd *rfdvirtual;
RFD_STRUC *hwptrvirtual;
RFD_STRUC *hwphysvirtual;
DEBUGFUNC("BuildSwRfd");
// first spin the cached pointer along to where it needs to be
rfdvirtual = (D100SwRfd *) newmem->CachedMem.VirtualAddress;
rfdptr = &rfdvirtual[startpoint];
// now move the uncached pointer along also
hwptrvirtual = (RFD_STRUC *) newmem->UnCachedMem.VirtualAddress;
hwptr = &hwptrvirtual[startpoint];
hwphysvirtual = (RFD_STRUC *) NdisGetPhysicalAddressLow(newmem->UnCachedMem.PhysicalAddress);
hwphys = (ULONG) PtrToUlong(&hwphysvirtual[startpoint]);
INITSTR((" RfdCount=%d\n", startpoint));
INITSTR((" SwRfdPtr=%lx\n", rfdptr));
INITSTR((" HwRfdPtr=%lx\n", hwptr));
INITSTR((" HwRfdPhys=%lx\n", hwphys));
// point the logical RFD to the pointer of the physical one
rfdptr->Rfd = hwptr;
// store the physical address in the Software RFD Structure
rfdptr->RfdPhys = hwphys;
// Init each RFD header
hwptr->RfdCbHeader.CbStatus = 0;
hwptr->RfdRbdPointer = DRIVER_NULL;
hwptr->RfdActualCount= 0;
hwptr->RfdSize = sizeof(ETH_RX_BUFFER_STRUC);
// set up the packet structure for passing up this Rfd
// with NdisMIndicateReceivePacket
NdisAllocatePacket(&AllocationStatus,
&rfdptr->ReceivePacket,
Adapter->ReceivePacketPool);
if (AllocationStatus != NDIS_STATUS_SUCCESS)
{
INITSTR(("Ran out of packet pool\n"));
return(NULL);
}
NDIS_SET_PACKET_HEADER_SIZE(rfdptr->ReceivePacket,
ETHERNET_HEADER_SIZE);
// point our buffer for receives at this Rfd
NdisAllocateBuffer(&AllocationStatus,
&rfdptr->ReceiveBuffer,
Adapter->ReceiveBufferPool,
(PVOID)&hwptr->RfdBuffer.RxMacHeader,
MAXIMUM_ETHERNET_PACKET_SIZE);
if (AllocationStatus != NDIS_STATUS_SUCCESS)
{
INITSTR(("Ran out of packet buffer pool\n"));
return(NULL);
}
NdisChainBufferAtFront(rfdptr->ReceivePacket,
rfdptr->ReceiveBuffer);
// set up the reverse path from Packet to SwRfd
// this is so when D100GetReturnedPackets is called we
// can find our software superstructure that owns this receive area.
TempPtr = (D100SwRfd **) &rfdptr->ReceivePacket->MiniportReserved;
*TempPtr = rfdptr;
return(rfdptr);
}
//-----------------------------------------------------------------------------
// Procedure: FreeSwRfd
//
// Description: this function unlinks the SwRfd structure, preparing it
// to be freed
//
// Arguments: adapter - the adapter structure
// rfd - a pointer to the SwRfd to operate on
//
// Returns: nothing but a modified rfd pointer
//
//-----------------------------------------------------------------------------
VOID
FreeSwRfd(D100_ADAPTER *adapter,
D100SwRfd *rfd)
{
DEBUGFUNC("FreeSwRfd");
INITSTR(("rfd %8lX, rfdphys=%8lX\n",rfd->Rfd,rfd->RfdPhys));
// unchain from packet and free the buffer back to the pool
NdisFreeBuffer(rfd->ReceiveBuffer);
// free the packet back to the pool
NdisFreePacket(rfd->ReceivePacket);
return;
}
//-----------------------------------------------------------------------------
// Procedure: FreeRMD
//
// Description: This function uninitializes a RMD and frees its memory
//
// Arguments: adapter - the adapter structure pointer
// rmd - the RMD to be operated upon
//
// Returns: nothing but a modified and uninitialized RMD pointer
//
//-----------------------------------------------------------------------------
VOID
FreeRMD(D100_ADAPTER *adapter,
ReceiveMemoryDescriptor *rmd)
{
DEBUGFUNC("FreeRMD");
TRACESTR(adapter, ("Freeing %d bytes ExtraRecvCached\n", rmd->CachedMem.Size));
// free the cached memory
NdisFreeMemory((PVOID) rmd->CachedMem.VirtualAddress, rmd->CachedMem.Size, 0);
rmd->CachedMem.VirtualAddress = (ULONG) PtrToUlong(NULL);
TRACESTR(adapter, ("Freeing %d bytes ExtraRecvUnCached\n", rmd->UnCachedMem.Size));
// Now free the shared memory that was used for the receive buffers.
NdisMFreeSharedMemory(
adapter->D100AdapterHandle,
rmd->UnCachedMem.Size,
FALSE,
(PVOID) rmd->UnCachedMem.VirtualAddress,
rmd->UnCachedMem.PhysicalAddress);
rmd->UnCachedMem.VirtualAddress = (ULONG) PtrToUlong(NULL);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -