[HDAUDBUS] Wait until the correct number of responses was received. CORE-15465
authorThomas Faber <thomas.faber@reactos.org>
Wed, 27 Feb 2019 14:02:38 +0000 (15:02 +0100)
committerThomas Faber <thomas.faber@reactos.org>
Thu, 28 Feb 2019 09:27:06 +0000 (10:27 +0100)
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
drivers/wdm/audio/hdaudbus/hdaudbus.h

index a6d2ca8..8a08371 100644 (file)
@@ -129,6 +129,7 @@ HDA_DpcForIsr(
         /* store response */
         Codec->Responses[Codec->ResponseCount] = Response;
         Codec->ResponseCount++;
         /* 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;
 
             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);
     }
 
             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));
     }
     if (Responses != NULL) {
         memcpy(Responses, Codec->Responses, Codec->ResponseCount * sizeof(ULONG));
     }
@@ -207,6 +212,7 @@ HDA_InitCodec(
 
     /* init codec */
     Entry->Addr = codecAddress;
 
     /* init codec */
     Entry->Addr = codecAddress;
+    KeInitializeSemaphore(&Entry->ResponseSemaphore, 0, MAX_CODEC_RESPONSES);
 
     /* get device extension */
     DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
     /* get device extension */
     DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
index 6bdbc54..3a957c1 100644 (file)
@@ -53,6 +53,7 @@ typedef struct
 
        ULONG Responses[MAX_CODEC_RESPONSES];
        ULONG ResponseCount;
 
        ULONG Responses[MAX_CODEC_RESPONSES];
        ULONG ResponseCount;
+       KSEMAPHORE ResponseSemaphore;
 
        PHDA_CODEC_AUDIO_GROUP AudioGroups[HDA_MAX_AUDIO_GROUPS];
        ULONG AudioGroupCount;
 
        PHDA_CODEC_AUDIO_GROUP AudioGroups[HDA_MAX_AUDIO_GROUPS];
        ULONG AudioGroupCount;