mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1137 lines
26 KiB
1137 lines
26 KiB
/*++
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|