Author: cgutman
Date: Sat May 16 05:44:20 2009
New Revision: 40934

URL: http://svn.reactos.org/svn/reactos?rev=40934&view=rev
Log:
 - Restore the old loopback implementation
 - Should fix the buildbot test hang

Modified:
    trunk/reactos/lib/drivers/ip/network/loopback.c

Modified: trunk/reactos/lib/drivers/ip/network/loopback.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/network/loopback.c?rev=40934&r1=40933&r2=40934&view=diff
==============================================================================
--- trunk/reactos/lib/drivers/ip/network/loopback.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/network/loopback.c [iso-8859-1] Sat May 16 
05:44:20 2009
@@ -1,14 +1,128 @@
 /*
  * COPYRIGHT:   See COPYING in the top level directory
  * PROJECT:     ReactOS TCP/IP protocol driver
- * FILE:        lib/drivers/ip/network/loopback.c
+ * FILE:        datalink/loopback.c
  * PURPOSE:     Loopback adapter
- * PROGRAMMERS: Cameron Gutman (cgut...@reactos.org)
+ * PROGRAMMERS: Casper S. Hornstrup (cho...@users.sourceforge.net)
+ * REVISIONS:
+ *   CSH 01/08-2000 Created
  */
 
 #include "precomp.h"
 
 PIP_INTERFACE Loopback = NULL;
