Sync with trunk (48237)
[reactos.git] / drivers / network / ndis / ndis / protocol.c
index aadf0d4..f41017b 100644 (file)
@@ -325,7 +325,6 @@ ProRequest(
   PADAPTER_BINDING AdapterBinding;
   PLOGICAL_ADAPTER Adapter;
   PNDIS_REQUEST_MAC_BLOCK MacBlock = (PNDIS_REQUEST_MAC_BLOCK)NdisRequest->MacReserved;
-  NDIS_STATUS Status;
 
   NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
 
@@ -337,15 +336,17 @@ ProRequest(
 
   MacBlock->Binding = &AdapterBinding->NdisOpenBlock;
 
-  Status = MiniBeginRequest(Adapter, NdisWorkItemRequest, NdisRequest);
-  if (!NT_SUCCESS(Status))
-      return Status;
-
-  Status = MiniDoRequest(Adapter, NdisRequest);
-  if (Status != NDIS_STATUS_PENDING)
-      MiniEndRequest(Adapter, NdisWorkItemRequest);
+#if WORKER_TEST
+  MiniQueueWorkItem(Adapter, NdisWorkItemRequest, NdisRequest, FALSE);
+  return NDIS_STATUS_PENDING;
+#else
+  if (MiniIsBusy(Adapter, NdisWorkItemRequest)) {
+      MiniQueueWorkItem(Adapter, NdisWorkItemRequest, NdisRequest, FALSE);
+      return NDIS_STATUS_PENDING;
+  }
 
-  return Status;
+  return MiniDoRequest(Adapter, NdisRequest);
+#endif
 }
 
 
@@ -392,12 +393,17 @@ ScatterGatherSendPacket(
 NDIS_STATUS
 proSendPacketToMiniport(PLOGICAL_ADAPTER Adapter, PNDIS_PACKET Packet)
 {
+#if WORKER_TEST
+   MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet, FALSE);
+   return NDIS_STATUS_PENDING;
+#else
    KIRQL RaiseOldIrql;
    NDIS_STATUS NdisStatus;
 
-   NdisStatus = MiniBeginRequest(Adapter, NdisWorkItemSend, Packet);
-   if (!NT_SUCCESS(NdisStatus))
-       return NdisStatus;
+   if(MiniIsBusy(Adapter, NdisWorkItemSend)) {
+      MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet, FALSE);
+      return NDIS_STATUS_PENDING;
+   }
 
    if(Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler)
    {
@@ -419,15 +425,11 @@ proSendPacketToMiniport(PLOGICAL_ADAPTER Adapter, PNDIS_PACKET Packet)
 
             NdisStatus = NDIS_GET_PACKET_STATUS(Packet);
             if (NdisStatus == NDIS_STATUS_RESOURCES) {
-                /* We don't need to add to head here because it's already guaranteed to the
-                   the first packet in the queue */
+                MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet, TRUE);
                 NdisStatus = NDIS_STATUS_PENDING;
             }
         }
 
-        if (NdisStatus != NDIS_STATUS_PENDING)
-            MiniEndRequest(Adapter, NdisWorkItemSend);
-
         return NdisStatus;
    } else {
         if(Adapter->NdisMiniportBlock.Flags & NDIS_ATTRIBUTE_DESERIALIZE)
@@ -446,16 +448,14 @@ proSendPacketToMiniport(PLOGICAL_ADAPTER Adapter, PNDIS_PACKET Packet)
             KeLowerIrql(RaiseOldIrql);
 
             if (NdisStatus == NDIS_STATUS_RESOURCES) {
-                /* See comment above */
+                MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet, TRUE);
                 NdisStatus = NDIS_STATUS_PENDING;
             }
         }
 
-        if (NdisStatus != NDIS_STATUS_PENDING)
-            MiniEndRequest(Adapter, NdisWorkItemSend);
-
         return NdisStatus;
    }
+#endif
 }
 
 \f
