[HDAUDBUS] Implement PDO removal. CORE-14617

This commit is contained in:
Thomas Faber 2019-02-25 13:47:14 +01:00
parent c8c0fc8d64
commit 584baf79d9
No known key found for this signature in database
GPG key ID: 076E7C3D44720826
4 changed files with 64 additions and 0 deletions

View file

@ -248,6 +248,7 @@ HDA_InitCodec(
/* init child pdo*/ /* init child pdo*/
ChildDeviceExtension = (PHDA_PDO_DEVICE_EXTENSION)AudioGroup->ChildPDO->DeviceExtension; ChildDeviceExtension = (PHDA_PDO_DEVICE_EXTENSION)AudioGroup->ChildPDO->DeviceExtension;
ChildDeviceExtension->IsFDO = FALSE; ChildDeviceExtension->IsFDO = FALSE;
ChildDeviceExtension->ReportedMissing = FALSE;
ChildDeviceExtension->Codec = Entry; ChildDeviceExtension->Codec = Entry;
ChildDeviceExtension->AudioGroup = AudioGroup; ChildDeviceExtension->AudioGroup = AudioGroup;
ChildDeviceExtension->FDO = DeviceObject; ChildDeviceExtension->FDO = DeviceObject;
@ -646,6 +647,8 @@ HDA_FDORemoveDevice(
PHDA_FDO_DEVICE_EXTENSION DeviceExtension; PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
ULONG CodecIndex, AFGIndex; ULONG CodecIndex, AFGIndex;
PHDA_CODEC_ENTRY CodecEntry; PHDA_CODEC_ENTRY CodecEntry;
PDEVICE_OBJECT ChildPDO;
PHDA_PDO_DEVICE_EXTENSION ChildDeviceExtension;
/* get device extension */ /* get device extension */
DeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension); DeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
@ -670,6 +673,7 @@ HDA_FDORemoveDevice(
{ {
MmFreeContiguousMemory(DeviceExtension->CorbBase); MmFreeContiguousMemory(DeviceExtension->CorbBase);
} }
for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++) for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
{ {
CodecEntry = DeviceExtension->Codecs[CodecIndex]; CodecEntry = DeviceExtension->Codecs[CodecIndex];
@ -680,6 +684,16 @@ HDA_FDORemoveDevice(
for (AFGIndex = 0; AFGIndex < CodecEntry->AudioGroupCount; AFGIndex++) 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->AudioGroups[AFGIndex]);
} }
FreeItem(CodecEntry); FreeItem(CodecEntry);

View file

@ -39,6 +39,9 @@ HDA_FdoPnp(
NTSTATUS Status; NTSTATUS Status;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
PHDA_FDO_DEVICE_EXTENSION FDODeviceExtension; 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); FDODeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
@ -52,6 +55,19 @@ HDA_FdoPnp(
return Status; return Status;
case IRP_MN_REMOVE_DEVICE: case IRP_MN_REMOVE_DEVICE:
return HDA_FDORemoveDevice(DeviceObject, Irp); 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_QUERY_REMOVE_DEVICE:
case IRP_MN_CANCEL_REMOVE_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE:
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
@ -92,6 +108,13 @@ HDA_PdoPnp(
/* no op for pdo */ /* no op for pdo */
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
break; 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: case IRP_MN_QUERY_BUS_INFORMATION:
/* query bus information */ /* query bus information */
Status = HDA_PDOQueryBusInformation(Irp); Status = HDA_PDOQueryBusInformation(Irp);

View file

@ -84,6 +84,7 @@ typedef struct
typedef struct typedef struct
{ {
BOOLEAN IsFDO; BOOLEAN IsFDO;
BOOLEAN ReportedMissing;
PHDA_CODEC_ENTRY Codec; PHDA_CODEC_ENTRY Codec;
PHDA_CODEC_AUDIO_GROUP AudioGroup; PHDA_CODEC_AUDIO_GROUP AudioGroup;
PDEVICE_OBJECT FDO; PDEVICE_OBJECT FDO;
@ -149,6 +150,10 @@ HDA_SendVerbs(
/* pdo.cpp*/ /* pdo.cpp*/
NTSTATUS
HDA_PDORemoveDevice(
_In_ PDEVICE_OBJECT DeviceObject);
NTSTATUS NTSTATUS
HDA_PDOQueryBusInformation( HDA_PDOQueryBusInformation(
IN PIRP Irp); IN PIRP Irp);

View file

@ -7,6 +7,28 @@
*/ */
#include "hdaudbus.h" #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 NTSTATUS
HDA_PDOQueryBusInformation( HDA_PDOQueryBusInformation(
IN PIRP Irp) IN PIRP Irp)