[ISAPNP] Implement IRP_MN_QUERY_RESOURCES/IRP_MN_QUERY_RESOURCE_REQUIREMENTS for...
authorHervé Poussineau <hpoussin@reactos.org>
Mon, 16 Mar 2020 19:50:29 +0000 (20:50 +0100)
committerHervé Poussineau <hpoussin@reactos.org>
Fri, 20 Mar 2020 21:40:11 +0000 (22:40 +0100)
drivers/bus/isapnp/pdo.c

index 639f07d..55ab0da 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <isapnp.h>
+#include <isapnphw.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -122,6 +123,96 @@ IsaPdoQueryId(
     return STATUS_SUCCESS;
 }
 
+NTSTATUS
+NTAPI
+IsaPdoQueryResources(
+  IN PISAPNP_PDO_EXTENSION PdoExt,
+  IN PIRP Irp,
+  IN PIO_STACK_LOCATION IrpSp)
+{
+    USHORT Ports[] = { ISAPNP_WRITE_DATA, ISAPNP_ADDRESS };
+    ULONG ListSize, i;
+    PCM_RESOURCE_LIST ResourceList;
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
+
+    ListSize = sizeof(CM_RESOURCE_LIST)
+             + (ARRAYSIZE(Ports) - 1) * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
+    ResourceList = ExAllocatePool(NonPagedPool, ListSize);
+    if (!ResourceList)
+        return STATUS_NO_MEMORY;
+
+    RtlZeroMemory(ResourceList, ListSize);
+    ResourceList->Count = 1;
+    ResourceList->List[0].InterfaceType = Internal;
+    ResourceList->List[0].PartialResourceList.Version = 1;
+    ResourceList->List[0].PartialResourceList.Revision = 1;
+    ResourceList->List[0].PartialResourceList.Count = 2;
+
+    for (i = 0; i < ARRAYSIZE(Ports); i++)
+    {
+        Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[i];
+        Descriptor->Type = CmResourceTypePort;
+        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+        Descriptor->Flags = CM_RESOURCE_PORT_16_BIT_DECODE;
+        Descriptor->u.Port.Length = 0x01;
+        Descriptor->u.Port.Start.LowPart = Ports[i];
+    }
+
+    Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+IsaPdoQueryResourceRequirements(
+  IN PISAPNP_PDO_EXTENSION PdoExt,
+  IN PIRP Irp,
+  IN PIO_STACK_LOCATION IrpSp)
+{
+    USHORT Ports[] = { ISAPNP_WRITE_DATA, ISAPNP_ADDRESS, 0x274, 0x3e4, 0x204, 0x2e4, 0x354, 0x2f4 };
+    ULONG ListSize, i;
+    PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
+    PIO_RESOURCE_DESCRIPTOR Descriptor;
+
+    ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST)
+             + 2 * ARRAYSIZE(Ports) * sizeof(IO_RESOURCE_DESCRIPTOR);
+    RequirementsList = ExAllocatePool(NonPagedPool, ListSize);
+    if (!RequirementsList)
+        return STATUS_NO_MEMORY;
+
+    RtlZeroMemory(RequirementsList, ListSize);
+    RequirementsList->ListSize = ListSize;
+    RequirementsList->AlternativeLists = 1;
+
+    RequirementsList->List[0].Version = 1;
+    RequirementsList->List[0].Revision = 1;
+    RequirementsList->List[0].Count = 2 * ARRAYSIZE(Ports);
+
+    for (i = 0; i < 2 * ARRAYSIZE(Ports); i += 2)
+    {
+        Descriptor = &RequirementsList->List[0].Descriptors[i];
+
+        /* Expected port */
+        Descriptor[0].Type = CmResourceTypePort;
+        Descriptor[0].ShareDisposition = CmResourceShareDeviceExclusive;
+        Descriptor[0].Flags = CM_RESOURCE_PORT_16_BIT_DECODE;
+        Descriptor[0].u.Port.Length = Ports[i / 2] & 1 ? 0x01 : 0x04;
+        Descriptor[0].u.Port.Alignment = 0x01;
+        Descriptor[0].u.Port.MinimumAddress.LowPart = Ports[i / 2];
+        Descriptor[0].u.Port.MaximumAddress.LowPart = Ports[i / 2] + Descriptor[0].u.Port.Length - 1;
+
+        /* ... but mark it as optional */
+        Descriptor[1].Option = IO_RESOURCE_ALTERNATIVE;
+        Descriptor[1].Type = CmResourceTypePort;
+        Descriptor[1].ShareDisposition = CmResourceShareDeviceExclusive;
+        Descriptor[1].Flags = CM_RESOURCE_PORT_16_BIT_DECODE;
+        Descriptor[1].u.Port.Alignment = 0x01;
+    }
+
+    Irp->IoStatus.Information = (ULONG_PTR)RequirementsList;
+    return STATUS_SUCCESS;
+}
+
 NTSTATUS
 NTAPI
 IsaPdoPnp(
@@ -133,49 +224,55 @@ IsaPdoPnp(
 
     switch (IrpSp->MinorFunction)
     {
-       case IRP_MN_START_DEVICE:
-           if (PdoExt->IsaPnpDevice)
-               Status = IsaHwActivateDevice(PdoExt->IsaPnpDevice);
-           else
-               Status = STATUS_SUCCESS;
-
-         if (NT_SUCCESS(Status))
-             PdoExt->Common.State = dsStarted;
-         break;
-
-       case IRP_MN_STOP_DEVICE:
-           if (PdoExt->IsaPnpDevice)
-               Status = IsaHwDeactivateDevice(PdoExt->IsaPnpDevice);
-           else
-               Status = STATUS_SUCCESS;
-
-         if (NT_SUCCESS(Status))
-             PdoExt->Common.State = dsStopped;
-         break;
-
-       case IRP_MN_QUERY_DEVICE_RELATIONS:
-         Status = IsaPdoQueryDeviceRelations(PdoExt, Irp, IrpSp);
-         break;
-
-       case IRP_MN_QUERY_CAPABILITIES:
-         Status = IsaPdoQueryCapabilities(PdoExt, Irp, IrpSp);
-         break;
-
-       case IRP_MN_QUERY_RESOURCES:
-         DPRINT1("IRP_MN_QUERY_RESOURCES is UNIMPLEMENTED!\n");
-         break;
-
-       case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
-         DPRINT1("IRP_MN_QUERY_RESOURCE_REQUIREMENTS is UNIMPLEMENTED!\n");
-         break;
-
-       case IRP_MN_QUERY_ID:
-         Status = IsaPdoQueryId(PdoExt, Irp, IrpSp);
-         break;
-
-       default:
-         DPRINT1("Unknown PnP code: %x\n", IrpSp->MinorFunction);
-         break;
+        case IRP_MN_START_DEVICE:
+            if (PdoExt->IsaPnpDevice)
+                Status = IsaHwActivateDevice(PdoExt->IsaPnpDevice);
+            else
+                Status = STATUS_SUCCESS;
+
+            if (NT_SUCCESS(Status))
+                PdoExt->Common.State = dsStarted;
+            break;
+
+        case IRP_MN_STOP_DEVICE:
+            if (PdoExt->IsaPnpDevice)
+                Status = IsaHwDeactivateDevice(PdoExt->IsaPnpDevice);
+            else
+                Status = STATUS_SUCCESS;
+
+            if (NT_SUCCESS(Status))
+                PdoExt->Common.State = dsStopped;
+            break;
+
+        case IRP_MN_QUERY_DEVICE_RELATIONS:
+            Status = IsaPdoQueryDeviceRelations(PdoExt, Irp, IrpSp);
+            break;
+
+        case IRP_MN_QUERY_CAPABILITIES:
+            Status = IsaPdoQueryCapabilities(PdoExt, Irp, IrpSp);
+            break;
+
+        case IRP_MN_QUERY_RESOURCES:
+            if (PdoExt->Common.Self == PdoExt->FdoExt->DataPortPdo)
+                Status = IsaPdoQueryResources(PdoExt, Irp, IrpSp);
+            else
+                DPRINT1("IRP_MN_QUERY_RESOURCES is UNIMPLEMENTED!\n");
+            break;
+
+        case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
+            if (PdoExt->Common.Self == PdoExt->FdoExt->DataPortPdo)
+                Status = IsaPdoQueryResourceRequirements(PdoExt, Irp, IrpSp);
+            else
+                DPRINT1("IRP_MN_QUERY_RESOURCE_REQUIREMENTS is UNIMPLEMENTED!\n");
+            break;
+
+        case IRP_MN_QUERY_ID:
+            Status = IsaPdoQueryId(PdoExt, Irp, IrpSp);
+            break;
+
+        default:
+            DPRINT1("Unknown PnP code: %x\n", IrpSp->MinorFunction);
+            break;
     }
 
     Irp->IoStatus.Status = Status;