Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmemory.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS NDIS library 00004 * FILE: ndis/memory.c 00005 * PURPOSE: Memory management routines 00006 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) 00007 * Vizzini (vizzini@plasmic.com) 00008 * REVISIONS: 00009 * CSH 01/08-2000 Created 00010 * 15 Aug 2003 Vizzini - DMA support 00011 * 3 Oct 2003 Vizzini - formatting and minor bugfixing 00012 */ 00013 00014 #include "ndissys.h" 00015 00016 00017 /* 00018 * @implemented 00019 */ 00020 NDIS_STATUS 00021 EXPORT 00022 NdisAllocateMemoryWithTag( 00023 OUT PVOID *VirtualAddress, 00024 IN UINT Length, 00025 IN ULONG Tag) 00026 /* 00027 * FUNCTION: Allocates a block of memory, with a 32-bit tag 00028 * ARGUMENTS: 00029 * VirtualAddress = a pointer to the returned memory block 00030 * Length = the number of requested bytes 00031 * Tag = 32-bit pool tag 00032 * RETURNS: 00033 * NDIS_STATUS_SUCCESS on success 00034 * NDIS_STATUS_FAILURE on failure 00035 */ 00036 { 00037 PVOID Block; 00038 00039 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 00040 00041 Block = ExAllocatePoolWithTag(NonPagedPool, Length, Tag); 00042 *VirtualAddress = Block; 00043 00044 if (!Block) { 00045 NDIS_DbgPrint(MIN_TRACE, ("Failed to allocate memory (%lx)\n", Length)); 00046 return NDIS_STATUS_FAILURE; 00047 } 00048 00049 return NDIS_STATUS_SUCCESS; 00050 } 00051 00052 00053 00054 /* 00055 * @implemented 00056 */ 00057 NDIS_STATUS 00058 EXPORT 00059 NdisAllocateMemory( 00060 OUT PVOID *VirtualAddress, 00061 IN UINT Length, 00062 IN UINT MemoryFlags, 00063 IN NDIS_PHYSICAL_ADDRESS HighestAcceptableAddress) 00064 /* 00065 * FUNCTION: Allocates a block of memory 00066 * ARGUMENTS: 00067 * VirtualAddress = Address of buffer to place virtual 00068 * address of the allocated memory 00069 * Length = Size of the memory block to allocate 00070 * MemoryFlags = Flags to specify special restrictions 00071 * HighestAcceptableAddress = Specifies -1 00072 * RETURNS: 00073 * NDIS_STATUS_SUCCESS on success 00074 * NDIS_STATUS_FAILURE on failure 00075 */ 00076 { 00077 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 00078 00079 if (MemoryFlags & NDIS_MEMORY_CONTIGUOUS) 00080 { 00081 /* Allocate contiguous memory (possibly noncached) */ 00082 *VirtualAddress = MmAllocateContiguousMemorySpecifyCache(Length, 00083 RtlConvertUlongToLargeInteger(0), 00084 HighestAcceptableAddress, 00085 RtlConvertUlongToLargeInteger(0), 00086 (MemoryFlags & NDIS_MEMORY_NONCACHED) ? MmNonCached : MmCached); 00087 } 00088 else if (MemoryFlags & NDIS_MEMORY_NONCACHED) 00089 { 00090 /* Allocate noncached noncontiguous memory */ 00091 *VirtualAddress = MmAllocateNonCachedMemory(Length); 00092 } 00093 else 00094 { 00095 /* Allocate plain nonpaged memory */ 00096 *VirtualAddress = ExAllocatePool(NonPagedPool, Length); 00097 } 00098 00099 if (!*VirtualAddress) { 00100 NDIS_DbgPrint(MIN_TRACE, ("Allocation failed (%lx, %lx)\n", MemoryFlags, Length)); 00101 return NDIS_STATUS_FAILURE; 00102 } 00103 00104 return NDIS_STATUS_SUCCESS; 00105 } 00106 00107 00108 /* 00109 * @implemented 00110 */ 00111 VOID 00112 EXPORT 00113 NdisFreeMemory( 00114 IN PVOID VirtualAddress, 00115 IN UINT Length, 00116 IN UINT MemoryFlags) 00117 /* 00118 * FUNCTION: Frees a memory block allocated with NdisAllocateMemory 00119 * ARGUMENTS: 00120 * VirtualAddress = Pointer to the base virtual address of the allocated memory 00121 * Length = Size of the allocated memory block as passed to NdisAllocateMemory 00122 * MemoryFlags = Memory flags passed to NdisAllocateMemory 00123 */ 00124 { 00125 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 00126 00127 if (MemoryFlags & NDIS_MEMORY_CONTIGUOUS) 00128 { 00129 /* Free contiguous memory (possibly noncached) */ 00130 MmFreeContiguousMemorySpecifyCache(VirtualAddress, 00131 Length, 00132 (MemoryFlags & NDIS_MEMORY_NONCACHED) ? MmNonCached : MmCached); 00133 } 00134 else if (MemoryFlags & NDIS_MEMORY_NONCACHED) 00135 { 00136 /* Free noncached noncontiguous memory */ 00137 MmFreeNonCachedMemory(VirtualAddress, Length); 00138 } 00139 else 00140 { 00141 /* Free nonpaged pool */ 00142 ExFreePool(VirtualAddress); 00143 } 00144 } 00145 00146 00147 /* 00148 * @implemented 00149 */ 00150 VOID 00151 EXPORT 00152 NdisMAllocateSharedMemory( 00153 IN NDIS_HANDLE MiniportAdapterHandle, 00154 IN ULONG Length, 00155 IN BOOLEAN Cached, 00156 OUT PVOID *VirtualAddress, 00157 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress) 00158 /* 00159 * FUNCTION: Allocate a common buffer for DMA 00160 * ARGUMENTS: 00161 * MiniportAdapterHandle: Handle passed into MiniportInitialize 00162 * Length: Number of bytes to allocate 00163 * Cached: Whether or not the memory can be cached 00164 * VirtualAddress: Pointer to memory is returned here 00165 * PhysicalAddress: Physical address corresponding to virtual address 00166 * NOTES: 00167 * - Cached is ignored; we always allocate non-cached 00168 */ 00169 { 00170 PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle; 00171 00172 NDIS_DbgPrint(MAX_TRACE,("Called.\n")); 00173 00174 if (KeGetCurrentIrql() != PASSIVE_LEVEL) 00175 { 00176 KeBugCheckEx(BUGCODE_ID_DRIVER, 00177 (ULONG_PTR)MiniportAdapterHandle, 00178 Length, 00179 0, 00180 1); 00181 } 00182 00183 *VirtualAddress = Adapter->NdisMiniportBlock.SystemAdapterObject->DmaOperations->AllocateCommonBuffer( 00184 Adapter->NdisMiniportBlock.SystemAdapterObject, Length, PhysicalAddress, Cached); 00185 } 00186 00187 00188 VOID 00189 NTAPI 00190 NdisMFreeSharedMemoryPassive( 00191 PDEVICE_OBJECT DeviceObject, 00192 PVOID Context) 00193 /* 00194 * FUNCTION: Free a common buffer 00195 * ARGUMENTS: 00196 * Context: Pointer to a miniport shared memory context 00197 * NOTES: 00198 * - Called by NdisMFreeSharedMemory to do the actual work 00199 */ 00200 { 00201 PMINIPORT_SHARED_MEMORY Memory = (PMINIPORT_SHARED_MEMORY)Context; 00202 00203 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 00204 00205 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); 00206 00207 Memory->AdapterObject->DmaOperations->FreeCommonBuffer( 00208 Memory->AdapterObject, Memory->Length, Memory->PhysicalAddress, 00209 Memory->VirtualAddress, Memory->Cached); 00210 00211 IoFreeWorkItem(Memory->WorkItem); 00212 ExFreePool(Memory); 00213 } 00214 00215 00216 /* 00217 * @implemented 00218 */ 00219 VOID 00220 EXPORT 00221 NdisMFreeSharedMemory( 00222 IN NDIS_HANDLE MiniportAdapterHandle, 00223 IN ULONG Length, 00224 IN BOOLEAN Cached, 00225 IN PVOID VirtualAddress, 00226 IN NDIS_PHYSICAL_ADDRESS PhysicalAddress) 00227 /* 00228 * FUNCTION: Free a shared memory block 00229 * ARGUMENTS: 00230 * MiniportAdapterHandle: Handle passed into MiniportInitialize 00231 * Length: Number of bytes in the block to free 00232 * Cached: Whether or not the memory was cached 00233 * VirtualAddress: Address to free 00234 * PhysicalAddress: corresponding physical addres 00235 * NOTES: 00236 * - This function can be called at dispatch_level or passive_level. 00237 * Therefore we have to do this in a worker thread. 00238 */ 00239 { 00240 PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle; 00241 PMINIPORT_SHARED_MEMORY Memory; 00242 PDMA_ADAPTER DmaAdapter = Adapter->NdisMiniportBlock.SystemAdapterObject; 00243 00244 NDIS_DbgPrint(MAX_TRACE,("Called.\n")); 00245 00246 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00247 00248 /* Call FreeCommonBuffer synchronously if we are at PASSIVE_LEVEL */ 00249 if (KeGetCurrentIrql() == PASSIVE_LEVEL) 00250 { 00251 /* We need this case because we free shared memory asynchronously 00252 * and the miniport (and DMA adapter object) could be freed before 00253 * our work item executes. Lucky for us, the scenarios where the 00254 * freeing needs to be synchronous (failed init, MiniportHalt, 00255 * and driver unload) are all at PASSIVE_LEVEL so we can just 00256 * call FreeCommonBuffer synchronously and not have to worry 00257 * about the miniport falling out from under us */ 00258 00259 NDIS_DbgPrint(MID_TRACE,("Freeing shared memory synchronously\n")); 00260 00261 DmaAdapter->DmaOperations->FreeCommonBuffer(DmaAdapter, 00262 Length, 00263 PhysicalAddress, 00264 VirtualAddress, 00265 Cached); 00266 return; 00267 } 00268 00269 /* Must be NonpagedPool because by definition we're at DISPATCH_LEVEL */ 00270 Memory = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_SHARED_MEMORY)); 00271 00272 if(!Memory) 00273 { 00274 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n")); 00275 return; 00276 } 00277 00278 Memory->AdapterObject = Adapter->NdisMiniportBlock.SystemAdapterObject; 00279 Memory->Length = Length; 00280 Memory->PhysicalAddress = PhysicalAddress; 00281 Memory->VirtualAddress = VirtualAddress; 00282 Memory->Cached = Cached; 00283 Memory->Adapter = &Adapter->NdisMiniportBlock; 00284 00285 Memory->WorkItem = IoAllocateWorkItem(Adapter->NdisMiniportBlock.DeviceObject); 00286 if (!Memory->WorkItem) 00287 { 00288 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n")); 00289 ExFreePool(Memory); 00290 return; 00291 } 00292 00293 IoQueueWorkItem(Memory->WorkItem, 00294 NdisMFreeSharedMemoryPassive, 00295 CriticalWorkQueue, 00296 Memory); 00297 } 00298 00299 VOID 00300 NTAPI 00301 NdisMAllocateSharedMemoryPassive( 00302 PDEVICE_OBJECT DeviceObject, 00303 PVOID Context) 00304 /* 00305 * FUNCTION: Allocate a common buffer 00306 * ARGUMENTS: 00307 * Context: Pointer to a miniport shared memory context 00308 * NOTES: 00309 * - Called by NdisMAllocateSharedMemoryAsync to do the actual work 00310 */ 00311 { 00312 PMINIPORT_SHARED_MEMORY Memory = (PMINIPORT_SHARED_MEMORY)Context; 00313 00314 NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); 00315 00316 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); 00317 00318 Memory->VirtualAddress = Memory->AdapterObject->DmaOperations->AllocateCommonBuffer( 00319 Memory->AdapterObject, Memory->Length, &Memory->PhysicalAddress, Memory->Cached); 00320 00321 if (Memory->Adapter->DriverHandle->MiniportCharacteristics.AllocateCompleteHandler) 00322 Memory->Adapter->DriverHandle->MiniportCharacteristics.AllocateCompleteHandler( 00323 Memory->Adapter->MiniportAdapterContext, Memory->VirtualAddress, 00324 &Memory->PhysicalAddress, Memory->Length, Memory->Context); 00325 00326 IoFreeWorkItem(Memory->WorkItem); 00327 ExFreePool(Memory); 00328 } 00329 00330 00331 /* 00332 * @implemented 00333 */ 00334 NDIS_STATUS 00335 EXPORT 00336 NdisMAllocateSharedMemoryAsync( 00337 IN NDIS_HANDLE MiniportAdapterHandle, 00338 IN ULONG Length, 00339 IN BOOLEAN Cached, 00340 IN PVOID Context) 00341 { 00342 PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle; 00343 PMINIPORT_SHARED_MEMORY Memory; 00344 00345 NDIS_DbgPrint(MAX_TRACE,("Called.\n")); 00346 00347 ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); 00348 00349 /* Must be NonpagedPool because by definition we're at DISPATCH_LEVEL */ 00350 Memory = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_SHARED_MEMORY)); 00351 00352 if(!Memory) 00353 { 00354 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n")); 00355 return NDIS_STATUS_FAILURE; 00356 } 00357 00358 Memory->AdapterObject = Adapter->NdisMiniportBlock.SystemAdapterObject; 00359 Memory->Length = Length; 00360 Memory->Cached = Cached; 00361 Memory->Adapter = &Adapter->NdisMiniportBlock; 00362 Memory->Context = Context; 00363 00364 Memory->WorkItem = IoAllocateWorkItem(Adapter->NdisMiniportBlock.DeviceObject); 00365 if (!Memory->WorkItem) 00366 { 00367 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n")); 00368 ExFreePool(Memory); 00369 return NDIS_STATUS_FAILURE; 00370 } 00371 00372 IoQueueWorkItem(Memory->WorkItem, 00373 NdisMAllocateSharedMemoryPassive, 00374 DelayedWorkQueue, 00375 Memory); 00376 00377 return NDIS_STATUS_PENDING; 00378 } 00379 00380 /* 00381 * @implemented 00382 */ 00383 VOID 00384 EXPORT 00385 NdisAllocateSharedMemory( 00386 IN NDIS_HANDLE NdisAdapterHandle, 00387 IN ULONG Length, 00388 IN BOOLEAN Cached, 00389 OUT PVOID *VirtualAddress, 00390 OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress) 00391 { 00392 NdisMAllocateSharedMemory(NdisAdapterHandle, 00393 Length, 00394 Cached, 00395 VirtualAddress, 00396 PhysicalAddress); 00397 } 00398 00399 00400 /* 00401 * @implemented 00402 */ 00403 VOID 00404 EXPORT 00405 NdisFreeSharedMemory( 00406 IN NDIS_HANDLE NdisAdapterHandle, 00407 IN ULONG Length, 00408 IN BOOLEAN Cached, 00409 IN PVOID VirtualAddress, 00410 IN NDIS_PHYSICAL_ADDRESS PhysicalAddress) 00411 /* 00412 * FUNCTION: 00413 * ARGUMENTS: 00414 * NOTES: 00415 * NDIS 4.0 00416 */ 00417 { 00418 NdisMFreeSharedMemory(NdisAdapterHandle, 00419 Length, 00420 Cached, 00421 VirtualAddress, 00422 PhysicalAddress); 00423 } 00424 00425 00426 /* EOF */ 00427 Generated on Fri May 25 2012 04:16:30 for ReactOS by
1.7.6.1
|