https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2981e63a310e635365a47…
commit 2981e63a310e635365a476bd80a015acf783adf8
Author: Dmitry Borisov <di.sean(a)protonmail.com>
AuthorDate: Fri May 3 20:42:21 2024 +0600
Commit: Dmitry Borisov <di.sean(a)protonmail.com>
CommitDate: Sat Aug 3 17:08:43 2024 +0600
[ISAPNP] Refactor the configuration code
- Remove useless checks
- Increase code readability
---
drivers/bus/isapnp/hardware.c | 322 ++++++++++++++++++++----------------------
drivers/bus/isapnp/isapnp.c | 4 +-
drivers/bus/isapnp/isapnphw.h | 1 +
3 files changed, 157 insertions(+), 170 deletions(-)
diff --git a/drivers/bus/isapnp/hardware.c b/drivers/bus/isapnp/hardware.c
index 937923959a3..ecaec120c14 100644
--- a/drivers/bus/isapnp/hardware.c
+++ b/drivers/bus/isapnp/hardware.c
@@ -1079,7 +1079,7 @@ ReadCurrentResources(
{
LogDevice->Dma[i].CurrentChannel = ReadDmaChannel(ReadDataPort, i);
- if (LogDevice->Dma[i].CurrentChannel == 4)
+ if (LogDevice->Dma[i].CurrentChannel == DMACHANNEL_NONE)
break;
}
for (i = 0; i < RTL_NUMBER_OF(LogDevice->MemRange); i++)
@@ -1128,165 +1128,119 @@ ReadCurrentResources(
static
CODE_SEG("PAGE")
VOID
-WriteResources(
- _In_ PUCHAR ReadDataPort,
- _In_ PISAPNP_LOGICAL_DEVICE LogDevice,
- _In_ PCM_PARTIAL_RESOURCE_LIST PartialResourceList)
+IsaProgramIoDecoder(
+ _In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
+ _In_ UCHAR Index)
{
- UCHAR i,
- NumberOfIo = 0,
- NumberOfIrq = 0,
- NumberOfDma = 0,
- NumberOfMemory = 0,
- NumberOfMemory32 = 0;
-
PAGED_CODE();
- WriteLogicalDeviceNumber(LogDevice->LDN);
-
- for (i = 0; i < PartialResourceList->Count; i++)
- {
- PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor =
&PartialResourceList->PartialDescriptors[i];
+ ASSERT(Descriptor->u.Port.Start.QuadPart <= 0xFFFF);
- switch (Descriptor->Type)
- {
- case CmResourceTypePort:
- {
- (VOID)FindIoDescriptor(LogDevice,
- 0,
- Descriptor->u.Port.Start.LowPart,
- Descriptor->u.Port.Start.LowPart +
- Descriptor->u.Port.Length - 1,
- NULL,
- NULL);
-
- WriteWord(ISAPNP_IOBASE(NumberOfIo),
(USHORT)Descriptor->u.Port.Start.LowPart);
-
- ++NumberOfIo;
- break;
- }
-
- case CmResourceTypeInterrupt:
- {
- (VOID)FindIrqDescriptor(LogDevice, Descriptor->u.Interrupt.Level);
-
- 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);
-
- ++NumberOfIrq;
- break;
- }
-
- case CmResourceTypeDma:
- {
- (VOID)FindDmaDescriptor(LogDevice, Descriptor->u.Dma.Channel);
+ WriteWord(ISAPNP_IOBASE(Index), Descriptor->u.Port.Start.LowPart);
+}
- WriteByte(ISAPNP_DMACHANNEL(NumberOfDma),
(UCHAR)Descriptor->u.Dma.Channel);
+static
+CODE_SEG("PAGE")
+VOID
+IsaProgramIrqSelect(
+ _In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
+ _In_ UCHAR Index)
+{
+ UCHAR TypeSelect;
- ++NumberOfDma;
- break;
- }
+ PAGED_CODE();
- case CmResourceTypeMemory:
- {
- UCHAR Information;
- UCHAR MemoryControl = MEMORY_USE_8_BIT_DECODER;
+ ASSERT(Descriptor->u.Interrupt.Level <= 15);
- (VOID)FindMemoryDescriptor(LogDevice,
- Descriptor->u.Memory.Start.LowPart,
- Descriptor->u.Memory.Start.LowPart +
- Descriptor->u.Memory.Length - 1,
- &Information);
+ if (Descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
+ TypeSelect = IRQTYPE_HIGH_EDGE;
+ else
+ TypeSelect = IRQTYPE_LOW_LEVEL;
- if (LogicalDevice->Flags & ISAPNP_HAS_MEM24_DECODER)
- {
- if (Information & MEMRANGE_16_BIT_MEMORY_MASK)
- MemoryControl = MEMORY_USE_16_BIT_DECODER;
+ WriteByte(ISAPNP_IRQNO(Index), Descriptor->u.Interrupt.Level);
+ WriteByte(ISAPNP_IRQTYPE(Index), TypeSelect);
+}
- WriteWord(ISAPNP_MEMBASE(NumberOfMemory),
- (USHORT)(Descriptor->u.Memory.Start.LowPart >>
8));
+static
+CODE_SEG("PAGE")
+VOID
+IsaProgramDmaSelect(
+ _In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
+ _In_ UCHAR Index)
+{
+ PAGED_CODE();
- if (ReadMemoryControl(ReadDataPort, NumberOfMemory) &
MEMORY_UPPER_LIMIT)
- {
- WriteByte(ISAPNP_MEMCONTROL(NumberOfMemory),
- MemoryControl | MEMORY_UPPER_LIMIT);
- WriteWord(ISAPNP_MEMLIMIT(NumberOfMemory),
- (USHORT)((Descriptor->u.Memory.Start.LowPart +
- Descriptor->u.Memory.Length) >>
8));
- }
- else
- {
- WriteByte(ISAPNP_MEMCONTROL(NumberOfMemory), MemoryControl);
- WriteWord(ISAPNP_MEMLIMIT(NumberOfMemory),
- (USHORT)(LENGTH_TO_RANGE_LENGTH(Descriptor->
- u.Memory.Length)
>> 8));
- }
+ ASSERT(Descriptor->u.Dma.Channel <= 7);
- ++NumberOfMemory;
- }
- else
- {
- WriteDoubleWord(ISAPNP_MEMBASE32(NumberOfMemory32),
- Descriptor->u.Memory.Start.LowPart);
+ WriteByte(ISAPNP_DMACHANNEL(Index), Descriptor->u.Dma.Channel);
+}
- if ((Information & MEMRANGE_16_BIT_MEMORY_MASK) ==
MEMRANGE_32_BIT_MEMORY_ONLY)
- MemoryControl = MEMORY_USE_32_BIT_DECODER;
- else if (Information & MEMRANGE_16_BIT_MEMORY_MASK)
- MemoryControl = MEMORY_USE_16_BIT_DECODER;
+static
+CODE_SEG("PAGE")
+NTSTATUS
+IsaProgramMemoryDecoder(
+ _In_ PUCHAR ReadDataPort,
+ _In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor,
+ _In_ BOOLEAN IsMemory32,
+ _In_ UCHAR Information,
+ _In_ UCHAR Index)
+{
+ UCHAR MemoryControl;
+ ULONG LengthLimit;
- if (ReadMemoryControl32(ReadDataPort, NumberOfMemory32) &
MEMORY_UPPER_LIMIT)
- {
- WriteByte(ISAPNP_MEMCONTROL32(NumberOfMemory32),
- MemoryControl | MEMORY_UPPER_LIMIT);
- WriteDoubleWord(ISAPNP_MEMLIMIT32(NumberOfMemory32),
- Descriptor->u.Memory.Start.LowPart +
- Descriptor->u.Memory.Length);
- }
- else
- {
- WriteByte(ISAPNP_MEMCONTROL32(NumberOfMemory32), MemoryControl);
- WriteDoubleWord(ISAPNP_MEMLIMIT32(NumberOfMemory32),
-
LENGTH_TO_RANGE_LENGTH(Descriptor->u.Memory.Length));
- }
+ PAGED_CODE();
- ++NumberOfMemory32;
- }
+ if (!IsMemory32)
+ {
+ /* The 24-bit memory address decoder always considers bits 0:7 to be zeros */
+ if (Descriptor->u.Memory.Start.LowPart & 0xFF)
+ return STATUS_INVALID_PARAMETER;
- break;
- }
+ if (Information & MEMRANGE_16_BIT_MEMORY_MASK)
+ MemoryControl = MEMORY_USE_16_BIT_DECODER;
+ else
+ MemoryControl = MEMORY_USE_8_BIT_DECODER;
- default:
- break;
+ if (ReadMemoryControl(ReadDataPort, Index) & MEMORY_UPPER_LIMIT)
+ {
+ MemoryControl |= MEMORY_UPPER_LIMIT;
+ LengthLimit = Descriptor->u.Memory.Start.LowPart +
Descriptor->u.Memory.Length;
}
- }
+ else
+ {
+ LengthLimit = LENGTH_TO_RANGE_LENGTH(Descriptor->u.Memory.Length);
+ }
+ LengthLimit >>= 8;
- for (i = NumberOfIo; i < RTL_NUMBER_OF(LogDevice->Io); i++)
- {
- WriteWord(ISAPNP_IOBASE(i), 0);
+ WriteWord(ISAPNP_MEMBASE(Index), Descriptor->u.Memory.Start.LowPart >>
8);
+ WriteByte(ISAPNP_MEMCONTROL(Index), MemoryControl);
+ WriteWord(ISAPNP_MEMLIMIT(Index), LengthLimit);
}
- for (i = NumberOfIrq; i < RTL_NUMBER_OF(LogDevice->Irq); i++)
- {
- WriteByte(ISAPNP_IRQNO(i), 0);
- WriteByte(ISAPNP_IRQTYPE(i), 0);
- }
- for (i = NumberOfDma; i < RTL_NUMBER_OF(LogDevice->Dma); i++)
- {
- WriteByte(ISAPNP_DMACHANNEL(i), 4);
- }
- for (i = NumberOfMemory; i < RTL_NUMBER_OF(LogDevice->MemRange); i++)
- {
- WriteWord(ISAPNP_MEMBASE(i), 0);
- WriteByte(ISAPNP_MEMCONTROL(i), 0);
- WriteWord(ISAPNP_MEMLIMIT(i), 0);
- }
- for (i = NumberOfMemory32; i < RTL_NUMBER_OF(LogDevice->MemRange32); i++)
+ else
{
- WriteDoubleWord(ISAPNP_MEMBASE32(i), 0);
- WriteByte(ISAPNP_MEMCONTROL32(i), 0);
- WriteDoubleWord(ISAPNP_MEMLIMIT32(i), 0);
+ if ((Information & MEMRANGE_16_BIT_MEMORY_MASK) ==
MEMRANGE_32_BIT_MEMORY_ONLY)
+ MemoryControl = MEMORY_USE_32_BIT_DECODER;
+ else if (Information & MEMRANGE_16_BIT_MEMORY_MASK)
+ MemoryControl = MEMORY_USE_16_BIT_DECODER;
+ else
+ MemoryControl = MEMORY_USE_8_BIT_DECODER;
+
+ if (ReadMemoryControl32(ReadDataPort, Index) & MEMORY_UPPER_LIMIT)
+ {
+ MemoryControl |= MEMORY_UPPER_LIMIT;
+ LengthLimit = Descriptor->u.Memory.Start.LowPart +
Descriptor->u.Memory.Length;
+ }
+ else
+ {
+ LengthLimit = LENGTH_TO_RANGE_LENGTH(Descriptor->u.Memory.Length);
+ }
+
+ WriteDoubleWord(ISAPNP_MEMBASE32(Index), Descriptor->u.Memory.Start.LowPart);
+ WriteByte(ISAPNP_MEMCONTROL32(Index), MemoryControl);
+ WriteDoubleWord(ISAPNP_MEMLIMIT32(Index), LengthLimit);
}
+
+ return STATUS_SUCCESS;
}
CODE_SEG("PAGE")
@@ -1554,18 +1508,20 @@ IsaHwConfigureDevice(
_In_ PISAPNP_LOGICAL_DEVICE LogicalDevice,
_In_ PCM_RESOURCE_LIST Resources)
{
- UCHAR i,
- NumberOfIo = 0,
+ ULONG i;
+ UCHAR NumberOfIo = 0,
NumberOfIrq = 0,
NumberOfDma = 0,
- NumberOfMemory = 0;
+ NumberOfMemory = 0,
+ NumberOfMemory32 = 0;
PAGED_CODE();
if (!Resources)
return STATUS_INSUFFICIENT_RESOURCES;
- /* Validate the resource list */
+ WriteLogicalDeviceNumber(LogicalDevice->LDN);
+
for (i = 0; i < Resources->List[0].PartialResourceList.Count; i++)
{
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor =
@@ -1575,63 +1531,68 @@ IsaHwConfigureDevice(
{
case CmResourceTypePort:
{
- if (++NumberOfIo > RTL_NUMBER_OF(LogicalDevice->Io))
+ if (NumberOfIo >= RTL_NUMBER_OF(LogicalDevice->Io))
return STATUS_INVALID_PARAMETER_1;
- if (!FindIoDescriptor(LogicalDevice,
- 0,
- Descriptor->u.Port.Start.LowPart,
- Descriptor->u.Port.Start.LowPart +
- Descriptor->u.Port.Length - 1,
- NULL,
- NULL))
- {
- return STATUS_RESOURCE_DATA_NOT_FOUND;
- }
-
+ IsaProgramIoDecoder(Descriptor, NumberOfIo++);
break;
}
case CmResourceTypeInterrupt:
{
- if (++NumberOfIrq > RTL_NUMBER_OF(LogicalDevice->Irq))
+ if (NumberOfIrq >= RTL_NUMBER_OF(LogicalDevice->Irq))
return STATUS_INVALID_PARAMETER_2;
- if (!FindIrqDescriptor(LogicalDevice, Descriptor->u.Interrupt.Level))
- return STATUS_RESOURCE_DATA_NOT_FOUND;
-
+ IsaProgramIrqSelect(Descriptor, NumberOfIrq++);
break;
}
case CmResourceTypeDma:
{
- if (++NumberOfDma > RTL_NUMBER_OF(LogicalDevice->Dma))
+ if (NumberOfDma >= RTL_NUMBER_OF(LogicalDevice->Dma))
return STATUS_INVALID_PARAMETER_3;
- if (!FindDmaDescriptor(LogicalDevice, Descriptor->u.Dma.Channel))
- return STATUS_RESOURCE_DATA_NOT_FOUND;
-
+ IsaProgramDmaSelect(Descriptor, NumberOfDma++);
break;
}
case CmResourceTypeMemory:
{
- BOOLEAN Memory32;
+ BOOLEAN IsMemory32;
+ UCHAR Index, Information;
+ NTSTATUS Status;
- if (++NumberOfMemory > RTL_NUMBER_OF(LogicalDevice->MemRange))
+ if ((NumberOfMemory + NumberOfMemory32) >=
RTL_NUMBER_OF(LogicalDevice->MemRange))
return STATUS_INVALID_PARAMETER_4;
+ /*
+ * The PNP ROM provides an information byte for each memory descriptor
+ * which is then used to program the memory control register.
+ */
if (!FindMemoryDescriptor(LogicalDevice,
Descriptor->u.Memory.Start.LowPart,
Descriptor->u.Memory.Start.LowPart +
Descriptor->u.Memory.Length - 1,
- NULL))
+ &Information))
{
return STATUS_RESOURCE_DATA_NOT_FOUND;
}
- if ((LogicalDevice->Flags & ISAPNP_HAS_MEM24_DECODER) &&
(Descriptor->u.Memory.Start.LowPart & 0xFF))
- return STATUS_INVALID_PARAMETER;
+ /* We can have a 24- or 32-bit memory decoder, but not both */
+ IsMemory32 = !!(LogicalDevice->Flags & ISAPNP_HAS_MEM32_DECODER);
+
+ if (IsMemory32)
+ Index = NumberOfMemory32++;
+ else
+ Index = NumberOfMemory++;
+
+ Status = IsaProgramMemoryDecoder(FdoExt->ReadDataPort,
+ Descriptor,
+ IsMemory32,
+ Information,
+ Index);
+ if (!NT_SUCCESS(Status))
+ return Status;
break;
}
@@ -1641,7 +1602,32 @@ IsaHwConfigureDevice(
}
}
- WriteResources(FdoExt->ReadDataPort, LogicalDevice,
&Resources->List[0].PartialResourceList);
+ /* Disable the unclaimed device resources */
+ for (i = NumberOfIo; i < RTL_NUMBER_OF(LogicalDevice->Io); i++)
+ {
+ WriteWord(ISAPNP_IOBASE(i), 0);
+ }
+ for (i = NumberOfIrq; i < RTL_NUMBER_OF(LogicalDevice->Irq); i++)
+ {
+ WriteByte(ISAPNP_IRQNO(i), 0);
+ WriteByte(ISAPNP_IRQTYPE(i), 0);
+ }
+ for (i = NumberOfDma; i < RTL_NUMBER_OF(LogicalDevice->Dma); i++)
+ {
+ WriteByte(ISAPNP_DMACHANNEL(i), DMACHANNEL_NONE);
+ }
+ for (i = NumberOfMemory; i < RTL_NUMBER_OF(LogicalDevice->MemRange); i++)
+ {
+ WriteWord(ISAPNP_MEMBASE(i), 0);
+ WriteByte(ISAPNP_MEMCONTROL(i), 0);
+ WriteWord(ISAPNP_MEMLIMIT(i), 0);
+ }
+ for (i = NumberOfMemory32; i < RTL_NUMBER_OF(LogicalDevice->MemRange32); i++)
+ {
+ WriteDoubleWord(ISAPNP_MEMBASE32(i), 0);
+ WriteByte(ISAPNP_MEMCONTROL32(i), 0);
+ WriteDoubleWord(ISAPNP_MEMLIMIT32(i), 0);
+ }
KeStallExecutionProcessor(10000);
diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c
index bf5b6cde8c8..2450d367413 100644
--- a/drivers/bus/isapnp/isapnp.c
+++ b/drivers/bus/isapnp/isapnp.c
@@ -652,7 +652,7 @@ IsaPnpCreateLogicalDeviceResources(
}
for (i = 0; i < RTL_NUMBER_OF(LogDev->Dma); i++)
{
- if (LogDev->Dma[i].CurrentChannel != 4)
+ if (LogDev->Dma[i].CurrentChannel != DMACHANNEL_NONE)
ResourceCount++;
else
break;
@@ -736,7 +736,7 @@ IsaPnpCreateLogicalDeviceResources(
}
for (i = 0; i < RTL_NUMBER_OF(LogDev->Dma); i++)
{
- if (LogDev->Dma[i].CurrentChannel == 4)
+ if (LogDev->Dma[i].CurrentChannel == DMACHANNEL_NONE)
break;
Descriptor =
&ResourceList->List[0].PartialResourceList.PartialDescriptors[ResourceCount++];
diff --git a/drivers/bus/isapnp/isapnphw.h b/drivers/bus/isapnp/isapnphw.h
index 3c5a2590729..5eb62746450 100644
--- a/drivers/bus/isapnp/isapnphw.h
+++ b/drivers/bus/isapnp/isapnphw.h
@@ -46,6 +46,7 @@ extern "C" {
#define IRQTYPE_LOW_LEVEL 0x01
#define IRQTYPE_HIGH_EDGE 0x02
#define ISAPNP_DMACHANNEL(n) (0x74 + (n))
+#define DMACHANNEL_NONE 4
#define ISAPNP_MEMBASE32(n) ((n) == 0 ? 0x76 : (0x70 + (n) * 16))
#define ISAPNP_MEMCONTROL32(n) ((n) == 0 ? 0x7A : (0x74 + (n) * 16))
#define ISAPNP_MEMLIMIT32(n) ((n) == 0 ? 0x7B : (0x75 + (n) * 16))