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

commit b29a3ac524901bc17e66ebbbcd87d8e70cab6a72
Author:     Dmitry Borisov <[email protected]>
AuthorDate: Sat Mar 20 20:51:05 2021 +0600
Commit:     Dmitry Borisov <[email protected]>
CommitDate: Sun Jun 20 19:24:31 2021 +0600

    [ISAPNP] Read all resources when detecting devices
---
 drivers/bus/isapnp/hardware.c | 180 ++++++++++++++++++++++++++++++++++++++----
 drivers/bus/isapnp/isapnp.h   |   1 +
 drivers/bus/isapnp/isapnphw.h |  10 +++
 drivers/bus/isapnp/pdo.c      |   7 ++
 4 files changed, 182 insertions(+), 16 deletions(-)

diff --git a/drivers/bus/isapnp/hardware.c b/drivers/bus/isapnp/hardware.c
index 9dae1c66eb6..0b6e200478a 100644
--- a/drivers/bus/isapnp/hardware.c
+++ b/drivers/bus/isapnp/hardware.c
@@ -83,6 +83,17 @@ ReadWord(
             (ReadByte(ReadDataPort, Address + 1)));
 }
 
+static
+inline
+ULONG
+ReadDoubleWord(
+    _In_ PUCHAR ReadDataPort,
+    _In_ UCHAR Address)
+{
+    return ((ReadWord(ReadDataPort, Address) << 8) |
+            (ReadWord(ReadDataPort, Address + 2)));
+}
+
 static
 inline
 VOID
@@ -198,7 +209,7 @@ ReadIrqNo(
     _In_ PUCHAR ReadDataPort,
     _In_ UCHAR Index)
 {
-    return ReadByte(ReadDataPort, ISAPNP_IRQNO(Index));
+    return ReadByte(ReadDataPort, ISAPNP_IRQNO(Index)) & 0x0F;
 }
 
 static
@@ -218,7 +229,67 @@ ReadDmaChannel(
     _In_ PUCHAR ReadDataPort,
     _In_ UCHAR Index)
 {
-    return ReadByte(ReadDataPort, ISAPNP_DMACHANNEL(Index));
+    return ReadByte(ReadDataPort, ISAPNP_DMACHANNEL(Index)) & 0x07;
+}
+
+static
+inline
+USHORT
+ReadMemoryBase(
+    _In_ PUCHAR ReadDataPort,
+    _In_ UCHAR Index)
+{
+    return ReadWord(ReadDataPort, ISAPNP_MEMBASE(Index));
+}
+
+static
+inline
+UCHAR
+ReadMemoryControl(
+    _In_ PUCHAR ReadDataPort,
+    _In_ UCHAR Index)
+{
+    return ReadByte(ReadDataPort, ISAPNP_MEMCONTROL(Index));
+}
+
+static
+inline
+USHORT
+ReadMemoryLimit(
+    _In_ PUCHAR ReadDataPort,
+    _In_ UCHAR Index)
+{
+    return ReadWord(ReadDataPort, ISAPNP_MEMLIMIT(Index));
+}
+
+static
+inline
+ULONG
+ReadMemoryBase32(
+    _In_ PUCHAR ReadDataPort,
+    _In_ UCHAR Index)
+{
+    return ReadDoubleWord(ReadDataPort, ISAPNP_MEMBASE32(Index));
+}
+
+static
+inline
+UCHAR
+ReadMemoryControl32(
+    _In_ PUCHAR ReadDataPort,
+    _In_ UCHAR Index)
+{
+    return ReadByte(ReadDataPort, ISAPNP_MEMCONTROL32(Index));
+}
+
+static
+inline
+ULONG
+ReadMemoryLimit32(
+    _In_ PUCHAR ReadDataPort,
+    _In_ UCHAR Index)
+{
+    return ReadDoubleWord(ReadDataPort, ISAPNP_MEMLIMIT32(Index));
 }
 
 static
@@ -1016,6 +1087,95 @@ SkipTag:
     }
 }
 
