[NDIS]
[reactos.git] / reactos / drivers / network / ndis / ndis / miniport.c
index 3da2ad1..b1ca384 100644 (file)
@@ -357,11 +357,23 @@ MiniResetComplete(
     PADAPTER_BINDING AdapterBinding;
     KIRQL OldIrql;
 
+    if (AddressingReset)
+        MiniDoAddressingReset(Adapter);
+
     NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_END, NULL, 0);
     NdisMIndicateStatusComplete(Adapter);
 
     KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql);
 
+    if (Adapter->NdisMiniportBlock.ResetStatus != NDIS_STATUS_PENDING)
+    {
+        KeBugCheckEx(BUGCODE_ID_DRIVER,
+                     (ULONG_PTR)MiniportAdapterHandle,
+                     (ULONG_PTR)Status,
+                     (ULONG_PTR)AddressingReset,
+                     0);
+    }
+
     Adapter->NdisMiniportBlock.ResetStatus = Status;
 
     CurrentEntry = Adapter->ProtocolListHead.Flink;
@@ -638,7 +650,45 @@ MiniLocateDevice(
   return Adapter;
 }
 
-\f
+NDIS_STATUS
+MiniSetInformation(
+    PLOGICAL_ADAPTER    Adapter,
+    NDIS_OID            Oid,
+    ULONG               Size,
+    PVOID               Buffer,
+    PULONG              BytesRead)
+{
+  NDIS_STATUS NdisStatus;
+  PNDIS_REQUEST NdisRequest;
+
+  NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
+
+  NdisRequest = ExAllocatePool(NonPagedPool, sizeof(NDIS_REQUEST));
+  if (!NdisRequest) {
+      NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources\n"));
+      return NDIS_STATUS_RESOURCES;
+  }
+
+  RtlZeroMemory(NdisRequest, sizeof(NDIS_REQUEST));
+
+  NdisRequest->RequestType = NdisRequestSetInformation;
+  NdisRequest->DATA.SET_INFORMATION.Oid = Oid;
+  NdisRequest->DATA.SET_INFORMATION.InformationBuffer = Buffer;
+  NdisRequest->DATA.SET_INFORMATION.InformationBufferLength = Size;
+
+  NdisStatus = MiniDoRequest(Adapter, NdisRequest);
+
+  /* FIXME: Wait in pending case! */
+
+  ASSERT(NdisStatus != NDIS_STATUS_PENDING);
+
+  *BytesRead = NdisRequest->DATA.SET_INFORMATION.BytesRead;
+
+  ExFreePool(NdisRequest);
+
+  return NdisStatus;
+}
+
 NDIS_STATUS
 MiniQueryInformation(
     PLOGICAL_ADAPTER    Adapter,
@@ -712,21 +762,34 @@ MiniCheckForHang( PLOGICAL_ADAPTER Adapter )
    return Ret;
 }
 
+VOID
+MiniDoAddressingReset(PLOGICAL_ADAPTER Adapter)
+{
+   ULONG BytesRead;
+
+   MiniSetInformation(Adapter,
+                      OID_GEN_CURRENT_LOOKAHEAD,
+                      sizeof(ULONG),
+                      &Adapter->NdisMiniportBlock.CurrentLookahead,
+                      &BytesRead);
+
+   /* FIXME: Set more stuff */
+}
+
 NDIS_STATUS
 MiniReset(
-    PLOGICAL_ADAPTER Adapter,
-    PBOOLEAN AddressingReset)
+    PLOGICAL_ADAPTER Adapter)
 /*
  * FUNCTION: Resets the miniport
  * ARGUMENTS:
  *     Adapter = Pointer to the logical adapter object
- *     AddressingReset = Set to TRUE if we need to call MiniportSetInformation later
  * RETURNS:
  *     Status of the operation
  */
 {
    NDIS_STATUS Status;
    KIRQL OldIrql;
+   BOOLEAN AddressingReset = TRUE;
 
    if (MiniIsBusy(Adapter, NdisWorkItemResetRequested)) {
        MiniQueueWorkItem(Adapter, NdisWorkItemResetRequested, NULL, FALSE);
@@ -739,7 +802,7 @@ MiniReset(
    KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
    Status = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.ResetHandler)(
             Adapter->NdisMiniportBlock.MiniportAdapterContext,
-            AddressingReset);
+            &AddressingReset);
 
    KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock);
    Adapter->NdisMiniportBlock.ResetStatus = Status;
