ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

memory.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.