https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1001e6089fecaa1b13c4d91a162d956742c4134e

commit 1001e6089fecaa1b13c4d91a162d956742c4134e
Author:     Thomas Faber <thomas.fa...@reactos.org>
AuthorDate: Wed Feb 27 15:02:38 2019 +0100
Commit:     Thomas Faber <thomas.fa...@reactos.org>
CommitDate: Thu Feb 28 10:27:06 2019 +0100

    [HDAUDBUS] Wait until the correct number of responses was received. 
CORE-15465
    
    We previously only gave the device a hard-coded amount of time to respond,
    which could lead to interpreting the contents of uninitialized memory as
    a response. This would lead to an unreasonably large number of audio 
function
    groups being detected.
    
    A KSEMAPHORE mirrors what Haiku uses here, though it may not be the optimal
    synchronization primitive for this case under Windows.
---
 drivers/wdm/audio/hdaudbus/fdo.cpp    | 16 +++++++++++-----
 drivers/wdm/audio/hdaudbus/hdaudbus.h |  1 +
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/wdm/audio/hdaudbus/fdo.cpp 
b/drivers/wdm/audio/hdaudbus/fdo.cpp
index a6d2ca8f11..8a08371fd2 100644
--- a/drivers/wdm/audio/hdaudbus/fdo.cpp
+++ b/drivers/wdm/audio/hdaudbus/fdo.cpp
@@ -129,6 +129,7 @@ HDA_DpcForIsr(
         /* store response */
         Codec->Responses[Codec->ResponseCount] = Response;
         Codec->ResponseCount++;
+        KeReleaseSemaphore(&Codec->ResponseSemaphore, IO_NO_INCREMENT, 1, 
FALSE);
     }
 }
 
@@ -167,17 +168,21 @@ HDA_SendVerbs(
 
             DeviceExtension->CorbBase[WritePosition] = Verbs[Sent++];
             DeviceExtension->CorbWritePos = WritePosition;
-
-            // FIXME HACK
-            // do proper synchronization
-            WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + 
HDAC_CORB_WRITE_POS), DeviceExtension->CorbWritePos);
-            KeStallExecutionProcessor(30);
             Queued++;
         }
 
         WRITE_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + 
HDAC_CORB_WRITE_POS), DeviceExtension->CorbWritePos);
     }
 
+    while (Queued--)
+    {
+        KeWaitForSingleObject(&Codec->ResponseSemaphore,
+                              Executive,
+                              KernelMode,
+                              FALSE,
+                              NULL);
+    }
+
     if (Responses != NULL) {
         memcpy(Responses, Codec->Responses, Codec->ResponseCount * 
sizeof(ULONG));
     }
@@ -207,6 +212,7 @@ HDA_InitCodec(
 
     /* init codec */
     Entry->Addr = codecAddress;
+    KeInitializeSemaphore(&Entry->ResponseSemaphore, 0, MAX_CODEC_RESPONSES);
 
     /* get device extension */
     DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
diff --git a/drivers/wdm/audio/hdaudbus/hdaudbus.h 
b/drivers/wdm/audio/hdaudbus/hdaudbus.h
index 6bdbc542f4..3a957c1506 100644
--- a/drivers/wdm/audio/hdaudbus/hdaudbus.h
+++ b/drivers/wdm/audio/hdaudbus/hdaudbus.h
@@ -53,6 +53,7 @@ typedef struct
 
        ULONG Responses[MAX_CODEC_RESPONSES];
        ULONG ResponseCount;
+       KSEMAPHORE ResponseSemaphore;
 
        PHDA_CODEC_AUDIO_GROUP AudioGroups[HDA_MAX_AUDIO_GROUPS];
        ULONG AudioGroupCount;

Reply via email to