@@ -748,6 +811,9 @@ MiniReset(
    KeLowerIrql(OldIrql);
 
    if (Status != NDIS_STATUS_PENDING) {
+       if (AddressingReset)
+           MiniDoAddressingReset(Adapter);
+
        NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_END, NULL, 0);
        NdisMIndicateStatusComplete(Adapter);
    }
@@ -763,15 +829,11 @@ MiniportHangDpc(
         PVOID SystemArgument2)
 {
   PLOGICAL_ADAPTER Adapter = DeferredContext;
-  BOOLEAN AddressingReset = FALSE;
-
 
   if (MiniCheckForHang(Adapter)) {
       NDIS_DbgPrint(MIN_TRACE, ("Miniport detected adapter hang\n"));
-      MiniReset(Adapter, &AddressingReset);
+      MiniReset(Adapter);
   }
-
-  /* FIXME: We should call MiniportSetInformation if AddressingReset is TRUE */
 }
 
 \f
@@ -1133,12 +1195,9 @@ MiniportWorker(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
                           Adapter->NdisMiniportBlock.MiniportAdapterContext,
                           &AddressingReset);
 
-            if (NdisStatus == NDIS_STATUS_PENDING)
-            {
-                KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock);
-                Adapter->NdisMiniportBlock.ResetStatus = NDIS_STATUS_PENDING;
-                KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock);
-            }
+            KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock);
+            Adapter->NdisMiniportBlock.ResetStatus = NdisStatus;
+            KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock);
 
             KeLowerIrql(OldIrql);
 
@@ -1422,7 +1481,7 @@ NdisInitializeWrapper(
   *NdisWrapperHandle = NULL;
 
 #if BREAK_ON_MINIPORT_INIT
-  __asm__ ("int $3\n");
+  DbgBreakPoint();
 #endif
 
   Miniport = ExAllocatePool(NonPagedPool, sizeof(NDIS_M_DRIVER_BLOCK));
@@ -1672,6 +1731,20 @@ NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter, PIRP Irp)
   return Status;
 }
 
+NTSTATUS
+NTAPI
+NdisICreateClose(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+  Irp->IoStatus.Status = STATUS_SUCCESS;
+  Irp->IoStatus.Information = 0;
+
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+  return STATUS_SUCCESS;
+}
+
 \f
 NTSTATUS
 NTAPI
