https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8530ae99509ae81041fdb…
commit 8530ae99509ae81041fdbc98b336467a84f88243
Author: Thomas Faber <thomas.faber(a)reactos.org>
AuthorDate: Wed Feb 27 14:34:23 2019 +0100
Commit: Thomas Faber <thomas.faber(a)reactos.org>
CommitDate: Thu Feb 28 10:06:18 2019 +0100
[HDAUDBUS] Handle responses in a DPC instead of the ISR.
---
drivers/wdm/audio/hdaudbus/fdo.cpp | 93 ++++++++++++++++++++-------------
drivers/wdm/audio/hdaudbus/hdaudbus.cpp | 1 +
drivers/wdm/audio/hdaudbus/hdaudbus.h | 7 +--
3 files changed, 59 insertions(+), 42 deletions(-)
diff --git a/drivers/wdm/audio/hdaudbus/fdo.cpp b/drivers/wdm/audio/hdaudbus/fdo.cpp
index 36a6a0fa6a..a6d2ca8f11 100644
--- a/drivers/wdm/audio/hdaudbus/fdo.cpp
+++ b/drivers/wdm/audio/hdaudbus/fdo.cpp
@@ -13,14 +13,14 @@ HDA_InterruptService(
IN PKINTERRUPT Interrupt,
IN PVOID ServiceContext)
{
+ PDEVICE_OBJECT DeviceObject;
PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
- ULONG InterruptStatus, Response, ResponseFlags, Cad;
+ ULONG InterruptStatus;
UCHAR RirbStatus, CorbStatus;
- USHORT WritePos;
- PHDA_CODEC_ENTRY Codec;
/* get device extension */
- DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)ServiceContext;
+ DeviceObject = static_cast<PDEVICE_OBJECT>(ServiceContext);
+ DeviceExtension =
static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
ASSERT(DeviceExtension->IsFDO == TRUE);
// Check if this interrupt is ours
@@ -46,38 +46,7 @@ HDA_InterruptService(
}
if ((RirbStatus & RIRB_STATUS_RESPONSE) != 0) {
- WritePos = (READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase +
HDAC_RIRB_WRITE_POS)) + 1) % DeviceExtension->RirbLength;
-
- for (; DeviceExtension->RirbReadPos != WritePos;
DeviceExtension->RirbReadPos = (DeviceExtension->RirbReadPos + 1) %
DeviceExtension->RirbLength)
- {
-
- Response =
DeviceExtension->RirbBase[DeviceExtension->RirbReadPos].response;
- ResponseFlags =
DeviceExtension->RirbBase[DeviceExtension->RirbReadPos].flags;
- Cad = ResponseFlags & RESPONSE_FLAGS_CODEC_MASK;
- DPRINT1("Response %lx ResponseFlags %lx Cad %lx\n",
Response, ResponseFlags, Cad);
-
- /* get codec */
- Codec = DeviceExtension->Codecs[Cad];
- if (Codec == NULL)
- {
- DPRINT1("hda: response for unknown codec %x Response %x
ResponseFlags %x\n", Cad, Response, ResponseFlags);
- continue;
- }
-
- /* check response count */
- if (Codec->ResponseCount >= MAX_CODEC_RESPONSES)
- {
- DPRINT1("too many responses for codec %x Response %x
ResponseFlags %x\n", Cad, Response, ResponseFlags);
- continue;
- }
-
- // FIXME handle unsolicited responses
- ASSERT((ResponseFlags & RESPONSE_FLAGS_UNSOLICITED) == 0);
-
- /* store response */
- Codec->Responses[Codec->ResponseCount] = Response;
- Codec->ResponseCount++;
- }
+ IoRequestDpc(DeviceObject, NULL, NULL);
}
if ((RirbStatus & RIRB_STATUS_OVERRUN) != 0)
@@ -113,6 +82,56 @@ HDA_InterruptService(
return TRUE;
}
+VOID
+NTAPI
+HDA_DpcForIsr(
+ _In_ PKDPC Dpc,
+ _In_opt_ PDEVICE_OBJECT DeviceObject,
+ _Inout_ PIRP Irp,
+ _In_opt_ PVOID Context)
+{
+ PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
+ ULONG Response, ResponseFlags, Cad;
+ USHORT WritePos;
+ PHDA_CODEC_ENTRY Codec;
+
+ /* get device extension */
+ DeviceExtension =
static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
+ ASSERT(DeviceExtension->IsFDO == TRUE);
+
+ WritePos = (READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase +
HDAC_RIRB_WRITE_POS)) + 1) % DeviceExtension->RirbLength;
+
+ for (; DeviceExtension->RirbReadPos != WritePos; DeviceExtension->RirbReadPos =
(DeviceExtension->RirbReadPos + 1) % DeviceExtension->RirbLength)
+ {
+ Response =
DeviceExtension->RirbBase[DeviceExtension->RirbReadPos].response;
+ ResponseFlags =
DeviceExtension->RirbBase[DeviceExtension->RirbReadPos].flags;
+ Cad = ResponseFlags & RESPONSE_FLAGS_CODEC_MASK;
+ DPRINT1("Response %lx ResponseFlags %lx Cad %lx\n", Response,
ResponseFlags, Cad);
+
+ /* get codec */
+ Codec = DeviceExtension->Codecs[Cad];
+ if (Codec == NULL)
+ {
+ DPRINT1("hda: response for unknown codec %x Response %x ResponseFlags
%x\n", Cad, Response, ResponseFlags);
+ continue;
+ }
+
+ /* check response count */
+ if (Codec->ResponseCount >= MAX_CODEC_RESPONSES)
+ {
+ DPRINT1("too many responses for codec %x Response %x ResponseFlags
%x\n", Cad, Response, ResponseFlags);
+ continue;
+ }
+
+ // FIXME handle unsolicited responses
+ ASSERT((ResponseFlags & RESPONSE_FLAGS_UNSOLICITED) == 0);
+
+ /* store response */
+ Codec->Responses[Codec->ResponseCount] = Response;
+ Codec->ResponseCount++;
+ }
+}
+
VOID
HDA_SendVerbs(
@@ -582,7 +601,7 @@ HDA_FDOStartDevice(
{
Status = IoConnectInterrupt(&DeviceExtension->Interrupt,
HDA_InterruptService,
- (PVOID)DeviceExtension,
+ DeviceObject,
NULL,
Descriptor->u.Interrupt.Vector,
Descriptor->u.Interrupt.Level,
diff --git a/drivers/wdm/audio/hdaudbus/hdaudbus.cpp
b/drivers/wdm/audio/hdaudbus/hdaudbus.cpp
index aa62a820ba..96438b786b 100644
--- a/drivers/wdm/audio/hdaudbus/hdaudbus.cpp
+++ b/drivers/wdm/audio/hdaudbus/hdaudbus.cpp
@@ -284,6 +284,7 @@ HDA_AddDevice(
/* init device extension*/
DeviceExtension->IsFDO = TRUE;
DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject,
PhysicalDeviceObject);
+ IoInitializeDpcRequest(DeviceObject, HDA_DpcForIsr);
RtlZeroMemory(DeviceExtension->Codecs, sizeof(PHDA_CODEC_ENTRY) * (HDA_MAX_CODECS
+ 1));
/* set device flags */
diff --git a/drivers/wdm/audio/hdaudbus/hdaudbus.h
b/drivers/wdm/audio/hdaudbus/hdaudbus.h
index f246238cd9..6bdbc542f4 100644
--- a/drivers/wdm/audio/hdaudbus/hdaudbus.h
+++ b/drivers/wdm/audio/hdaudbus/hdaudbus.h
@@ -116,11 +116,8 @@ FreeItem(
IN PVOID Item);
/* fdo.cpp */
-BOOLEAN
-NTAPI
-HDA_InterruptService(
- IN PKINTERRUPT Interrupt,
- IN PVOID ServiceContext);
+KSERVICE_ROUTINE HDA_InterruptService;
+IO_DPC_ROUTINE HDA_DpcForIsr;
NTSTATUS
NTAPI