@@ -508,7 +508,12 @@ ProSend(
   if ((Adapter->NdisMiniportBlock.MacOptions & NDIS_MAC_OPTION_NO_LOOPBACK) &&
       MiniAdapterHasAddress(Adapter, Packet))
     {
+#if WORKER_TEST
+        MiniQueueWorkItem(Adapter, NdisWorkItemSendLoopback, Packet, FALSE);
+        return NDIS_STATUS_PENDING;
+#else
         return ProIndicatePacket(Adapter, Packet);
+#endif
     } else {
         if (Adapter->NdisMiniportBlock.ScatterGatherListSize != 0)
         {
@@ -565,14 +570,11 @@ ProSendPackets(
     IN  PPNDIS_PACKET   PacketArray,
     IN  UINT            NumberOfPackets)
 {
-    UNIMPLEMENTED
-#if 0
     PADAPTER_BINDING AdapterBinding = NdisBindingHandle;
     PLOGICAL_ADAPTER Adapter = AdapterBinding->Adapter;
     KIRQL RaiseOldIrql;
     NDIS_STATUS NdisStatus;
     UINT i;
-    BOOLEAN QueuePackets;
 
     if(Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler)
     {
@@ -588,15 +590,10 @@ ProSendPackets(
           (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler)(
            Adapter->NdisMiniportBlock.MiniportAdapterContext, PacketArray, NumberOfPackets);
           KeLowerIrql(RaiseOldIrql);
-          for (i = 0, QueuePackets = FALSE; i < NumberOfPackets; i++)
+          for (i = 0; i < NumberOfPackets; i++)
           {
              NdisStatus = NDIS_GET_PACKET_STATUS(PacketArray[i]);
-             if (NdisStatus == NDIS_STATUS_RESOURCES)
-                 QueuePackets = TRUE;
-
-             if (QueuePackets)
-                 NdisQueueWorkItemHead(Adapter, NdisWorkItemSend, PacketArray[i]);
-             else
+             if (NdisStatus != NDIS_STATUS_PENDING)
                  MiniSendComplete(Adapter, PacketArray[i], NdisStatus);
           }
        }
@@ -627,7 +624,6 @@ ProSendPackets(
          KeLowerIrql(RaiseOldIrql);
        }
      }
-#endif
 }
 
 \f
@@ -869,9 +865,39 @@ NdisOpenAdapter(
   *Status = NDIS_STATUS_SUCCESS;
 }
 
+PADAPTER_BINDING
+NTAPI
+LocateAdapterBindingByName(IN PPROTOCOL_BINDING ProtocolBinding, IN PNDIS_STRING AdapterName)
+{
+    PLIST_ENTRY CurrentEntry;
+    PADAPTER_BINDING AdapterBinding;
+    KIRQL OldIrql;
+
+    KeAcquireSpinLock(&ProtocolBinding->Lock, &OldIrql);
+
+    CurrentEntry = ProtocolBinding->AdapterListHead.Flink;
+
+    while (CurrentEntry != &ProtocolBinding->AdapterListHead)
+    {
+         AdapterBinding = CONTAINING_RECORD(CurrentEntry, ADAPTER_BINDING, ProtocolListEntry);
+
+         if (RtlCompareUnicodeString(AdapterName, &AdapterBinding->Adapter->NdisMiniportBlock.MiniportName, TRUE) == 0)
+         {
+             KeReleaseSpinLock(&ProtocolBinding->Lock, OldIrql);
+             return AdapterBinding;
+         }
+
+         CurrentEntry = CurrentEntry->Flink;
+    }
+
+    KeReleaseSpinLock(&ProtocolBinding->Lock, OldIrql);
+
+    return NULL;
+}
+
 VOID
 NTAPI
-ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics)
+ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PPROTOCOL_BINDING Protocol)
 {
   /*
    * bind the protocol to all of its miniports
@@ -887,6 +913,7 @@ ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PNDIS_PROTOCOL_CHARACTER
     WCHAR *DataPtr;
     HANDLE DriverKeyHandle = NULL;
     PKEY_VALUE_PARTIAL_INFORMATION KeyInformation = NULL;
+    PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics = &Protocol->Chars;
 
     RegistryPathStr = ExAllocatePoolWithTag(PagedPool, sizeof(SERVICES_KEY) + ProtocolCharacteristics->Name.Length + sizeof(LINKAGE_KEY), NDIS_TAG + __LINE__);
     if(!RegistryPathStr)
@@ -956,6 +983,9 @@ ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PNDIS_PROTOCOL_CHARACTER
       }
   }
 
+  /* Assume success for now */
+  *Status = NDIS_STATUS_SUCCESS;
+
   for (DataPtr = (WCHAR *)KeyInformation->Data;
        *DataPtr != 0;
        DataPtr += wcslen(DataPtr) + 1)
@@ -969,6 +999,20 @@ ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PNDIS_PROTOCOL_CHARACTER
 
       RtlInitUnicodeString(&DeviceName, DataPtr);      /* we know this is 0-term */
 
+      /* Make sure the adapter has started */
+      if (!MiniLocateDevice(&DeviceName))
+      {
+          /* It wasn't in the global miniport list, so skip the bind entry */
+          continue;
+      }
+
+      /* Make sure this device isn't already bound to this protocol */
+      if (LocateAdapterBindingByName(Protocol, &DeviceName))
+      {
+          /* It was already in this protocol's bound adapter list, so skip the bind entry */
+          continue;
+      }
+
       /*
        * RegistryPath should be:
        *     \Registry\Machine\System\CurrentControlSet\Services\Nic1\Parameters\Tcpip
@@ -1006,13 +1050,15 @@ ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PNDIS_PROTOCOL_CHARACTER
         {
           BIND_HANDLER BindHandler = ProtocolCharacteristics->BindAdapterHandler;
           if(BindHandler)
+          {
             BindHandler(Status, BindContext, &DeviceName, &RegistryPath, 0);
+            NDIS_DbgPrint(MIN_TRACE, ("%wZ's BindAdapter handler returned 0x%x for %wZ\n", &ProtocolCharacteristics->Name, *Status, &DeviceName));
+          }
           else
             NDIS_DbgPrint(MIN_TRACE, ("No protocol bind handler specified\n"));
         }
     }
 
-   *Status = NDIS_STATUS_SUCCESS;
    ExFreePool(KeyInformation);
 }
 
@@ -1112,7 +1158,7 @@ NdisRegisterProtocol(
 
   *NdisProtocolHandle = Protocol;
 
-  ndisBindMiniportsToProtocol(Status, &Protocol->Chars);
+  ndisBindMiniportsToProtocol(Status, Protocol);
 
   /* Should we only send this if ndisBindMiniportsToProtocol succeeds? */
   PnPEvent = ProSetupPnPEvent(NetEventBindsComplete, NULL, 0);
@@ -1253,10 +1299,9 @@ VOID
 NTAPI
 NdisReEnumerateProtocolBindings(IN NDIS_HANDLE NdisProtocolHandle)
 {
-    PPROTOCOL_BINDING Protocol = NdisProtocolHandle;
     NDIS_STATUS NdisStatus;
 
-    ndisBindMiniportsToProtocol(&NdisStatus, &Protocol->Chars);
+    ndisBindMiniportsToProtocol(&NdisStatus, NdisProtocolHandle);
 }