2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS library
5 * PURPOSE: Memory management routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Vizzini (vizzini@plasmic.com)
9 * CSH 01/08-2000 Created
10 * 15 Aug 2003 Vizzini - DMA support
11 * 3 Oct 2003 Vizzini - formatting and minor bugfixing
22 NdisAllocateMemoryWithTag(
23 OUT PVOID
*VirtualAddress
,
27 * FUNCTION: Allocates a block of memory, with a 32-bit tag
29 * VirtualAddress = a pointer to the returned memory block
30 * Length = the number of requested bytes
31 * Tag = 32-bit pool tag
33 * NDIS_STATUS_SUCCESS on success
34 * NDIS_STATUS_FAILURE on failure
39 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
41 Block
= ExAllocatePoolWithTag(NonPagedPool
, Length
, Tag
);
42 *VirtualAddress
= Block
;
45 return NDIS_STATUS_FAILURE
;
47 return NDIS_STATUS_SUCCESS
;
58 OUT PVOID
*VirtualAddress
,
61 IN NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress
)
63 * FUNCTION: Allocates a block of memory
65 * VirtualAddress = Address of buffer to place virtual
66 * address of the allocated memory
67 * Length = Size of the memory block to allocate
68 * MemoryFlags = Flags to specify special restrictions
69 * HighestAcceptableAddress = Specifies -1
71 * NDIS_STATUS_SUCCESS on success
72 * NDIS_STATUS_FAILURE on failure
75 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
77 if (MemoryFlags
& NDIS_MEMORY_NONCACHED
)
79 *VirtualAddress
= MmAllocateNonCachedMemory(Length
);
81 return NDIS_STATUS_FAILURE
;
83 return NDIS_STATUS_SUCCESS
;
86 if (MemoryFlags
& NDIS_MEMORY_CONTIGUOUS
)
88 *VirtualAddress
= MmAllocateContiguousMemory(Length
, HighestAcceptableAddress
);
90 return NDIS_STATUS_FAILURE
;
92 return NDIS_STATUS_SUCCESS
;
95 /* Plain nonpaged memory */
96 *VirtualAddress
= ExAllocatePool(NonPagedPool
, Length
);
98 return NDIS_STATUS_FAILURE
;
100 return NDIS_STATUS_SUCCESS
;
110 IN PVOID VirtualAddress
,
114 * FUNCTION: Frees a memory block allocated with NdisAllocateMemory
116 * VirtualAddress = Pointer to the base virtual address of the allocated memory
117 * Length = Size of the allocated memory block as passed to NdisAllocateMemory
118 * MemoryFlags = Memory flags passed to NdisAllocateMemory
121 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
123 if (MemoryFlags
& NDIS_MEMORY_NONCACHED
)
125 MmFreeNonCachedMemory(VirtualAddress
, Length
);
129 if (MemoryFlags
& NDIS_MEMORY_CONTIGUOUS
)
131 MmFreeContiguousMemory(VirtualAddress
);
135 ExFreePool(VirtualAddress
);
144 NdisMAllocateSharedMemory(
145 IN NDIS_HANDLE MiniportAdapterHandle
,
148 OUT PVOID
*VirtualAddress
,
149 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress
)
151 * FUNCTION: Allocate a common buffer for DMA
153 * MiniportAdapterHandle: Handle passed into MiniportInitialize
154 * Length: Number of bytes to allocate
155 * Cached: Whether or not the memory can be cached
156 * VirtualAddress: Pointer to memory is returned here
157 * PhysicalAddress: Physical address corresponding to virtual address
159 * - Cached is ignored; we always allocate non-cached
162 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
164 NDIS_DbgPrint(MAX_TRACE
,("Called.\n"));
166 *VirtualAddress
= Adapter
->NdisMiniportBlock
.SystemAdapterObject
->DmaOperations
->AllocateCommonBuffer(
167 Adapter
->NdisMiniportBlock
.SystemAdapterObject
, Length
, PhysicalAddress
, Cached
);
173 NdisMFreeSharedMemoryPassive(
176 * FUNCTION: Free a common buffer
178 * Context: Pointer to a miniport shared memory context
180 * - Called by NdisMFreeSharedMemory to do the actual work
183 PMINIPORT_SHARED_MEMORY Memory
= (PMINIPORT_SHARED_MEMORY
)Context
;
184 PRKEVENT Event
= Memory
->Event
;
186 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
188 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL
);
190 Memory
->AdapterObject
->DmaOperations
->FreeCommonBuffer(
191 Memory
->AdapterObject
, Memory
->Length
, Memory
->PhysicalAddress
,
192 Memory
->VirtualAddress
, Memory
->Cached
);
207 NdisMFreeSharedMemory(
208 IN NDIS_HANDLE MiniportAdapterHandle
,
211 IN PVOID VirtualAddress
,
212 IN NDIS_PHYSICAL_ADDRESS PhysicalAddress
)
214 * FUNCTION: Free a shared memory block
216 * MiniportAdapterHandle: Handle passed into MiniportInitialize
217 * Length: Number of bytes in the block to free
218 * Cached: Whether or not the memory was cached
219 * VirtualAddress: Address to free
220 * PhysicalAddress: corresponding physical addres
222 * - This function can be called at dispatch_level or passive_level.
223 * Therefore we have to do this in a worker thread.
227 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
228 PMINIPORT_SHARED_MEMORY Memory
;
231 NDIS_DbgPrint(MAX_TRACE
,("Called.\n"));
233 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL
);
235 /* Must be NonpagedPool because by definition we're at DISPATCH_LEVEL */
236 Memory
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_SHARED_MEMORY
));
240 NDIS_DbgPrint(MID_TRACE
, ("Insufficient resources\n"));
244 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
246 Memory
->AdapterObject
= Adapter
->NdisMiniportBlock
.SystemAdapterObject
;
247 Memory
->Length
= Length
;
248 Memory
->PhysicalAddress
= PhysicalAddress
;
249 Memory
->VirtualAddress
= VirtualAddress
;
250 Memory
->Cached
= Cached
;
251 Memory
->Adapter
= &Adapter
->NdisMiniportBlock
;
252 Memory
->Event
= &Event
;
254 PsCreateSystemThread(&ThreadHandle
, THREAD_ALL_ACCESS
, 0, 0, 0, NdisMFreeSharedMemoryPassive
, Memory
);
255 ZwClose(ThreadHandle
);
257 KeWaitForSingleObject(&Event
,
266 NdisMAllocateSharedMemoryPassive(
269 * FUNCTION: Allocate a common buffer
271 * Context: Pointer to a miniport shared memory context
273 * - Called by NdisMAllocateSharedMemoryAsync to do the actual work
276 PMINIPORT_SHARED_MEMORY Memory
= (PMINIPORT_SHARED_MEMORY
)Context
;
278 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
280 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL
);
282 Memory
->VirtualAddress
= Memory
->AdapterObject
->DmaOperations
->AllocateCommonBuffer(
283 Memory
->AdapterObject
, Memory
->Length
, &Memory
->PhysicalAddress
, Memory
->Cached
);
285 if (Memory
->Adapter
->DriverHandle
->MiniportCharacteristics
.AllocateCompleteHandler
)
286 Memory
->Adapter
->DriverHandle
->MiniportCharacteristics
.AllocateCompleteHandler(
287 Memory
->Adapter
->MiniportAdapterContext
, Memory
->VirtualAddress
,
288 &Memory
->PhysicalAddress
, Memory
->Length
, Memory
->Context
);
299 NdisMAllocateSharedMemoryAsync(
300 IN NDIS_HANDLE MiniportAdapterHandle
,
306 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
307 PMINIPORT_SHARED_MEMORY Memory
;
309 NDIS_DbgPrint(MAX_TRACE
,("Called.\n"));
311 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL
);
313 /* Must be NonpagedPool because by definition we're at DISPATCH_LEVEL */
314 Memory
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_SHARED_MEMORY
));
318 NDIS_DbgPrint(MID_TRACE
, ("Insufficient resources\n"));
319 return NDIS_STATUS_FAILURE
;
322 Memory
->AdapterObject
= Adapter
->NdisMiniportBlock
.SystemAdapterObject
;
323 Memory
->Length
= Length
;
324 Memory
->Cached
= Cached
;
325 Memory
->Adapter
= &Adapter
->NdisMiniportBlock
;
326 Memory
->Context
= Context
;
328 PsCreateSystemThread(&ThreadHandle
, THREAD_ALL_ACCESS
, 0, 0, 0, NdisMAllocateSharedMemoryPassive
, Memory
);
329 ZwClose(ThreadHandle
);
331 return NDIS_STATUS_PENDING
;
339 NdisAllocateSharedMemory(
340 IN NDIS_HANDLE NdisAdapterHandle
,
343 OUT PVOID
*VirtualAddress
,
344 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress
)
346 NdisMAllocateSharedMemory(NdisAdapterHandle
,
359 NdisFreeSharedMemory(
360 IN NDIS_HANDLE NdisAdapterHandle
,
363 IN PVOID VirtualAddress
,
364 IN NDIS_PHYSICAL_ADDRESS PhysicalAddress
)
372 NdisMFreeSharedMemory(NdisAdapterHandle
,