https://git.reactos.org/?p=reactos.git;a=commitdiff;h=584baf79d935a95987ac5…
commit 584baf79d935a95987ac5752566185912968f81c
Author: Thomas Faber <thomas.faber(a)reactos.org>
AuthorDate: Mon Feb 25 13:47:14 2019 +0100
Commit: Thomas Faber <thomas.faber(a)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)