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

commit 7cda1ed2f52d47ecd9b708a982ceab9cb25a9986
Author:     Hervé Poussineau <[email protected]>
AuthorDate: Sun Mar 22 23:23:04 2020 +0100
Commit:     Hervé Poussineau <[email protected]>
CommitDate: Thu Mar 26 16:36:23 2020 +0100

    [ISAPNP] Report DMA channels
---
 drivers/bus/isapnp/hardware.c | 22 +++++++++++-
 drivers/bus/isapnp/isapnp.c   | 79 ++++++++++++++++++++++++++++++++++++++++++-
 drivers/bus/isapnp/isapnp.h   |  6 ++++
 drivers/bus/isapnp/isapnphw.h |  6 ++++
 4 files changed, 111 insertions(+), 2 deletions(-)

diff --git a/drivers/bus/isapnp/hardware.c b/drivers/bus/isapnp/hardware.c
index 36638e0632d..8b84038ef8a 100644
--- a/drivers/bus/isapnp/hardware.c
+++ b/drivers/bus/isapnp/hardware.c
@@ -199,6 +199,16 @@ ReadIrqType(
     return ReadByte(ReadDataPort, ISAPNP_IRQTYPE(Index));
 }
 
+static
+inline
+USHORT
+ReadDmaChannel(
+    IN PUCHAR ReadDataPort,
+    IN USHORT Index)
+{
+    return ReadByte(ReadDataPort, ISAPNP_DMACHANNEL(Index));
+}
+
 static
 inline
 VOID
@@ -305,7 +315,7 @@ ReadTags(
     BOOLEAN res = FALSE;
     PVOID Buffer;
     USHORT Tag, TagLen, MaxLen;
-    ULONG NumberOfIo = 0, NumberOfIrq = 0;
+    ULONG NumberOfIo = 0, NumberOfIrq = 0, NumberOfDma = 0;
 
     LogDev += 1;
 
@@ -344,6 +354,12 @@ ReadTags(
             Buffer = &LogDevice->Io[NumberOfIo].Description;
             NumberOfIo++;
         }
+        else if (Tag == ISAPNP_TAG_DMA && NumberOfDma < 
ARRAYSIZE(LogDevice->Dma))
+        {
+            MaxLen = sizeof(LogDevice->Dma[NumberOfDma].Description);
+            Buffer = &LogDevice->Dma[NumberOfDma].Description;
+            NumberOfDma++;
+        }
         else if (LogDev == 0)
         {
             DPRINT1("Found unknown tag 0x%x (len %d)\n", Tag, TagLen);
@@ -552,6 +568,10 @@ ProbeIsaPnpBus(
                 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);
+            }
 
             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->Io[0].CurrentBase, 
LogDevice->Irq[0].CurrentNo);
diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c
index f810532921e..913721b3acd 100644
--- a/drivers/bus/isapnp/isapnp.c
+++ b/drivers/bus/isapnp/isapnp.c
@@ -145,10 +145,12 @@ IsaFdoCreateRequirements(
 {
     PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
     RTL_BITMAP IrqBitmap[ARRAYSIZE(LogDev->Irq)];
+    RTL_BITMAP DmaBitmap[ARRAYSIZE(LogDev->Dma)];
     ULONG IrqData[ARRAYSIZE(LogDev->Irq)];
+    ULONG DmaData[ARRAYSIZE(LogDev->Dma)];
     ULONG ResourceCount = 0;
     ULONG ListSize, i, j;
-    BOOLEAN FirstIrq = TRUE;
+    BOOLEAN FirstIrq = TRUE, FirstDma = TRUE;
     PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
     PIO_RESOURCE_DESCRIPTOR Descriptor;
 
@@ -174,6 +176,14 @@ IsaFdoCreateRequirements(
     }
     if (ResourceCount == 0)
         return STATUS_SUCCESS;
+    for (i = 0; i < ARRAYSIZE(LogDev->Irq); i++)
+    {
+        if (!LogDev->Dma[i].Description.Mask)
+            break;
+        DmaData[i] = LogDev->Dma[i].Description.Mask;
+        RtlInitializeBitMap(&DmaBitmap[i], &DmaData[i], 8);
+        ResourceCount += RtlNumberOfSetBits(&DmaBitmap[i]);
+    }
 
     /* Allocate memory to store requirements */
     ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST)
@@ -243,6 +253,41 @@ IsaFdoCreateRequirements(
             }
         }
     }
