https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0ca55678941e6a6951ce1bc78e2e749a6e97a2e1

commit 0ca55678941e6a6951ce1bc78e2e749a6e97a2e1
Author:     Hervé Poussineau <[email protected]>
AuthorDate: Sat Mar 21 23:08:00 2020 +0100
Commit:     Hervé Poussineau <[email protected]>
CommitDate: Sun Mar 22 14:29:38 2020 +0100

    [ISAPNP] Read all tags when detecting devices, and keep interesting ones
    
    Currently, we only keep device identification, IO ports and IRQs.
---
 drivers/bus/isapnp/fdo.c      |   1 +
 drivers/bus/isapnp/hardware.c | 117 +++++++++++++++++++++++++++---------------
 drivers/bus/isapnp/isapnp.c   |   1 -
 drivers/bus/isapnp/isapnp.h   |  17 +++++-
 drivers/bus/isapnp/isapnphw.h |  17 ++++++
 drivers/bus/isapnp/pdo.c      |   1 +
 6 files changed, 109 insertions(+), 45 deletions(-)

diff --git a/drivers/bus/isapnp/fdo.c b/drivers/bus/isapnp/fdo.c
index caa4b69c7e2..be044407f20 100644
--- a/drivers/bus/isapnp/fdo.c
+++ b/drivers/bus/isapnp/fdo.c
@@ -3,6 +3,7 @@
  * FILE:            fdo.c
  * PURPOSE:         FDO-specific code
  * PROGRAMMERS:     Cameron Gutman ([email protected])
+ *                  Hervé Poussineau
  */
 
 #include <isapnp.h>
diff --git a/drivers/bus/isapnp/hardware.c b/drivers/bus/isapnp/hardware.c
index 53b71b78abb..36638e0632d 100644
--- a/drivers/bus/isapnp/hardware.c
+++ b/drivers/bus/isapnp/hardware.c
@@ -3,10 +3,10 @@
  * FILE:            hardware.c
  * PURPOSE:         Hardware support code
  * PROGRAMMERS:     Cameron Gutman ([email protected])
+ *                  Hervé Poussineau
  */
 
 #include <isapnp.h>
-#include <isapnphw.h>
 
 #define NDEBUG
 #include <debug.h>
@@ -189,6 +189,16 @@ ReadIrqNo(
     return ReadByte(ReadDataPort, ISAPNP_IRQNO(Index));
 }
 
+static
+inline
+USHORT
+ReadIrqType(
+    IN PUCHAR ReadDataPort,
+    IN USHORT Index)
+{
+    return ReadByte(ReadDataPort, ISAPNP_IRQTYPE(Index));
+}
+
 static
 inline
 VOID
