https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2981e63a310e635365a476bd80a015acf783adf8
commit 2981e63a310e635365a476bd80a015acf783adf8 Author: Dmitry Borisov <di.s...@protonmail.com> AuthorDate: Fri May 3 20:42:21 2024 +0600 Commit: Dmitry Borisov <di.s...@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))