[HDAUDBUS] Handle responses in a DPC instead of the ISR.

This commit is contained in:
Thomas Faber 2019-02-27 14:34:23 +01:00
parent a7431880bd
commit 8530ae9950
No known key found for this signature in database
GPG key ID: 076E7C3D44720826
3 changed files with 59 additions and 42 deletions

View file

@ -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,

View file

@ -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 */

View file

@ -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