2020-09-30 17:12:29 +02:00

1138 lines
26 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1990-1992 Microsoft Corporation
Module Name:
alloc.c
Abstract:
This file contains the code for allocating and freeing adapter
resources for the National Semiconductor SONIC Ethernet controller.
This driver conforms to the NDIS 3.0 miniport interface.
Author:
Adam Barr (adamba) 14-Nov-1990
Environment:
Kernel Mode - Or whatever is the equivalent.
Revision History:
--*/
#include <ndis.h>
#include <sonichrd.h>
#include <sonicsft.h>
STATIC
PNDIS_BUFFER
AllocateFlushBuffer(
IN PSONIC_ADAPTER Adapter,
IN PVOID VirtualAddress,
IN ULONG Length
);
#pragma NDIS_INIT_FUNCTION(AllocateFlushBuffer)
STATIC
PNDIS_BUFFER
AllocateFlushBuffer(
IN PSONIC_ADAPTER Adapter,
IN PVOID VirtualAddress,
IN ULONG Length
)
/*++
Routine Description:
Allocates an NDIS_BUFFER for the specified address and length.
This function is intended to create NDIS_BUFFERs for flushing.
Arguments:
Adapter - The adapter the buffer is for. It must have a
FlushBufferPoolHandle that points to a valid buffer pool.
VirtualAddress - A pointer to the buffer to describe.
Length - The length of the buffer.
Return Value:
The NDIS_BUFFER if one was allocated.
NULL if an NDIS_BUFFER could not be allocated.
--*/
{
PNDIS_BUFFER ReturnBuffer;
NDIS_STATUS Status;
NdisAllocateBuffer(
&Status,
&ReturnBuffer,
Adapter->FlushBufferPoolHandle,
VirtualAddress,
Length
);
if (Status != NDIS_STATUS_SUCCESS) {
#if DBG
DbgPrint("SONIC: Could not allocate flush buffer, %x\n", Status);
#endif
ReturnBuffer = (PNDIS_BUFFER)NULL;
}
return ReturnBuffer;
}
#pragma NDIS_INIT_FUNCTION(AllocateAdapterMemory)
extern
BOOLEAN
AllocateAdapterMemory(
IN PSONIC_ADAPTER Adapter
)
/*++
Routine Description:
This routine allocates memory for:
- Transmit ring entries
- Receive ring entries
- Receive buffers
- Adapter buffers for use if user transmit buffers don't meet hardware
contraints
- Structures to map transmit ring entries back to the packets.
Arguments:
Adapter - The adapter to allocate memory for.
Return Value:
Returns FALSE if some memory needed for the adapter could not
be allocated. It does NOT call DeleteAdapterMemory in this
case.
--*/
{
//
// Pointer to a transmit ring entry. Used while initializing
// the TDA.
//
PSONIC_TRANSMIT_DESCRIPTOR CurrentTransmitDescriptor;
//
// Pointer to a receive buffer. Used while allocated the
// RBAs.
//
PVOID * CurrentReceiveBuffer;
//
// Pointer to a receive descriptor. Used while initialing
// the RDA.
//
PSONIC_RECEIVE_DESCRIPTOR CurrentReceiveDescriptor;
//
// Used for determining physical addresses.
//
SONIC_PHYSICAL_ADDRESS SonicPhysicalAdr;
//
// Used for NDIS allocation routines that return an NDIS_PHYSICAL_ADDRESS
//
NDIS_PHYSICAL_ADDRESS NdisPhysicalAdr;
//
// Simple iteration variable.
//
UINT i;
//
// Used to flush buffers that only need to be flushed once.
//
PNDIS_BUFFER FlushBuffer;
//
// The size of the buffer pool needed.
//
UINT PoolBuffersNeeded;
//
// Holds the result of calls to SONIC_ALLOC_MEMORY
//
NDIS_STATUS AllocStatus;
//
// We need some NDIS_BUFFERs to describe memory that we
// allocate (generally either to flush the buffer, or
// because we need its physical address). To do this
// we need a buffer pool, so we have to determine how
// many buffers we need.
//
PoolBuffersNeeded =
1 + // for CamDescriptorArea
1 + // for ReceiveResourceArea
1 + // for BlankBuffer
Adapter->NumberOfReceiveBuffers + // for flushing cached receive buffers.
SONIC_NUMBER_OF_SMALL_BUFFERS +
SONIC_NUMBER_OF_MEDIUM_BUFFERS +
SONIC_NUMBER_OF_LARGE_BUFFERS ;
NdisAllocateBufferPool(
&AllocStatus,
&Adapter->FlushBufferPoolHandle,
PoolBuffersNeeded
);
if (AllocStatus != NDIS_STATUS_SUCCESS) {
#if DBG
DbgPrint("SONIC: Could not allocate flush buffer pool\n");
#endif
return FALSE;
}
//
// Allocate the transmit ring descriptors.
//
NdisMAllocateSharedMemory(
Adapter->MiniportAdapterHandle,
sizeof(SONIC_TRANSMIT_DESCRIPTOR)*
Adapter->NumberOfTransmitDescriptors,
FALSE, // non-cached
(PVOID *)&Adapter->TransmitDescriptorArea,
&Adapter->TransmitDescriptorAreaPhysical
);
if (Adapter->TransmitDescriptorArea == NULL) {
#if DBG
DbgPrint("SONIC: TransmitDescriptorArea memory invalid\n");
#endif
return FALSE;
}
if (NdisGetPhysicalAddressHigh(Adapter->TransmitDescriptorAreaPhysical) != 0) {
#if DBG
DbgPrint("SONIC: TransmitDescriptorArea memory too high\n");
#endif
return FALSE;
}
//
// Clean the above memory
//
SONIC_ZERO_MEMORY(
Adapter->TransmitDescriptorArea,
(sizeof(SONIC_TRANSMIT_DESCRIPTOR)*Adapter->NumberOfTransmitDescriptors)
);
//
// We have the transmit ring descriptors. Initialize the Link
// fields.
//
for (
i = 0, CurrentTransmitDescriptor = Adapter->TransmitDescriptorArea;
i < Adapter->NumberOfTransmitDescriptors;
i++,CurrentTransmitDescriptor++
) {
SonicPhysicalAdr = NdisGetPhysicalAddressLow(Adapter->TransmitDescriptorAreaPhysical) +
(i * sizeof(SONIC_TRANSMIT_DESCRIPTOR));
if (i == 0) {
Adapter->TransmitDescriptorArea[Adapter->NumberOfTransmitDescriptors-1].Link = SonicPhysicalAdr;
} else {
(CurrentTransmitDescriptor-1)->Link = SonicPhysicalAdr;
}
}
//
// Allocate the ring to packet structure.
//
SONIC_ALLOC_MEMORY(
&AllocStatus,
&Adapter->DescriptorToPacket,
sizeof(SONIC_DESCRIPTOR_TO_PACKET)
*Adapter->NumberOfTransmitDescriptors
);
if (AllocStatus != NDIS_STATUS_SUCCESS) {
return FALSE;
}
//
// We have to do this now. The PrevLinkPointer field is used
// to point to where the Link field of the previous transmit
// descriptor is; it is normally set when the previous
// transmit descriptor is filled. For the very first packet
// transmitted there will have been no previous transmit
// descriptor, so we fill it in ourselves. We use the
// Link field of the last transmit descriptor (the actual
// location used doesn't really matter, as long as it is
// a valid address).
//
Adapter->DescriptorToPacket->PrevLinkPointer =
&(Adapter->TransmitDescriptorArea[
Adapter->NumberOfTransmitDescriptors-1].Link);
//
// Allocate the receive resource area and the
// CAM descriptor area. These are allocated together
// since they must have the same high 16 bits in
// their addresses.
//
NdisMAllocateSharedMemory(
Adapter->MiniportAdapterHandle,
(sizeof(SONIC_RECEIVE_RESOURCE)*Adapter->NumberOfReceiveBuffers) +
sizeof(SONIC_CAM_DESCRIPTOR_AREA),
TRUE, // CACHED!
(PVOID *)&Adapter->ReceiveResourceArea,
&Adapter->ReceiveResourceAreaPhysical
);
if (Adapter->ReceiveResourceArea == NULL) {
#if DBG
DbgPrint("SONIC: ReceiveResourceArea memory invalid\n");
#endif
return FALSE;
}
if (NdisGetPhysicalAddressHigh(Adapter->ReceiveResourceAreaPhysical) != 0) {
#if DBG
DbgPrint("SONIC: ReceiveResourceArea memory too high\n");
#endif
return FALSE;
}
//
// The CAM Descriptor Area is immediately after the RRA.
//
Adapter->CamDescriptorArea = (PSONIC_CAM_DESCRIPTOR_AREA)
(Adapter->ReceiveResourceArea + Adapter->NumberOfReceiveBuffers);
Adapter->CamDescriptorAreaPhysical =
NdisGetPhysicalAddressLow(Adapter->ReceiveResourceAreaPhysical) +
((PUCHAR)Adapter->CamDescriptorArea -
(PUCHAR)Adapter->ReceiveResourceArea);
//
// Allocate the NDIS_BUFFER to flush the CAM Descriptor Area.
//
Adapter->CamDescriptorAreaFlushBuffer = AllocateFlushBuffer(
Adapter,
Adapter->CamDescriptorArea,
sizeof(SONIC_CAM_DESCRIPTOR_AREA)
);
if (!Adapter->CamDescriptorAreaFlushBuffer) {
return FALSE;
}
SONIC_ZERO_MEMORY(
Adapter->CamDescriptorArea,
sizeof(SONIC_CAM_DESCRIPTOR_AREA)
);
SONIC_FLUSH_WRITE_BUFFER(Adapter->CamDescriptorAreaFlushBuffer);
#if DBG
if (SonicDbg) {
DbgPrint("SONIC: Cam Descriptor Area: %lx physical: %lx\n",
Adapter->CamDescriptorArea,
Adapter->CamDescriptorAreaPhysical);
}
#endif
//
// Allocate the array to hold pointers to the RBAs.
//
SONIC_ALLOC_MEMORY(
&AllocStatus,
&Adapter->ReceiveBufferArea,
sizeof(PVOID) * Adapter->NumberOfReceiveBuffers
);
if (AllocStatus != NDIS_STATUS_SUCCESS) {
return FALSE;
}
//
// Allocate the array to hold pointers to the receive ndis
// (flush) buffers.
//
SONIC_ALLOC_MEMORY(
&AllocStatus,
&Adapter->ReceiveNdisBufferArea,
sizeof(PNDIS_BUFFER) * Adapter->NumberOfReceiveBuffers
);
if (AllocStatus != NDIS_STATUS_SUCCESS) {
return FALSE;
}
#if DBG
if (SonicDbg) {
DbgPrint("SONIC: Receive Buffer Area: %lx\n",
(ULONG)Adapter->ReceiveBufferArea);
}
#endif
//
// We have the receive buffer pointers. Allocate the buffer
// for each entry and zero them.
//
// For each receive buffer, the Physical address and length
// will be in Adapter->ReceiveResourceArea[i], while the
// virtual address will be in Adapter->ReceiveBufferArea[i].
//
for (
i = 0, CurrentReceiveBuffer = Adapter->ReceiveBufferArea;
i < Adapter->NumberOfReceiveBuffers;
i++,CurrentReceiveBuffer++
) {
//
// Allocate the next [cached] receive buffer.
//
NdisMAllocateSharedMemory(
Adapter->MiniportAdapterHandle,
SONIC_SIZE_OF_RECEIVE_BUFFERS,
TRUE, // CACHED!
CurrentReceiveBuffer,
&NdisPhysicalAdr
);
//
// Did the allocation fail?
//
if ( *CurrentReceiveBuffer == NULL ) {
return FALSE;
}
if ( NdisGetPhysicalAddressHigh(NdisPhysicalAdr) != 0) {
return FALSE;
}
//
// Zero the [cached] receive buffer.
//
SONIC_ZERO_MEMORY(
*CurrentReceiveBuffer,
SONIC_SIZE_OF_RECEIVE_BUFFERS
);
//
// Allocate an NDIS_BUFFER for this receive buffer.
//
Adapter->ReceiveNdisBufferArea[i] = AllocateFlushBuffer(
Adapter,
*CurrentReceiveBuffer,
SONIC_SIZE_OF_RECEIVE_BUFFERS
);
if ( Adapter->ReceiveNdisBufferArea[i] == NULL ) {
return FALSE;
}
SONIC_SET_RECEIVE_RESOURCE_ADDRESS(
&Adapter->ReceiveResourceArea[i],
NdisGetPhysicalAddressLow(NdisPhysicalAdr)
);
SONIC_SET_RECEIVE_RESOURCE_LENGTH(
&Adapter->ReceiveResourceArea[i],
SONIC_SIZE_OF_RECEIVE_BUFFERS
);
}
//
// The Receive Resource Area is set up, we can flush
// it now since it does not change.
//
FlushBuffer = AllocateFlushBuffer(
Adapter,
(PVOID)Adapter->ReceiveResourceArea,
(sizeof(SONIC_RECEIVE_RESOURCE)*Adapter->NumberOfReceiveBuffers)
);
if (!FlushBuffer) {
return FALSE;
}
SONIC_FLUSH_WRITE_BUFFER(FlushBuffer);
NdisFreeBuffer(FlushBuffer);
//
// Allocate memory to hold the receive descriptor pointers.
//
NdisMAllocateSharedMemory(
Adapter->MiniportAdapterHandle,
sizeof(SONIC_RECEIVE_DESCRIPTOR) * Adapter->NumberOfReceiveDescriptors,
FALSE, // NON-CACHED!
(PVOID *)&Adapter->ReceiveDescriptorArea,
&Adapter->ReceiveDescriptorAreaPhysical
);
if (Adapter->ReceiveDescriptorArea == NULL) {
#if DBG
DbgPrint("SONIC: ReceiveDescriptorArea memory invalid\n");
#endif
return FALSE;
}
if (NdisGetPhysicalAddressHigh(Adapter->ReceiveDescriptorAreaPhysical) != 0) {
#if DBG
DbgPrint("SONIC: ReceiveDescriptorArea memory too high\n");
#endif
return FALSE;
}
//
// Clean the above memory
//
SONIC_ZERO_MEMORY(
Adapter->ReceiveDescriptorArea,
(sizeof(SONIC_RECEIVE_DESCRIPTOR)*Adapter->NumberOfReceiveDescriptors)
);
//
// Now set up the Link fields in the receive descriptors.
//
for (
i = 0, CurrentReceiveDescriptor = Adapter->ReceiveDescriptorArea;
i < Adapter->NumberOfReceiveDescriptors;
i++,CurrentReceiveDescriptor++
) {
//
// belongs to SONIC.
//
CurrentReceiveDescriptor->InUse = SONIC_OWNED_BY_SONIC;
SonicPhysicalAdr = NdisGetPhysicalAddressLow(Adapter->ReceiveDescriptorAreaPhysical) +
(i * sizeof(SONIC_RECEIVE_DESCRIPTOR));
if (i == 0) {
Adapter->ReceiveDescriptorArea[
Adapter->NumberOfReceiveDescriptors-1].Link =
SonicPhysicalAdr | SONIC_END_OF_LIST;
} else {
Adapter->ReceiveDescriptorArea[i-1].Link = SonicPhysicalAdr;
}
}
//
// Allocate the array of buffer descriptors.
//
SONIC_ALLOC_MEMORY(
&AllocStatus,
&Adapter->SonicBuffers,
sizeof(SONIC_BUFFER_DESCRIPTOR)*
(SONIC_NUMBER_OF_SMALL_BUFFERS +
SONIC_NUMBER_OF_MEDIUM_BUFFERS +
SONIC_NUMBER_OF_LARGE_BUFFERS)
);
if (AllocStatus != NDIS_STATUS_SUCCESS) {
return FALSE;
}
//
// Zero the memory of all the descriptors so that we can
// know which buffers wern't allocated incase we can't allocate
// them all.
//
SONIC_ZERO_MEMORY(
Adapter->SonicBuffers,
sizeof(SONIC_BUFFER_DESCRIPTOR)*
(SONIC_NUMBER_OF_SMALL_BUFFERS +
SONIC_NUMBER_OF_MEDIUM_BUFFERS +
SONIC_NUMBER_OF_LARGE_BUFFERS)
);
//
// Allocate space for the small sonic buffers and fill in the
// buffer descriptors.
//
Adapter->SonicBufferListHeads[0] = -1;
Adapter->SonicBufferListHeads[1] = 0;
NdisMAllocateSharedMemory(
Adapter->MiniportAdapterHandle,
SONIC_SMALL_BUFFER_SIZE * SONIC_NUMBER_OF_SMALL_BUFFERS,
TRUE, // CACHED!
&Adapter->SmallSonicBuffers,
&NdisPhysicalAdr
);
if (NdisGetPhysicalAddressHigh(NdisPhysicalAdr) != 0) {
return FALSE;
}
if ( Adapter->SmallSonicBuffers == NULL ) {
return FALSE;
}
for (
i = 0;
i < SONIC_NUMBER_OF_SMALL_BUFFERS;
i++
) {
Adapter->SonicBuffers[i].VirtualSonicBuffer = (PVOID)
((PUCHAR)Adapter->SmallSonicBuffers +
(i * SONIC_SMALL_BUFFER_SIZE));
NdisSetPhysicalAddressHigh(
Adapter->SonicBuffers[i].PhysicalSonicBuffer,
0);
NdisSetPhysicalAddressLow(
Adapter->SonicBuffers[i].PhysicalSonicBuffer,
NdisGetPhysicalAddressLow(NdisPhysicalAdr) +
(i * SONIC_SMALL_BUFFER_SIZE));
Adapter->SonicBuffers[i].FlushBuffer =
AllocateFlushBuffer(
Adapter,
Adapter->SonicBuffers[i].VirtualSonicBuffer,
SONIC_SMALL_BUFFER_SIZE
);
if (!Adapter->SonicBuffers[i].FlushBuffer) {
return FALSE;
}
Adapter->SonicBuffers[i].Next = i+1;
}
//
// Make sure that the last buffer correctly terminates the free list.
//
Adapter->SonicBuffers[i-1].Next = -1;
//
// Do the medium buffers now.
//
Adapter->SonicBufferListHeads[2] = i;
NdisMAllocateSharedMemory(
Adapter->MiniportAdapterHandle,
SONIC_MEDIUM_BUFFER_SIZE * SONIC_NUMBER_OF_MEDIUM_BUFFERS,
TRUE, // CACHED!
&Adapter->MediumSonicBuffers,
&NdisPhysicalAdr
);
if (Adapter->MediumSonicBuffers == NULL) {
return FALSE;
}
if (NdisGetPhysicalAddressHigh(NdisPhysicalAdr) != 0) {
return FALSE;
}
for (
;
i < SONIC_NUMBER_OF_SMALL_BUFFERS + SONIC_NUMBER_OF_MEDIUM_BUFFERS;
i++
) {
Adapter->SonicBuffers[i].VirtualSonicBuffer = (PVOID)
((PUCHAR)Adapter->MediumSonicBuffers +
((i - SONIC_NUMBER_OF_SMALL_BUFFERS) * SONIC_MEDIUM_BUFFER_SIZE));
NdisSetPhysicalAddressHigh(
Adapter->SonicBuffers[i].PhysicalSonicBuffer,
0);
NdisSetPhysicalAddressLow(
Adapter->SonicBuffers[i].PhysicalSonicBuffer,
NdisGetPhysicalAddressLow(NdisPhysicalAdr) +
((i - SONIC_NUMBER_OF_SMALL_BUFFERS) * SONIC_MEDIUM_BUFFER_SIZE));
Adapter->SonicBuffers[i].FlushBuffer =
AllocateFlushBuffer(
Adapter,
Adapter->SonicBuffers[i].VirtualSonicBuffer,
SONIC_MEDIUM_BUFFER_SIZE
);
if (!Adapter->SonicBuffers[i].FlushBuffer) {
return FALSE;
}
Adapter->SonicBuffers[i].Next = i+1;
}
//
// Make sure that the last buffer correctly terminates the free list.
//
Adapter->SonicBuffers[i-1].Next = -1;
//
// Now do the large buffers; note that they have one
// Physical address per buffer.
//
Adapter->SonicBufferListHeads[3] = i;
for (
;
i < SONIC_NUMBER_OF_SMALL_BUFFERS +
SONIC_NUMBER_OF_MEDIUM_BUFFERS +
SONIC_NUMBER_OF_LARGE_BUFFERS;
i++
) {
NdisMAllocateSharedMemory(
Adapter->MiniportAdapterHandle,
SONIC_LARGE_BUFFER_SIZE,
TRUE, // CACHED!
(PVOID *)&Adapter->SonicBuffers[i].VirtualSonicBuffer,
&Adapter->SonicBuffers[i].PhysicalSonicBuffer
);
if (Adapter->SonicBuffers[i].VirtualSonicBuffer == NULL) {
return FALSE;
}
if (NdisGetPhysicalAddressHigh(Adapter->SonicBuffers[i].PhysicalSonicBuffer) != 0) {
return FALSE;
}
Adapter->SonicBuffers[i].FlushBuffer =
AllocateFlushBuffer(
Adapter,
Adapter->SonicBuffers[i].VirtualSonicBuffer,
SONIC_LARGE_BUFFER_SIZE
);
if (!Adapter->SonicBuffers[i].FlushBuffer) {
return FALSE;
}
Adapter->SonicBuffers[i].Next = i+1;
}
//
// Make sure that the last buffer correctly terminates the free list.
//
Adapter->SonicBuffers[i-1].Next = -1;
//
// Allocate the BlankBuffer
//
NdisMAllocateSharedMemory(
Adapter->MiniportAdapterHandle,
SONIC_SMALL_BUFFER_SIZE,
TRUE, // CACHED!
(PVOID *)&Adapter->BlankBuffer,
&Adapter->BlankBufferAddress
);
if (Adapter->BlankBuffer == NULL) {
return FALSE;
}
if (NdisGetPhysicalAddressHigh(Adapter->BlankBufferAddress) != 0) {
return FALSE;
}
for (i=0; i < SONIC_SMALL_BUFFER_SIZE; i++) {
Adapter->BlankBuffer[i] = ' ';
}
//
// Flush the blank buffer now, it never changes.
//
FlushBuffer = AllocateFlushBuffer(
Adapter,
Adapter->BlankBuffer,
SONIC_SMALL_BUFFER_SIZE
);
if (!FlushBuffer) {
return FALSE;
}
SONIC_FLUSH_WRITE_BUFFER(FlushBuffer);
//
// We are done with the FlushBuffer.
//
NdisFreeBuffer(FlushBuffer);
return TRUE;
}
extern
VOID
DeleteAdapterMemory(
IN PSONIC_ADAPTER Adapter
)
/*++
Routine Description:
This routine deallocates memory for:
- Transmit ring entries
- Receive ring entries
- Receive buffers
- Adapter buffers for use if user transmit buffers don't meet hardware
contraints
- Structures to map transmit ring entries back to the packets.
Arguments:
Adapter - The adapter to deallocate memory for.
Return Value:
None.
--*/
{
if (Adapter->TransmitDescriptorArea) {
NdisMFreeSharedMemory(
Adapter->MiniportAdapterHandle,
sizeof(SONIC_TRANSMIT_DESCRIPTOR)*
Adapter->NumberOfTransmitDescriptors,
FALSE,
Adapter->TransmitDescriptorArea,
Adapter->TransmitDescriptorAreaPhysical
);
}
if (Adapter->CamDescriptorAreaFlushBuffer) {
NdisFreeBuffer(Adapter->CamDescriptorAreaFlushBuffer);
}
if (Adapter->ReceiveBufferArea) {
UINT i;
NDIS_PHYSICAL_ADDRESS PhysicalAddr;
for (
i = 0;
i < Adapter->NumberOfReceiveBuffers;
i++
) {
//
// Free the receive flush buffer.
//
if ( Adapter->ReceiveNdisBufferArea[i] != NULL ) {
NdisFreeBuffer(Adapter->ReceiveNdisBufferArea[i]);
}
//
// Free the receive buffer.
//
if ( Adapter->ReceiveBufferArea[i] != NULL ) {
NdisSetPhysicalAddressHigh(PhysicalAddr, 0);
NdisSetPhysicalAddressLow(
PhysicalAddr,
SONIC_GET_RECEIVE_RESOURCE_ADDRESS(&Adapter->ReceiveResourceArea[i]));
NdisMFreeSharedMemory(
Adapter->MiniportAdapterHandle,
SONIC_SIZE_OF_RECEIVE_BUFFERS,
TRUE, //... CACHED!
Adapter->ReceiveBufferArea[i],
PhysicalAddr
);
}
}
SONIC_FREE_MEMORY(
Adapter->ReceiveBufferArea,
sizeof(PVOID) * Adapter->NumberOfReceiveBuffers
);
SONIC_FREE_MEMORY(
Adapter->ReceiveNdisBufferArea,
sizeof(PNDIS_BUFFER) * Adapter->NumberOfReceiveBuffers
);
}
if (Adapter->ReceiveResourceArea) {
NdisMFreeSharedMemory(
Adapter->MiniportAdapterHandle,
(sizeof(SONIC_RECEIVE_RESOURCE)*Adapter->NumberOfReceiveBuffers) +
sizeof(SONIC_CAM_DESCRIPTOR_AREA),
TRUE,
Adapter->ReceiveResourceArea,
Adapter->ReceiveResourceAreaPhysical
);
}
if (Adapter->ReceiveDescriptorArea) {
NdisMFreeSharedMemory(
Adapter->MiniportAdapterHandle,
sizeof(SONIC_RECEIVE_DESCRIPTOR) *
Adapter->NumberOfReceiveDescriptors,
FALSE,
Adapter->ReceiveDescriptorArea,
Adapter->ReceiveDescriptorAreaPhysical
);
}
if (Adapter->DescriptorToPacket) {
SONIC_FREE_MEMORY(Adapter->DescriptorToPacket,
sizeof(SONIC_DESCRIPTOR_TO_PACKET)
*Adapter->NumberOfTransmitDescriptors);
}
if (Adapter->SmallSonicBuffers) {
NdisMFreeSharedMemory(
Adapter->MiniportAdapterHandle,
SONIC_SMALL_BUFFER_SIZE * SONIC_NUMBER_OF_SMALL_BUFFERS,
TRUE,
Adapter->SmallSonicBuffers,
Adapter->SonicBuffers[0].PhysicalSonicBuffer
);
}
if (Adapter->MediumSonicBuffers) {
NdisMFreeSharedMemory(
Adapter->MiniportAdapterHandle,
SONIC_MEDIUM_BUFFER_SIZE * SONIC_NUMBER_OF_MEDIUM_BUFFERS,
TRUE,
Adapter->MediumSonicBuffers,
Adapter->SonicBuffers[SONIC_NUMBER_OF_SMALL_BUFFERS].PhysicalSonicBuffer
);
}
if (Adapter->SonicBuffers) {
UINT i;
//
// First free the large buffers.
//
for (
i = SONIC_NUMBER_OF_SMALL_BUFFERS +
SONIC_NUMBER_OF_MEDIUM_BUFFERS;
i < SONIC_NUMBER_OF_SMALL_BUFFERS +
SONIC_NUMBER_OF_MEDIUM_BUFFERS +
SONIC_NUMBER_OF_LARGE_BUFFERS;
i++) {
if (Adapter->SonicBuffers[i].VirtualSonicBuffer) {
NdisMFreeSharedMemory(
Adapter->MiniportAdapterHandle,
SONIC_LARGE_BUFFER_SIZE,
TRUE,
Adapter->SonicBuffers[i].VirtualSonicBuffer,
Adapter->SonicBuffers[i].PhysicalSonicBuffer
);
} else {
break;
}
}
//
// Now free the flush buffers.
//
for (
i = 0;
i < SONIC_NUMBER_OF_SMALL_BUFFERS +
SONIC_NUMBER_OF_MEDIUM_BUFFERS +
SONIC_NUMBER_OF_LARGE_BUFFERS;
i++) {
if (Adapter->SonicBuffers[i].FlushBuffer) {
NdisFreeBuffer(Adapter->SonicBuffers[i].FlushBuffer);
}
}
SONIC_FREE_MEMORY(Adapter->SonicBuffers,
sizeof(SONIC_BUFFER_DESCRIPTOR)*
(SONIC_NUMBER_OF_SMALL_BUFFERS +
SONIC_NUMBER_OF_MEDIUM_BUFFERS +
SONIC_NUMBER_OF_LARGE_BUFFERS)
);
}
if (Adapter->BlankBuffer) {
NdisMFreeSharedMemory(
Adapter->MiniportAdapterHandle,
SONIC_SMALL_BUFFER_SIZE,
TRUE,
Adapter->BlankBuffer,
Adapter->BlankBufferAddress
);
}
if (Adapter->FlushBufferPoolHandle) {
NdisFreeBufferPool(Adapter->FlushBufferPoolHandle);
}
}