[ISAPNP] Report DMA channels

This commit is contained in:
Hervé Poussineau 2020-03-22 23:23:04 +01:00
parent eb66324d7c
commit 7cda1ed2f5
4 changed files with 111 additions and 2 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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