@@ -287,15 +297,19 @@ IsaPnpChecksum(
 
 static
 BOOLEAN
-FindTag(
+ReadTags(
     IN PUCHAR ReadDataPort,
-    IN USHORT WantedTag,
-    IN OUT PVOID Buffer,
-    IN ULONG Length)
+    IN USHORT LogDev,
+    IN OUT PISAPNP_LOGICAL_DEVICE LogDevice)
 {
-    USHORT Tag, TagLen;
+    BOOLEAN res = FALSE;
+    PVOID Buffer;
+    USHORT Tag, TagLen, MaxLen;
+    ULONG NumberOfIo = 0, NumberOfIrq = 0;
 
-    do
+    LogDev += 1;
+
+    while (TRUE)
     {
         Tag = PeekByte(ReadDataPort);
         if (ISAPNP_IS_SMALL_TAG(Tag))
@@ -308,41 +322,55 @@ FindTag(
             TagLen = PeekByte(ReadDataPort) + (PeekByte(ReadDataPort) << 8);
             Tag = ISAPNP_LARGE_TAG_NAME(Tag);
         }
+        if (Tag == ISAPNP_TAG_END)
+            break;
 
-        if (Tag == WantedTag)
+        Buffer = NULL;
+        if (Tag == ISAPNP_TAG_LOGDEVID)
         {
-            if (Length > TagLen)
-                Length = TagLen;
-
-            Peek(ReadDataPort, Buffer, Length);
+            MaxLen = sizeof(LogDevice->LogDevId);
+            Buffer = &LogDevice->LogDevId;
+            LogDev--;
+        }
+        else if (Tag == ISAPNP_TAG_IRQ && NumberOfIrq < 
ARRAYSIZE(LogDevice->Irq))
+        {
+            MaxLen = sizeof(LogDevice->Irq[NumberOfIrq].Description);
+            Buffer = &LogDevice->Irq[NumberOfIrq].Description;
+            NumberOfIrq++;
+        }
+        else if (Tag == ISAPNP_TAG_IOPORT && NumberOfIo < 
ARRAYSIZE(LogDevice->Io))
+        {
+            MaxLen = sizeof(LogDevice->Io[NumberOfIo].Description);
+            Buffer = &LogDevice->Io[NumberOfIo].Description;
+            NumberOfIo++;
+        }
+        else if (LogDev == 0)
+        {
+            DPRINT1("Found unknown tag 0x%x (len %d)\n", Tag, TagLen);
+        }
 
-            return TRUE;
+        if (Buffer && LogDev == 0)
+        {
+            res = TRUE;
+            if (MaxLen > TagLen)
+            {
+                Peek(ReadDataPort, Buffer, TagLen);
+            }
+            else
+            {
+                Peek(ReadDataPort, Buffer, MaxLen);
+                Peek(ReadDataPort, NULL, TagLen - MaxLen);
+            }
         }
         else
         {
+            /* We don't want to read informations on this
+             * logical device, or we don't know the tag. */
             Peek(ReadDataPort, NULL, TagLen);
         }
-    } while (Tag != ISAPNP_TAG_END);
+    };
 
-    return FALSE;
-}
-
-static
-BOOLEAN
-FindLogDevId(
-    IN PUCHAR ReadDataPort,
-    IN USHORT LogDev,
-    IN OUT PISAPNP_LOGDEVID LogDeviceId)
-{
-    USHORT i;
-
-    for (i = 0; i <= LogDev; i++)
-    {
-        if (!FindTag(ReadDataPort, ISAPNP_TAG_LOGDEVID, LogDeviceId, 
sizeof(*LogDeviceId)))
-            return FALSE;
-    }
-
-    return TRUE;
+    return res;
 }
 
 static
@@ -476,9 +504,9 @@ ProbeIsaPnpBus(
 {
     PISAPNP_LOGICAL_DEVICE LogDevice;
     ISAPNP_IDENTIFIER Identifier;
-    ISAPNP_LOGDEVID LogDevId;
     USHORT Csn;
     USHORT LogDev;
+    ULONG i;
 
     ASSERT(FdoExt->ReadDataPort);
 
@@ -507,21 +535,26 @@ ProbeIsaPnpBus(
                 return STATUS_SUCCESS;
             }
 
-            if (!FindLogDevId(FdoExt->ReadDataPort, LogDev, &LogDevId))
+            if (!ReadTags(FdoExt->ReadDataPort, LogDev, LogDevice))
                 break;
 
             WriteLogicalDeviceNumber(LogDev);
 
-            LogDevice->VendorId[0] = ((LogDevId.VendorId >> 2) & 0x1f) + 'A' - 
1,
-            LogDevice->VendorId[1] = (((LogDevId.VendorId & 0x3) << 3) | 
((LogDevId.VendorId >> 13) & 0x7)) + 'A' - 1,
-            LogDevice->VendorId[2] = ((LogDevId.VendorId >> 8) & 0x1f) + 'A' - 
1,
-            LogDevice->ProdId = RtlUshortByteSwap(LogDevId.ProdId);
+            LogDevice->VendorId[0] = ((LogDevice->LogDevId.VendorId >> 2) & 
0x1f) + 'A' - 1,
+            LogDevice->VendorId[1] = (((LogDevice->LogDevId.VendorId & 0x3) << 
3) | ((LogDevice->LogDevId.VendorId >> 13) & 0x7)) + 'A' - 1,
+            LogDevice->VendorId[2] = ((LogDevice->LogDevId.VendorId >> 8) & 
0x1f) + 'A' - 1,
+            LogDevice->ProdId = RtlUshortByteSwap(LogDevice->LogDevId.ProdId);
             LogDevice->SerialNumber = Identifier.Serial;
-            LogDevice->IoAddr = ReadIoBase(FdoExt->ReadDataPort, 0);
-            LogDevice->IrqNo = ReadIrqNo(FdoExt->ReadDataPort, 0);
+            for (i = 0; i < ARRAYSIZE(LogDevice->Io); i++)
+                LogDevice->Io[i].CurrentBase = 
ReadIoBase(FdoExt->ReadDataPort, i);
+            for (i = 0; i < ARRAYSIZE(LogDevice->Irq); i++)
+            {
+                LogDevice->Irq[i].CurrentNo = ReadIrqNo(FdoExt->ReadDataPort, 
i);
+                LogDevice->Irq[i].CurrentType = 
ReadIrqType(FdoExt->ReadDataPort, i);
+            }
 
             DPRINT1("Detected ISA PnP device - VID: '%3s' PID: 0x%x SN: 0x%08x 
IoBase: 0x%x IRQ:0x%x\n",
-                    LogDevice->VendorId, LogDevice->ProdId, 
LogDevice->SerialNumber, LogDevice->IoAddr, LogDevice->IrqNo);
+                    LogDevice->VendorId, LogDevice->ProdId, 
LogDevice->SerialNumber, LogDevice->Io[0].CurrentBase, 
LogDevice->Irq[0].CurrentNo);
 
             WaitForKey();
 
diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c
index 6f22efcd014..5c5321b3308 100644
--- a/drivers/bus/isapnp/isapnp.c
+++ b/drivers/bus/isapnp/isapnp.c
@@ -6,7 +6,6 @@
  */
 
 #include <isapnp.h>
-#include <isapnphw.h>
 
 #define NDEBUG
 #include <debug.h>
diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h
index 416ed2df55f..ea7fca25cb6 100644
--- a/drivers/bus/isapnp/isapnp.h
+++ b/drivers/bus/isapnp/isapnp.h
@@ -3,6 +3,7 @@
 
 #include <wdm.h>
 #include <ntstrsafe.h>
+#include <isapnphw.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -15,13 +16,25 @@ typedef enum {
     dsStarted
 } ISAPNP_DEVICE_STATE;
 