+    for (i = 0; i < ARRAYSIZE(LogDev->Dma); i++)
+    {
+        if (!LogDev->Dma[i].Description.Mask)
+            break;
+        DPRINT("Device.Dma[%d].Mask = 0x%02x\n", i, 
LogDev->Dma[i].Description.Mask);
+        DPRINT("Device.Dma[%d].Information = 0x%02x\n", i, 
LogDev->Dma[i].Description.Information);
+        for (j = 0; j < 8; j++)
+        {
+            if (!RtlCheckBit(&DmaBitmap[i], j))
+                continue;
+            if (FirstDma)
+                FirstDma = FALSE;
+            else
+                Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
+            Descriptor->Type = CmResourceTypeDma;
+            switch (LogDev->Dma[i].Description.Information & 0x3)
+            {
+                case 0x0: Descriptor->Flags |= CM_RESOURCE_DMA_8; break;
+                case 0x1: Descriptor->Flags |= CM_RESOURCE_DMA_8_AND_16; break;
+                case 0x2: Descriptor->Flags |= CM_RESOURCE_DMA_16; break;
+                default: break;
+            }
+            if (LogDev->Dma[i].Description.Information & 0x4)
+                Descriptor->Flags |= CM_RESOURCE_DMA_BUS_MASTER;
+            switch ((LogDev->Dma[i].Description.Information >> 5) & 0x3)
+            {
+                case 0x1: Descriptor->Flags |= CM_RESOURCE_DMA_TYPE_A; break;
+                case 0x2: Descriptor->Flags |= CM_RESOURCE_DMA_TYPE_B; break;
+                case 0x3: Descriptor->Flags |= CM_RESOURCE_DMA_TYPE_F; break;
+                default: break;
+            }
+            Descriptor->u.Dma.MinimumChannel = 
Descriptor->u.Dma.MaximumChannel = j;
+            Descriptor++;
+        }
+    }
 
     PdoExt->RequirementsList = RequirementsList;
     return STATUS_SUCCESS;
@@ -275,6 +320,13 @@ IsaFdoCreateResources(
         else
             break;
     }
+    for (i = 0; i < ARRAYSIZE(LogDev->Dma); i++)
+    {
+        if (LogDev->Dma[i].CurrentChannel != 4)
+            ResourceCount++;
+        else
+            break;
+    }
     if (ResourceCount == 0)
         return STATUS_SUCCESS;
 
@@ -323,6 +375,31 @@ IsaFdoCreateResources(
         Descriptor->u.Interrupt.Vector = LogDev->Irq[i].CurrentNo;
         Descriptor->u.Interrupt.Affinity = -1;
     }
+    for (i = 0; i < ARRAYSIZE(LogDev->Dma); i++)
+    {
+        if (LogDev->Dma[i].CurrentChannel == 4)
+            continue;
+        Descriptor = 
&ResourceList->List[0].PartialResourceList.PartialDescriptors[ResourceCount++];
+        Descriptor->Type = CmResourceTypeDma;
+        Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
+        switch (LogDev->Dma[i].Description.Information & 0x3)
+        {
+            case 0x0: Descriptor->Flags |= CM_RESOURCE_DMA_8; break;
+            case 0x1: Descriptor->Flags |= CM_RESOURCE_DMA_8 | 
CM_RESOURCE_DMA_16; break;
+            case 0x2: Descriptor->Flags |= CM_RESOURCE_DMA_16; break;
+            default: break;
+        }
+        if (LogDev->Dma[i].Description.Information & 0x4)
+            Descriptor->Flags |= CM_RESOURCE_DMA_BUS_MASTER;
+        switch ((LogDev->Dma[i].Description.Information >> 5) & 0x3)
+        {
+            case 0x1: Descriptor->Flags |= CM_RESOURCE_DMA_TYPE_A; break;
+            case 0x2: Descriptor->Flags |= CM_RESOURCE_DMA_TYPE_B; break;
+            case 0x3: Descriptor->Flags |= CM_RESOURCE_DMA_TYPE_F; break;
+            default: break;
+        }
+        Descriptor->u.Dma.Channel = LogDev->Dma[i].CurrentChannel;
+    }
 
     PdoExt->ResourceList = ResourceList;
     PdoExt->ResourceListSize = ListSize;
diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h
index ea7fca25cb6..ed1d81b4bc9 100644
--- a/drivers/bus/isapnp/isapnp.h
+++ b/drivers/bus/isapnp/isapnp.h
@@ -27,6 +27,11 @@ typedef struct _ISAPNP_IRQ {
     ISAPNP_IRQ_DESCRIPTION Description;
 } ISAPNP_IRQ, *PISAPNP_IRQ;
 
+typedef struct _ISAPNP_DMA {
+    UCHAR CurrentChannel;
+    ISAPNP_DMA_DESCRIPTION Description;
+} ISAPNP_DMA, *PISAPNP_DMA;
+
 typedef struct _ISAPNP_LOGICAL_DEVICE {
     PDEVICE_OBJECT Pdo;
     ISAPNP_LOGDEVID LogDevId;
@@ -35,6 +40,7 @@ typedef struct _ISAPNP_LOGICAL_DEVICE {
     ULONG SerialNumber;
     ISAPNP_IO Io[8];
     ISAPNP_IRQ Irq[2];
+    ISAPNP_DMA Dma[2];
     UCHAR CSN;
     UCHAR LDN;
     LIST_ENTRY ListEntry;
diff --git a/drivers/bus/isapnp/isapnphw.h b/drivers/bus/isapnp/isapnphw.h
index 86a55073615..9f1cc0c9cab 100644
--- a/drivers/bus/isapnp/isapnphw.h
+++ b/drivers/bus/isapnp/isapnphw.h
@@ -30,6 +30,7 @@ extern "C" {
 #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_CONFIG_RESET (1 << 0)
 #define ISAPNP_CONFIG_WAIT_FOR_KEY (1 << 1)
@@ -116,6 +117,11 @@ typedef struct _ISAPNP_IRQ_DESCRIPTION {
     UCHAR Information;
 } ISAPNP_IRQ_DESCRIPTION;
 
+typedef struct _ISAPNP_DMA_DESCRIPTION {
+    UCHAR Mask;
+    UCHAR Information;
+} ISAPNP_DMA_DESCRIPTION;
+
 #include <poppack.h>
 
 #ifdef __cplusplus

Reply via email to