https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5b9929a07687d202ec3f8…
commit 5b9929a07687d202ec3f8240af8579f7fc51538a
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Mon Mar 16 20:58:53 2020 +0100
Commit: Hervé Poussineau <hpoussin(a)reactos.org>
CommitDate: Fri Mar 20 22:40:11 2020 +0100
[ISAPNP] Detect devices only once ReadDataPort is started
Also let kernel choose the read data port address, by using the resources given in
IRP_MN_START_DEVICE.
---
drivers/bus/isapnp/fdo.c | 24 ----------------------
drivers/bus/isapnp/hardware.c | 37 +++------------------------------
drivers/bus/isapnp/isapnp.h | 4 ++--
drivers/bus/isapnp/pdo.c | 48 ++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 52 insertions(+), 61 deletions(-)
diff --git a/drivers/bus/isapnp/fdo.c b/drivers/bus/isapnp/fdo.c
index f232766b180..caa4b69c7e2 100644
--- a/drivers/bus/isapnp/fdo.c
+++ b/drivers/bus/isapnp/fdo.c
@@ -17,21 +17,9 @@ IsaFdoStartDevice(
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
- NTSTATUS Status;
- KIRQL OldIrql;
-
UNREFERENCED_PARAMETER(Irp);
UNREFERENCED_PARAMETER(IrpSp);
- KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
- Status = IsaHwDetectReadDataPort(FdoExt);
- KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
-
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
FdoExt->Common.State = dsStarted;
return STATUS_SUCCESS;
@@ -44,21 +32,9 @@ IsaFdoQueryDeviceRelations(
IN PIRP Irp,
IN PIO_STACK_LOCATION IrpSp)
{
- NTSTATUS Status;
- KIRQL OldIrql;
-
if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations)
return Irp->IoStatus.Status;
- KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
- Status = IsaHwFillDeviceList(FdoExt);
- KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
-
- if (!NT_SUCCESS(Status))
- {
- return Status;
- }
-
return IsaPnpFillDeviceRelations(FdoExt, Irp, TRUE);
}
diff --git a/drivers/bus/isapnp/hardware.c b/drivers/bus/isapnp/hardware.c
index 77ca6c40b4b..4a3d49bb1e7 100644
--- a/drivers/bus/isapnp/hardware.c
+++ b/drivers/bus/isapnp/hardware.c
@@ -451,28 +451,6 @@ TryIsolate(
return Csn;
}
-static
-PUCHAR
-Isolate(VOID)
-{
- PUCHAR ReadPort;
-
- for (ReadPort = (PUCHAR)ISAPNP_READ_PORT_START;
- (ULONG_PTR)ReadPort <= ISAPNP_READ_PORT_MAX;
- ReadPort += ISAPNP_READ_PORT_STEP)
- {
- /* Avoid the NE2000 probe space */
- if ((ULONG_PTR)ReadPort >= 0x280 &&
- (ULONG_PTR)ReadPort <= 0x380)
- continue;
-
- if (TryIsolate(ReadPort) > 0)
- return ReadPort;
- }
-
- return 0;
-}
-
VOID
DeviceActivation(
IN PISAPNP_LOGICAL_DEVICE IsaDevice,
@@ -557,19 +535,10 @@ ProbeIsaPnpBus(
NTSTATUS
NTAPI
-IsaHwDetectReadDataPort(
- IN PISAPNP_FDO_EXTENSION FdoExt)
+IsaHwTryReadDataPort(
+ IN PUCHAR ReadDataPort)
{
- FdoExt->ReadDataPort = Isolate();
- if (!FdoExt->ReadDataPort)
- {
- DPRINT1("No read data port found\n");
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- DPRINT1("Detected read data port at 0x%p\n", FdoExt->ReadDataPort);
-
- return STATUS_SUCCESS;
+ return TryIsolate(ReadDataPort) > 0 ? STATUS_SUCCESS :
STATUS_INSUFFICIENT_RESOURCES;
}
NTSTATUS
diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h
index e62381b6760..4a68b5ee11d 100644
--- a/drivers/bus/isapnp/isapnp.h
+++ b/drivers/bus/isapnp/isapnp.h
@@ -106,8 +106,8 @@ IsaPdoPnp(
/* hardware.c */
NTSTATUS
NTAPI
-IsaHwDetectReadDataPort(
- IN PISAPNP_FDO_EXTENSION FdoExt);
+IsaHwTryReadDataPort(
+ IN PUCHAR ReadDataPort);
NTSTATUS
NTAPI
diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c
index 55ab0da804a..f0481119758 100644
--- a/drivers/bus/isapnp/pdo.c
+++ b/drivers/bus/isapnp/pdo.c
@@ -213,6 +213,52 @@ IsaPdoQueryResourceRequirements(
return STATUS_SUCCESS;
}
+static
+NTSTATUS
+NTAPI
+IsaPdoStartReadPort(
+ IN PISAPNP_FDO_EXTENSION FdoExt,
+ IN PIO_STACK_LOCATION IrpSp)
+{
+ PCM_RESOURCE_LIST ResourceList =
IrpSp->Parameters.StartDevice.AllocatedResources;
+ NTSTATUS Status;
+ KIRQL OldIrql;
+ ULONG i;
+
+ if (!ResourceList || ResourceList->Count != 1)
+ {
+ DPRINT1("No resource list (%p) or bad count (%d)\n", ResourceList,
ResourceList ? ResourceList->Count : 0);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ if (ResourceList->List[0].PartialResourceList.Version != 1
+ || ResourceList->List[0].PartialResourceList.Revision != 1)
+ {
+ DPRINT1("Bad resource list version (%d.%d)\n",
ResourceList->List[0].PartialResourceList.Version,
ResourceList->List[0].PartialResourceList.Revision);
+ return STATUS_REVISION_MISMATCH;
+ }
+ for (i = 0; i < ResourceList->List[0].PartialResourceList.Count; i++)
+ {
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor =
&ResourceList->List[0].PartialResourceList.PartialDescriptors[i];
+ if (PartialDescriptor->Type == CmResourceTypePort)
+ {
+ PUCHAR ReadDataPort = (PUCHAR)PartialDescriptor->u.Port.Start.u.LowPart +
3;
+ if (PartialDescriptor->u.Port.Length > 1 &&
!FdoExt->ReadDataPort && NT_SUCCESS(IsaHwTryReadDataPort(ReadDataPort)))
+ {
+ FdoExt->ReadDataPort = ReadDataPort;
+ KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
+ Status = IsaHwFillDeviceList(FdoExt);
+ KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
+ if (FdoExt->DeviceCount > 0)
+ {
+ IoInvalidateDeviceRelations(FdoExt->Pdo, BusRelations);
+ IoInvalidateDeviceRelations(FdoExt->DataPortPdo,
RemovalRelations);
+ }
+ }
+ }
+ }
+ return Status;
+}
+
NTSTATUS
NTAPI
IsaPdoPnp(
@@ -228,7 +274,7 @@ IsaPdoPnp(
if (PdoExt->IsaPnpDevice)
Status = IsaHwActivateDevice(PdoExt->IsaPnpDevice);
else
- Status = STATUS_SUCCESS;
+ Status = IsaPdoStartReadPort(PdoExt->FdoExt, IrpSp);
if (NT_SUCCESS(Status))
PdoExt->Common.State = dsStarted;