mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[ISAPNP] Fix parsing of complex resource data
- Properly handle the case when the dependent function is placed after fixed resources - Initialize the version and revision fields of resource lists - Improve validation of resource data - Add more debug prints CORE-18562
This commit is contained in:
parent
c1d7087352
commit
76ec8411a4
5 changed files with 551 additions and 825 deletions
|
@ -20,13 +20,6 @@
|
|||
|
||||
#endif /* UNIT_TEST */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
dfNotStarted,
|
||||
dfStarted,
|
||||
dfDone
|
||||
} DEPEDENT_FUNCTION_STATE;
|
||||
|
||||
static
|
||||
inline
|
||||
VOID
|
||||
|
@ -390,24 +383,6 @@ Peek(
|
|||
}
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
VOID
|
||||
PeekCached(
|
||||
_In_reads_bytes_(Length) PUCHAR ResourceData,
|
||||
_Out_writes_bytes_all_(Length) PVOID Buffer,
|
||||
_In_ USHORT Length)
|
||||
{
|
||||
PUCHAR Dest = Buffer;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
while (Length--)
|
||||
{
|
||||
*Dest++ = *ResourceData++;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
UCHAR
|
||||
|
@ -454,19 +429,28 @@ ReadTags(
|
|||
_In_ PUCHAR ReadDataPort,
|
||||
_Out_writes_(ISAPNP_MAX_RESOURCEDATA) PUCHAR Buffer,
|
||||
_In_ ULONG MaxLength,
|
||||
_Out_ PUSHORT MaxLogDev)
|
||||
_Out_ PUSHORT MaxLogDev,
|
||||
_Out_ PULONG MaxTagsPerDevice)
|
||||
{
|
||||
ULONG TagCount = 0;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
*MaxLogDev = 0;
|
||||
*MaxTagsPerDevice = 0;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
UCHAR Tag;
|
||||
USHORT TagLen;
|
||||
|
||||
++TagCount;
|
||||
|
||||
if (MaxLength < 1)
|
||||
{
|
||||
DPRINT("Too small tag\n");
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
Tag = PeekByte(ReadDataPort);
|
||||
if (Tag == 0)
|
||||
|
@ -487,7 +471,10 @@ ReadTags(
|
|||
UCHAR Temp[2];
|
||||
|
||||
if (MaxLength < sizeof(Temp))
|
||||
{
|
||||
DPRINT("Too small tag\n");
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
Peek(ReadDataPort, &Temp, sizeof(Temp));
|
||||
*Buffer++ = Temp[0];
|
||||
|
@ -505,18 +492,29 @@ ReadTags(
|
|||
}
|
||||
|
||||
if (TagLen > MaxLength)
|
||||
{
|
||||
DPRINT("Too large resource data structure\n");
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
Peek(ReadDataPort, Buffer, TagLen);
|
||||
MaxLength -= TagLen;
|
||||
Buffer += TagLen;
|
||||
|
||||
if (Tag == ISAPNP_TAG_LOGDEVID)
|
||||
(*MaxLogDev)++;
|
||||
{
|
||||
/* Attempt to guess the allocation size based on the tags available */
|
||||
*MaxTagsPerDevice = max(*MaxTagsPerDevice, TagCount);
|
||||
TagCount = 0;
|
||||
|
||||
if (Tag == ISAPNP_TAG_END)
|
||||
(*MaxLogDev)++;
|
||||
}
|
||||
else if (Tag == ISAPNP_TAG_END)
|
||||
{
|
||||
*MaxTagsPerDevice = max(*MaxTagsPerDevice, TagCount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@ -534,8 +532,8 @@ FreeLogicalDevice(
|
|||
if (LogDevice->FriendlyName)
|
||||
ExFreePoolWithTag(LogDevice->FriendlyName, TAG_ISAPNP);
|
||||
|
||||
if (LogDevice->Alternatives)
|
||||
ExFreePoolWithTag(LogDevice->Alternatives, TAG_ISAPNP);
|
||||
if (LogDevice->Resources)
|
||||
ExFreePoolWithTag(LogDevice->Resources, TAG_ISAPNP);
|
||||
|
||||
Entry = LogDevice->CompatibleIdList.Flink;
|
||||
while (Entry != &LogDevice->CompatibleIdList)
|
||||
|
@ -562,15 +560,10 @@ ParseTags(
|
|||
_Inout_ PISAPNP_LOGICAL_DEVICE LogDevice)
|
||||
{
|
||||
USHORT LogDev;
|
||||
DEPEDENT_FUNCTION_STATE DfState = dfNotStarted;
|
||||
ISAPNP_DEPENDENT_FUNCTION_STATE DfState = dfNotStarted;
|
||||
PISAPNP_RESOURCE Resource = LogDevice->Resources;
|
||||
PUCHAR IdStrPos = NULL;
|
||||
USHORT IdStrLen = 0;
|
||||
UCHAR NumberOfIo = 0,
|
||||
NumberOfIrq = 0,
|
||||
NumberOfDma = 0,
|
||||
NumberOfMemRange = 0,
|
||||
NumberOfMemRange32 = 0,
|
||||
NumberOfDepedentSet = 0;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
|
@ -613,7 +606,7 @@ ParseTags(
|
|||
goto SkipTag;
|
||||
}
|
||||
|
||||
PeekCached(ResourceData, &Temp, TagLen);
|
||||
RtlCopyMemory(&Temp, ResourceData, TagLen);
|
||||
ResourceData += TagLen;
|
||||
|
||||
DPRINT("Found tag 0x%X (len %u)\n"
|
||||
|
@ -643,7 +636,7 @@ ParseTags(
|
|||
if (!CompatibleId)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
PeekCached(ResourceData, &Temp, TagLen);
|
||||
RtlCopyMemory(&Temp, ResourceData, TagLen);
|
||||
ResourceData += TagLen;
|
||||
|
||||
DPRINT("Found tag 0x%X (len %u)\n"
|
||||
|
@ -665,30 +658,21 @@ ParseTags(
|
|||
{
|
||||
PISAPNP_IRQ_DESCRIPTION Description;
|
||||
|
||||
if (LogDev != 0 ||
|
||||
(TagLen > sizeof(ISAPNP_IRQ_DESCRIPTION) ||
|
||||
TagLen < (sizeof(ISAPNP_IRQ_DESCRIPTION) - 1)) ||
|
||||
NumberOfIrq >= RTL_NUMBER_OF(LogDevice->Irq))
|
||||
{
|
||||
goto SkipTag;
|
||||
}
|
||||
|
||||
if (DfState == dfStarted)
|
||||
{
|
||||
if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
|
||||
if (LogDev != 0)
|
||||
goto SkipTag;
|
||||
|
||||
Description = &LogDevice->Alternatives->Irq[NumberOfDepedentSet];
|
||||
}
|
||||
else
|
||||
if (TagLen > sizeof(ISAPNP_IRQ_DESCRIPTION) ||
|
||||
TagLen < (sizeof(ISAPNP_IRQ_DESCRIPTION) - 1))
|
||||
{
|
||||
Description = &LogDevice->Irq[NumberOfIrq].Description;
|
||||
|
||||
LogDevice->Irq[NumberOfIrq].Index = NumberOfIrq;
|
||||
++NumberOfIrq;
|
||||
DPRINT1("Invalid tag %x\n", ISAPNP_TAG_IRQ);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
PeekCached(ResourceData, Description, TagLen);
|
||||
Resource->Type = ISAPNP_RESOURCE_TYPE_IRQ;
|
||||
Description = &Resource->IrqDescription;
|
||||
++Resource;
|
||||
|
||||
RtlCopyMemory(Description, ResourceData, TagLen);
|
||||
ResourceData += TagLen;
|
||||
|
||||
if (TagLen == (sizeof(ISAPNP_IRQ_DESCRIPTION) - 1))
|
||||
|
@ -708,28 +692,20 @@ ParseTags(
|
|||
{
|
||||
PISAPNP_DMA_DESCRIPTION Description;
|
||||
|
||||
if (LogDev != 0 || TagLen != sizeof(ISAPNP_DMA_DESCRIPTION) ||
|
||||
NumberOfDma >= RTL_NUMBER_OF(LogDevice->Dma))
|
||||
{
|
||||
goto SkipTag;
|
||||
}
|
||||
|
||||
if (DfState == dfStarted)
|
||||
{
|
||||
if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
|
||||
if (LogDev != 0)
|
||||
goto SkipTag;
|
||||
|
||||
Description = &LogDevice->Alternatives->Dma[NumberOfDepedentSet];
|
||||
}
|
||||
else
|
||||
if (TagLen != sizeof(ISAPNP_DMA_DESCRIPTION))
|
||||
{
|
||||
Description = &LogDevice->Dma[NumberOfDma].Description;
|
||||
|
||||
LogDevice->Dma[NumberOfDma].Index = NumberOfDma;
|
||||
++NumberOfDma;
|
||||
DPRINT1("Invalid tag %x\n", ISAPNP_TAG_DMA);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
PeekCached(ResourceData, Description, TagLen);
|
||||
Resource->Type = ISAPNP_RESOURCE_TYPE_DMA;
|
||||
Description = &Resource->DmaDescription;
|
||||
++Resource;
|
||||
|
||||
RtlCopyMemory(Description, ResourceData, TagLen);
|
||||
ResourceData += TagLen;
|
||||
|
||||
DPRINT("Found tag 0x%X (len %u)\n"
|
||||
|
@ -744,48 +720,39 @@ ParseTags(
|
|||
|
||||
case ISAPNP_TAG_STARTDEP:
|
||||
{
|
||||
if (LogDev != 0 || TagLen > 1 ||
|
||||
NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
|
||||
{
|
||||
if (LogDev != 0)
|
||||
goto SkipTag;
|
||||
|
||||
if (TagLen > 1)
|
||||
{
|
||||
DPRINT1("Invalid tag %x\n", ISAPNP_TAG_STARTDEP);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
if (DfState == dfNotStarted)
|
||||
{
|
||||
LogDevice->Alternatives = ExAllocatePoolZero(PagedPool,
|
||||
sizeof(ISAPNP_ALTERNATIVES),
|
||||
TAG_ISAPNP);
|
||||
if (!LogDevice->Alternatives)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
DfState = dfStarted;
|
||||
}
|
||||
else if (DfState == dfStarted)
|
||||
{
|
||||
++NumberOfDepedentSet;
|
||||
}
|
||||
else
|
||||
else if (DfState != dfStarted)
|
||||
{
|
||||
goto SkipTag;
|
||||
}
|
||||
|
||||
++LogDevice->Alternatives->Count;
|
||||
Resource->Type = ISAPNP_RESOURCE_TYPE_START_DEPENDENT;
|
||||
++Resource;
|
||||
|
||||
if (TagLen != 1)
|
||||
{
|
||||
LogDevice->Alternatives->Priority[NumberOfDepedentSet] = 1;
|
||||
Resource->Priority = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
PeekCached(ResourceData,
|
||||
&LogDevice->Alternatives->Priority[NumberOfDepedentSet],
|
||||
TagLen);
|
||||
RtlCopyMemory(&Resource->Priority, ResourceData, TagLen);
|
||||
ResourceData += TagLen;
|
||||
}
|
||||
|
||||
DPRINT("*** Start depedent set %u, priority %u ***\n",
|
||||
NumberOfDepedentSet,
|
||||
LogDevice->Alternatives->Priority[NumberOfDepedentSet]);
|
||||
DPRINT("*** Start dependent set, priority %u ***\n",
|
||||
Resource->Priority);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -795,22 +762,14 @@ ParseTags(
|
|||
if (LogDev != 0 || DfState != dfStarted)
|
||||
goto SkipTag;
|
||||
|
||||
Resource->Type = ISAPNP_RESOURCE_TYPE_END_DEPENDENT;
|
||||
++Resource;
|
||||
|
||||
DfState = dfDone;
|
||||
|
||||
ResourceData += TagLen;
|
||||
|
||||
if (HasIoAlternatives(LogDevice->Alternatives))
|
||||
LogDevice->Alternatives->IoIndex = NumberOfIo++;
|
||||
if (HasIrqAlternatives(LogDevice->Alternatives))
|
||||
LogDevice->Alternatives->IrqIndex = NumberOfIrq++;
|
||||
if (HasDmaAlternatives(LogDevice->Alternatives))
|
||||
LogDevice->Alternatives->DmaIndex = NumberOfDma++;
|
||||
if (HasMemoryAlternatives(LogDevice->Alternatives))
|
||||
LogDevice->Alternatives->MemRangeIndex = NumberOfMemRange++;
|
||||
if (HasMemory32Alternatives(LogDevice->Alternatives))
|
||||
LogDevice->Alternatives->MemRange32Index = NumberOfMemRange32++;
|
||||
|
||||
DPRINT("*** End of depedent set ***\n");
|
||||
DPRINT("*** End of dependent set ***\n");
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -819,28 +778,20 @@ ParseTags(
|
|||
{
|
||||
PISAPNP_IO_DESCRIPTION Description;
|
||||
|
||||
if (LogDev != 0 || TagLen != sizeof(ISAPNP_IO_DESCRIPTION) ||
|
||||
NumberOfIo >= RTL_NUMBER_OF(LogDevice->Io))
|
||||
{
|
||||
goto SkipTag;
|
||||
}
|
||||
|
||||
if (DfState == dfStarted)
|
||||
{
|
||||
if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
|
||||
if (LogDev != 0)
|
||||
goto SkipTag;
|
||||
|
||||
Description = &LogDevice->Alternatives->Io[NumberOfDepedentSet];
|
||||
}
|
||||
else
|
||||
if (TagLen != sizeof(ISAPNP_IO_DESCRIPTION))
|
||||
{
|
||||
Description = &LogDevice->Io[NumberOfIo].Description;
|
||||
|
||||
LogDevice->Io[NumberOfIo].Index = NumberOfIo;
|
||||
++NumberOfIo;
|
||||
DPRINT1("Invalid tag %x\n", ISAPNP_TAG_IOPORT);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
PeekCached(ResourceData, Description, TagLen);
|
||||
Resource->Type = ISAPNP_RESOURCE_TYPE_IO;
|
||||
Description = &Resource->IoDescription;
|
||||
++Resource;
|
||||
|
||||
RtlCopyMemory(Description, ResourceData, TagLen);
|
||||
ResourceData += TagLen;
|
||||
|
||||
DPRINT("Found tag 0x%X (len %u)\n"
|
||||
|
@ -864,28 +815,20 @@ ParseTags(
|
|||
ISAPNP_FIXED_IO_DESCRIPTION Temp;
|
||||
PISAPNP_IO_DESCRIPTION Description;
|
||||
|
||||
if (LogDev != 0 || TagLen != sizeof(ISAPNP_FIXED_IO_DESCRIPTION) ||
|
||||
NumberOfIo >= RTL_NUMBER_OF(LogDevice->Io))
|
||||
{
|
||||
goto SkipTag;
|
||||
}
|
||||
|
||||
if (DfState == dfStarted)
|
||||
{
|
||||
if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
|
||||
if (LogDev != 0)
|
||||
goto SkipTag;
|
||||
|
||||
Description = &LogDevice->Alternatives->Io[NumberOfDepedentSet];
|
||||
}
|
||||
else
|
||||
if (TagLen != sizeof(ISAPNP_FIXED_IO_DESCRIPTION))
|
||||
{
|
||||
Description = &LogDevice->Io[NumberOfIo].Description;
|
||||
|
||||
LogDevice->Io[NumberOfIo].Index = NumberOfIo;
|
||||
++NumberOfIo;
|
||||
DPRINT1("Invalid tag %x\n", ISAPNP_TAG_FIXEDIO);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
PeekCached(ResourceData, &Temp, TagLen);
|
||||
Resource->Type = ISAPNP_RESOURCE_TYPE_IO;
|
||||
Description = &Resource->IoDescription;
|
||||
++Resource;
|
||||
|
||||
RtlCopyMemory(&Temp, ResourceData, TagLen);
|
||||
ResourceData += TagLen;
|
||||
|
||||
/* Save the address bits [0:9] */
|
||||
|
@ -919,7 +862,7 @@ ParseTags(
|
|||
if (!LogDevice->FriendlyName)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
PeekCached(IdStrPos, LogDevice->FriendlyName, IdStrLen);
|
||||
RtlCopyMemory(LogDevice->FriendlyName, IdStrPos, IdStrLen);
|
||||
|
||||
End = LogDevice->FriendlyName + IdStrLen - 1;
|
||||
while (End > LogDevice->FriendlyName && *End == ' ')
|
||||
|
@ -929,6 +872,8 @@ ParseTags(
|
|||
*++End = ANSI_NULL;
|
||||
}
|
||||
|
||||
Resource->Type = ISAPNP_RESOURCE_TYPE_END;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -936,28 +881,23 @@ ParseTags(
|
|||
{
|
||||
PISAPNP_MEMRANGE_DESCRIPTION Description;
|
||||
|
||||
if (LogDev != 0 || TagLen != sizeof(ISAPNP_MEMRANGE_DESCRIPTION) ||
|
||||
NumberOfMemRange >= RTL_NUMBER_OF(LogDevice->MemRange))
|
||||
{
|
||||
goto SkipTag;
|
||||
}
|
||||
|
||||
if (DfState == dfStarted)
|
||||
{
|
||||
if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
|
||||
if (LogDev != 0)
|
||||
goto SkipTag;
|
||||
|
||||
Description = &LogDevice->Alternatives->MemRange[NumberOfDepedentSet];
|
||||
}
|
||||
else
|
||||
if (TagLen != sizeof(ISAPNP_MEMRANGE_DESCRIPTION))
|
||||
{
|
||||
Description = &LogDevice->MemRange[NumberOfMemRange].Description;
|
||||
|
||||
LogDevice->MemRange[NumberOfMemRange].Index = NumberOfMemRange;
|
||||
++NumberOfMemRange;
|
||||
DPRINT1("Invalid tag %x\n", ISAPNP_TAG_MEMRANGE);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
PeekCached(ResourceData, Description, TagLen);
|
||||
LogDevice->Flags |= ISAPNP_HAS_MEM24_DECODER;
|
||||
ASSERT(!(LogDevice->Flags & ISAPNP_HAS_MEM32_DECODER));
|
||||
|
||||
Resource->Type = ISAPNP_RESOURCE_TYPE_MEMRANGE;
|
||||
Description = &Resource->MemRangeDescription;
|
||||
++Resource;
|
||||
|
||||
RtlCopyMemory(Description, ResourceData, TagLen);
|
||||
ResourceData += TagLen;
|
||||
|
||||
DPRINT("Found tag 0x%X (len %u)\n"
|
||||
|
@ -1004,28 +944,23 @@ ParseTags(
|
|||
{
|
||||
PISAPNP_MEMRANGE32_DESCRIPTION Description;
|
||||
|
||||
if (LogDev != 0 || TagLen != sizeof(ISAPNP_MEMRANGE32_DESCRIPTION) ||
|
||||
NumberOfMemRange32 >= RTL_NUMBER_OF(LogDevice->MemRange32))
|
||||
{
|
||||
goto SkipTag;
|
||||
}
|
||||
|
||||
if (DfState == dfStarted)
|
||||
{
|
||||
if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
|
||||
if (LogDev != 0)
|
||||
goto SkipTag;
|
||||
|
||||
Description = &LogDevice->Alternatives->MemRange32[NumberOfDepedentSet];
|
||||
}
|
||||
else
|
||||
if (TagLen != sizeof(ISAPNP_MEMRANGE32_DESCRIPTION))
|
||||
{
|
||||
Description = &LogDevice->MemRange32[NumberOfMemRange32].Description;
|
||||
|
||||
LogDevice->MemRange32[NumberOfMemRange32].Index = NumberOfMemRange32;
|
||||
++NumberOfMemRange32;
|
||||
DPRINT1("Invalid tag %x\n", ISAPNP_TAG_MEM32RANGE);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
PeekCached(ResourceData, Description, TagLen);
|
||||
LogDevice->Flags |= ISAPNP_HAS_MEM32_DECODER;
|
||||
ASSERT(!(LogDevice->Flags & ISAPNP_HAS_MEM24_DECODER));
|
||||
|
||||
Resource->Type = ISAPNP_RESOURCE_TYPE_MEMRANGE32;
|
||||
Description = &Resource->MemRange32Description;
|
||||
++Resource;
|
||||
|
||||
RtlCopyMemory(Description, ResourceData, TagLen);
|
||||
ResourceData += TagLen;
|
||||
|
||||
DPRINT("Found tag 0x%X (len %u)\n"
|
||||
|
@ -1049,28 +984,23 @@ ParseTags(
|
|||
ISAPNP_FIXEDMEMRANGE_DESCRIPTION Temp;
|
||||
PISAPNP_MEMRANGE32_DESCRIPTION Description;
|
||||
|
||||
if (LogDev != 0 || TagLen != sizeof(ISAPNP_FIXEDMEMRANGE_DESCRIPTION) ||
|
||||
NumberOfMemRange32 >= RTL_NUMBER_OF(LogDevice->MemRange32))
|
||||
{
|
||||
goto SkipTag;
|
||||
}
|
||||
|
||||
if (DfState == dfStarted)
|
||||
{
|
||||
if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES)
|
||||
if (LogDev != 0)
|
||||
goto SkipTag;
|
||||
|
||||
Description = &LogDevice->Alternatives->MemRange32[NumberOfDepedentSet];
|
||||
}
|
||||
else
|
||||
if (TagLen != sizeof(ISAPNP_FIXEDMEMRANGE_DESCRIPTION))
|
||||
{
|
||||
Description = &LogDevice->MemRange32[NumberOfMemRange32].Description;
|
||||
|
||||
LogDevice->MemRange32[NumberOfMemRange32].Index = NumberOfMemRange32;
|
||||
++NumberOfMemRange32;
|
||||
DPRINT1("Invalid tag %x\n", ISAPNP_TAG_FIXEDMEM32RANGE);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
PeekCached(ResourceData, &Temp, TagLen);
|
||||
LogDevice->Flags |= ISAPNP_HAS_MEM32_DECODER;
|
||||
ASSERT(!(LogDevice->Flags & ISAPNP_HAS_MEM24_DECODER));
|
||||
|
||||
Resource->Type = ISAPNP_RESOURCE_TYPE_MEMRANGE32;
|
||||
Description = &Resource->MemRange32Description;
|
||||
++Resource;
|
||||
|
||||
RtlCopyMemory(&Temp, ResourceData, TagLen);
|
||||
ResourceData += TagLen;
|
||||
|
||||
Description->Information = Temp.Information;
|
||||
|
@ -1121,7 +1051,7 @@ ReadCurrentResources(
|
|||
|
||||
WriteLogicalDeviceNumber(LogDevice->LDN);
|
||||
|
||||
/* If the device is not activated by BIOS we just report a NULL resource list */
|
||||
/* If the device is not activated by BIOS then the device has no boot resources */
|
||||
if (!(ReadByte(ReadDataPort, ISAPNP_ACTIVATE) & 1))
|
||||
{
|
||||
LogDevice->Flags &= ~ISAPNP_HAS_RESOURCES;
|
||||
|
@ -1217,7 +1147,6 @@ WriteResources(
|
|||
for (i = 0; i < PartialResourceList->Count; i++)
|
||||
{
|
||||
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor = &PartialResourceList->PartialDescriptors[i];
|
||||
UCHAR Index;
|
||||
|
||||
switch (Descriptor->Type)
|
||||
{
|
||||
|
@ -1229,10 +1158,9 @@ WriteResources(
|
|||
Descriptor->u.Port.Start.LowPart +
|
||||
Descriptor->u.Port.Length - 1,
|
||||
NULL,
|
||||
NULL,
|
||||
&Index);
|
||||
NULL);
|
||||
|
||||
WriteWord(ISAPNP_IOBASE(Index), (USHORT)Descriptor->u.Port.Start.LowPart);
|
||||
WriteWord(ISAPNP_IOBASE(NumberOfIo), (USHORT)Descriptor->u.Port.Start.LowPart);
|
||||
|
||||
++NumberOfIo;
|
||||
break;
|
||||
|
@ -1240,10 +1168,10 @@ WriteResources(
|
|||
|
||||
case CmResourceTypeInterrupt:
|
||||
{
|
||||
(VOID)FindIrqDescriptor(LogDevice, Descriptor->u.Interrupt.Level, &Index);
|
||||
(VOID)FindIrqDescriptor(LogDevice, Descriptor->u.Interrupt.Level);
|
||||
|
||||
WriteByte(ISAPNP_IRQNO(Index), (UCHAR)Descriptor->u.Interrupt.Level);
|
||||
WriteByte(ISAPNP_IRQTYPE(Index),
|
||||
WriteByte(ISAPNP_IRQNO(NumberOfIrq), (UCHAR)Descriptor->u.Interrupt.Level);
|
||||
WriteByte(ISAPNP_IRQTYPE(NumberOfIrq),
|
||||
Descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED
|
||||
? IRQTYPE_HIGH_EDGE : IRQTYPE_LOW_LEVEL);
|
||||
|
||||
|
@ -1253,9 +1181,9 @@ WriteResources(
|
|||
|
||||
case CmResourceTypeDma:
|
||||
{
|
||||
(VOID)FindDmaDescriptor(LogDevice, Descriptor->u.Dma.Channel, &Index);
|
||||
(VOID)FindDmaDescriptor(LogDevice, Descriptor->u.Dma.Channel);
|
||||
|
||||
WriteByte(ISAPNP_DMACHANNEL(Index), (UCHAR)Descriptor->u.Dma.Channel);
|
||||
WriteByte(ISAPNP_DMACHANNEL(NumberOfDma), (UCHAR)Descriptor->u.Dma.Channel);
|
||||
|
||||
++NumberOfDma;
|
||||
break;
|
||||
|
@ -1263,7 +1191,6 @@ WriteResources(
|
|||
|
||||
case CmResourceTypeMemory:
|
||||
{
|
||||
BOOLEAN Memory32;
|
||||
UCHAR Information;
|
||||
UCHAR MemoryControl = MEMORY_USE_8_BIT_DECODER;
|
||||
|
||||
|
@ -1271,30 +1198,28 @@ WriteResources(
|
|||
Descriptor->u.Memory.Start.LowPart,
|
||||
Descriptor->u.Memory.Start.LowPart +
|
||||
Descriptor->u.Memory.Length - 1,
|
||||
&Memory32,
|
||||
&Information,
|
||||
&Index);
|
||||
&Information);
|
||||
|
||||
if (!Memory32)
|
||||
if (LogicalDevice->Flags & ISAPNP_HAS_MEM24_DECODER)
|
||||
{
|
||||
if (Information & MEMRANGE_16_BIT_MEMORY_MASK)
|
||||
MemoryControl = MEMORY_USE_16_BIT_DECODER;
|
||||
|
||||
WriteWord(ISAPNP_MEMBASE(Index),
|
||||
WriteWord(ISAPNP_MEMBASE(NumberOfMemory),
|
||||
(USHORT)(Descriptor->u.Memory.Start.LowPart >> 8));
|
||||
|
||||
if (ReadMemoryControl(ReadDataPort, Index) & MEMORY_UPPER_LIMIT)
|
||||
if (ReadMemoryControl(ReadDataPort, NumberOfMemory) & MEMORY_UPPER_LIMIT)
|
||||
{
|
||||
WriteByte(ISAPNP_MEMCONTROL(Index),
|
||||
WriteByte(ISAPNP_MEMCONTROL(NumberOfMemory),
|
||||
MemoryControl | MEMORY_UPPER_LIMIT);
|
||||
WriteWord(ISAPNP_MEMLIMIT(Index),
|
||||
WriteWord(ISAPNP_MEMLIMIT(NumberOfMemory),
|
||||
(USHORT)((Descriptor->u.Memory.Start.LowPart +
|
||||
Descriptor->u.Memory.Length) >> 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteByte(ISAPNP_MEMCONTROL(Index), MemoryControl);
|
||||
WriteWord(ISAPNP_MEMLIMIT(Index),
|
||||
WriteByte(ISAPNP_MEMCONTROL(NumberOfMemory), MemoryControl);
|
||||
WriteWord(ISAPNP_MEMLIMIT(NumberOfMemory),
|
||||
(USHORT)(LENGTH_TO_RANGE_LENGTH(Descriptor->
|
||||
u.Memory.Length) >> 8));
|
||||
}
|
||||
|
@ -1303,7 +1228,7 @@ WriteResources(
|
|||
}
|
||||
else
|
||||
{
|
||||
WriteDoubleWord(ISAPNP_MEMBASE32(Index),
|
||||
WriteDoubleWord(ISAPNP_MEMBASE32(NumberOfMemory32),
|
||||
Descriptor->u.Memory.Start.LowPart);
|
||||
|
||||
if ((Information & MEMRANGE_16_BIT_MEMORY_MASK) == MEMRANGE_32_BIT_MEMORY_ONLY)
|
||||
|
@ -1311,18 +1236,18 @@ WriteResources(
|
|||
else if (Information & MEMRANGE_16_BIT_MEMORY_MASK)
|
||||
MemoryControl = MEMORY_USE_16_BIT_DECODER;
|
||||
|
||||
if (ReadMemoryControl32(ReadDataPort, Index) & MEMORY_UPPER_LIMIT)
|
||||
if (ReadMemoryControl32(ReadDataPort, NumberOfMemory32) & MEMORY_UPPER_LIMIT)
|
||||
{
|
||||
WriteByte(ISAPNP_MEMCONTROL32(Index),
|
||||
WriteByte(ISAPNP_MEMCONTROL32(NumberOfMemory32),
|
||||
MemoryControl | MEMORY_UPPER_LIMIT);
|
||||
WriteDoubleWord(ISAPNP_MEMLIMIT32(Index),
|
||||
WriteDoubleWord(ISAPNP_MEMLIMIT32(NumberOfMemory32),
|
||||
Descriptor->u.Memory.Start.LowPart +
|
||||
Descriptor->u.Memory.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteByte(ISAPNP_MEMCONTROL32(Index), MemoryControl);
|
||||
WriteDoubleWord(ISAPNP_MEMLIMIT32(Index),
|
||||
WriteByte(ISAPNP_MEMCONTROL32(NumberOfMemory32), MemoryControl);
|
||||
WriteDoubleWord(ISAPNP_MEMLIMIT32(NumberOfMemory32),
|
||||
LENGTH_TO_RANGE_LENGTH(Descriptor->u.Memory.Length));
|
||||
}
|
||||
|
||||
|
@ -1501,6 +1426,7 @@ IsaHwFillDeviceList(
|
|||
NTSTATUS Status;
|
||||
UCHAR TempId[3], LogDev;
|
||||
ISAPNP_IDENTIFIER Identifier;
|
||||
ULONG MaxTagsPerDevice;
|
||||
USHORT MaxLogDev;
|
||||
|
||||
Wake(Csn);
|
||||
|
@ -1510,7 +1436,11 @@ IsaHwFillDeviceList(
|
|||
IsaPnpExtractAscii(TempId, Identifier.VendorId);
|
||||
Identifier.ProdId = RtlUshortByteSwap(Identifier.ProdId);
|
||||
|
||||
Status = ReadTags(FdoExt->ReadDataPort, ResourceData, ISAPNP_MAX_RESOURCEDATA, &MaxLogDev);
|
||||
Status = ReadTags(FdoExt->ReadDataPort,
|
||||
ResourceData,
|
||||
ISAPNP_MAX_RESOURCEDATA,
|
||||
&MaxLogDev,
|
||||
&MaxTagsPerDevice);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to read tags with status 0x%08lx, CSN %u\n", Status, Csn);
|
||||
|
@ -1572,6 +1502,16 @@ IsaHwFillDeviceList(
|
|||
LogDevice->CSN = Csn;
|
||||
LogDevice->LDN = LogDev;
|
||||
|
||||
LogDevice->Resources = ExAllocatePoolWithTag(PagedPool,
|
||||
MaxTagsPerDevice * sizeof(ISAPNP_RESOURCE),
|
||||
TAG_ISAPNP);
|
||||
if (!LogDevice->Resources)
|
||||
{
|
||||
DPRINT1("Failed to allocate the resources array\n");
|
||||
FreeLogicalDevice(LogDevice);
|
||||
goto Deactivate;
|
||||
}
|
||||
|
||||
Status = ParseTags(ResourceData, LogDev, LogDevice);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -1644,7 +1584,6 @@ IsaHwConfigureDevice(
|
|||
Descriptor->u.Port.Start.LowPart +
|
||||
Descriptor->u.Port.Length - 1,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL))
|
||||
{
|
||||
return STATUS_RESOURCE_DATA_NOT_FOUND;
|
||||
|
@ -1658,7 +1597,7 @@ IsaHwConfigureDevice(
|
|||
if (++NumberOfIrq > RTL_NUMBER_OF(LogicalDevice->Irq))
|
||||
return STATUS_INVALID_PARAMETER_2;
|
||||
|
||||
if (!FindIrqDescriptor(LogicalDevice, Descriptor->u.Interrupt.Level, NULL))
|
||||
if (!FindIrqDescriptor(LogicalDevice, Descriptor->u.Interrupt.Level))
|
||||
return STATUS_RESOURCE_DATA_NOT_FOUND;
|
||||
|
||||
break;
|
||||
|
@ -1669,7 +1608,7 @@ IsaHwConfigureDevice(
|
|||
if (++NumberOfDma > RTL_NUMBER_OF(LogicalDevice->Dma))
|
||||
return STATUS_INVALID_PARAMETER_3;
|
||||
|
||||
if (!FindDmaDescriptor(LogicalDevice, Descriptor->u.Dma.Channel, NULL))
|
||||
if (!FindDmaDescriptor(LogicalDevice, Descriptor->u.Dma.Channel))
|
||||
return STATUS_RESOURCE_DATA_NOT_FOUND;
|
||||
|
||||
break;
|
||||
|
@ -1686,14 +1625,12 @@ IsaHwConfigureDevice(
|
|||
Descriptor->u.Memory.Start.LowPart,
|
||||
Descriptor->u.Memory.Start.LowPart +
|
||||
Descriptor->u.Memory.Length - 1,
|
||||
&Memory32,
|
||||
NULL,
|
||||
NULL))
|
||||
{
|
||||
return STATUS_RESOURCE_DATA_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (!Memory32 && (Descriptor->u.Memory.Start.LowPart & 0xFF))
|
||||
if ((LogicalDevice->Flags & ISAPNP_HAS_MEM24_DECODER) && (Descriptor->u.Memory.Start.LowPart & 0xFF))
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
break;
|
||||
|
|
|
@ -10,12 +10,8 @@
|
|||
/* INCLUDES *******************************************************************/
|
||||
|
||||
#ifndef UNIT_TEST
|
||||
|
||||
#include "isapnp.h"
|
||||
#endif /* UNIT_TEST */
|
||||
|
||||
#include <search.h>
|
||||
|
||||
#ifndef UNIT_TEST
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
@ -32,46 +28,8 @@ LIST_ENTRY BusListHead;
|
|||
|
||||
#endif /* UNIT_TEST */
|
||||
|
||||
static PUCHAR Priority;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
int
|
||||
__cdecl
|
||||
IsaComparePriority(
|
||||
const void *A,
|
||||
const void *B)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
return Priority[*(PUCHAR)A] - Priority[*(PUCHAR)B];
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
VOID
|
||||
IsaDetermineBestConfig(
|
||||
_Out_writes_all_(ISAPNP_MAX_ALTERNATIVES) PUCHAR BestConfig,
|
||||
_In_ PISAPNP_ALTERNATIVES Alternatives)
|
||||
{
|
||||
UCHAR i;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
for (i = 0; i < ISAPNP_MAX_ALTERNATIVES; i++)
|
||||
{
|
||||
BestConfig[i] = i;
|
||||
}
|
||||
|
||||
Priority = Alternatives->Priority;
|
||||
qsort(BestConfig,
|
||||
Alternatives->Count,
|
||||
sizeof(*BestConfig),
|
||||
IsaComparePriority);
|
||||
}
|
||||
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
VOID
|
||||
|
@ -194,323 +152,298 @@ IsaConvertMemRange32Requirement(
|
|||
Description->Length - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* For example, the PnP ROM
|
||||
* 0x15, 0x04, ... // Logical device ID
|
||||
* 0x47, 0x01, 0x30, 0x03, 0x30, 0x03, 0x04, 0x04, // IO 330, len 4, align 4
|
||||
* 0x30, // **** Start DF ****
|
||||
* 0x22, 0x04, 0x00, // IRQ 2
|
||||
* 0x31, 0x02, // **** Start DF ****
|
||||
* 0x22, 0xC0, 0x00, // IRQ 6 or 7
|
||||
* 0x38, // **** End DF ******
|
||||
* 0x2A, 0x20, 0x3A, // DMA 5
|
||||
* 0x22, 0x00, 0x08, // IRQ 12
|
||||
* 0x79, 0x00, // END
|
||||
*
|
||||
* becomes the following resource requirements list:
|
||||
* Interface 1 Bus 0 Slot 0 AlternativeLists 2
|
||||
*
|
||||
* AltList #0, AltList->Count 4
|
||||
* [Option 0, ShareDisposition 1, Flags 11] IO: Min 0:330, Max 0:333, Align 4 Len 4
|
||||
* [Option 0, ShareDisposition 1, Flags 1] INT: Min 2 Max 2
|
||||
* [Option 0, ShareDisposition 0, Flags 0] DMA: Min 5 Max 5
|
||||
* [Option 0, ShareDisposition 1, Flags 1] INT: Min B Max B
|
||||
*
|
||||
* AltList #1, AltList->Count 5
|
||||
* [Option 0, ShareDisposition 1, Flags 11] IO: Min 0:330, Max 0:333, Align 4 Len 4
|
||||
* [Option 0, ShareDisposition 1, Flags 1] INT: Min 6 Max 6
|
||||
* [Option 8, ShareDisposition 1, Flags 1] INT: Min 7 Max 7
|
||||
* [Option 0, ShareDisposition 0, Flags 0] DMA: Min 5 Max 5
|
||||
* [Option 0, ShareDisposition 1, Flags 1] INT: Min B Max B
|
||||
*/
|
||||
static
|
||||
CODE_SEG("PAGE")
|
||||
NTSTATUS
|
||||
IsaPnpCreateLogicalDeviceRequirements(
|
||||
_In_ PISAPNP_PDO_EXTENSION PdoExt)
|
||||
{
|
||||
PISAPNP_LOGICAL_DEVICE LogDev = PdoExt->IsaPnpDevice;
|
||||
RTL_BITMAP TempBitmap;
|
||||
ULONG TempBuffer;
|
||||
ULONG ResourceCount = 0, AltCount = 0, AltOptionalCount = 0;
|
||||
ULONG ListSize, i, j;
|
||||
BOOLEAN FirstDescriptor;
|
||||
PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
|
||||
PIO_RESOURCE_DESCRIPTOR Descriptor;
|
||||
PISAPNP_ALTERNATIVES Alternatives = LogDev->Alternatives;
|
||||
ISAPNP_DEPENDENT_FUNCTION_STATE DfState;
|
||||
ULONG FirstFixedDescriptors, LastFixedDescriptors;
|
||||
ULONG ResourceCount, AltListCount, ListSize, i;
|
||||
BOOLEAN IsFirstAltList, IsFirstDescriptor;
|
||||
PIO_RESOURCE_LIST AltList;
|
||||
PISAPNP_RESOURCE Resource;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
/* Count number of requirements */
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDev->Io); i++)
|
||||
/* Count the number of requirements */
|
||||
DfState = dfNotStarted;
|
||||
FirstFixedDescriptors = 0;
|
||||
LastFixedDescriptors = 0;
|
||||
ResourceCount = 0;
|
||||
AltListCount = 1;
|
||||
Resource = PdoExt->IsaPnpDevice->Resources;
|
||||
while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
|
||||
{
|
||||
/*
|
||||
* Use the continue statement to count the number of requirements.
|
||||
* We handle a possible gap because depedent function can appear at
|
||||
* any position in the logical device's requirements list.
|
||||
*/
|
||||
if (!LogDev->Io[i].Description.Length)
|
||||
continue;
|
||||
switch (Resource->Type)
|
||||
{
|
||||
case ISAPNP_RESOURCE_TYPE_START_DEPENDENT:
|
||||
{
|
||||
if (DfState == dfStarted)
|
||||
++AltListCount;
|
||||
|
||||
ResourceCount++;
|
||||
DfState = dfStarted;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDev->Irq); i++)
|
||||
{
|
||||
if (!LogDev->Irq[i].Description.Mask)
|
||||
continue;
|
||||
|
||||
TempBuffer = LogDev->Irq[i].Description.Mask;
|
||||
RtlInitializeBitMap(&TempBitmap,
|
||||
&TempBuffer,
|
||||
RTL_BITS_OF(LogDev->Irq[i].Description.Mask));
|
||||
ResourceCount += RtlNumberOfSetBits(&TempBitmap);
|
||||
}
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDev->Dma); i++)
|
||||
case ISAPNP_RESOURCE_TYPE_END_DEPENDENT:
|
||||
{
|
||||
if (!LogDev->Dma[i].Description.Mask)
|
||||
continue;
|
||||
DfState = dfDone;
|
||||
break;
|
||||
}
|
||||
|
||||
TempBuffer = LogDev->Dma[i].Description.Mask;
|
||||
RtlInitializeBitMap(&TempBitmap,
|
||||
&TempBuffer,
|
||||
RTL_BITS_OF(LogDev->Dma[i].Description.Mask));
|
||||
ResourceCount += RtlNumberOfSetBits(&TempBitmap);
|
||||
}
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDev->MemRange); i++)
|
||||
case ISAPNP_RESOURCE_TYPE_IRQ:
|
||||
case ISAPNP_RESOURCE_TYPE_DMA:
|
||||
{
|
||||
if (!LogDev->MemRange[i].Description.Length)
|
||||
continue;
|
||||
RTL_BITMAP ResourceBitmap;
|
||||
ULONG BitmapSize, BitmapBuffer, BitCount;
|
||||
|
||||
ResourceCount++;
|
||||
}
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDev->MemRange32); i++)
|
||||
if (Resource->Type == ISAPNP_RESOURCE_TYPE_IRQ)
|
||||
{
|
||||
if (!LogDev->MemRange32[i].Description.Length)
|
||||
continue;
|
||||
|
||||
ResourceCount++;
|
||||
}
|
||||
if (Alternatives)
|
||||
{
|
||||
ULONG BitCount;
|
||||
|
||||
if (HasIoAlternatives(Alternatives))
|
||||
AltCount++;
|
||||
if (HasIrqAlternatives(Alternatives))
|
||||
AltCount++;
|
||||
if (HasDmaAlternatives(Alternatives))
|
||||
AltCount++;
|
||||
if (HasMemoryAlternatives(Alternatives))
|
||||
AltCount++;
|
||||
if (HasMemory32Alternatives(Alternatives))
|
||||
AltCount++;
|
||||
ResourceCount += AltCount;
|
||||
|
||||
if (HasIrqAlternatives(Alternatives))
|
||||
{
|
||||
for (i = 0; i < Alternatives->Count; i++)
|
||||
{
|
||||
TempBuffer = Alternatives->Irq[i].Mask;
|
||||
RtlInitializeBitMap(&TempBitmap,
|
||||
&TempBuffer,
|
||||
RTL_BITS_OF(Alternatives->Irq[i].Mask));
|
||||
BitCount = RtlNumberOfSetBits(&TempBitmap);
|
||||
|
||||
if (BitCount > 1)
|
||||
AltOptionalCount += BitCount - 1;
|
||||
}
|
||||
}
|
||||
if (HasDmaAlternatives(Alternatives))
|
||||
{
|
||||
for (i = 0; i < Alternatives->Count; i++)
|
||||
{
|
||||
TempBuffer = Alternatives->Dma[i].Mask;
|
||||
RtlInitializeBitMap(&TempBitmap,
|
||||
&TempBuffer,
|
||||
RTL_BITS_OF(Alternatives->Dma[i].Mask));
|
||||
BitCount = RtlNumberOfSetBits(&TempBitmap);
|
||||
|
||||
if (BitCount > 1)
|
||||
AltOptionalCount += BitCount - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ResourceCount == 0)
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
/* Allocate memory to store requirements */
|
||||
ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST);
|
||||
if (Alternatives)
|
||||
{
|
||||
ListSize += sizeof(IO_RESOURCE_DESCRIPTOR) * (ResourceCount - 1) * Alternatives->Count
|
||||
+ sizeof(IO_RESOURCE_LIST) * (Alternatives->Count - 1)
|
||||
+ sizeof(IO_RESOURCE_DESCRIPTOR) * AltOptionalCount;
|
||||
BitmapSize = RTL_BITS_OF(Resource->IrqDescription.Mask);
|
||||
BitmapBuffer = Resource->IrqDescription.Mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
ListSize += sizeof(IO_RESOURCE_DESCRIPTOR) * (ResourceCount - 1);
|
||||
BitmapSize = RTL_BITS_OF(Resource->DmaDescription.Mask);
|
||||
BitmapBuffer = Resource->DmaDescription.Mask;
|
||||
}
|
||||
RtlInitializeBitMap(&ResourceBitmap, &BitmapBuffer, BitmapSize);
|
||||
|
||||
BitCount = RtlNumberOfSetBits(&ResourceBitmap);
|
||||
switch (DfState)
|
||||
{
|
||||
case dfNotStarted:
|
||||
FirstFixedDescriptors += BitCount;
|
||||
break;
|
||||
|
||||
case dfStarted:
|
||||
ResourceCount += BitCount;
|
||||
break;
|
||||
|
||||
case dfDone:
|
||||
LastFixedDescriptors += BitCount;
|
||||
break;
|
||||
|
||||
DEFAULT_UNREACHABLE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ISAPNP_RESOURCE_TYPE_IO:
|
||||
case ISAPNP_RESOURCE_TYPE_MEMRANGE:
|
||||
case ISAPNP_RESOURCE_TYPE_MEMRANGE32:
|
||||
{
|
||||
switch (DfState)
|
||||
{
|
||||
case dfNotStarted:
|
||||
++FirstFixedDescriptors;
|
||||
break;
|
||||
|
||||
case dfStarted:
|
||||
++ResourceCount;
|
||||
break;
|
||||
|
||||
case dfDone:
|
||||
++LastFixedDescriptors;
|
||||
break;
|
||||
|
||||
DEFAULT_UNREACHABLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
UNREACHABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
++Resource;
|
||||
}
|
||||
|
||||
/* This logical device has no resource requirements */
|
||||
if ((ResourceCount == 0) && (FirstFixedDescriptors == 0) && (LastFixedDescriptors == 0))
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
/* Allocate memory to store requirements */
|
||||
ListSize = FIELD_OFFSET(IO_RESOURCE_REQUIREMENTS_LIST, List) +
|
||||
FIELD_OFFSET(IO_RESOURCE_LIST, Descriptors) * AltListCount +
|
||||
sizeof(IO_RESOURCE_DESCRIPTOR) * ResourceCount +
|
||||
sizeof(IO_RESOURCE_DESCRIPTOR) * AltListCount *
|
||||
(FirstFixedDescriptors + LastFixedDescriptors);
|
||||
RequirementsList = ExAllocatePoolZero(PagedPool, ListSize, TAG_ISAPNP);
|
||||
if (!RequirementsList)
|
||||
return STATUS_NO_MEMORY;
|
||||
|
||||
RequirementsList->ListSize = ListSize;
|
||||
RequirementsList->InterfaceType = Isa;
|
||||
RequirementsList->AlternativeLists = Alternatives ? Alternatives->Count : 1;
|
||||
RequirementsList->AlternativeLists = AltListCount;
|
||||
|
||||
RequirementsList->List[0].Version = 1;
|
||||
RequirementsList->List[0].Revision = 1;
|
||||
RequirementsList->List[0].Count = ResourceCount;
|
||||
|
||||
/* Store requirements */
|
||||
Descriptor = RequirementsList->List[0].Descriptors;
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDev->Io); i++)
|
||||
IsFirstAltList = TRUE;
|
||||
AltList = &RequirementsList->List[0];
|
||||
Descriptor = &RequirementsList->List[0].Descriptors[0];
|
||||
Resource = PdoExt->IsaPnpDevice->Resources;
|
||||
while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
|
||||
{
|
||||
if (!LogDev->Io[i].Description.Length)
|
||||
break;
|
||||
|
||||
IsaConvertIoRequirement(Descriptor++, &LogDev->Io[i].Description);
|
||||
}
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDev->Irq); i++)
|
||||
switch (Resource->Type)
|
||||
{
|
||||
if (!LogDev->Irq[i].Description.Mask)
|
||||
continue;
|
||||
|
||||
FirstDescriptor = TRUE;
|
||||
|
||||
for (j = 0; j < RTL_BITS_OF(LogDev->Irq[i].Description.Mask); j++)
|
||||
case ISAPNP_RESOURCE_TYPE_START_DEPENDENT:
|
||||
{
|
||||
if (!(LogDev->Irq[i].Description.Mask & (1 << j)))
|
||||
continue;
|
||||
|
||||
IsaConvertIrqRequirement(Descriptor++,
|
||||
&LogDev->Irq[i].Description,
|
||||
j,
|
||||
FirstDescriptor);
|
||||
|
||||
if (FirstDescriptor)
|
||||
FirstDescriptor = FALSE;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDev->Dma); i++)
|
||||
if (!IsFirstAltList)
|
||||
{
|
||||
if (!LogDev->Dma[i].Description.Mask)
|
||||
continue;
|
||||
/* Add room for the fixed descriptors */
|
||||
AltList->Count += LastFixedDescriptors;
|
||||
|
||||
FirstDescriptor = TRUE;
|
||||
|
||||
for (j = 0; j < RTL_BITS_OF(LogDev->Dma[i].Description.Mask); j++)
|
||||
{
|
||||
if (!(LogDev->Dma[i].Description.Mask & (1 << j)))
|
||||
continue;
|
||||
|
||||
IsaConvertDmaRequirement(Descriptor++,
|
||||
&LogDev->Dma[i].Description,
|
||||
j,
|
||||
FirstDescriptor);
|
||||
|
||||
if (FirstDescriptor)
|
||||
FirstDescriptor = FALSE;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDev->MemRange); i++)
|
||||
{
|
||||
if (!LogDev->MemRange[i].Description.Length)
|
||||
continue;
|
||||
|
||||
IsaConvertMemRangeRequirement(Descriptor++,
|
||||
&LogDev->MemRange[i].Description);
|
||||
}
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDev->MemRange32); i++)
|
||||
{
|
||||
if (!LogDev->MemRange32[i].Description.Length)
|
||||
continue;
|
||||
|
||||
IsaConvertMemRange32Requirement(Descriptor++,
|
||||
&LogDev->MemRange32[i].Description);
|
||||
}
|
||||
if (Alternatives)
|
||||
{
|
||||
UCHAR BestConfig[ISAPNP_MAX_ALTERNATIVES];
|
||||
PIO_RESOURCE_LIST AltList = &RequirementsList->List[0];
|
||||
PIO_RESOURCE_LIST NextList = AltList;
|
||||
|
||||
IsaDetermineBestConfig(BestConfig, Alternatives);
|
||||
|
||||
for (i = 0; i < RequirementsList->AlternativeLists; i++)
|
||||
{
|
||||
RtlMoveMemory(NextList, AltList, sizeof(IO_RESOURCE_LIST));
|
||||
|
||||
/* Just because the 'NextList->Count++' correction */
|
||||
NextList->Count = ResourceCount;
|
||||
/*
|
||||
* For example, the ROM
|
||||
* 0x15, ... // Logical device ID
|
||||
* 0x30, // Start DF
|
||||
* 0x22, 0x04, 0x00 // IRQ
|
||||
* 0x30, // Start DF
|
||||
* 0x22, 0xC0, 0x00 // IRQ
|
||||
* 0x38, // End DF
|
||||
* 0x2A, 0x20, 0x3A // DMA
|
||||
* 0x22, 0x00, 0x08 // IRQ
|
||||
* 0x79, 0x00 // END
|
||||
*
|
||||
* will be represented as the following resource requirements list:
|
||||
* Interface 1 Bus 0 Slot 0 AlternativeLists 2
|
||||
* AltList 1, AltList->Count 3
|
||||
* [Option 0, ShareDisposition 1, Flags 1] INT: Min B Max B
|
||||
* [Option 0, ShareDisposition 0, Flags 0] DMA: Min 5 Max 5
|
||||
* [Option 0, ShareDisposition 1, Flags 1] INT: Min 2 Max 2
|
||||
* End Descriptors
|
||||
* AltList 2, AltList->Count 4
|
||||
* [Option 0, ShareDisposition 1, Flags 1] INT: Min B Max B
|
||||
* [Option 0, ShareDisposition 0, Flags 0] DMA: Min 5 Max 5
|
||||
* [Option 0, ShareDisposition 1, Flags 1] INT: Min 6 Max 6
|
||||
* [Option 8, ShareDisposition 1, Flags 1] INT: Min 7 Max 7
|
||||
* End Descriptors
|
||||
*/
|
||||
/* Move on to the next list */
|
||||
AltList = (PIO_RESOURCE_LIST)(AltList->Descriptors + AltList->Count);
|
||||
AltList->Version = 1;
|
||||
AltList->Revision = 1;
|
||||
|
||||
/* Propagate the fixed resources to our new list */
|
||||
for (j = 0; j < AltList->Count - AltCount; j++)
|
||||
{
|
||||
RtlMoveMemory(&NextList->Descriptors[j],
|
||||
&AltList->Descriptors[j],
|
||||
sizeof(IO_RESOURCE_DESCRIPTOR));
|
||||
RtlCopyMemory(&AltList->Descriptors,
|
||||
RequirementsList->List[0].Descriptors,
|
||||
sizeof(IO_RESOURCE_DESCRIPTOR) * FirstFixedDescriptors);
|
||||
AltList->Count += FirstFixedDescriptors;
|
||||
|
||||
Descriptor = &AltList->Descriptors[FirstFixedDescriptors];
|
||||
}
|
||||
|
||||
Descriptor = &NextList->Descriptors[NextList->Count - AltCount];
|
||||
|
||||
/*
|
||||
* Append alternatives.
|
||||
* NOTE: To keep it simple, we append these to the end of the list.
|
||||
*/
|
||||
if (HasIoAlternatives(Alternatives))
|
||||
{
|
||||
IsaConvertIoRequirement(Descriptor++,
|
||||
&Alternatives->Io[BestConfig[i]]);
|
||||
IsFirstAltList = FALSE;
|
||||
break;
|
||||
}
|
||||
if (HasIrqAlternatives(Alternatives))
|
||||
{
|
||||
FirstDescriptor = TRUE;
|
||||
|
||||
for (j = 0; j < RTL_BITS_OF(Alternatives->Irq[BestConfig[i]].Mask); j++)
|
||||
case ISAPNP_RESOURCE_TYPE_END_DEPENDENT:
|
||||
break;
|
||||
|
||||
case ISAPNP_RESOURCE_TYPE_IO:
|
||||
{
|
||||
if (!(Alternatives->Irq[BestConfig[i]].Mask & (1 << j)))
|
||||
IsaConvertIoRequirement(Descriptor++, &Resource->IoDescription);
|
||||
|
||||
++AltList->Count;
|
||||
break;
|
||||
}
|
||||
|
||||
case ISAPNP_RESOURCE_TYPE_IRQ:
|
||||
{
|
||||
IsFirstDescriptor = TRUE;
|
||||
|
||||
for (i = 0; i < RTL_BITS_OF(Resource->IrqDescription.Mask); i++)
|
||||
{
|
||||
if (!(Resource->IrqDescription.Mask & (1 << i)))
|
||||
continue;
|
||||
|
||||
IsaConvertIrqRequirement(Descriptor++,
|
||||
&Alternatives->Irq[BestConfig[i]],
|
||||
j,
|
||||
FirstDescriptor);
|
||||
&Resource->IrqDescription,
|
||||
i,
|
||||
IsFirstDescriptor);
|
||||
++AltList->Count;
|
||||
|
||||
if (FirstDescriptor)
|
||||
FirstDescriptor = FALSE;
|
||||
else
|
||||
NextList->Count++;
|
||||
IsFirstDescriptor = FALSE;
|
||||
}
|
||||
}
|
||||
if (HasDmaAlternatives(Alternatives))
|
||||
{
|
||||
FirstDescriptor = TRUE;
|
||||
|
||||
for (j = 0; j < RTL_BITS_OF(Alternatives->Dma[BestConfig[i]].Mask); j++)
|
||||
break;
|
||||
}
|
||||
|
||||
case ISAPNP_RESOURCE_TYPE_DMA:
|
||||
{
|
||||
if (!(Alternatives->Dma[BestConfig[i]].Mask & (1 << j)))
|
||||
IsFirstDescriptor = TRUE;
|
||||
|
||||
for (i = 0; i < RTL_BITS_OF(Resource->DmaDescription.Mask); i++)
|
||||
{
|
||||
if (!(Resource->DmaDescription.Mask & (1 << i)))
|
||||
continue;
|
||||
|
||||
IsaConvertDmaRequirement(Descriptor++,
|
||||
&Alternatives->Dma[BestConfig[i]],
|
||||
j,
|
||||
FirstDescriptor);
|
||||
&Resource->DmaDescription,
|
||||
i,
|
||||
IsFirstDescriptor);
|
||||
++AltList->Count;
|
||||
|
||||
if (FirstDescriptor)
|
||||
FirstDescriptor = FALSE;
|
||||
else
|
||||
NextList->Count++;
|
||||
IsFirstDescriptor = FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (HasMemoryAlternatives(Alternatives))
|
||||
|
||||
case ISAPNP_RESOURCE_TYPE_MEMRANGE:
|
||||
{
|
||||
IsaConvertMemRangeRequirement(Descriptor++,
|
||||
&Alternatives->MemRange[BestConfig[i]]);
|
||||
IsaConvertMemRangeRequirement(Descriptor++, &Resource->MemRangeDescription);
|
||||
|
||||
++AltList->Count;
|
||||
break;
|
||||
}
|
||||
if (HasMemory32Alternatives(Alternatives))
|
||||
|
||||
case ISAPNP_RESOURCE_TYPE_MEMRANGE32:
|
||||
{
|
||||
IsaConvertMemRange32Requirement(Descriptor++,
|
||||
&Alternatives->MemRange32[BestConfig[i]]);
|
||||
IsaConvertMemRange32Requirement(Descriptor++, &Resource->MemRange32Description);
|
||||
|
||||
++AltList->Count;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
UNREACHABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
++Resource;
|
||||
}
|
||||
|
||||
/* Append the fixed resources */
|
||||
if (LastFixedDescriptors)
|
||||
{
|
||||
PIO_RESOURCE_LIST NextList = &RequirementsList->List[0];
|
||||
|
||||
/* Make the descriptor point to the fixed resources */
|
||||
Descriptor -= LastFixedDescriptors;
|
||||
|
||||
/* Propagate the fixed resources onto previous lists */
|
||||
AltListCount = RequirementsList->AlternativeLists - 1;
|
||||
for (i = 0; i < AltListCount; i++)
|
||||
{
|
||||
RtlCopyMemory(&NextList->Descriptors[NextList->Count - LastFixedDescriptors],
|
||||
Descriptor,
|
||||
sizeof(IO_RESOURCE_DESCRIPTOR) * LastFixedDescriptors);
|
||||
|
||||
NextList = (PIO_RESOURCE_LIST)(NextList->Descriptors + NextList->Count);
|
||||
}
|
||||
}
|
||||
|
@ -527,22 +460,29 @@ FindIoDescriptor(
|
|||
_In_ ULONG RangeStart,
|
||||
_In_ ULONG RangeEnd,
|
||||
_Out_opt_ PUCHAR Information,
|
||||
_Out_opt_ PULONG Length,
|
||||
_Out_opt_ PUCHAR WriteOrder)
|
||||
_Out_opt_ PULONG Length)
|
||||
{
|
||||
ULONG i;
|
||||
BOOLEAN Match;
|
||||
PISAPNP_IO_DESCRIPTION Description;
|
||||
PISAPNP_RESOURCE Resource;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDevice->Io); i++)
|
||||
Resource = LogDevice->Resources;
|
||||
while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
|
||||
{
|
||||
Description = &LogDevice->Io[i].Description;
|
||||
if (Resource->Type == ISAPNP_RESOURCE_TYPE_IO)
|
||||
{
|
||||
PISAPNP_IO_DESCRIPTION Description = &Resource->IoDescription;
|
||||
BOOLEAN Match;
|
||||
|
||||
Match = Base ? (Base >= Description->Minimum) && (Base <= Description->Maximum)
|
||||
: (RangeStart >= Description->Minimum) &&
|
||||
if (Base)
|
||||
{
|
||||
Match = (Base >= Description->Minimum) && (Base <= Description->Maximum);
|
||||
}
|
||||
else
|
||||
{
|
||||
Match = (RangeStart >= Description->Minimum) &&
|
||||
(RangeEnd <= (ULONG)(Description->Maximum + Description->Length - 1));
|
||||
}
|
||||
|
||||
if (Match)
|
||||
{
|
||||
|
@ -550,35 +490,12 @@ FindIoDescriptor(
|
|||
*Information = Description->Information;
|
||||
if (Length)
|
||||
*Length = Description->Length;
|
||||
if (WriteOrder)
|
||||
*WriteOrder = LogDevice->Io[i].Index;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!LogDevice->Alternatives)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < LogDevice->Alternatives->Count; i++)
|
||||
{
|
||||
Description = &LogDevice->Alternatives->Io[i];
|
||||
|
||||
Match = Base ? (Base >= Description->Minimum) && (Base <= Description->Maximum)
|
||||
: (RangeStart >= Description->Minimum) &&
|
||||
(RangeEnd <= (ULONG)(Description->Maximum + Description->Length - 1));
|
||||
|
||||
if (Match)
|
||||
{
|
||||
if (Information)
|
||||
*Information = Description->Information;
|
||||
if (Length)
|
||||
*Length = Description->Length;
|
||||
if (WriteOrder)
|
||||
*WriteOrder = LogDevice->Alternatives->IoIndex;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
++Resource;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
@ -588,53 +505,24 @@ CODE_SEG("PAGE")
|
|||
BOOLEAN
|
||||
FindIrqDescriptor(
|
||||
_In_ PISAPNP_LOGICAL_DEVICE LogDevice,
|
||||
_In_ ULONG Vector,
|
||||
_Out_opt_ PUCHAR WriteOrder)
|
||||
_In_ ULONG Vector)
|
||||
{
|
||||
ULONG i, j;
|
||||
PISAPNP_IRQ_DESCRIPTION Description;
|
||||
PISAPNP_RESOURCE Resource;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDevice->Irq); i++)
|
||||
Resource = LogDevice->Resources;
|
||||
while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
|
||||
{
|
||||
Description = &LogDevice->Irq[i].Description;
|
||||
|
||||
for (j = 0; j < RTL_BITS_OF(Description->Mask); j++)
|
||||
{
|
||||
if (Description->Mask & (1 << j))
|
||||
{
|
||||
if (j == Vector)
|
||||
{
|
||||
if (WriteOrder)
|
||||
*WriteOrder = LogDevice->Irq[i].Index;
|
||||
if (Resource->Type == ISAPNP_RESOURCE_TYPE_IRQ)
|
||||
{
|
||||
PISAPNP_IRQ_DESCRIPTION Description = &Resource->IrqDescription;
|
||||
|
||||
if (Description->Mask & (1 << Vector))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!LogDevice->Alternatives)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < LogDevice->Alternatives->Count; i++)
|
||||
{
|
||||
Description = &LogDevice->Alternatives->Irq[i];
|
||||
|
||||
for (j = 0; j < RTL_BITS_OF(Description->Mask); j++)
|
||||
{
|
||||
if (Description->Mask & (1 << j))
|
||||
{
|
||||
if (j == Vector)
|
||||
{
|
||||
if (WriteOrder)
|
||||
*WriteOrder = LogDevice->Alternatives->IrqIndex;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
++Resource;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
@ -644,53 +532,24 @@ CODE_SEG("PAGE")
|
|||
BOOLEAN
|
||||
FindDmaDescriptor(
|
||||
_In_ PISAPNP_LOGICAL_DEVICE LogDevice,
|
||||
_In_ ULONG Channel,
|
||||
_Out_opt_ PUCHAR WriteOrder)
|
||||
_In_ ULONG Channel)
|
||||
{
|
||||
ULONG i, j;
|
||||
PISAPNP_DMA_DESCRIPTION Description;
|
||||
PISAPNP_RESOURCE Resource;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDevice->Dma); i++)
|
||||
Resource = LogDevice->Resources;
|
||||
while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
|
||||
{
|
||||
Description = &LogDevice->Dma[i].Description;
|
||||
|
||||
for (j = 0; j < RTL_BITS_OF(Description->Mask); j++)
|
||||
{
|
||||
if (Description->Mask & (1 << j))
|
||||
{
|
||||
if (j == Channel)
|
||||
{
|
||||
if (WriteOrder)
|
||||
*WriteOrder = LogDevice->Dma[i].Index;
|
||||
if (Resource->Type == ISAPNP_RESOURCE_TYPE_DMA)
|
||||
{
|
||||
PISAPNP_DMA_DESCRIPTION Description = &Resource->DmaDescription;
|
||||
|
||||
if (Description->Mask & (1 << Channel))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!LogDevice->Alternatives)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < LogDevice->Alternatives->Count; i++)
|
||||
{
|
||||
Description = &LogDevice->Alternatives->Dma[i];
|
||||
|
||||
for (j = 0; j < RTL_BITS_OF(Description->Mask); j++)
|
||||
{
|
||||
if (Description->Mask & (1 << j))
|
||||
{
|
||||
if (j == Channel)
|
||||
{
|
||||
if (WriteOrder)
|
||||
*WriteOrder = LogDevice->Alternatives->DmaIndex;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
++Resource;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
@ -702,87 +561,57 @@ FindMemoryDescriptor(
|
|||
_In_ PISAPNP_LOGICAL_DEVICE LogDevice,
|
||||
_In_ ULONG RangeStart,
|
||||
_In_ ULONG RangeEnd,
|
||||
_Out_opt_ PBOOLEAN Memory32,
|
||||
_Out_opt_ PUCHAR Information,
|
||||
_Out_opt_ PUCHAR WriteOrder)
|
||||
_Out_opt_ PUCHAR Information)
|
||||
{
|
||||
ULONG i;
|
||||
PISAPNP_MEMRANGE_DESCRIPTION Description;
|
||||
PISAPNP_MEMRANGE32_DESCRIPTION Description32;
|
||||
PISAPNP_RESOURCE Resource;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDevice->MemRange); i++)
|
||||
Resource = LogDevice->Resources;
|
||||
while (Resource->Type != ISAPNP_RESOURCE_TYPE_END)
|
||||
{
|
||||
Description = &LogDevice->MemRange[i].Description;
|
||||
switch (Resource->Type)
|
||||
{
|
||||
case ISAPNP_RESOURCE_TYPE_MEMRANGE:
|
||||
{
|
||||
PISAPNP_MEMRANGE_DESCRIPTION Description;
|
||||
|
||||
Description = &Resource->MemRangeDescription;
|
||||
|
||||
if ((RangeStart >= (ULONG)(Description->Minimum << 8)) &&
|
||||
(RangeEnd <= (ULONG)((Description->Maximum << 8) + (Description->Length << 8) - 1)))
|
||||
(RangeEnd <= (ULONG)((Description->Maximum << 8) +
|
||||
(Description->Length << 8) - 1)))
|
||||
{
|
||||
if (Memory32)
|
||||
*Memory32 = FALSE;
|
||||
if (Information)
|
||||
*Information = Description->Information;
|
||||
if (WriteOrder)
|
||||
*WriteOrder = LogDevice->MemRange[i].Index;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDevice->MemRange32); i++)
|
||||
|
||||
case ISAPNP_RESOURCE_TYPE_MEMRANGE32:
|
||||
{
|
||||
Description32 = &LogDevice->MemRange32[i].Description;
|
||||
PISAPNP_MEMRANGE32_DESCRIPTION Description32;
|
||||
|
||||
Description32 = &Resource->MemRange32Description;
|
||||
|
||||
if ((RangeStart >= Description32->Minimum) &&
|
||||
(RangeEnd <= (Description32->Maximum + Description32->Length - 1)))
|
||||
{
|
||||
if (Memory32)
|
||||
*Memory32 = TRUE;
|
||||
if (Information)
|
||||
*Information = Description32->Information;
|
||||
if (WriteOrder)
|
||||
*WriteOrder = LogDevice->MemRange32[i].Index;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!LogDevice->Alternatives)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < LogDevice->Alternatives->Count; i++)
|
||||
{
|
||||
Description = &LogDevice->Alternatives->MemRange[i];
|
||||
|
||||
if ((RangeStart >= (ULONG)(Description->Minimum << 8)) &&
|
||||
(RangeEnd <= (ULONG)((Description->Maximum << 8) + (Description->Length << 8) - 1)))
|
||||
{
|
||||
if (Memory32)
|
||||
*Memory32 = FALSE;
|
||||
if (Information)
|
||||
*Information = Description->Information;
|
||||
if (WriteOrder)
|
||||
*WriteOrder = LogDevice->Alternatives->MemRangeIndex;
|
||||
|
||||
return TRUE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < LogDevice->Alternatives->Count; i++)
|
||||
{
|
||||
Description32 = &LogDevice->Alternatives->MemRange32[i];
|
||||
|
||||
if ((RangeStart >= Description32->Minimum) &&
|
||||
(RangeEnd <= (Description32->Maximum + Description32->Length - 1)))
|
||||
{
|
||||
if (Memory32)
|
||||
*Memory32 = TRUE;
|
||||
if (Information)
|
||||
*Information = Description32->Information;
|
||||
if (WriteOrder)
|
||||
*WriteOrder = LogDevice->Alternatives->MemRange32Index;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
++Resource;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
@ -872,9 +701,9 @@ IsaPnpCreateLogicalDeviceResources(
|
|||
0,
|
||||
0,
|
||||
&Information,
|
||||
&CurrentLength,
|
||||
NULL))
|
||||
&CurrentLength))
|
||||
{
|
||||
DPRINT1("I/O entry #%lu %x not found\n", i, LogDev->Io[i].CurrentBase);
|
||||
goto InvalidBiosResources;
|
||||
}
|
||||
|
||||
|
@ -894,9 +723,6 @@ IsaPnpCreateLogicalDeviceResources(
|
|||
if (!LogDev->Irq[i].CurrentNo)
|
||||
break;
|
||||
|
||||
if (!FindIrqDescriptor(LogDev, LogDev->Irq[i].CurrentNo, NULL))
|
||||
goto InvalidBiosResources;
|
||||
|
||||
Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[ResourceCount++];
|
||||
Descriptor->Type = CmResourceTypeInterrupt;
|
||||
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
|
||||
|
@ -906,16 +732,13 @@ IsaPnpCreateLogicalDeviceResources(
|
|||
Descriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
|
||||
Descriptor->u.Interrupt.Level = LogDev->Irq[i].CurrentNo;
|
||||
Descriptor->u.Interrupt.Vector = LogDev->Irq[i].CurrentNo;
|
||||
Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
|
||||
Descriptor->u.Interrupt.Affinity = (KAFFINITY)-1;
|
||||
}
|
||||
for (i = 0; i < RTL_NUMBER_OF(LogDev->Dma); i++)
|
||||
{
|
||||
if (LogDev->Dma[i].CurrentChannel == 4)
|
||||
break;
|
||||
|
||||
if (!FindDmaDescriptor(LogDev, LogDev->Dma[i].CurrentChannel, NULL))
|
||||
goto InvalidBiosResources;
|
||||
|
||||
Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[ResourceCount++];
|
||||
Descriptor->Type = CmResourceTypeDma;
|
||||
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
|
||||
|
@ -930,10 +753,12 @@ IsaPnpCreateLogicalDeviceResources(
|
|||
if (!FindMemoryDescriptor(LogDev,
|
||||
LogDev->MemRange[i].CurrentBase,
|
||||
LogDev->MemRange[i].CurrentLength,
|
||||
NULL,
|
||||
&Information,
|
||||
NULL))
|
||||
&Information))
|
||||
{
|
||||
DPRINT1("MEM entry #%lu %lx %lx not found\n",
|
||||
i,
|
||||
LogDev->MemRange[i].CurrentBase,
|
||||
LogDev->MemRange[i].CurrentLength);
|
||||
goto InvalidBiosResources;
|
||||
}
|
||||
|
||||
|
@ -956,10 +781,12 @@ IsaPnpCreateLogicalDeviceResources(
|
|||
if (!FindMemoryDescriptor(LogDev,
|
||||
LogDev->MemRange32[i].CurrentBase,
|
||||
LogDev->MemRange32[i].CurrentLength,
|
||||
NULL,
|
||||
&Information,
|
||||
NULL))
|
||||
&Information))
|
||||
{
|
||||
DPRINT1("MEM32 entry #%lu %lx %lx not found\n",
|
||||
i,
|
||||
LogDev->MemRange32[i].CurrentBase,
|
||||
LogDev->MemRange32[i].CurrentLength);
|
||||
goto InvalidBiosResources;
|
||||
}
|
||||
|
||||
|
@ -980,7 +807,7 @@ IsaPnpCreateLogicalDeviceResources(
|
|||
return STATUS_SUCCESS;
|
||||
|
||||
InvalidBiosResources:
|
||||
DPRINT("Invalid boot resources! (CSN %u, LDN %u)\n", LogDev->CSN, LogDev->LDN);
|
||||
DPRINT1("Invalid boot resources! (CSN %u, LDN %u)\n", LogDev->CSN, LogDev->LDN);
|
||||
|
||||
LogDev->Flags &= ~ISAPNP_HAS_RESOURCES;
|
||||
ExFreePoolWithTag(ResourceList, TAG_ISAPNP);
|
||||
|
|
|
@ -151,22 +151,19 @@ FindIoDescriptor(
|
|||
_In_ ULONG RangeStart,
|
||||
_In_ ULONG RangeEnd,
|
||||
_Out_opt_ PUCHAR Information,
|
||||
_Out_opt_ PULONG Length,
|
||||
_Out_opt_ PUCHAR WriteOrder);
|
||||
_Out_opt_ PULONG Length);
|
||||
|
||||
CODE_SEG("PAGE")
|
||||
BOOLEAN
|
||||
FindIrqDescriptor(
|
||||
_In_ PISAPNP_LOGICAL_DEVICE LogDevice,
|
||||
_In_ ULONG Vector,
|
||||
_Out_opt_ PUCHAR WriteOrder);
|
||||
_In_ ULONG Vector);
|
||||
|
||||
CODE_SEG("PAGE")
|
||||
BOOLEAN
|
||||
FindDmaDescriptor(
|
||||
_In_ PISAPNP_LOGICAL_DEVICE LogDevice,
|
||||
_In_ ULONG Channel,
|
||||
_Out_opt_ PUCHAR WriteOrder);
|
||||
_In_ ULONG Channel);
|
||||
|
||||
CODE_SEG("PAGE")
|
||||
BOOLEAN
|
||||
|
@ -174,9 +171,7 @@ FindMemoryDescriptor(
|
|||
_In_ PISAPNP_LOGICAL_DEVICE LogDevice,
|
||||
_In_ ULONG RangeStart,
|
||||
_In_ ULONG RangeEnd,
|
||||
_Out_opt_ PBOOLEAN Memory32,
|
||||
_Out_opt_ PUCHAR Information,
|
||||
_Out_opt_ PUCHAR WriteOrder);
|
||||
_Out_opt_ PUCHAR Information);
|
||||
|
||||
CODE_SEG("PAGE")
|
||||
PIO_RESOURCE_REQUIREMENTS_LIST
|
||||
|
|
|
@ -11,9 +11,6 @@
|
|||
/** @brief Maximum size of resource data structure supported by the driver. */
|
||||
#define ISAPNP_MAX_RESOURCEDATA 0x1000
|
||||
|
||||
/** @brief Maximum number of Start DF tags supported by the driver. */
|
||||
#define ISAPNP_MAX_ALTERNATIVES 8
|
||||
|
||||
typedef struct _ISAPNP_IO
|
||||
{
|
||||
USHORT CurrentBase;
|
||||
|
@ -59,23 +56,35 @@ typedef struct _ISAPNP_COMPATIBLE_ID_ENTRY
|
|||
LIST_ENTRY IdLink;
|
||||
} ISAPNP_COMPATIBLE_ID_ENTRY, *PISAPNP_COMPATIBLE_ID_ENTRY;
|
||||
|
||||
typedef struct _ISAPNP_ALTERNATIVES
|
||||
typedef enum
|
||||
{
|
||||
ISAPNP_IO_DESCRIPTION Io[ISAPNP_MAX_ALTERNATIVES];
|
||||
ISAPNP_IRQ_DESCRIPTION Irq[ISAPNP_MAX_ALTERNATIVES];
|
||||
ISAPNP_DMA_DESCRIPTION Dma[ISAPNP_MAX_ALTERNATIVES];
|
||||
ISAPNP_MEMRANGE_DESCRIPTION MemRange[ISAPNP_MAX_ALTERNATIVES];
|
||||
ISAPNP_MEMRANGE32_DESCRIPTION MemRange32[ISAPNP_MAX_ALTERNATIVES];
|
||||
UCHAR Priority[ISAPNP_MAX_ALTERNATIVES];
|
||||
UCHAR IoIndex;
|
||||
UCHAR IrqIndex;
|
||||
UCHAR DmaIndex;
|
||||
UCHAR MemRangeIndex;
|
||||
UCHAR MemRange32Index;
|
||||
dfNotStarted,
|
||||
dfStarted,
|
||||
dfDone
|
||||
} ISAPNP_DEPENDENT_FUNCTION_STATE;
|
||||
|
||||
_Field_range_(0, ISAPNP_MAX_ALTERNATIVES)
|
||||
UCHAR Count;
|
||||
} ISAPNP_ALTERNATIVES, *PISAPNP_ALTERNATIVES;
|
||||
typedef struct _ISAPNP_RESOURCE
|
||||
{
|
||||
UCHAR Type;
|
||||
#define ISAPNP_RESOURCE_TYPE_END 0
|
||||
#define ISAPNP_RESOURCE_TYPE_IO 1
|
||||
#define ISAPNP_RESOURCE_TYPE_IRQ 2
|
||||
#define ISAPNP_RESOURCE_TYPE_DMA 3
|
||||
#define ISAPNP_RESOURCE_TYPE_MEMRANGE 4
|
||||
#define ISAPNP_RESOURCE_TYPE_MEMRANGE32 5
|
||||
#define ISAPNP_RESOURCE_TYPE_START_DEPENDENT 6
|
||||
#define ISAPNP_RESOURCE_TYPE_END_DEPENDENT 7
|
||||
|
||||
union
|
||||
{
|
||||
ISAPNP_IO_DESCRIPTION IoDescription;
|
||||
ISAPNP_IRQ_DESCRIPTION IrqDescription;
|
||||
ISAPNP_DMA_DESCRIPTION DmaDescription;
|
||||
ISAPNP_MEMRANGE_DESCRIPTION MemRangeDescription;
|
||||
ISAPNP_MEMRANGE32_DESCRIPTION MemRange32Description;
|
||||
UCHAR Priority;
|
||||
};
|
||||
} ISAPNP_RESOURCE, *PISAPNP_RESOURCE;
|
||||
|
||||
typedef struct _ISAPNP_LOGICAL_DEVICE
|
||||
{
|
||||
|
@ -92,6 +101,12 @@ typedef struct _ISAPNP_LOGICAL_DEVICE
|
|||
/** Cleared when the device has no boot resources */
|
||||
#define ISAPNP_HAS_RESOURCES 0x00000004
|
||||
|
||||
/** The card implements 24-bit memory decoder */
|
||||
#define ISAPNP_HAS_MEM24_DECODER 0x00000008
|
||||
|
||||
/** The card implements 32-bit memory decoder */
|
||||
#define ISAPNP_HAS_MEM32_DECODER 0x00000010
|
||||
|
||||
/**
|
||||
* @name The card data.
|
||||
* @{
|
||||
|
@ -109,7 +124,7 @@ typedef struct _ISAPNP_LOGICAL_DEVICE
|
|||
UCHAR LDN;
|
||||
UCHAR LogVendorId[3];
|
||||
USHORT LogProdId;
|
||||
PISAPNP_ALTERNATIVES Alternatives;
|
||||
PISAPNP_RESOURCE Resources;
|
||||
PSTR FriendlyName;
|
||||
LIST_ENTRY CompatibleIdList;
|
||||
|
||||
|
@ -120,43 +135,3 @@ typedef struct _ISAPNP_LOGICAL_DEVICE
|
|||
ISAPNP_MEMRANGE32 MemRange32[4];
|
||||
/**@}*/
|
||||
} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
|
||||
|
||||
FORCEINLINE
|
||||
BOOLEAN
|
||||
HasIoAlternatives(
|
||||
_In_ PISAPNP_ALTERNATIVES Alternatives)
|
||||
{
|
||||
return (Alternatives->Io[0].Length != 0);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
BOOLEAN
|
||||
HasIrqAlternatives(
|
||||
_In_ PISAPNP_ALTERNATIVES Alternatives)
|
||||
{
|
||||
return (Alternatives->Irq[0].Mask != 0);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
BOOLEAN
|
||||
HasDmaAlternatives(
|
||||
_In_ PISAPNP_ALTERNATIVES Alternatives)
|
||||
{
|
||||
return (Alternatives->Dma[0].Mask != 0);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
BOOLEAN
|
||||
HasMemoryAlternatives(
|
||||
_In_ PISAPNP_ALTERNATIVES Alternatives)
|
||||
{
|
||||
return (Alternatives->MemRange[0].Length != 0);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
BOOLEAN
|
||||
HasMemory32Alternatives(
|
||||
_In_ PISAPNP_ALTERNATIVES Alternatives)
|
||||
{
|
||||
return (Alternatives->MemRange32[0].Length != 0);
|
||||
}
|
||||
|
|
|
@ -488,12 +488,6 @@ IsaPdoQueryResources(
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (!(PdoExt->IsaPnpDevice->Flags & ISAPNP_HAS_RESOURCES))
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (!PdoExt->ResourceList)
|
||||
return Irp->IoStatus.Status;
|
||||
|
||||
|
@ -847,8 +841,8 @@ IsaPnpRemoveLogicalDeviceDO(
|
|||
if (LogDev->FriendlyName)
|
||||
ExFreePoolWithTag(LogDev->FriendlyName, TAG_ISAPNP);
|
||||
|
||||
if (LogDev->Alternatives)
|
||||
ExFreePoolWithTag(LogDev->Alternatives, TAG_ISAPNP);
|
||||
if (LogDev->Resources)
|
||||
ExFreePoolWithTag(LogDev->Resources, TAG_ISAPNP);
|
||||
|
||||
Entry = LogDev->CompatibleIdList.Flink;
|
||||
while (Entry != &LogDev->CompatibleIdList)
|
||||
|
@ -983,18 +977,16 @@ IsaPdoPnp(
|
|||
break;
|
||||
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
if (PdoExt->Common.Signature == IsaPnpLogicalDevice)
|
||||
Status = IsaPdoRemoveDevice(PdoExt, FALSE);
|
||||
else
|
||||
Status = IsaReadPortRemoveDevice(PdoExt, FALSE);
|
||||
break;
|
||||
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
{
|
||||
BOOLEAN FinalRemove = (IrpSp->MinorFunction == IRP_MN_REMOVE_DEVICE);
|
||||
|
||||
if (PdoExt->Common.Signature == IsaPnpLogicalDevice)
|
||||
Status = IsaPdoRemoveDevice(PdoExt, TRUE);
|
||||
Status = IsaPdoRemoveDevice(PdoExt, FinalRemove);
|
||||
else
|
||||
Status = IsaReadPortRemoveDevice(PdoExt, TRUE);
|
||||
Status = IsaReadPortRemoveDevice(PdoExt, FinalRemove);
|
||||
break;
|
||||
}
|
||||
|
||||
case IRP_MN_QUERY_PNP_DEVICE_STATE:
|
||||
Status = IsaPdoQueryPnpDeviceState(PdoExt, Irp);
|
||||
|
|
Loading…
Reference in a new issue