[HDAUDBUS] Implement PDO removal. CORE-14617
authorThomas Faber <thomas.faber@reactos.org>
Mon, 25 Feb 2019 12:47:14 +0000 (13:47 +0100)
committerThomas Faber <thomas.faber@reactos.org>
Tue, 26 Feb 2019 08:51:38 +0000 (09:51 +0100)
drivers/wdm/audio/hdaudbus/fdo.cpp
drivers/wdm/audio/hdaudbus/hdaudbus.cpp
drivers/wdm/audio/hdaudbus/hdaudbus.h
drivers/wdm/audio/hdaudbus/pdo.cpp

index 44e41d2..a14b5b9 100644 (file)
@@ -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);
index 79b0746..0202385 100644 (file)
@@ -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);
index f29aae5..f246238 100644 (file)
@@ -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);
index b0e3c4f..f93c6fa 100644 (file)
@@ -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)