[ISAPNP] Detect devices only once ReadDataPort is started
authorHervé Poussineau <hpoussin@reactos.org>
Mon, 16 Mar 2020 19:58:53 +0000 (20:58 +0100)
committerHervé Poussineau <hpoussin@reactos.org>
Fri, 20 Mar 2020 21:40:11 +0000 (22:40 +0100)
Also let kernel choose the read data port address, by using the resources given in IRP_MN_START_DEVICE.

drivers/bus/isapnp/fdo.c
drivers/bus/isapnp/hardware.c
drivers/bus/isapnp/isapnp.h
drivers/bus/isapnp/pdo.c

index f232766..caa4b69 100644 (file)
@@ -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);
 }
 
index 77ca6c4..4a3d49b 100644 (file)
@@ -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
index e62381b..4a68b5e 100644 (file)
@@ -106,8 +106,8 @@ IsaPdoPnp(
 /* hardware.c */
 NTSTATUS
 NTAPI
-IsaHwDetectReadDataPort(
-    IN PISAPNP_FDO_EXTENSION FdoExt);
+IsaHwTryReadDataPort(
+    IN PUCHAR ReadDataPort);
 
 NTSTATUS
 NTAPI
index 55ab0da..f048111 100644 (file)
@@ -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;