update for HEAD-2003091401
[reactos.git] / drivers / net / ndis / ndis / memory.c
index f4facd2..96e8c44 100644 (file)
@@ -4,12 +4,17 @@
  * FILE:        ndis/memory.c
  * PURPOSE:     Memory management routines
  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ *              Vizzini (vizzini@plasmic.com)
  * REVISIONS:
  *   CSH 01/08-2000 Created
+ *   8/15/2003 Vizzini - DMA support
  */
 #include <ndissys.h>
+#include <miniport.h>
 
-
+/*
+ * @implemented
+ */
 NDIS_STATUS
 EXPORT
 NdisAllocateMemoryWithTag(
@@ -17,18 +22,33 @@ NdisAllocateMemoryWithTag(
     IN  UINT    Length,
     IN  ULONG   Tag)
 /*
- * FUNCTION:
+ * FUNCTION:  Allocates a block of memory, with a 32-bit tag
  * ARGUMENTS:
- * NOTES:
- *    NDIS 5.0
+ *   VirtualAddress = a pointer to the returned memory block
+ *   Length         = the number of requested bytes
+ *   Tag            = 32-bit pool tag 
+ * RETURNS:  
+ *   NDIS_STATUS_SUCCESS on success
+ *   NDIS_STATUS_FAILURE on failure
  */
 {
-    UNIMPLEMENTED
+  PVOID Block;
 
+  NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+  Block = ExAllocatePoolWithTag(NonPagedPool, Length, Tag);
+  *VirtualAddress = Block;
+
+  if (!Block)
     return NDIS_STATUS_FAILURE;
+
+  return NDIS_STATUS_SUCCESS;
 }
 
 
+/*
+ * @unimplemented
+ */
 VOID
 EXPORT
 NdisCreateLookaheadBufferFromSharedMemory(
@@ -40,6 +60,9 @@ NdisCreateLookaheadBufferFromSharedMemory(
 }
 
 
+/*
+ * @unimplemented
+ */
 VOID
 EXPORT
 NdisDestroyLookaheadBufferFromSharedMemory(
@@ -49,6 +72,9 @@ NdisDestroyLookaheadBufferFromSharedMemory(
 }
 
 
+/*
+ * @unimplemented
+ */
 VOID
 EXPORT
 NdisMoveFromMappedMemory(
@@ -60,6 +86,9 @@ NdisMoveFromMappedMemory(
 }
 
 
+/*
+ * @unimplemented
+ */
 VOID
 EXPORT
 NdisMoveMappedMemory(
@@ -71,6 +100,9 @@ NdisMoveMappedMemory(
 }
 
 
+/*
+ * @unimplemented
+ */
 VOID
 EXPORT
 NdisMoveToMappedMemory(
@@ -82,6 +114,9 @@ NdisMoveToMappedMemory(
 }
 
 
+/*
+ * @unimplemented
+ */
 VOID
 EXPORT
 NdisMUpdateSharedMemory(
@@ -94,6 +129,9 @@ NdisMUpdateSharedMemory(
 }
 
 
+/*
+ * @implemented
+ */
 NDIS_STATUS
 EXPORT
 NdisAllocateMemory(
@@ -109,32 +147,43 @@ NdisAllocateMemory(
  *     Length                   = Size of the memory block to allocate
  *     MemoryFlags              = Flags to specify special restrictions
  *     HighestAcceptableAddress = Specifies -1
+ * RETURNS:
+ *     NDIS_STATUS_SUCCESS on success
+ *     NDIS_STATUS_FAILURE on failure
  */
 {
-    PVOID Block;
+  NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
-    if (MemoryFlags & NDIS_MEMORY_CONTIGUOUS) {
-        /* FIXME */
-        *VirtualAddress = NULL;
+  if (MemoryFlags & NDIS_MEMORY_NONCACHED) 
+    {
+      *VirtualAddress = MmAllocateNonCachedMemory(Length);
+      if(!*VirtualAddress)
         return NDIS_STATUS_FAILURE;
+
+      return NDIS_STATUS_SUCCESS;
     }
 
-    if (MemoryFlags & NDIS_MEMORY_NONCACHED) {
-        /* FIXME */
-        *VirtualAddress = NULL;
+  if (MemoryFlags & NDIS_MEMORY_CONTIGUOUS) 
+    {
+      *VirtualAddress = MmAllocateContiguousMemory(Length, HighestAcceptableAddress);
+      if(!*VirtualAddress)
         return NDIS_STATUS_FAILURE;
+
+      return NDIS_STATUS_SUCCESS;
     }
 
-    /* Plain nonpaged memory */
-    Block           = ExAllocatePool(NonPagedPool, Length);
-    *VirtualAddress = Block;
-    if (!Block)
-        return NDIS_STATUS_FAILURE;
+  /* Plain nonpaged memory */
+  *VirtualAddress = ExAllocatePool(NonPagedPool, Length);
+  if (!*VirtualAddress)
+    return NDIS_STATUS_FAILURE;
 
-       return NDIS_STATUS_SUCCESS;
+  return NDIS_STATUS_SUCCESS;
 }
 
 
+/*
+ * @implemented
+ */
 VOID
 EXPORT
 NdisFreeMemory(
@@ -149,21 +198,27 @@ NdisFreeMemory(
  *     MemoryFlags    = Memory flags passed to NdisAllocateMemory
  */
 {
-    if (MemoryFlags & NDIS_MEMORY_CONTIGUOUS) {
-        /* FIXME */
-        return;
+  NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+  if (MemoryFlags & NDIS_MEMORY_NONCACHED) 
+    {
+      MmFreeNonCachedMemory(VirtualAddress, Length);
+      return;
     }
 
-    if (MemoryFlags & NDIS_MEMORY_NONCACHED) {
-        /* FIXME */
-        return;
+  if (MemoryFlags & NDIS_MEMORY_CONTIGUOUS) 
+    {
+      MmFreeContiguousMemory(VirtualAddress);
+      return;
     }
 
-    /* Plain nonpaged memory */
-    ExFreePool(VirtualAddress);
+  ExFreePool(VirtualAddress);
 }
 
 
+/*
+ * @unimplemented
+ */
 VOID
 EXPORT
 NdisImmediateReadSharedMemory(
@@ -172,9 +227,13 @@ NdisImmediateReadSharedMemory(
     OUT PUCHAR      Buffer,
     IN  ULONG       Length)
 {
+    UNIMPLEMENTED
 }
 
 
+/*
+ * @unimplemented
+ */
 VOID
 EXPORT
 NdisImmediateWriteSharedMemory(
@@ -187,6 +246,9 @@ NdisImmediateWriteSharedMemory(
 }
 
 
+/*
+ * @implemented
+ */
 VOID
 EXPORT
 NdisMAllocateSharedMemory(
@@ -195,11 +257,29 @@ NdisMAllocateSharedMemory(
     IN BOOLEAN                 Cached,
     OUT        PVOID                   *VirtualAddress,
     OUT        PNDIS_PHYSICAL_ADDRESS  PhysicalAddress)
+/*
+ * FUNCTION: Allocate a common buffer for DMA
+ * ARGUMENTS:
+ *     MiniportAdapterHandle:  Handle passed into MiniportInitialize
+ *     Length:  Number of bytes to allocate
+ *     Cached:  Whether or not the memory can be cached
+ *     VirtualAddress:  Pointer to memory is returned here
+ *     PhysicalAddress:  Physical address corresponding to virtual address
+ * NOTES:
+ *     - Cached is ignored; we always allocate non-cached
+ */
 {
-    UNIMPLEMENTED
+  PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle;
+
+  NDIS_DbgPrint(MAX_TRACE,("Called.\n"));
+
+  *VirtualAddress = HalAllocateCommonBuffer(Adapter->AdapterObject, Length, PhysicalAddress, Cached);
 }
 
 
+/*
+ * @unimplemented
+ */
 NDIS_STATUS
 EXPORT
 NdisMAllocateSharedMemoryAsync(
@@ -208,12 +288,43 @@ NdisMAllocateSharedMemoryAsync(
     IN  BOOLEAN     Cached,
     IN  PVOID       Context)
 {
+    NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
     UNIMPLEMENTED
 
        return NDIS_STATUS_FAILURE;
 }
 
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+NdisMFreeSharedMemoryPassive(
+    PVOID Context) 
+/*
+ * FUNCTION:  Free a common buffer
+ * ARGUMENTS:
+ *     Context:  Pointer to a miniport shared memory context
+ * NOTES:
+ *     - Called by NdisMFreeSharedMemory to do the actual work
+ */
+{
+  PMINIPORT_SHARED_MEMORY Memory = (PMINIPORT_SHARED_MEMORY)Context;
+
+  NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
+
+  ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
+
+  HalFreeCommonBuffer(Memory->AdapterObject, Memory->Length, Memory->PhysicalAddress,
+      Memory->VirtualAddress, Memory->Cached);
+
+  ExFreePool(Memory);
+}
+
 
+/*
+ * @implemented
+ */
 VOID
 EXPORT
 NdisMFreeSharedMemory(
@@ -222,8 +333,45 @@ NdisMFreeSharedMemory(
     IN  BOOLEAN                 Cached,
     IN  PVOID                   VirtualAddress,
     IN  NDIS_PHYSICAL_ADDRESS   PhysicalAddress)
+/*
+ * FUNCTION:  Free a shared memory block
+ * ARGUMENTS:
+ *     MiniportAdapterHandle:  Handle passed into MiniportInitialize
+ *     Length:  Number of bytes in the block to free
+ *     Cached:  Whether or not the memory was cached
+ *     VirtualAddress:  Address to free
+ *     PhysicalAddress:  corresponding physical addres
+ * NOTES:
+ *     - This function can be called at dispatch_level or passive_level.
+ *       Therefore we have to do this in a worker thread.
+ */
 {
-    UNIMPLEMENTED
+  HANDLE ThreadHandle;
+  PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle;
+  PMINIPORT_SHARED_MEMORY Memory;
+
+  NDIS_DbgPrint(MAX_TRACE,("Called.\n"));
+       
+  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+
+  /* Must be NonpagedPool because by definition we're at DISPATCH_LEVEL */
+  Memory = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_SHARED_MEMORY));
+
+  if(!Memory)
+    {
+      NDIS_DbgPrint(MID_TRACE, ("Insufficient resources\n"));
+      return;
+    }
+
+  Memory->AdapterObject = Adapter->AdapterObject;
+  Memory->Length = Length;
+  Memory->PhysicalAddress = PhysicalAddress;
+  Memory->VirtualAddress = VirtualAddress;
+  Memory->Cached = Cached;
+    
+  PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, 0, 0, 0, NdisMFreeSharedMemoryPassive, Memory);
+  ZwClose(ThreadHandle);
 }
 
 /* EOF */
+