diff --git a/drivers/wdm/audio/hdaudbus/fdo.cpp b/drivers/wdm/audio/hdaudbus/fdo.cpp index b032073eb9..6b98d19cdf 100644 --- a/drivers/wdm/audio/hdaudbus/fdo.cpp +++ b/drivers/wdm/audio/hdaudbus/fdo.cpp @@ -235,7 +235,7 @@ HDA_InitCodec( AudioGroup->FunctionGroup = FUNCTION_GROUP_NODETYPE_AUDIO; // Found an Audio Function Group! - DPRINT1("NodeId %x found an audio function group!\n"); + DPRINT1("NodeId %x found an audio function group!\n", NodeId); Status = IoCreateDevice(DeviceObject->DriverObject, sizeof(HDA_PDO_DEVICE_EXTENSION), NULL, FILE_DEVICE_SOUND, FILE_AUTOGENERATED_DEVICE_NAME, FALSE, &AudioGroup->ChildPDO); if (!NT_SUCCESS(Status)) @@ -257,10 +257,12 @@ HDA_InitCodec( AudioGroup->ChildPDO->Flags &= ~DO_DEVICE_INITIALIZING; /* add audio group*/ + ASSERT(Entry->AudioGroupCount < HDA_MAX_AUDIO_GROUPS); Entry->AudioGroups[Entry->AudioGroupCount] = AudioGroup; Entry->AudioGroupCount++; } } + DPRINT1("Codec %lu %p has %lu AudioGroups\n", codecAddress, Entry, Entry->AudioGroupCount); return STATUS_SUCCESS; } @@ -538,11 +540,13 @@ HDA_FDOStartDevice( /* get device extension */ DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; ASSERT(DeviceExtension->IsFDO == TRUE); + NT_VERIFY(InterlockedExchange(&DeviceExtension->Started, 1) == 0); /* forward irp to lower device */ Status = HDA_SyncForwardIrp(DeviceExtension->LowerDevice, Irp); if (!NT_SUCCESS(Status)) { + NT_VERIFY(InterlockedExchange(&DeviceExtension->Started, 0) == 1); // failed to start DPRINT1("HDA_StartDevice Lower device failed to start %x\n", Status); return Status; @@ -592,11 +596,19 @@ HDA_FDOStartDevice( { // Get controller into valid state Status = HDA_ResetController(DeviceObject); - if (!NT_SUCCESS(Status)) return Status; + if (!NT_SUCCESS(Status)) + { + NT_VERIFY(InterlockedExchange(&DeviceExtension->Started, 0) == 1); + return Status; + } // Setup CORB/RIRB/DMA POS Status = HDA_InitCorbRirbPos(DeviceObject); - if (!NT_SUCCESS(Status)) return Status; + if (!NT_SUCCESS(Status)) + { + NT_VERIFY(InterlockedExchange(&DeviceExtension->Started, 0) == 1); + return Status; + } // Don't enable codec state change interrupts. We don't handle @@ -613,6 +625,7 @@ HDA_FDOStartDevice( Value = READ_REGISTER_USHORT((PUSHORT)(DeviceExtension->RegBase + HDAC_STATE_STATUS)); if (!Value) { + NT_VERIFY(InterlockedExchange(&DeviceExtension->Started, 0) == 1); DPRINT1("hda: bad codec status\n"); return STATUS_UNSUCCESSFUL; } @@ -622,11 +635,26 @@ HDA_FDOStartDevice( DPRINT1("Codecs %lx\n", Value); for (Index = 0; Index < HDA_MAX_CODECS; Index++) { if ((Value & (1 << Index)) != 0) { - HDA_InitCodec(DeviceObject, Index); + Status = HDA_InitCodec(DeviceObject, Index); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Codec %lu %p initialization failed\n", Index, DeviceExtension->Codecs[Index]); + ASSERTMSG("Codec initialization failed", FALSE); + } } } + Status = STATUS_SUCCESS; } + DPRINT1("Device %p started with status %lx\n", DeviceObject, Status); + if (NT_SUCCESS(Status)) + { + NT_VERIFY(InterlockedExchange(&DeviceExtension->Started, 2) == 1); + } + else + { + NT_VERIFY(InterlockedExchange(&DeviceExtension->Started, 0) == 1); + } return Status; } @@ -644,6 +672,7 @@ HDA_FDOQueryBusRelations( /* get device extension */ DeviceExtension = (PHDA_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; ASSERT(DeviceExtension->IsFDO == TRUE); + NT_VERIFY(DeviceExtension->Started == 2); DeviceCount = 0; for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++) @@ -669,14 +698,28 @@ HDA_FDOQueryBusRelations( continue; Codec = DeviceExtension->Codecs[CodecIndex]; + ASSERT(Codec->AudioGroupCount <= HDA_MAX_AUDIO_GROUPS); for (AFGIndex = 0; AFGIndex < Codec->AudioGroupCount; AFGIndex++) { + if (Codec->AudioGroups[AFGIndex] == NULL) + { + DPRINT1("Codec %lu %p AudioGroup %lu is NULL\n", CodecIndex, Codec, AFGIndex); + ASSERTMSG("AudioGroup is NULL", FALSE); + } + if (Codec->AudioGroups[AFGIndex]->ChildPDO == NULL) + { + DPRINT1("Codec %lu %p AudioGroup %lu %p ChildPDO is NULL\n", CodecIndex, Codec, AFGIndex, Codec->AudioGroups[AFGIndex]); + ASSERTMSG("ChildPDO is NULL", FALSE); + } + ASSERT(DeviceRelations->Count < DeviceCount); DeviceRelations->Objects[DeviceRelations->Count] = Codec->AudioGroups[AFGIndex]->ChildPDO; ObReferenceObject(Codec->AudioGroups[AFGIndex]->ChildPDO); DeviceRelations->Count++; } } + ASSERT(DeviceRelations->Count == DeviceCount); + /* FIXME handle existing device relations */ ASSERT(Irp->IoStatus.Information == 0); diff --git a/drivers/wdm/audio/hdaudbus/hdaudbus.cpp b/drivers/wdm/audio/hdaudbus/hdaudbus.cpp index 9239354c12..b2d81f1c59 100644 --- a/drivers/wdm/audio/hdaudbus/hdaudbus.cpp +++ b/drivers/wdm/audio/hdaudbus/hdaudbus.cpp @@ -115,7 +115,31 @@ HDA_Pnp( { Status = Irp->IoStatus.Status; } - } + } + else if (IoStack->MinorFunction == IRP_MN_QUERY_STOP_DEVICE) + { + ASSERTMSG("Device stop not implemented (query)", FALSE); + } + else if (IoStack->MinorFunction == IRP_MN_CANCEL_STOP_DEVICE) + { + ASSERTMSG("Device stop not implemented (cancel)", FALSE); + } + else if (IoStack->MinorFunction == IRP_MN_STOP_DEVICE) + { + ASSERTMSG("Device stop not implemented", FALSE); + } + else if (IoStack->MinorFunction == IRP_MN_QUERY_REMOVE_DEVICE) + { + ASSERTMSG("Device removal not implemented (query)", FALSE); + } + else if (IoStack->MinorFunction == IRP_MN_CANCEL_REMOVE_DEVICE) + { + ASSERTMSG("Device removal not implemented (cancel)", FALSE); + } + else if (IoStack->MinorFunction == IRP_MN_REMOVE_DEVICE) + { + ASSERTMSG("Device removal not implemented", FALSE); + } else { /* get default status */ @@ -238,6 +262,7 @@ IN PDEVICE_OBJECT PhysicalDeviceObject) /* init device extension*/ DeviceExtension->IsFDO = TRUE; DeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject); + DeviceExtension->Started = 0; 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 1496f6de24..ab672e8005 100644 --- a/drivers/wdm/audio/hdaudbus/hdaudbus.h +++ b/drivers/wdm/audio/hdaudbus/hdaudbus.h @@ -64,7 +64,7 @@ typedef struct { BOOLEAN IsFDO; PDEVICE_OBJECT LowerDevice; - + LONG Started; PUCHAR RegBase; PKINTERRUPT Interrupt;