https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7cda1ed2f52d47ecd9b70…
commit 7cda1ed2f52d47ecd9b708a982ceab9cb25a9986
Author: Hervé Poussineau <hpoussin(a)reactos.org>
AuthorDate: Sun Mar 22 23:23:04 2020 +0100
Commit: Hervé Poussineau <hpoussin(a)reactos.org>
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