ReactOS  0.4.14-dev-606-g14ebc0b
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  */
20 EXPORT
23  IN UINT Length,
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));
45  return NDIS_STATUS_FAILURE;
46  }
47 
48  return NDIS_STATUS_SUCCESS;
49 }
50 
51 
52 /*
53  * @implemented
54  */
56 EXPORT
59  IN UINT Length,
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));
99  return NDIS_STATUS_FAILURE;
100  }
101 
102  return NDIS_STATUS_SUCCESS;
103 }
104 
105 /*
106  * @implemented
107  */
108 VOID
109 EXPORT
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  */
146 VOID
147 EXPORT
150  IN ULONG Length,
151  IN BOOLEAN Cached,
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 
183 VOID
184 NTAPI
187  PVOID Context)
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  */
213 VOID
214 EXPORT
217  IN ULONG Length,
218  IN BOOLEAN Cached,
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 
293 VOID
294 NTAPI
297  PVOID Context)
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  */
329 EXPORT
332  IN ULONG Length,
333  IN BOOLEAN Cached,
334  IN PVOID Context)
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  */
377 VOID
378 EXPORT
380  IN NDIS_HANDLE NdisAdapterHandle,
381  IN ULONG Length,
382  IN BOOLEAN Cached,
385 {
386  NdisMAllocateSharedMemory(NdisAdapterHandle,
387  Length,
388  Cached,
391 }
392 
393 
394 /*
395  * @implemented
396  */
397 VOID
398 EXPORT
400  IN NDIS_HANDLE NdisAdapterHandle,
401  IN ULONG Length,
402  IN BOOLEAN Cached,
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 */
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define IN
Definition: typedefs.h:38
#define MID_TRACE
Definition: debug.h:15
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
#define NDIS_STATUS_PENDING
Definition: ndis.h:347
NDIS_STATUS EXPORT NdisAllocateMemoryWithTag(OUT PVOID *VirtualAddress, IN UINT Length, IN ULONG Tag)
Definition: memory.c:21
#define NDIS_MEMORY_CONTIGUOUS
Definition: ndis.h:579
_In_ NDIS_HANDLE MiniportAdapterHandle
Definition: ndis.h:4668
static ULONGLONG Memory
Definition: CcMapData_drv.c:35
_In_ ULONG _In_ BOOLEAN Cached
Definition: ndis.h:3788
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
struct _DMA_OPERATIONS * DmaOperations
Definition: iotypes.h:2187
int NDIS_STATUS
Definition: ntddndis.h:471
uint32_t ULONG_PTR
Definition: typedefs.h:63
struct _MINIPORT_SHARED_MEMORY * PMINIPORT_SHARED_MEMORY
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define NDIS_MEMORY_NONCACHED
Definition: ndis.h:580
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 NdisMAllocateSharedMemoryPassive(PDEVICE_OBJECT DeviceObject, PVOID Context)
Definition: memory.c:295
unsigned char BOOLEAN
NTSYSAPI ULONGLONG WINAPI RtlConvertUlongToLargeInteger(ULONG)
Definition: largeint.c:47
NDIS_MINIPORT_BLOCK NdisMiniportBlock
Definition: miniport.h:89
NDIS_STATUS EXPORT NdisAllocateMemory(OUT PVOID *VirtualAddress, IN UINT Length, IN UINT MemoryFlags, IN NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress)
Definition: memory.c:57
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
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1061
struct _LOGICAL_ADAPTER * PLOGICAL_ADAPTER
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
NDIS_STATUS EXPORT NdisMAllocateSharedMemoryAsync(IN NDIS_HANDLE MiniportAdapterHandle, IN ULONG Length, IN BOOLEAN Cached, IN PVOID Context)
Definition: memory.c:330
_Out_ PNDIS_HANDLE _Out_ PUINT _In_ PNDIS_STRING _In_ NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress
Definition: ndis.h:3227
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define MAX_TRACE
Definition: debug.h:16
PDEVICE_OBJECT DeviceObject
Definition: ndis.h:2552
unsigned int UINT
Definition: ndis.h:50
VOID NTAPI MmFreeNonCachedMemory(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: ncache.c:172
VOID NTAPI NdisMFreeSharedMemoryPassive(PDEVICE_OBJECT DeviceObject, PVOID Context)
Definition: memory.c:185
#define NDIS_DbgPrint(_t_, _x_)
Definition: debug.h:40
IN ULONG IN ULONG Tag
Definition: evtlib.h:159
VOID NTAPI MmFreeContiguousMemorySpecifyCache(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: contmem.c:666
#define OUT
Definition: typedefs.h:39
struct tagContext Context
Definition: acpixf.h:1030
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14
PVOID NTAPI MmAllocateNonCachedMemory(IN SIZE_T NumberOfBytes)
Definition: ncache.c:25
#define NDIS_STATUS_FAILURE
Definition: ndis.h:465
VOID EXPORT NdisFreeMemory(IN PVOID VirtualAddress, IN UINT Length, IN UINT MemoryFlags)
Definition: memory.c:110
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:107
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
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