https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5a404e6c5048a29a4e6c3…
commit 5a404e6c5048a29a4e6c3dc2d1bf2df776cf0d44
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Mon Mar 16 20:50:29 2020 +0100
Commit: Hervé Poussineau <hpoussin(a)reactos.org>
CommitDate: Fri Mar 20 22:40:11 2020 +0100
[ISAPNP] Implement IRP_MN_QUERY_RESOURCES/IRP_MN_QUERY_RESOURCE_REQUIREMENTS for
ReadDataPort
---
drivers/bus/isapnp/pdo.c | 183 ++++++++++++++++++++++++++++++++++++-----------
1 file changed, 140 insertions(+), 43 deletions(-)
diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c
index 639f07d5aa1..55ab0da804a 100644
--- a/drivers/bus/isapnp/pdo.c
+++ b/drivers/bus/isapnp/pdo.c
@@ -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;