+typedef struct _LAN_WQ_ITEM {
+    LIST_ENTRY ListEntry;
+    PNDIS_PACKET Packet;
+    PLAN_ADAPTER Adapter;
+    UINT BytesTransferred;
+} LAN_WQ_ITEM, *PLAN_WQ_ITEM;
+
+/* Work around being called back into afd at Dpc level */
+KSPIN_LOCK LoopWorkLock;
+LIST_ENTRY LoopWorkList;
+WORK_QUEUE_ITEM LoopWorkItem;
+BOOLEAN LoopReceiveWorkerBusy = FALSE;
+
+VOID NTAPI LoopReceiveWorker( PVOID Context ) {
+    PLIST_ENTRY ListEntry;
+    PLAN_WQ_ITEM WorkItem;
+    PNDIS_PACKET Packet;
+    PLAN_ADAPTER Adapter;
+    UINT BytesTransferred;
+    PNDIS_BUFFER NdisBuffer;
+    IP_PACKET IPPacket;
+       KIRQL OldIrql;
+
+    TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
+
+       TcpipAcquireSpinLock( &LoopWorkLock, &OldIrql );
+    while( !IsListEmpty(&LoopWorkList) )
+    {
+               ListEntry = RemoveHeadList( &LoopWorkList );
+               TcpipReleaseSpinLock( &LoopWorkLock, OldIrql );
+
+               WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
+               
+               TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem));
+               
+               Packet = WorkItem->Packet;
+               Adapter = WorkItem->Adapter;
+               BytesTransferred = WorkItem->BytesTransferred;
+               
+               exFreePool( WorkItem );
+
+        IPInitializePacket(&IPPacket, 0);
+               
+        IPPacket.NdisPacket = Packet;
+               
+        TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x Trans %x\n",
+                                     Packet, Adapter, BytesTransferred));
+               
+        NdisGetFirstBufferFromPacket(Packet,
+                                     &NdisBuffer,
+                                     &IPPacket.Header,
+                                     &IPPacket.ContigSize,
+                                     &IPPacket.TotalSize);
+
+               IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred;
+        /* Determine which upper layer protocol that should receive
+           this packet and pass it to the correct receive handler */
+               
+               TI_DbgPrint
+                       (MID_TRACE,
+                        ("ContigSize: %d, TotalSize: %d, BytesTransferred: 
%d\n",
+                         IPPacket.ContigSize, IPPacket.TotalSize,
+                         BytesTransferred));
+               
+               IPPacket.Position = 0;
+               
+        IPReceive(Loopback, &IPPacket);
+               
+               FreeNdisPacket( Packet );
+               TcpipAcquireSpinLock( &LoopWorkLock, &OldIrql );
+    }
+    TI_DbgPrint(DEBUG_DATALINK, ("Leaving\n"));
+    LoopReceiveWorkerBusy = FALSE;
+       TcpipReleaseSpinLock( &LoopWorkLock, OldIrql );
+}
+
+VOID LoopSubmitReceiveWork(
+    NDIS_HANDLE BindingContext,
+    PNDIS_PACKET Packet,
+    NDIS_STATUS Status,
+    UINT BytesTransferred) {
+    PLAN_WQ_ITEM WQItem;
+    PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
+    KIRQL OldIrql;
+
+    TcpipAcquireSpinLock( &LoopWorkLock, &OldIrql );
+
+    WQItem = exAllocatePool( NonPagedPool, sizeof(LAN_WQ_ITEM) );
+    if( !WQItem ) {
+       TcpipReleaseSpinLock( &LoopWorkLock, OldIrql );
+       return;
+    }
+
+    WQItem->Packet = Packet;
+    WQItem->Adapter = Adapter;
+    WQItem->BytesTransferred = BytesTransferred;
+    InsertTailList( &LoopWorkList, &WQItem->ListEntry );
+
+    TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x BytesTrans %x\n",
+                                 Packet, Adapter, BytesTransferred));
+
+    if( !LoopReceiveWorkerBusy ) {
+       LoopReceiveWorkerBusy = TRUE;
+       ExQueueWorkItem( &LoopWorkItem, CriticalWorkQueue );
+       TI_DbgPrint(DEBUG_DATALINK,
+                   ("Work item inserted %x %x\n", &LoopWorkItem, WQItem));
+    } else {
+        TI_DbgPrint(DEBUG_DATALINK,
+                    ("LOOP WORKER BUSY %x %x\n", &LoopWorkItem, WQItem));
+    }
+    TcpipReleaseSpinLock( &LoopWorkLock, OldIrql );
+}
 
 VOID LoopTransmit(
   PVOID Context,
@@ -26,46 +140,31 @@
  *   Type        = LAN protocol type (unused)
  */
 {
-    IP_PACKET IPPacket;
-    PNDIS_PACKET XmitPacket;
-    PNDIS_BUFFER NdisBuffer;
-    NDIS_STATUS NdisStatus;
     PCHAR PacketBuffer;
     UINT PacketLength;
-
-    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
-
-    GetDataPtr( NdisPacket, Offset, &PacketBuffer, &PacketLength );
+    PNDIS_PACKET XmitPacket;
+    NDIS_STATUS NdisStatus;
+
+    ASSERT_KM_POINTER(NdisPacket);
+    ASSERT_KM_POINTER(PC(NdisPacket));
+    ASSERT_KM_POINTER(PC(NdisPacket)->DLComplete);
+
+    TI_DbgPrint(MAX_TRACE, ("Called (NdisPacket = %x)\n", NdisPacket));
+
+    GetDataPtr( NdisPacket, MaxLLHeaderSize, &PacketBuffer, &PacketLength );
 
     NdisStatus = AllocatePacketWithBuffer
         ( &XmitPacket, PacketBuffer, PacketLength );
 
-    if (NdisStatus != NDIS_STATUS_SUCCESS)
-    {
-        (PC(NdisPacket)->DLComplete)( PC(NdisPacket)->Context, NdisPacket, 
NdisStatus );
-        return;
-    }
-
-    IPInitializePacket(&IPPacket, 0);
-
-    NdisGetFirstBufferFromPacket(XmitPacket,
-                                 &NdisBuffer,
-                                 &IPPacket.Header,
-                                 &IPPacket.ContigSize,
-                                 &IPPacket.TotalSize);
-
-    IPPacket.NdisPacket = XmitPacket;
-    IPPacket.Position = 0;
-
-    TI_DbgPrint(MID_TRACE,
-                ("ContigSize: %d, TotalSize: %d\n",
-                 IPPacket.ContigSize, IPPacket.TotalSize));
-               
-    IPReceive(Loopback, &IPPacket);
-
-    FreeNdisPacket(XmitPacket);
-
-    (PC(NdisPacket)->DLComplete)( PC(NdisPacket)->Context, NdisPacket, 
NDIS_STATUS_SUCCESS );
+    if( NT_SUCCESS(NdisStatus) ) {
+        LoopSubmitReceiveWork
+            ( NULL, XmitPacket, STATUS_SUCCESS, PacketLength );
+    }
+
+    (PC(NdisPacket)->DLComplete)
+        ( PC(NdisPacket)->Context, NdisPacket, STATUS_SUCCESS );
+
+    TI_DbgPrint(MAX_TRACE, ("Done\n"));
 }
 
 NDIS_STATUS LoopRegisterAdapter(
@@ -80,9 +179,15 @@
  *   Status of operation
  */
 {
+  NDIS_STATUS Status;
   LLIP_BIND_INFO BindInfo;
 
+  Status = NDIS_STATUS_SUCCESS;
+
   TI_DbgPrint(MID_TRACE, ("Called.\n"));
+
+  InitializeListHead( &LoopWorkList );
+  ExInitializeWorkItem( &LoopWorkItem, LoopReceiveWorker, NULL );
 
   /* Bind the adapter to network (IP) layer */
   BindInfo.Context = NULL;
@@ -108,7 +213,7 @@
 
   TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
 
-  return NDIS_STATUS_SUCCESS;
+  return Status;
 }
 
 

Reply via email to