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