https://git.reactos.org/?p=reactos.git;a=commitdiff;h=584baf79d935a95987ac57...
commit 584baf79d935a95987ac5752566185912968f81c Author: Thomas Faber thomas.faber@reactos.org AuthorDate: Mon Feb 25 13:47:14 2019 +0100 Commit: Thomas Faber thomas.faber@reactos.org CommitDate: Tue Feb 26 09:51:38 2019 +0100
[HDAUDBUS] Implement PDO removal. CORE-14617 --- drivers/wdm/audio/hdaudbus/fdo.cpp | 14 ++++++++++++++ drivers/wdm/audio/hdaudbus/hdaudbus.cpp | 23 +++++++++++++++++++++++ drivers/wdm/audio/hdaudbus/hdaudbus.h | 5 +++++ drivers/wdm/audio/hdaudbus/pdo.cpp | 22 ++++++++++++++++++++++ 4 files changed, 64 insertions(+)
diff --git a/drivers/wdm/audio/hdaudbus/fdo.cpp b/drivers/wdm/audio/hdaudbus/fdo.cpp index 44e41d22c1..a14b5b9dda 100644 --- a/drivers/wdm/audio/hdaudbus/fdo.cpp +++ b/drivers/wdm/audio/hdaudbus/fdo.cpp @@ -248,6 +248,7 @@ HDA_InitCodec( /* init child pdo*/ ChildDeviceExtension = (PHDA_PDO_DEVICE_EXTENSION)AudioGroup->ChildPDO->DeviceExtension; ChildDeviceExtension->IsFDO = FALSE; + ChildDeviceExtension->ReportedMissing = FALSE; ChildDeviceExtension->Codec = Entry; ChildDeviceExtension->AudioGroup = AudioGroup; ChildDeviceExtension->FDO = DeviceObject; @@ -646,6 +647,8 @@ HDA_FDORemoveDevice( PHDA_FDO_DEVICE_EXTENSION DeviceExtension; ULONG CodecIndex, AFGIndex; PHDA_CODEC_ENTRY CodecEntry; + PDEVICE_OBJECT ChildPDO; + PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
/* get device extension */ DeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); @@ -670,6 +673,7 @@ HDA_FDORemoveDevice( { MmFreeContiguousMemory(DeviceExtension->CorbBase); } + for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++) { CodecEntry = DeviceExtension->Codecs[CodecIndex]; @@ -680,6 +684,16 @@ HDA_FDORemoveDevice(
for (AFGIndex = 0; AFGIndex < CodecEntry->AudioGroupCount; AFGIndex++) { + ChildPDO = CodecEntry->AudioGroups[AFGIndex]->ChildPDO; + if (ChildPDO != NULL) + { + ChildDeviceExtension = static_cast<PHDA_PDO_DEVICE_EXTENSION>(ChildPDO->DeviceExtension); + ChildDeviceExtension->Codec = NULL; + ChildDeviceExtension->AudioGroup = NULL; + ChildDeviceExtension->FDO = NULL; + ChildDeviceExtension->ReportedMissing = TRUE; + HDA_PDORemoveDevice(ChildPDO); + } FreeItem(CodecEntry->AudioGroups[AFGIndex]); } FreeItem(CodecEntry); diff --git a/drivers/wdm/audio/hdaudbus/hdaudbus.cpp b/drivers/wdm/audio/hdaudbus/hdaudbus.cpp index 79b07463b8..0202385a82 100644 --- a/drivers/wdm/audio/hdaudbus/hdaudbus.cpp +++ b/drivers/wdm/audio/hdaudbus/hdaudbus.cpp @@ -39,6 +39,9 @@ HDA_FdoPnp( NTSTATUS Status; PIO_STACK_LOCATION IoStack; PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; + ULONG CodecIndex, AFGIndex; + PHDA_CODEC_ENTRY CodecEntry; + PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -52,6 +55,19 @@ HDA_FdoPnp( return Status; case IRP_MN_REMOVE_DEVICE: return HDA_FDORemoveDevice(DeviceObject, Irp); + case IRP_MN_SURPRISE_REMOVAL: + for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++) + { + CodecEntry = FDODeviceExtension->Codecs[CodecIndex]; + + for (AFGIndex = 0; AFGIndex < CodecEntry->AudioGroupCount; AFGIndex++) + { + ChildDeviceExtension = static_cast<PHDA_PDO_DEVICE_EXTENSION>(CodecEntry->AudioGroups[AFGIndex]->ChildPDO->DeviceExtension); + ChildDeviceExtension->ReportedMissing = TRUE; + } + } + Irp->IoStatus.Status = STATUS_SUCCESS; + break; case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE: Irp->IoStatus.Status = STATUS_SUCCESS; @@ -92,6 +108,13 @@ HDA_PdoPnp( /* no op for pdo */ Status = STATUS_SUCCESS; break; + case IRP_MN_REMOVE_DEVICE: + Status = HDA_PDORemoveDevice(DeviceObject); + break; + case IRP_MN_QUERY_REMOVE_DEVICE: + case IRP_MN_CANCEL_REMOVE_DEVICE: + Status = STATUS_SUCCESS; + break; case IRP_MN_QUERY_BUS_INFORMATION: /* query bus information */ Status = HDA_PDOQueryBusInformation(Irp); diff --git a/drivers/wdm/audio/hdaudbus/hdaudbus.h b/drivers/wdm/audio/hdaudbus/hdaudbus.h index f29aae5919..f246238cd9 100644 --- a/drivers/wdm/audio/hdaudbus/hdaudbus.h +++ b/drivers/wdm/audio/hdaudbus/hdaudbus.h @@ -84,6 +84,7 @@ typedef struct typedef struct { BOOLEAN IsFDO; + BOOLEAN ReportedMissing; PHDA_CODEC_ENTRY Codec; PHDA_CODEC_AUDIO_GROUP AudioGroup; PDEVICE_OBJECT FDO; @@ -149,6 +150,10 @@ HDA_SendVerbs(
/* pdo.cpp*/
+NTSTATUS +HDA_PDORemoveDevice( + _In_ PDEVICE_OBJECT DeviceObject); + NTSTATUS HDA_PDOQueryBusInformation( IN PIRP Irp); diff --git a/drivers/wdm/audio/hdaudbus/pdo.cpp b/drivers/wdm/audio/hdaudbus/pdo.cpp index b0e3c4f51c..f93c6fa168 100644 --- a/drivers/wdm/audio/hdaudbus/pdo.cpp +++ b/drivers/wdm/audio/hdaudbus/pdo.cpp @@ -7,6 +7,28 @@ */ #include "hdaudbus.h"
+NTSTATUS +HDA_PDORemoveDevice( + _In_ PDEVICE_OBJECT DeviceObject) +{ + PHDA_PDO_DEVICE_EXTENSION DeviceExtension; + + /* get device extension */ + DeviceExtension = static_cast<PHDA_PDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); + ASSERT(DeviceExtension->IsFDO == FALSE); + + if (DeviceExtension->ReportedMissing) + { + if (DeviceExtension->AudioGroup != NULL) + { + DeviceExtension->AudioGroup->ChildPDO = NULL; + } + IoDeleteDevice(DeviceObject); + } + + return STATUS_SUCCESS; +} + NTSTATUS HDA_PDOQueryBusInformation( IN PIRP Irp)