+typedef struct _ISAPNP_IO {
+    USHORT CurrentBase;
+    ISAPNP_IO_DESCRIPTION Description;
+} ISAPNP_IO, PISAPNP_IO;
+
+typedef struct _ISAPNP_IRQ {
+    UCHAR CurrentNo;
+    UCHAR CurrentType;
+    ISAPNP_IRQ_DESCRIPTION Description;
+} ISAPNP_IRQ, *PISAPNP_IRQ;
+
 typedef struct _ISAPNP_LOGICAL_DEVICE {
     PDEVICE_OBJECT Pdo;
+    ISAPNP_LOGDEVID LogDevId;
     UCHAR VendorId[3];
     USHORT ProdId;
     ULONG SerialNumber;
-    USHORT IoAddr;
-    UCHAR IrqNo;
+    ISAPNP_IO Io[8];
+    ISAPNP_IRQ Irq[2];
     UCHAR CSN;
     UCHAR LDN;
     LIST_ENTRY ListEntry;
diff --git a/drivers/bus/isapnp/isapnphw.h b/drivers/bus/isapnp/isapnphw.h
index eeef89951f0..86a55073615 100644
--- a/drivers/bus/isapnp/isapnphw.h
+++ b/drivers/bus/isapnp/isapnphw.h
@@ -101,6 +101,23 @@ typedef struct _ISAPNP_DEVICEID {
     USHORT ProdId;
 } ISAPNP_DEVICEID, *PISAPNP_DEVICEID;
 
+#include <pshpack1.h>
+
+typedef struct _ISAPNP_IO_DESCRIPTION {
+    UCHAR Information;
+    USHORT Minimum;
+    USHORT Maximum;
+    UCHAR Alignment;
+    UCHAR Length;
+} ISAPNP_IO_DESCRIPTION;
+
+typedef struct _ISAPNP_IRQ_DESCRIPTION {
+    USHORT Mask;
+    UCHAR Information;
+} ISAPNP_IRQ_DESCRIPTION;
+
+#include <poppack.h>
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c
index d4a34cf78ec..7cd8c7d3812 100644
--- a/drivers/bus/isapnp/pdo.c
+++ b/drivers/bus/isapnp/pdo.c
@@ -3,6 +3,7 @@
  * FILE:            pdo.c
  * PURPOSE:         PDO-specific code
  * PROGRAMMERS:     Cameron Gutman ([email protected])
+ *                  Hervé Poussineau
  */
 
 #include <isapnp.h>

Reply via email to