ReactOS 0.4.16-dev-2491-g3dc6630
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) */
82 ZeroAddress,
84 ZeroAddress,
85 (MemoryFlags & NDIS_MEMORY_NONCACHED) ? MmNonCached : MmCached);
86 }
87 else if (MemoryFlags & NDIS_MEMORY_NONCACHED)
88 {
89 /* Allocate noncached noncontiguous memory */
91 }
92 else
93 {
94 /* Allocate plain nonpaged memory */
96 }
97
98 if (!*VirtualAddress) {
99 NDIS_DbgPrint(MIN_TRACE, ("Allocation failed (%lx, %lx)\n", MemoryFlags, Length));
100 return NDIS_STATUS_FAILURE;
101 }
102
103 return NDIS_STATUS_SUCCESS;
104}
105
106/*
107 * @implemented
108 */
109VOID
110EXPORT
113 IN UINT Length,
114 IN UINT MemoryFlags)
115/*
116 * FUNCTION: Frees a memory block allocated with NdisAllocateMemory
117 * ARGUMENTS:
118 * VirtualAddress = Pointer to the base virtual address of the allocated memory
119 * Length = Size of the allocated memory block as passed to NdisAllocateMemory
120 * MemoryFlags = Memory flags passed to NdisAllocateMemory
121 */
122{
123 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
124
125 if (MemoryFlags & NDIS_MEMORY_CONTIGUOUS)
126 {
127 /* Free contiguous memory (possibly noncached) */
129 Length,
130 (MemoryFlags & NDIS_MEMORY_NONCACHED) ? MmNonCached : MmCached);
131 }
132 else if (MemoryFlags & NDIS_MEMORY_NONCACHED)
133 {
134 /* Free noncached noncontiguous memory */
136 }
137 else
138 {
139 /* Free nonpaged pool */
141 }
142}
143
144/*
145 * @implemented
146 */
147VOID
148EXPORT
155/*
156 * FUNCTION: Allocate a common buffer for DMA
157 * ARGUMENTS:
158 * MiniportAdapterHandle: Handle passed into MiniportInitialize
159 * Length: Number of bytes to allocate
160 * Cached: Whether or not the memory can be cached
161 * VirtualAddress: Pointer to memory is returned here
162 * PhysicalAddress: Physical address corresponding to virtual address
163 * NOTES:
164 * - Cached is ignored; we always allocate non-cached
165 */
166{
168
169 NDIS_DbgPrint(MAX_TRACE,("Called.\n"));
170
172 {
173 KeBugCheckEx(BUGCODE_ID_DRIVER,
175 Length,
176 0,
177 1);
178 }
179
180 *VirtualAddress = Adapter->NdisMiniportBlock.SystemAdapterObject->DmaOperations->AllocateCommonBuffer(
181 Adapter->NdisMiniportBlock.SystemAdapterObject, Length, PhysicalAddress, Cached);
182}
183
184VOID
185NTAPI
189/*
190 * FUNCTION: Free a common buffer
191 * ARGUMENTS:
192 * Context: Pointer to a miniport shared memory context
193 * NOTES:
194 * - Called by NdisMFreeSharedMemory to do the actual work
195 */
196{
198
199 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
200
202
203 Memory->AdapterObject->DmaOperations->FreeCommonBuffer(
204 Memory->AdapterObject, Memory->Length, Memory->PhysicalAddress,
205 Memory->VirtualAddress, Memory->Cached);
206
207 IoFreeWorkItem(Memory->WorkItem);
209}
210
211/*
212 * @implemented
213 */
214VOID
215EXPORT
222/*
223 * FUNCTION: Free a shared memory block
224 * ARGUMENTS:
225 * MiniportAdapterHandle: Handle passed into MiniportInitialize
226 * Length: Number of bytes in the block to free
227 * Cached: Whether or not the memory was cached
228 * VirtualAddress: Address to free
229 * PhysicalAddress: corresponding physical addres
230 * NOTES:
231 * - This function can be called at dispatch_level or passive_level.
232 * Therefore we have to do this in a worker thread.
233 */
234{
237 PDMA_ADAPTER DmaAdapter = Adapter->NdisMiniportBlock.SystemAdapterObject;
238
239 NDIS_DbgPrint(MAX_TRACE,("Called.\n"));
240
242
243 /* Call FreeCommonBuffer synchronously if we are at PASSIVE_LEVEL */
245 {
246 /* We need this case because we free shared memory asynchronously
247 * and the miniport (and DMA adapter object) could be freed before
248 * our work item executes. Lucky for us, the scenarios where the
249 * freeing needs to be synchronous (failed init, MiniportHalt,
250 * and driver unload) are all at PASSIVE_LEVEL so we can just
251 * call FreeCommonBuffer synchronously and not have to worry
252 * about the miniport falling out from under us */
253
254 NDIS_DbgPrint(MID_TRACE,("Freeing shared memory synchronously\n"));
255
256 DmaAdapter->DmaOperations->FreeCommonBuffer(DmaAdapter,
257 Length,
260 Cached);
261 return;
262 }
263
264 /* Must be NonpagedPool because by definition we're at DISPATCH_LEVEL */
266
267 if(!Memory)
268 {
269 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
270 return;
271 }
272
273 Memory->AdapterObject = Adapter->NdisMiniportBlock.SystemAdapterObject;
274 Memory->Length = Length;
275 Memory->PhysicalAddress = PhysicalAddress;
276 Memory->VirtualAddress = VirtualAddress;
277 Memory->Cached = Cached;
278 Memory->Adapter = &Adapter->NdisMiniportBlock;
279
281 if (!Memory->WorkItem)
282 {
283 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
285 return;
286 }
287
288 IoQueueWorkItem(Memory->WorkItem,
291 Memory);
292}
293
294VOID
295NTAPI
299/*
300 * FUNCTION: Allocate a common buffer
301 * ARGUMENTS:
302 * Context: Pointer to a miniport shared memory context
303 * NOTES:
304 * - Called by NdisMAllocateSharedMemoryAsync to do the actual work
305 */
306{
308
309 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
310
312
313 Memory->VirtualAddress = Memory->AdapterObject->DmaOperations->AllocateCommonBuffer(
314 Memory->AdapterObject, Memory->Length, &Memory->PhysicalAddress, Memory->Cached);
315
316 if (Memory->Adapter->DriverHandle->MiniportCharacteristics.AllocateCompleteHandler)
317 Memory->Adapter->DriverHandle->MiniportCharacteristics.AllocateCompleteHandler(
318 Memory->Adapter->MiniportAdapterContext, Memory->VirtualAddress,
319 &Memory->PhysicalAddress, Memory->Length, Memory->Context);
320
321 IoFreeWorkItem(Memory->WorkItem);
323}
324
325
326/*
327 * @implemented
328 */
330EXPORT
336{
339
340 NDIS_DbgPrint(MAX_TRACE,("Called.\n"));
341
343
344 /* Must be NonpagedPool because by definition we're at DISPATCH_LEVEL */
346
347 if(!Memory)
348 {
349 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
350 return NDIS_STATUS_FAILURE;
351 }
352
353 Memory->AdapterObject = Adapter->NdisMiniportBlock.SystemAdapterObject;
354 Memory->Length = Length;
355 Memory->Cached = Cached;
356 Memory->Adapter = &Adapter->NdisMiniportBlock;
357 Memory->Context = Context;
358
360 if (!Memory->WorkItem)
361 {
362 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
364 return NDIS_STATUS_FAILURE;
365 }
366
367 IoQueueWorkItem(Memory->WorkItem,
370 Memory);
371
372 return NDIS_STATUS_PENDING;
373}
374
375/*
376 * @implemented
377 */
378VOID
379EXPORT
381 IN NDIS_HANDLE NdisAdapterHandle,
386{
387 NdisMAllocateSharedMemory(NdisAdapterHandle,
388 Length,
389 Cached,
392}
393
394
395/*
396 * @implemented
397 */
398VOID
399EXPORT
401 IN NDIS_HANDLE NdisAdapterHandle,
406/*
407 * FUNCTION:
408 * ARGUMENTS:
409 * NOTES:
410 * NDIS 4.0
411 */
412{
413 NdisMFreeSharedMemory(NdisAdapterHandle,
414 Length,
415 Cached,
418}
419
420
421/* EOF */
unsigned char BOOLEAN
Definition: actypes.h:127
#define MIN_TRACE
Definition: debug.h:14
#define MID_TRACE
Definition: debug.h:15
#define MAX_TRACE
Definition: debug.h:16
DECLSPEC_NORETURN VOID NTAPI KeBugCheckEx(IN ULONG BugCheckCode, IN ULONG_PTR BugCheckParameter1, IN ULONG_PTR BugCheckParameter2, IN ULONG_PTR BugCheckParameter3, IN ULONG_PTR BugCheckParameter4)
Definition: debug.c:485
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:111
VOID EXPORT NdisAllocateSharedMemory(IN NDIS_HANDLE NdisAdapterHandle, IN ULONG Length, IN BOOLEAN Cached, OUT PVOID *VirtualAddress, OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
Definition: memory.c:380
VOID NTAPI NdisMAllocateSharedMemoryPassive(PDEVICE_OBJECT DeviceObject, PVOID Context)
Definition: memory.c:296
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:400
VOID NTAPI NdisMFreeSharedMemoryPassive(PDEVICE_OBJECT DeviceObject, PVOID Context)
Definition: memory.c:186
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:149
NDIS_STATUS EXPORT NdisMAllocateSharedMemoryAsync(IN NDIS_HANDLE MiniportAdapterHandle, IN ULONG Length, IN BOOLEAN Cached, IN PVOID Context)
Definition: memory.c:331
VOID EXPORT NdisMFreeSharedMemory(IN NDIS_HANDLE MiniportAdapterHandle, IN ULONG Length, IN BOOLEAN Cached, IN PVOID VirtualAddress, IN NDIS_PHYSICAL_ADDRESS PhysicalAddress)
Definition: memory.c:216
#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
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
#define NDIS_STATUS_FAILURE
Definition: ndis.h:465
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
unsigned int UINT
Definition: ndis.h:50
_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
#define RTL_CONSTANT_LARGE_INTEGER(quad_part)
Definition: ndissys.h:37
int NDIS_STATUS
Definition: ntddndis.h:496
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
_In_ PVOID Context
Definition: storport.h:2269
struct _DMA_OPERATIONS * DmaOperations
Definition: iotypes.h:2297
NDIS_MINIPORT_BLOCK NdisMiniportBlock
Definition: miniport.h:89
PDEVICE_OBJECT DeviceObject
Definition: ndis.h:2552
#define LL
Definition: tui.h:166
#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:2061
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4071
_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