ReactOS 0.4.15-dev-7934-g1dc8d80
memory.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS library
4 * FILE: ndis/memory.c
5 * PURPOSE: Memory management routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Vizzini (vizzini@plasmic.com)
8 * REVISIONS:
9 * CSH 01/08-2000 Created
10 * 15 Aug 2003 Vizzini - DMA support
11 * 3 Oct 2003 Vizzini - formatting and minor bugfixing
12 */
13
14#include "ndissys.h"
15
16/*
17 * @implemented
18 */
24 IN ULONG Tag)
25/*
26 * FUNCTION: Allocates a block of memory, with a 32-bit tag
27 * ARGUMENTS:
28 * VirtualAddress = a pointer to the returned memory block
29 * Length = the number of requested bytes
30 * Tag = 32-bit pool tag
31 * RETURNS:
32 * NDIS_STATUS_SUCCESS on success
33 * NDIS_STATUS_FAILURE on failure
34 */
35{
36 PVOID Block;
37
38 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
39
41 *VirtualAddress = Block;
42
43 if (!Block) {
44 NDIS_DbgPrint(MIN_TRACE, ("Failed to allocate memory (%lx)\n", Length));
46 }
47
49}
50
51
52/*
53 * @implemented
54 */
60 IN UINT MemoryFlags,
62/*
63 * FUNCTION: Allocates a block of memory
64 * ARGUMENTS:
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
70 * RETURNS:
71 * NDIS_STATUS_SUCCESS on success
72 * NDIS_STATUS_FAILURE on failure
73 */
74{
75 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
76
77 if (MemoryFlags & NDIS_MEMORY_CONTIGUOUS)
78 {
79 /* Allocate contiguous memory (possibly noncached) */
84 (MemoryFlags & NDIS_MEMORY_NONCACHED) ? MmNonCached : MmCached);
85 }
86 else if (MemoryFlags & NDIS_MEMORY_NONCACHED)
87 {
88 /* Allocate noncached noncontiguous memory */
90 }
91 else
92 {
93 /* Allocate plain nonpaged memory */
95 }
96
97 if (!*VirtualAddress) {
98 NDIS_DbgPrint(MIN_TRACE, ("Allocation failed (%lx, %lx)\n", MemoryFlags, Length));
100 }
101
102 return NDIS_STATUS_SUCCESS;
103}
104
105/*
106 * @implemented
107 */
108VOID
109EXPORT
112 IN UINT Length,
113 IN UINT MemoryFlags)
114/*
115 * FUNCTION: Frees a memory block allocated with NdisAllocateMemory
116 * ARGUMENTS:
117 * VirtualAddress = Pointer to the base virtual address of the allocated memory
118 * Length = Size of the allocated memory block as passed to NdisAllocateMemory
119 * MemoryFlags = Memory flags passed to NdisAllocateMemory
120 */
121{
122 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
123
124 if (MemoryFlags & NDIS_MEMORY_CONTIGUOUS)
125 {
126 /* Free contiguous memory (possibly noncached) */
128 Length,
129 (MemoryFlags & NDIS_MEMORY_NONCACHED) ? MmNonCached : MmCached);
130 }
131 else if (MemoryFlags & NDIS_MEMORY_NONCACHED)
132 {
133 /* Free noncached noncontiguous memory */
135 }
136 else
137 {
138 /* Free nonpaged pool */
140 }
141}
142
143/*
144 * @implemented
145 */
146VOID
147EXPORT
154/*
155 * FUNCTION: Allocate a common buffer for DMA
156 * ARGUMENTS:
157 * MiniportAdapterHandle: Handle passed into MiniportInitialize
158 * Length: Number of bytes to allocate
159 * Cached: Whether or not the memory can be cached
160 * VirtualAddress: Pointer to memory is returned here
161 * PhysicalAddress: Physical address corresponding to virtual address
162 * NOTES:
163 * - Cached is ignored; we always allocate non-cached
164 */
165{
167
168 NDIS_DbgPrint(MAX_TRACE,("Called.\n"));
169
171 {
172 KeBugCheckEx(BUGCODE_ID_DRIVER,
174 Length,
175 0,
176 1);
177 }
178
179 *VirtualAddress = Adapter->NdisMiniportBlock.SystemAdapterObject->DmaOperations->AllocateCommonBuffer(
180 Adapter->NdisMiniportBlock.SystemAdapterObject, Length, PhysicalAddress, Cached);
181}
182
183VOID
184NTAPI
188/*
189 * FUNCTION: Free a common buffer
190 * ARGUMENTS:
191 * Context: Pointer to a miniport shared memory context
192 * NOTES:
193 * - Called by NdisMFreeSharedMemory to do the actual work
194 */
195{
197
198 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
199
201
202 Memory->AdapterObject->DmaOperations->FreeCommonBuffer(
203 Memory->AdapterObject, Memory->Length, Memory->PhysicalAddress,
204 Memory->VirtualAddress, Memory->Cached);
205
206 IoFreeWorkItem(Memory->WorkItem);
208}
209
210/*
211 * @implemented
212 */
213VOID
214EXPORT
221/*
222 * FUNCTION: Free a shared memory block
223 * ARGUMENTS:
224 * MiniportAdapterHandle: Handle passed into MiniportInitialize
225 * Length: Number of bytes in the block to free
226 * Cached: Whether or not the memory was cached
227 * VirtualAddress: Address to free
228 * PhysicalAddress: corresponding physical addres
229 * NOTES:
230 * - This function can be called at dispatch_level or passive_level.
231 * Therefore we have to do this in a worker thread.
232 */
233{
236 PDMA_ADAPTER DmaAdapter = Adapter->NdisMiniportBlock.SystemAdapterObject;
237
238 NDIS_DbgPrint(MAX_TRACE,("Called.\n"));
239
241
242 /* Call FreeCommonBuffer synchronously if we are at PASSIVE_LEVEL */
244 {
245 /* We need this case because we free shared memory asynchronously
246 * and the miniport (and DMA adapter object) could be freed before
247 * our work item executes. Lucky for us, the scenarios where the
248 * freeing needs to be synchronous (failed init, MiniportHalt,
249 * and driver unload) are all at PASSIVE_LEVEL so we can just
250 * call FreeCommonBuffer synchronously and not have to worry
251 * about the miniport falling out from under us */
252
253 NDIS_DbgPrint(MID_TRACE,("Freeing shared memory synchronously\n"));
254
255 DmaAdapter->DmaOperations->FreeCommonBuffer(DmaAdapter,
256 Length,
259 Cached);
260 return;
261 }
262
263 /* Must be NonpagedPool because by definition we're at DISPATCH_LEVEL */
265
266 if(!Memory)
267 {
268 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
269 return;
270 }
271
272 Memory->AdapterObject = Adapter->NdisMiniportBlock.SystemAdapterObject;
273 Memory->Length = Length;
274 Memory->PhysicalAddress = PhysicalAddress;
275 Memory->VirtualAddress = VirtualAddress;
276 Memory->Cached = Cached;
277 Memory->Adapter = &Adapter->NdisMiniportBlock;
278
280 if (!Memory->WorkItem)
281 {
282 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
284 return;
285 }
286
287 IoQueueWorkItem(Memory->WorkItem,
290 Memory);
291}
292
293VOID
294NTAPI
298/*
299 * FUNCTION: Allocate a common buffer
300 * ARGUMENTS:
301 * Context: Pointer to a miniport shared memory context
302 * NOTES:
303 * - Called by NdisMAllocateSharedMemoryAsync to do the actual work
304 */
305{
307
308 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
309
311
312 Memory->VirtualAddress = Memory->AdapterObject->DmaOperations->AllocateCommonBuffer(
313 Memory->AdapterObject, Memory->Length, &Memory->PhysicalAddress, Memory->Cached);
314
315 if (Memory->Adapter->DriverHandle->MiniportCharacteristics.AllocateCompleteHandler)
316 Memory->Adapter->DriverHandle->MiniportCharacteristics.AllocateCompleteHandler(
317 Memory->Adapter->MiniportAdapterContext, Memory->VirtualAddress,
318 &Memory->PhysicalAddress, Memory->Length, Memory->Context);
319
320 IoFreeWorkItem(Memory->WorkItem);
322}
323
324
325/*
326 * @implemented
327 */
329EXPORT
335{
338
339 NDIS_DbgPrint(MAX_TRACE,("Called.\n"));
340
342
343 /* Must be NonpagedPool because by definition we're at DISPATCH_LEVEL */
345
346 if(!Memory)
347 {
348 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
349 return NDIS_STATUS_FAILURE;
350 }
351
352 Memory->AdapterObject = Adapter->NdisMiniportBlock.SystemAdapterObject;
353 Memory->Length = Length;
354 Memory->Cached = Cached;
355 Memory->Adapter = &Adapter->NdisMiniportBlock;
356 Memory->Context = Context;
357
359 if (!Memory->WorkItem)
360 {
361 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
363 return NDIS_STATUS_FAILURE;
364 }
365
366 IoQueueWorkItem(Memory->WorkItem,
369 Memory);
370
371 return NDIS_STATUS_PENDING;
372}
373
374/*
375 * @implemented
376 */
377VOID
378EXPORT
380 IN NDIS_HANDLE NdisAdapterHandle,
385{
386 NdisMAllocateSharedMemory(NdisAdapterHandle,
387 Length,
388 Cached,
391}
392
393
394/*
395 * @implemented
396 */
397VOID
398EXPORT
400 IN NDIS_HANDLE NdisAdapterHandle,
405/*
406 * FUNCTION:
407 * ARGUMENTS:
408 * NOTES:
409 * NDIS 4.0
410 */
411{
412 NdisMFreeSharedMemory(NdisAdapterHandle,
413 Length,
414 Cached,
417}
418
419
420/* EOF */
unsigned char BOOLEAN
#define MIN_TRACE
Definition: debug.h:14
#define MID_TRACE
Definition: debug.h:15
#define MAX_TRACE
Definition: debug.h:16
PVOID NTAPI MmAllocateContiguousMemorySpecifyCache(IN SIZE_T NumberOfBytes, IN PHYSICAL_ADDRESS LowestAcceptableAddress OPTIONAL, IN PHYSICAL_ADDRESS HighestAcceptableAddress, IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL, IN MEMORY_CACHING_TYPE CacheType OPTIONAL)
Definition: contmem.c:574
VOID NTAPI MmFreeContiguousMemorySpecifyCache(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: contmem.c:666
#define NDIS_DbgPrint(_t_, _x_)
Definition: debug.h:40
struct _LOGICAL_ADAPTER * PLOGICAL_ADAPTER
struct _MINIPORT_SHARED_MEMORY * PMINIPORT_SHARED_MEMORY
VOID EXPORT NdisFreeMemory(IN PVOID VirtualAddress, IN UINT Length, IN UINT MemoryFlags)
Definition: memory.c:110
VOID EXPORT NdisAllocateSharedMemory(IN NDIS_HANDLE NdisAdapterHandle, IN ULONG Length, IN BOOLEAN Cached, OUT PVOID *VirtualAddress, OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
Definition: memory.c:379
VOID NTAPI NdisMAllocateSharedMemoryPassive(PDEVICE_OBJECT DeviceObject, PVOID Context)
Definition: memory.c:295
NDIS_STATUS EXPORT NdisAllocateMemory(OUT PVOID *VirtualAddress, IN UINT Length, IN UINT MemoryFlags, IN NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress)
Definition: memory.c:57
VOID EXPORT NdisFreeSharedMemory(IN NDIS_HANDLE NdisAdapterHandle, IN ULONG Length, IN BOOLEAN Cached, IN PVOID VirtualAddress, IN NDIS_PHYSICAL_ADDRESS PhysicalAddress)
Definition: memory.c:399
VOID NTAPI NdisMFreeSharedMemoryPassive(PDEVICE_OBJECT DeviceObject, PVOID Context)
Definition: memory.c:185
NDIS_STATUS EXPORT NdisAllocateMemoryWithTag(OUT PVOID *VirtualAddress, IN UINT Length, IN ULONG Tag)
Definition: memory.c:21
VOID EXPORT NdisMAllocateSharedMemory(IN NDIS_HANDLE MiniportAdapterHandle, IN ULONG Length, IN BOOLEAN Cached, OUT PVOID *VirtualAddress, OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
Definition: memory.c:148
NDIS_STATUS EXPORT NdisMAllocateSharedMemoryAsync(IN NDIS_HANDLE MiniportAdapterHandle, IN ULONG Length, IN BOOLEAN Cached, IN PVOID Context)
Definition: memory.c:330
VOID EXPORT NdisMFreeSharedMemory(IN NDIS_HANDLE MiniportAdapterHandle, IN ULONG Length, IN BOOLEAN Cached, IN PVOID VirtualAddress, IN NDIS_PHYSICAL_ADDRESS PhysicalAddress)
Definition: memory.c:215
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
NTSYSAPI ULONGLONG WINAPI RtlConvertUlongToLargeInteger(ULONG)
Definition: largeint.c:47
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
#define ASSERT(a)
Definition: mode.c:44
VOID NTAPI MmFreeNonCachedMemory(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: ncache.c:172
PVOID NTAPI MmAllocateNonCachedMemory(IN SIZE_T NumberOfBytes)
Definition: ncache.c:25
#define NDIS_MEMORY_CONTIGUOUS
Definition: ndis.h:579
#define NDIS_STATUS_PENDING
Definition: ndis.h:347
#define NDIS_MEMORY_NONCACHED
Definition: ndis.h:580
unsigned int UINT
Definition: ndis.h:50
#define NDIS_STATUS_FAILURE
Definition: ndis.h:465
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
_In_ ULONG _In_ BOOLEAN Cached
Definition: ndis.h:3789
_In_ NDIS_HANDLE MiniportAdapterHandle
Definition: ndis.h:4668
_Out_ PNDIS_HANDLE _Out_ PUINT _In_ PNDIS_STRING _In_ NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress
Definition: ndis.h:3230
int NDIS_STATUS
Definition: ntddndis.h:475
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
struct _DMA_OPERATIONS * DmaOperations
Definition: iotypes.h:2295
NDIS_MINIPORT_BLOCK NdisMiniportBlock
Definition: miniport.h:89
PDEVICE_OBJECT DeviceObject
Definition: ndis.h:2552
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4065
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG _In_ _Out_ WDFMEMORY * Memory
Definition: wdfmemory.h:169
@ DelayedWorkQueue
Definition: extypes.h:190
@ CriticalWorkQueue
Definition: extypes.h:189
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098
@ MmCached
Definition: mmtypes.h:130
@ MmNonCached
Definition: mmtypes.h:129