@@ -1705,6 +1778,8 @@ NdisIPnPStartDevice(
   LARGE_INTEGER Timeout;
   UINT MaxMulticastAddresses;
   ULONG BytesWritten;
+  PLIST_ENTRY CurrentEntry;
+  PPROTOCOL_BINDING ProtocolBinding;
 
   /*
    * Prepare wrapper context used by HW and configuration routines.
@@ -1800,6 +1875,12 @@ NdisIPnPStartDevice(
    */
 
   NdisOpenConfiguration(&NdisStatus, &ConfigHandle, (NDIS_HANDLE)&WrapperContext);
+  if (NdisStatus != NDIS_STATUS_SUCCESS)
+  {
+      NDIS_DbgPrint(MIN_TRACE, ("Failed to open configuration key\n"));
+      ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
+      return NdisStatus;
+  }
 
   Size = sizeof(ULONG);
   Status = IoGetDeviceProperty(Adapter->NdisMiniportBlock.PhysicalDeviceObject,
@@ -1889,6 +1970,22 @@ NdisIPnPStartDevice(
     {
       NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter.\n"));
       ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
+      if (Adapter->NdisMiniportBlock.Interrupt)
+      {
+          KeBugCheckEx(BUGCODE_ID_DRIVER,
+                       (ULONG_PTR)Adapter,
+                       (ULONG_PTR)Adapter->NdisMiniportBlock.Interrupt,
+                       (ULONG_PTR)Adapter->NdisMiniportBlock.TimerQueue,
+                       1);
+      }
+      if (Adapter->NdisMiniportBlock.TimerQueue)
+      {
+          KeBugCheckEx(BUGCODE_ID_DRIVER,
+                       (ULONG_PTR)Adapter,
+                       (ULONG_PTR)Adapter->NdisMiniportBlock.Interrupt,
+                       (ULONG_PTR)Adapter->NdisMiniportBlock.TimerQueue,
+                       1);
+      }
       return NdisStatus;
     }
 
@@ -1961,6 +2058,17 @@ NdisIPnPStartDevice(
   /* Put adapter in adapter list for this miniport */
   ExInterlockedInsertTailList(&Adapter->NdisMiniportBlock.DriverHandle->DeviceList, &Adapter->MiniportListEntry, &Adapter->NdisMiniportBlock.DriverHandle->Lock);
 
+  /* Refresh bindings for all protocols */
+  CurrentEntry = ProtocolListHead.Flink;
+  while (CurrentEntry != &ProtocolListHead)
+  {
+      ProtocolBinding = CONTAINING_RECORD(CurrentEntry, PROTOCOL_BINDING, ListEntry);
+
+      ndisBindMiniportsToProtocol(&NdisStatus, &ProtocolBinding->Chars);
+
+      CurrentEntry = CurrentEntry->Flink;
+  }
+
   return STATUS_SUCCESS;
 }
 
@@ -2053,6 +2161,7 @@ NdisIDeviceIoControl(
   PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)DeviceObject->DeviceExtension;
   PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
   NDIS_STATUS Status = STATUS_NOT_SUPPORTED;
+  ULONG Written;
 
   Irp->IoStatus.Information = 0;
 
@@ -2065,7 +2174,8 @@ NdisIDeviceIoControl(
                                     *(PNDIS_OID)Irp->AssociatedIrp.SystemBuffer,
                                     Stack->Parameters.DeviceIoControl.OutputBufferLength,
                                     MmGetSystemAddressForMdl(Irp->MdlAddress),
-                                    &Irp->IoStatus.Information);
+                                    &Written);
+      Irp->IoStatus.Information = Written;
       break;
 
     default:
@@ -2180,7 +2290,7 @@ NdisIAddDevice(
    * Gain the access to the miniport data structure first.
    */
 
-  MiniportPtr = IoGetDriverObjectExtension(DriverObject, (PVOID)TAG('D','I','M','N'));
+  MiniportPtr = IoGetDriverObjectExtension(DriverObject, (PVOID)'NMID');
   if (MiniportPtr == NULL)
     {
       NDIS_DbgPrint(MIN_TRACE, ("Can't get driver object extension.\n"));
@@ -2431,7 +2541,7 @@ NdisMRegisterMiniport(
    * structure in the driver extension or what?
    */
 
-  Status = IoAllocateDriverObjectExtension(Miniport->DriverObject, (PVOID)TAG('D','I','M','N'),
+  Status = IoAllocateDriverObjectExtension(Miniport->DriverObject, (PVOID)'NMID',
                                            sizeof(PNDIS_M_DRIVER_BLOCK), (PVOID*)&MiniportPtr);
   if (!NT_SUCCESS(Status))
     {
@@ -2441,6 +2551,8 @@ NdisMRegisterMiniport(
 
   *MiniportPtr = Miniport;
 
+  Miniport->DriverObject->MajorFunction[IRP_MJ_CREATE] = NdisICreateClose;
+  Miniport->DriverObject->MajorFunction[IRP_MJ_CLOSE] = NdisICreateClose;
   Miniport->DriverObject->MajorFunction[IRP_MJ_PNP] = NdisIDispatchPnp;
   Miniport->DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = NdisIShutdown;
   Miniport->DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NdisIDeviceIoControl;
@@ -2902,6 +3014,12 @@ NdisMRegisterDevice(
 
     DriverBlock->DriverObject->MajorFunction[IRP_MJ_PNP] = NdisIDispatchPnp;
 
+    if (!DriverBlock->DriverObject->MajorFunction[IRP_MJ_CREATE])
+        DriverBlock->DriverObject->MajorFunction[IRP_MJ_CREATE] = NdisICreateClose;
+
+    if (!DriverBlock->DriverObject->MajorFunction[IRP_MJ_CLOSE])
+        DriverBlock->DriverObject->MajorFunction[IRP_MJ_CLOSE] = NdisICreateClose;
+
     DeviceBlock->DeviceObject = DeviceObject;
     DeviceBlock->SymbolicName = SymbolicName;