Implement NdisAllocatePacketPool by calling NdisAllocatePacketPoolEx.
[reactos.git] / reactos / drivers / net / ndis / ndis / buffer.c
index 37b736f..9891314 100644 (file)
@@ -7,8 +7,8 @@
  * REVISIONS:
  *   CSH 01/08-2000 Created
  */
-#include <buffer.h>
 
+#include <buffer.h>
 
 
 __inline ULONG SkipToOffset(
@@ -34,13 +34,13 @@ __inline ULONG SkipToOffset(
     for (;;) {
 
         if (!Buffer)
-            return -1;
+            return 0xFFFFFFFF;
 
         NdisQueryBuffer(Buffer, (PVOID)Data, Size);
 
         if (Offset < *Size) {
-            ((ULONG_PTR)*Data) += Offset;
-            *Size              -= Offset;
+            *Data  = (PUCHAR) ((ULONG_PTR) *Data + Offset);
+            *Size -= Offset;
             break;
         }
 
@@ -52,7 +52,6 @@ __inline ULONG SkipToOffset(
     return Offset;
 }
 
-
 UINT CopyBufferToBufferChain(
     PNDIS_BUFFER DstBuffer,
     UINT DstOffset,
@@ -61,7 +60,7 @@ UINT CopyBufferToBufferChain(
 /*
  * FUNCTION: Copies data from a buffer to an NDIS buffer chain
  * ARGUMENTS:
- *     DstBuffer = Pointer to destination NDIS buffer 
+ *     DstBuffer = Pointer to destination NDIS buffer
  *     DstOffset = Destination start offset
  *     SrcData   = Pointer to source buffer
  *     Length    = Number of bytes to copy
@@ -78,7 +77,7 @@ UINT CopyBufferToBufferChain(
     NDIS_DbgPrint(MAX_TRACE, ("DstBuffer (0x%X)  DstOffset (0x%X)  SrcData (0x%X)  Length (%d)\n", DstBuffer, DstOffset, SrcData, Length));
 
     /* Skip DstOffset bytes in the destination buffer chain */
-    if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == -1)
+    if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == 0xFFFFFFFF)
         return 0;
 
     /* Start copying the data */
@@ -87,8 +86,8 @@ UINT CopyBufferToBufferChain(
         BytesToCopy = MIN(DstSize, Length);
 
         RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
-        BytesCopied        += BytesToCopy;
-        (ULONG_PTR)SrcData += BytesToCopy;
+        BytesCopied += BytesToCopy;
+        SrcData      = (PUCHAR) ((ULONG_PTR) SrcData + BytesToCopy);
 
         Length -= BytesToCopy;
         if (Length == 0)
@@ -133,9 +132,9 @@ UINT CopyBufferChainToBuffer(
     PUCHAR SrcData;
 
     NDIS_DbgPrint(MAX_TRACE, ("DstData 0x%X  SrcBuffer 0x%X  SrcOffset 0x%X  Length %d\n",DstData,SrcBuffer, SrcOffset, Length));
-    
+
     /* Skip SrcOffset bytes in the source buffer chain */
-    if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1)
+    if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == 0xFFFFFFFF)
         return 0;
 
     /* Start copying the data */
@@ -146,8 +145,8 @@ UINT CopyBufferChainToBuffer(
         NDIS_DbgPrint(MAX_TRACE, ("Copying (%d) bytes from 0x%X to 0x%X\n", BytesToCopy, SrcData, DstData));
 
         RtlCopyMemory((PVOID)DstData, (PVOID)SrcData, BytesToCopy);
-        BytesCopied        += BytesToCopy;
-        (ULONG_PTR)DstData += BytesToCopy;
+        BytesCopied += BytesToCopy;
+        DstData      = (PUCHAR)((ULONG_PTR) DstData + BytesToCopy);
 
         Length -= BytesToCopy;
         if (Length == 0)
@@ -235,11 +234,11 @@ UINT CopyPacketToBufferChain(
 
     /* Skip DstOffset bytes in the destination buffer chain */
     NdisQueryBuffer(DstBuffer, (PVOID)&DstData, &DstSize);
-    if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == -1)
+    if (SkipToOffset(DstBuffer, DstOffset, &DstData, &DstSize) == 0xFFFFFFFF)
         return 0;
     /* Skip SrcOffset bytes in the source packet */
     NdisGetFirstBufferFromPacket(SrcPacket, &SrcBuffer, (PVOID)&SrcData, &SrcSize, &Total);
-    if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == -1)
+    if (SkipToOffset(SrcBuffer, SrcOffset, &SrcData, &SrcSize) == 0xFFFFFFFF)
         return 0;
     /* Copy the data */
     for (Total = 0;;) {
@@ -319,7 +318,7 @@ NDIS_BUFFER_TO_SPAN_PAGES(
 {
     if (MmGetMdlByteCount(Buffer) == 0)
         return 1;
-    
+
     return ADDRESS_AND_SIZE_TO_SPAN_PAGES(
             MmGetMdlVirtualAddress(Buffer),
             MmGetMdlByteCount(Buffer));
@@ -355,6 +354,18 @@ NdisAllocateBuffer(
         "VirtualAddress (0x%X)  Length (%d)\n",
         Status, Buffer, PoolHandle, VirtualAddress, Length));
 
+#if 0
+    Temp = Pool->FreeList;
+    while( Temp ) {
+       NDIS_DbgPrint(MID_TRACE,("Free buffer -> %x\n", Temp));
+       Temp = Temp->Next;
+    }
+
+    NDIS_DbgPrint(MID_TRACE,("|:. <- End free buffers"));
+#endif
+
+    if(!VirtualAddress && !Length) return;
+
     KeAcquireSpinLock(&Pool->SpinLock, &OldIrql);
 
     if (Pool->FreeList) {
@@ -365,26 +376,10 @@ NdisAllocateBuffer(
 
         Temp->Next = NULL;
 
-#ifdef _MSC_VER
         MmInitializeMdl(&Temp->Mdl, VirtualAddress, Length);
         Temp->Mdl.MdlFlags      |= (MDL_SOURCE_IS_NONPAGED_POOL | MDL_ALLOCATED_FIXED_SIZE);
         Temp->Mdl.MappedSystemVa = VirtualAddress;
-#else
-           Temp->Mdl.Next = (PMDL)NULL;
-           Temp->Mdl.Size = (CSHORT)(sizeof(MDL) +
-            (ADDRESS_AND_SIZE_TO_SPAN_PAGES(VirtualAddress, Length) * sizeof(ULONG)));
-           Temp->Mdl.MdlFlags   = (MDL_SOURCE_IS_NONPAGED_POOL | MDL_ALLOCATED_FIXED_SIZE);
-;          Temp->Mdl.StartVa    = (PVOID)PAGE_ROUND_DOWN(VirtualAddress);
-           Temp->Mdl.ByteOffset = (ULONG_PTR)(VirtualAddress - PAGE_ROUND_DOWN(VirtualAddress));
-           Temp->Mdl.ByteCount  = Length;
-        Temp->Mdl.MappedSystemVa = VirtualAddress;
-#if 0
-           //Temp->Mdl.Process    = PsGetCurrentProcess();
-#else
-        Temp->Mdl.Process    = NULL;
-#endif
-#endif
-        
+
         Temp->BufferPool = Pool;
 
         *Buffer = (PNDIS_BUFFER)Temp;
@@ -392,6 +387,8 @@ NdisAllocateBuffer(
     } else {
         KeReleaseSpinLock(&Pool->SpinLock, OldIrql);
         *Status = NDIS_STATUS_FAILURE;
+       NDIS_DbgPrint(MID_TRACE, ("Can't get another packet.\n"));
+       KeBugCheck(0);
     }
 }
 
@@ -429,10 +426,13 @@ NdisAllocateBufferPool(
 
         if (NumberOfDescriptors > 0) {
             Buffer             = &Pool->Buffers[0];
+           NDIS_DbgPrint(MAX_TRACE, ("NDIS BUFFER ADDRESS << %x >>\n", Buffer));
             Pool->FreeList     = Buffer;
             for (i = 1; i < NumberOfDescriptors; i++) {
                 Buffer->Next = &Pool->Buffers[i];
                 Buffer       = Buffer->Next;
+               NDIS_DbgPrint(MAX_TRACE, ("NDIS BUFFER ADDRESS << %x >>\n",
+                             Buffer));
             }
             Buffer->Next = NULL;
         } else
@@ -469,6 +469,12 @@ NdisAllocatePacket(
     NDIS_DbgPrint(MAX_TRACE, ("Status (0x%X)  Packet (0x%X)  PoolHandle (0x%X).\n",
         Status, Packet, PoolHandle));
 
+    if (Pool == NULL)
+    {
+        *Status = NDIS_STATUS_FAILURE;
+        return;
+    }
+
     KeAcquireSpinLock(&Pool->SpinLock.SpinLock, &OldIrql);
 
     if (Pool->FreeList) {
@@ -508,40 +514,12 @@ NdisAllocatePacketPool(
  *     ProtocolReservedLength = Size of protocol reserved area in bytes
  */
 {
-    PNDIS_PACKET_POOL Pool;
-    UINT Size, Length, i;
-    PNDIS_PACKET Packet, NextPacket;
-
-    NDIS_DbgPrint(MAX_TRACE, ("Status (0x%X)  PoolHandle (0x%X)  "
-        "NumberOfDescriptors (%d)  ProtocolReservedLength (%d).\n",
-        Status, PoolHandle, NumberOfDescriptors, ProtocolReservedLength));
-
-    Length = sizeof(NDIS_PACKET) + ProtocolReservedLength;
-    Size   = sizeof(NDIS_PACKET_POOL) + Length * NumberOfDescriptors;
-
-    Pool   = ExAllocatePool(NonPagedPool, Size);
-    if (Pool) {
-        KeInitializeSpinLock(&Pool->SpinLock.SpinLock);
-        Pool->PacketLength = Length;
-
-        if (NumberOfDescriptors > 0) {
-            Packet         = (PNDIS_PACKET)&Pool->Buffer;
-            Pool->FreeList = Packet;
-
-            NextPacket = (PNDIS_PACKET)((ULONG_PTR)Packet + Length);
-            for (i = 1; i < NumberOfDescriptors; i++) {
-                Packet->Private.Head = (PNDIS_BUFFER)NextPacket;
-                Packet               = NextPacket;
-                NextPacket           = (PNDIS_PACKET)((ULONG_PTR)Packet + Length);
-            }
-            Packet->Private.Head = NULL;
-        } else
-            Pool->FreeList = NULL;
-
-        *Status     = NDIS_STATUS_SUCCESS;
-        *PoolHandle = (PNDIS_HANDLE)Pool;
-    } else
-        *Status = NDIS_STATUS_RESOURCES;
+    NdisAllocatePacketPoolEx(
+        Status,
+        PoolHandle,
+        NumberOfDescriptors,
+        0,
+        ProtocolReservedLength);
 }
 
 
@@ -563,7 +541,57 @@ NdisAllocatePacketPoolEx(
  *    NDIS 5.0
  */
 {
-    UNIMPLEMENTED
+    PNDIS_PACKET_POOL Pool;
+    UINT Size, Length, i;
+    PNDIS_PACKET Packet, NextPacket;
+
+    NDIS_DbgPrint(MAX_TRACE, ("Status (0x%X)  PoolHandle (0x%X)  "
+        "NumberOfDescriptors (%d)  ProtocolReservedLength (%d).\n",
+        Status, PoolHandle, NumberOfDescriptors, ProtocolReservedLength));
+
+    if (NumberOfDescriptors > 0xffff)
+    {
+        *Status = NDIS_STATUS_RESOURCES;
+    }
+    else
+    {
+        NumberOfDescriptors += NumberOfOverflowDescriptors;
+        if (NumberOfDescriptors > 0xffff)
+        {
+            NumberOfDescriptors = 0xffff;
+        }
+
+        Length = sizeof(NDIS_PACKET) + ProtocolReservedLength;
+        Size   = sizeof(NDIS_PACKET_POOL) + Length * NumberOfDescriptors;
+
+        Pool   = ExAllocatePool(NonPagedPool, Size);
+        if (Pool) 
+        {
+            KeInitializeSpinLock(&Pool->SpinLock.SpinLock);
+            Pool->PacketLength = Length;
+
+            if (NumberOfDescriptors > 0) 
+            {
+                Packet         = (PNDIS_PACKET)&Pool->Buffer;
+                Pool->FreeList = Packet;
+
+                NextPacket = (PNDIS_PACKET)((ULONG_PTR)Packet + Length);
+                for (i = 1; i < NumberOfDescriptors; i++) 
+                {
+                    Packet->Private.Head = (PNDIS_BUFFER)NextPacket;
+                    Packet               = NextPacket;
+                    NextPacket           = (PNDIS_PACKET)((ULONG_PTR)Packet + Length);
+                }
+                Packet->Private.Head = NULL;
+            } 
+            else
+                Pool->FreeList = NULL;
+
+            *Status     = NDIS_STATUS_SUCCESS;
+            *PoolHandle = (PNDIS_HANDLE)Pool;
+        } else
+            *Status = NDIS_STATUS_RESOURCES;
+    }
 }
 
 
@@ -669,12 +697,12 @@ NdisCopyFromPacketToPacket(
 
     /* Skip DestinationOffset bytes in the destination packet */
     NdisGetFirstBufferFromPacket(Destination, &DstBuffer, (PVOID)&DstData, &DstSize, &Total);
-    if (SkipToOffset(DstBuffer, DestinationOffset, &DstData, &DstSize) == -1)
+    if (SkipToOffset(DstBuffer, DestinationOffset, &DstData, &DstSize) == 0xFFFFFFFF)
         return;
 
     /* Skip SourceOffset bytes in the source packet */
     NdisGetFirstBufferFromPacket(Source, &SrcBuffer, (PVOID)&SrcData, &SrcSize, &Total);
-    if (SkipToOffset(SrcBuffer, SourceOffset, &SrcData, &SrcSize) == -1)
+    if (SkipToOffset(SrcBuffer, SourceOffset, &SrcData, &SrcSize) == 0xFFFFFFFF)
         return;
 
     /* Copy the data */
@@ -850,8 +878,8 @@ NdisFreeBuffer(
     Pool = Temp->BufferPool;
 
     KeAcquireSpinLock(&Pool->SpinLock, &OldIrql);
-    Buffer->Next   = (PMDL)Pool->FreeList;
-    Pool->FreeList = (PNETWORK_HEADER)Buffer;
+    Temp->Next     = (PNETWORK_HEADER)Pool->FreeList;
+    Pool->FreeList = (PNETWORK_HEADER)Temp;
     KeReleaseSpinLock(&Pool->SpinLock, OldIrql);
 }
 
@@ -1008,6 +1036,29 @@ NdisQueryBuffer(
 }
 
 
+/*
+ * @implemented
+ */
+VOID
+EXPORT
+NdisQueryBufferSafe(
+    IN  PNDIS_BUFFER    Buffer,
+    OUT PVOID           *VirtualAddress OPTIONAL,
+    OUT PUINT           Length,
+    IN  UINT            Priority)
+/*
+ * FUNCTION:
+ * ARGUMENTS:
+ * NOTES:
+ *    NDIS 5.0
+ */
+{
+    if (VirtualAddress != NULL)
+        *VirtualAddress = MmGetSystemAddressForMdlSafe(Buffer, Priority);
+    *Length = MmGetMdlByteCount(Buffer);
+}
+
+
 /*
  * @implemented
  */