+static
+CODE_SEG("PAGE")
+BOOLEAN
+ReadCurrentResources(
+    _In_ PUCHAR ReadDataPort,
+    _Inout_ PISAPNP_LOGICAL_DEVICE LogDevice)
+{
+    UCHAR i;
+
+    PAGED_CODE();
+
+    DPRINT("%s for CSN %u, LDN %u\n", __FUNCTION__, LogDevice->CSN, 
LogDevice->LDN);
+
+    WriteLogicalDeviceNumber(LogDevice->LDN);
+
+    /* If the device is not activated by BIOS we just report a NULL resource 
list */
+    if (!(ReadByte(ReadDataPort, ISAPNP_ACTIVATE) & 1))
+    {
+        LogDevice->Flags &= ~ISAPNP_HAS_RESOURCES;
+        return FALSE;
+    }
+
+    for (i = 0; i < RTL_NUMBER_OF(LogDevice->Io); i++)
+    {
+        LogDevice->Io[i].CurrentBase = ReadIoBase(ReadDataPort, i);
+
+        /* Skip empty descriptors */
+        if (!LogDevice->Io[i].CurrentBase)
+            break;
+    }
+    for (i = 0; i < RTL_NUMBER_OF(LogDevice->Irq); i++)
+    {
+        LogDevice->Irq[i].CurrentNo = ReadIrqNo(ReadDataPort, i);
+
+        if (!LogDevice->Irq[i].CurrentNo)
+            break;
+
+        LogDevice->Irq[i].CurrentType = ReadIrqType(ReadDataPort, i);
+    }
+    for (i = 0; i < RTL_NUMBER_OF(LogDevice->Dma); i++)
+    {
+        LogDevice->Dma[i].CurrentChannel = ReadDmaChannel(ReadDataPort, i);
+
+        if (LogDevice->Dma[i].CurrentChannel == 4)
+            break;
+    }
+    for (i = 0; i < RTL_NUMBER_OF(LogDevice->MemRange); i++)
+    {
+        LogDevice->MemRange[i].CurrentBase = ReadMemoryBase(ReadDataPort, i) 
<< 8;
+
+        if (!LogDevice->MemRange[i].CurrentBase)
+            break;
+
+        LogDevice->MemRange[i].CurrentLength = ReadMemoryLimit(ReadDataPort, 
i) << 8;
+
+        if (ReadMemoryControl(ReadDataPort, i) & MEMORY_UPPER_LIMIT)
+        {
+            LogDevice->MemRange[i].CurrentLength -= 
LogDevice->MemRange[i].CurrentBase;
+        }
+        else
+        {
+            LogDevice->MemRange[i].CurrentLength =
+                RANGE_LENGTH_TO_LENGTH(LogDevice->MemRange[i].CurrentLength);
+        }
+    }
+    for (i = 0; i < RTL_NUMBER_OF(LogDevice->MemRange32); i++)
+    {
+        LogDevice->MemRange32[i].CurrentBase = ReadMemoryBase32(ReadDataPort, 
i);
+
+        if (!LogDevice->MemRange32[i].CurrentBase)
+            break;
+
+        LogDevice->MemRange32[i].CurrentLength = 
ReadMemoryLimit32(ReadDataPort, i);
+
+        if (ReadMemoryControl32(ReadDataPort, i) & MEMORY_UPPER_LIMIT)
+        {
+            LogDevice->MemRange32[i].CurrentLength -= 
LogDevice->MemRange32[i].CurrentBase;
+        }
+        else
+        {
+            LogDevice->MemRange32[i].CurrentLength =
+                RANGE_LENGTH_TO_LENGTH(LogDevice->MemRange32[i].CurrentLength);
+        }
+    }
+
+    LogDevice->Flags |= ISAPNP_HAS_RESOURCES;
+    return TRUE;
+}
+
 static
 CODE_SEG("PAGE")
 INT
@@ -1153,7 +1313,6 @@ IsaHwFillDeviceList(
 {
     PISAPNP_LOGICAL_DEVICE LogDevice;
     UCHAR Csn;
-    ULONG i;
     PLIST_ENTRY Entry;
     PUCHAR ResourceData;
 
@@ -1264,19 +1423,8 @@ IsaHwFillDeviceList(
                 goto Deactivate;
             }
 
-            WriteLogicalDeviceNumber(LogDev);
-
-            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);
-            }
-            for (i = 0; i < ARRAYSIZE(LogDevice->Dma); i++)
-            {
-                LogDevice->Dma[i].CurrentChannel = 
ReadDmaChannel(FdoExt->ReadDataPort, i);
-            }
+            if (!ReadCurrentResources(FdoExt->ReadDataPort, LogDevice))
+                DPRINT("Unable to read boot resources\n");
 
             IsaPnpExtractAscii(LogDevice->VendorId, Identifier.VendorId);
             LogDevice->ProdId = Identifier.ProdId;
diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h
index d80d05dced1..3ba3e5032ac 100644
--- a/drivers/bus/isapnp/isapnp.h
+++ b/drivers/bus/isapnp/isapnp.h
@@ -133,6 +133,7 @@ typedef struct _ISAPNP_LOGICAL_DEVICE
     ULONG Flags;
 #define ISAPNP_PRESENT              0x00000001 /**< @brief Cleared when the 
device is physically removed. */
 #define ISAPNP_HAS_MULTIPLE_LOGDEVS 0x00000002 /**< @brief Indicates if the 
parent card has multiple logical devices. */
+#define ISAPNP_HAS_RESOURCES        0x00000004 /**< @brief Cleared when the 
device has no boot resources. */
 
     LIST_ENTRY DeviceLink;
 } ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
diff --git a/drivers/bus/isapnp/isapnphw.h b/drivers/bus/isapnp/isapnphw.h
index b3d8021a62c..c41d6d1b7be 100644
--- a/drivers/bus/isapnp/isapnphw.h
+++ b/drivers/bus/isapnp/isapnphw.h
@@ -28,10 +28,17 @@ extern "C" {
 #define ISAPNP_ACTIVATE 0x30
 #define ISAPNP_IORANGECHECK 0x31
 
+#define ISAPNP_MEMBASE(n) (0x40 + ((n) * 8))
+#define ISAPNP_MEMCONTROL(n) (0x42 + ((n) * 8))
+#define    MEMORY_UPPER_LIMIT 0x01
+#define ISAPNP_MEMLIMIT(n) (0x43 + ((n) * 8))
 #define ISAPNP_IOBASE(n) (0x60 + ((n)*2))
 #define ISAPNP_IRQNO(n) (0x70 + ((n)*2))
 #define ISAPNP_IRQTYPE(n) (0x71 + ((n) * 2))
 #define ISAPNP_DMACHANNEL(n) (0x74 + (n))
+#define ISAPNP_MEMBASE32(n) ((n) == 0 ? 0x76 : (0x70 + (n) * 16))
+#define ISAPNP_MEMCONTROL32(n) ((n) == 0 ? 0x7A : (0x74 + (n) * 16))
+#define ISAPNP_MEMLIMIT32(n) ((n) == 0 ? 0x7B : (0x75 + (n) * 16))
 
 #define ISAPNP_CONFIG_RESET (1 << 0)
 #define ISAPNP_CONFIG_WAIT_FOR_KEY (1 << 1)
@@ -61,6 +68,9 @@ extern "C" {
 #define ISAPNP_TAG_MEM32RANGE 0x85
 #define ISAPNP_TAG_FIXEDMEM32RANGE 0x86
 
+#define RANGE_LENGTH_TO_LENGTH(RangeLength) ((~(RangeLength) + 1) & 0xFFFFFF)
+#define LENGTH_TO_RANGE_LENGTH(Length) (~(Length) + 1)
+
 #include <pshpack1.h>
 
 typedef struct _ISAPNP_IDENTIFIER
diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c
index 67a30891ac1..8490bf9c14d 100644
--- a/drivers/bus/isapnp/pdo.c
+++ b/drivers/bus/isapnp/pdo.c
@@ -478,6 +478,13 @@ IsaPdoQueryResources(
 
     PAGED_CODE();
 
+    if (PdoExt->Common.Signature == IsaPnpLogicalDevice &&
+        !(PdoExt->IsaPnpDevice->Flags & ISAPNP_HAS_RESOURCES))
+    {
+        Irp->IoStatus.Information = 0;
+        return STATUS_SUCCESS;
+    }
+
     if (!PdoExt->ResourceList)
         return Irp->IoStatus.Status;
 

Reply via email to