https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5b9929a07687d202ec3f8240af8579f7fc51538a

commit 5b9929a07687d202ec3f8240af8579f7fc51538a
Author:     Hervé Poussineau <[email protected]>
AuthorDate: Mon Mar 16 20:58:53 2020 +0100
Commit:     Hervé Poussineau <[email protected]>
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;

Reply via email to