[HDAUDBUS] Implement FDO removal. CORE-14617
authorThomas Faber <thomas.faber@reactos.org>
Sun, 24 Feb 2019 13:33:41 +0000 (14:33 +0100)
committerThomas Faber <thomas.faber@reactos.org>
Tue, 26 Feb 2019 08:51:21 +0000 (09:51 +0100)
drivers/wdm/audio/hdaudbus/fdo.cpp
drivers/wdm/audio/hdaudbus/hdaudbus.cpp
drivers/wdm/audio/hdaudbus/hdaudbus.h

index 3df33c9..44e41d2 100644 (file)
@@ -563,6 +563,7 @@ HDA_FDOStartDevice(
 
         if (Descriptor->Type == CmResourceTypeMemory)
         {
+            DeviceExtension->RegLength = Descriptor->u.Memory.Length;
             DeviceExtension->RegBase = (PUCHAR)MmMapIoSpace(Descriptor->u.Memory.Start, Descriptor->u.Memory.Length, MmNonCached);
             if (DeviceExtension->RegBase == NULL)
             {
@@ -635,6 +636,60 @@ HDA_FDOStartDevice(
     return Status;
 }
 
+NTSTATUS
+NTAPI
+HDA_FDORemoveDevice(
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp)
+{
+    NTSTATUS Status;
+    PHDA_FDO_DEVICE_EXTENSION DeviceExtension;
+    ULONG CodecIndex, AFGIndex;
+    PHDA_CODEC_ENTRY CodecEntry;
+
+    /* get device extension */
+    DeviceExtension = static_cast<PHDA_FDO_DEVICE_EXTENSION>(DeviceObject->DeviceExtension);
+    ASSERT(DeviceExtension->IsFDO == TRUE);
+
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    IoSkipCurrentIrpStackLocation(Irp);
+    Status = IoCallDriver(DeviceExtension->LowerDevice, Irp);
+
+    IoDetachDevice(DeviceExtension->LowerDevice);
+
+    if (DeviceExtension->RegBase != NULL)
+    {
+        MmUnmapIoSpace(DeviceExtension->RegBase,
+                       DeviceExtension->RegLength);
+    }
+    if (DeviceExtension->Interrupt != NULL)
+    {
+        IoDisconnectInterrupt(DeviceExtension->Interrupt);
+    }
+    if (DeviceExtension->CorbBase != NULL)
+    {
+        MmFreeContiguousMemory(DeviceExtension->CorbBase);
+    }
+    for (CodecIndex = 0; CodecIndex < HDA_MAX_CODECS; CodecIndex++)
+    {
+        CodecEntry = DeviceExtension->Codecs[CodecIndex];
+        if (CodecEntry == NULL)
+        {
+            continue;
+        }
+
+        for (AFGIndex = 0; AFGIndex < CodecEntry->AudioGroupCount; AFGIndex++)
+        {
+            FreeItem(CodecEntry->AudioGroups[AFGIndex]);
+        }
+        FreeItem(CodecEntry);
+    }
+
+    IoDeleteDevice(DeviceObject);
+
+    return Status;
+}
+
 NTSTATUS
 NTAPI
 HDA_FDOQueryBusRelations(
index 440d75a..79b0746 100644 (file)
@@ -50,6 +50,12 @@ HDA_FdoPnp(
         Irp->IoStatus.Status = Status;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
         return Status;
+    case IRP_MN_REMOVE_DEVICE:
+        return HDA_FDORemoveDevice(DeviceObject, Irp);
+    case IRP_MN_QUERY_REMOVE_DEVICE:
+    case IRP_MN_CANCEL_REMOVE_DEVICE:
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        break;
     case IRP_MN_QUERY_DEVICE_RELATIONS:
         /* handle bus device relations */
         if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations)
index fa7f04a..f29aae5 100644 (file)
@@ -64,8 +64,9 @@ typedef struct
 {
        BOOLEAN IsFDO;
        PDEVICE_OBJECT LowerDevice;
-       
+
        PUCHAR RegBase;
+       SIZE_T RegLength;
        PKINTERRUPT Interrupt;
 
        ULONG CorbLength;
@@ -126,6 +127,12 @@ HDA_FDOStartDevice(
     IN PDEVICE_OBJECT DeviceObject,
     IN PIRP Irp);
 
+NTSTATUS
+NTAPI
+HDA_FDORemoveDevice(
+    _In_ PDEVICE_OBJECT DeviceObject,
+    _Inout_ PIRP Irp);
+
 NTSTATUS
 NTAPI
 HDA_FDOQueryBusRelations(