[HAL] Use a spin lock for the DMA adapter list. CORE-16611 2301/head
authorThomas Faber <thomas.faber@reactos.org>
Fri, 31 Jan 2020 22:03:57 +0000 (23:03 +0100)
committerThomas Faber <thomas.faber@reactos.org>
Sun, 9 Feb 2020 07:32:56 +0000 (08:32 +0100)
This is necessary because HalPutDmaAdapter can be called at DISPATCH_LEVEL.

hal/halx86/generic/dma.c

index 7bcfc33..39c2efe 100644 (file)
@@ -85,6 +85,7 @@
 
 #ifndef _MINIHAL_
 static KEVENT HalpDmaLock;
+static KSPIN_LOCK HalpDmaAdapterListLock;
 static LIST_ENTRY HalpDmaAdapterList;
 static PADAPTER_OBJECT HalpEisaAdapter[8];
 #endif
@@ -165,6 +166,7 @@ HalpInitDma(VOID)
      * first map buffers.
      */
     InitializeListHead(&HalpDmaAdapterList);
+    KeInitializeSpinLock(&HalpDmaAdapterListLock);
     KeInitializeEvent(&HalpDmaLock, NotificationEvent, TRUE);
     HalpMasterAdapter = HalpDmaAllocateMasterAdapter();
 
@@ -621,6 +623,7 @@ HalGetAdapter(IN PDEVICE_DESCRIPTION DeviceDescription,
     BOOLEAN EisaAdapter;
     ULONG MapRegisters;
     ULONG MaximumLength;
+    KIRQL OldIrql;
 
     /* Validate parameters in device description */
     if (DeviceDescription->Version > DEVICE_DESCRIPTION_VERSION2) return NULL;
@@ -688,8 +691,7 @@ HalGetAdapter(IN PDEVICE_DESCRIPTION DeviceDescription,
     }
 
     /*
-     * Acquire the DMA lock that is used to protect adapter lists and
-     * EISA adapter array.
+     * Acquire the DMA lock that is used to protect the EISA adapter array.
      */
     KeWaitForSingleObject(&HalpDmaLock, Executive, KernelMode, FALSE, NULL);
 
@@ -745,14 +747,20 @@ HalGetAdapter(IN PDEVICE_DESCRIPTION DeviceDescription,
         }
     }
 
-    if (!EisaAdapter) InsertTailList(&HalpDmaAdapterList, &AdapterObject->AdapterList);
-
     /*
-     * Release the DMA lock. HalpDmaAdapterList and HalpEisaAdapter will
-     * no longer be touched, so we don't need it.
+     * Release the DMA lock. HalpEisaAdapter will no longer be touched,
+     * so we don't need it.
      */
     KeSetEvent(&HalpDmaLock, 0, 0);
 
+    if (!EisaAdapter)
+    {
+        /* If it's not one of the static adapters, add it to the list */
+        KeAcquireSpinLock(&HalpDmaAdapterListLock, &OldIrql);
+        InsertTailList(&HalpDmaAdapterList, &AdapterObject->AdapterList);
+        KeReleaseSpinLock(&HalpDmaAdapterListLock, OldIrql);
+    }
+
     /*
      * Setup the values in the adapter object that are common for all
      * types of buses.
@@ -818,11 +826,12 @@ VOID
 NTAPI
 HalPutDmaAdapter(IN PADAPTER_OBJECT AdapterObject)
 {
+    KIRQL OldIrql;
     if (AdapterObject->ChannelNumber == 0xFF)
     {
-        KeWaitForSingleObject(&HalpDmaLock, Executive, KernelMode, FALSE, NULL);
+        KeAcquireSpinLock(&HalpDmaAdapterListLock, &OldIrql);
         RemoveEntryList(&AdapterObject->AdapterList);
-        KeSetEvent(&HalpDmaLock, 0, 0);
+        KeReleaseSpinLock(&HalpDmaAdapterListLock, OldIrql);
     }
 
     ObDereferenceObject(AdapterObject);