ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
August 2024
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
26 participants
139 discussions
Start a n
N
ew thread
[reactos] 08/10: [ISAPNP] Refactor the configuration code
by Dmitry Borisov
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))
4 months, 3 weeks
1
0
0
0
[reactos] 07/10: [ISAPNP] Fix parsing of complex resource data
by Dmitry Borisov
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=76ec8411a44bd44a0c555…
commit 76ec8411a44bd44a0c5559fefc5e1b4dd3fed66b Author: Dmitry Borisov <di.sean(a)protonmail.com> AuthorDate: Fri May 3 20:39:26 2024 +0600 Commit: Dmitry Borisov <di.sean(a)protonmail.com> CommitDate: Sat Aug 3 17:08:43 2024 +0600 [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 --- drivers/bus/isapnp/hardware.c | 381 ++++++++----------- drivers/bus/isapnp/isapnp.c | 819 ++++++++++++++++------------------------- drivers/bus/isapnp/isapnp.h | 13 +- drivers/bus/isapnp/isapnpres.h | 97 ++--- drivers/bus/isapnp/pdo.c | 24 +- 5 files changed, 530 insertions(+), 804 deletions(-) diff --git a/drivers/bus/isapnp/hardware.c b/drivers/bus/isapnp/hardware.c index 135ab574a16..937923959a3 100644 --- a/drivers/bus/isapnp/hardware.c +++ b/drivers/bus/isapnp/hardware.c @@ -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,17 +492,28 @@ 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)) - { + if (LogDev != 0) goto SkipTag; - } - if (DfState == dfStarted) + if (TagLen > sizeof(ISAPNP_IRQ_DESCRIPTION) || + TagLen < (sizeof(ISAPNP_IRQ_DESCRIPTION) - 1)) { - if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES) - goto SkipTag; - - Description = &LogDevice->Alternatives->Irq[NumberOfDepedentSet]; + DPRINT1("Invalid tag %x\n", ISAPNP_TAG_IRQ); + return STATUS_UNSUCCESSFUL; } - else - { - Description = &LogDevice->Irq[NumberOfIrq].Description; - LogDevice->Irq[NumberOfIrq].Index = NumberOfIrq; - ++NumberOfIrq; - } + Resource->Type = ISAPNP_RESOURCE_TYPE_IRQ; + Description = &Resource->IrqDescription; + ++Resource; - PeekCached(ResourceData, Description, TagLen); + 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)) - { + if (LogDev != 0) goto SkipTag; - } - if (DfState == dfStarted) + if (TagLen != sizeof(ISAPNP_DMA_DESCRIPTION)) { - if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES) - goto SkipTag; - - Description = &LogDevice->Alternatives->Dma[NumberOfDepedentSet]; + DPRINT1("Invalid tag %x\n", ISAPNP_TAG_DMA); + return STATUS_UNSUCCESSFUL; } - else - { - Description = &LogDevice->Dma[NumberOfDma].Description; - LogDevice->Dma[NumberOfDma].Index = NumberOfDma; - ++NumberOfDma; - } + Resource->Type = ISAPNP_RESOURCE_TYPE_DMA; + Description = &Resource->DmaDescription; + ++Resource; - PeekCached(ResourceData, Description, TagLen); + 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)) - { + if (LogDev != 0) goto SkipTag; - } - if (DfState == dfStarted) + if (TagLen != sizeof(ISAPNP_IO_DESCRIPTION)) { - if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES) - goto SkipTag; - - Description = &LogDevice->Alternatives->Io[NumberOfDepedentSet]; + DPRINT1("Invalid tag %x\n", ISAPNP_TAG_IOPORT); + return STATUS_UNSUCCESSFUL; } - else - { - Description = &LogDevice->Io[NumberOfIo].Description; - LogDevice->Io[NumberOfIo].Index = NumberOfIo; - ++NumberOfIo; - } + Resource->Type = ISAPNP_RESOURCE_TYPE_IO; + Description = &Resource->IoDescription; + ++Resource; - PeekCached(ResourceData, Description, TagLen); + 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)) - { + if (LogDev != 0) goto SkipTag; - } - if (DfState == dfStarted) + if (TagLen != sizeof(ISAPNP_FIXED_IO_DESCRIPTION)) { - if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES) - goto SkipTag; - - Description = &LogDevice->Alternatives->Io[NumberOfDepedentSet]; + DPRINT1("Invalid tag %x\n", ISAPNP_TAG_FIXEDIO); + return STATUS_UNSUCCESSFUL; } - else - { - Description = &LogDevice->Io[NumberOfIo].Description; - LogDevice->Io[NumberOfIo].Index = NumberOfIo; - ++NumberOfIo; - } + Resource->Type = ISAPNP_RESOURCE_TYPE_IO; + Description = &Resource->IoDescription; + ++Resource; - PeekCached(ResourceData, &Temp, TagLen); + 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)) - { + if (LogDev != 0) goto SkipTag; - } - if (DfState == dfStarted) + if (TagLen != sizeof(ISAPNP_MEMRANGE_DESCRIPTION)) { - if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES) - goto SkipTag; - - Description = &LogDevice->Alternatives->MemRange[NumberOfDepedentSet]; + DPRINT1("Invalid tag %x\n", ISAPNP_TAG_MEMRANGE); + return STATUS_UNSUCCESSFUL; } - else - { - Description = &LogDevice->MemRange[NumberOfMemRange].Description; - LogDevice->MemRange[NumberOfMemRange].Index = NumberOfMemRange; - ++NumberOfMemRange; - } + LogDevice->Flags |= ISAPNP_HAS_MEM24_DECODER; + ASSERT(!(LogDevice->Flags & ISAPNP_HAS_MEM32_DECODER)); - PeekCached(ResourceData, Description, TagLen); + 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)) - { + if (LogDev != 0) goto SkipTag; - } - if (DfState == dfStarted) + if (TagLen != sizeof(ISAPNP_MEMRANGE32_DESCRIPTION)) { - if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES) - goto SkipTag; - - Description = &LogDevice->Alternatives->MemRange32[NumberOfDepedentSet]; + DPRINT1("Invalid tag %x\n", ISAPNP_TAG_MEM32RANGE); + return STATUS_UNSUCCESSFUL; } - else - { - Description = &LogDevice->MemRange32[NumberOfMemRange32].Description; - LogDevice->MemRange32[NumberOfMemRange32].Index = NumberOfMemRange32; - ++NumberOfMemRange32; - } + LogDevice->Flags |= ISAPNP_HAS_MEM32_DECODER; + ASSERT(!(LogDevice->Flags & ISAPNP_HAS_MEM24_DECODER)); + + Resource->Type = ISAPNP_RESOURCE_TYPE_MEMRANGE32; + Description = &Resource->MemRange32Description; + ++Resource; - PeekCached(ResourceData, Description, TagLen); + 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)) - { + if (LogDev != 0) goto SkipTag; - } - if (DfState == dfStarted) + if (TagLen != sizeof(ISAPNP_FIXEDMEMRANGE_DESCRIPTION)) { - if (NumberOfDepedentSet >= ISAPNP_MAX_ALTERNATIVES) - goto SkipTag; - - Description = &LogDevice->Alternatives->MemRange32[NumberOfDepedentSet]; + DPRINT1("Invalid tag %x\n", ISAPNP_TAG_FIXEDMEM32RANGE); + return STATUS_UNSUCCESSFUL; } - else - { - Description = &LogDevice->MemRange32[NumberOfMemRange32].Description; - LogDevice->MemRange32[NumberOfMemRange32].Index = NumberOfMemRange32; - ++NumberOfMemRange32; - } + LogDevice->Flags |= ISAPNP_HAS_MEM32_DECODER; + ASSERT(!(LogDevice->Flags & ISAPNP_HAS_MEM24_DECODER)); + + Resource->Type = ISAPNP_RESOURCE_TYPE_MEMRANGE32; + Description = &Resource->MemRange32Description; + ++Resource; - PeekCached(ResourceData, &Temp, TagLen); + 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; diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c index 7126166b092..bf5b6cde8c8 100644 --- a/drivers/bus/isapnp/isapnp.c +++ b/drivers/bus/isapnp/isapnp.c @@ -10,12 +10,8 @@ /* INCLUDES *******************************************************************/ #ifndef UNIT_TEST -#include "isapnp.h" -#endif /* UNIT_TEST */ -#include <search.h> - -#ifndef UNIT_TEST +#include "isapnp.h" #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++; - } - 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++) - { - if (!LogDev->Dma[i].Description.Mask) - continue; - - 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++) - { - if (!LogDev->MemRange[i].Description.Length) - continue; + DfState = dfStarted; + break; + } - ResourceCount++; - } - for (i = 0; i < RTL_NUMBER_OF(LogDev->MemRange32); i++) - { - if (!LogDev->MemRange32[i].Description.Length) - continue; + case ISAPNP_RESOURCE_TYPE_END_DEPENDENT: + { + DfState = dfDone; + break; + } - 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++) + case ISAPNP_RESOURCE_TYPE_IRQ: + case ISAPNP_RESOURCE_TYPE_DMA: { - TempBuffer = Alternatives->Irq[i].Mask; - RtlInitializeBitMap(&TempBitmap, - &TempBuffer, - RTL_BITS_OF(Alternatives->Irq[i].Mask)); - BitCount = RtlNumberOfSetBits(&TempBitmap); - - if (BitCount > 1) - AltOptionalCount += BitCount - 1; + RTL_BITMAP ResourceBitmap; + ULONG BitmapSize, BitmapBuffer, BitCount; + + if (Resource->Type == ISAPNP_RESOURCE_TYPE_IRQ) + { + BitmapSize = RTL_BITS_OF(Resource->IrqDescription.Mask); + BitmapBuffer = Resource->IrqDescription.Mask; + } + else + { + 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; } - } - if (HasDmaAlternatives(Alternatives)) - { - for (i = 0; i < Alternatives->Count; i++) + + case ISAPNP_RESOURCE_TYPE_IO: + case ISAPNP_RESOURCE_TYPE_MEMRANGE: + case ISAPNP_RESOURCE_TYPE_MEMRANGE32: { - TempBuffer = Alternatives->Dma[i].Mask; - RtlInitializeBitMap(&TempBitmap, - &TempBuffer, - RTL_BITS_OF(Alternatives->Dma[i].Mask)); - BitCount = RtlNumberOfSetBits(&TempBitmap); - - if (BitCount > 1) - AltOptionalCount += BitCount - 1; + switch (DfState) + { + case dfNotStarted: + ++FirstFixedDescriptors; + break; + + case dfStarted: + ++ResourceCount; + break; + + case dfDone: + ++LastFixedDescriptors; + break; + + DEFAULT_UNREACHABLE; + } + break; } + + default: + ASSERT(FALSE); + UNREACHABLE; + break; } + + ++Resource; } - if (ResourceCount == 0) + + /* This logical device has no resource requirements */ + if ((ResourceCount == 0) && (FirstFixedDescriptors == 0) && (LastFixedDescriptors == 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; - } - else - { - ListSize += sizeof(IO_RESOURCE_DESCRIPTOR) * (ResourceCount - 1); - } + 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++) - { - if (!LogDev->Io[i].Description.Length) - break; - - IsaConvertIoRequirement(Descriptor++, &LogDev->Io[i].Description); - } - for (i = 0; i < RTL_NUMBER_OF(LogDev->Irq); i++) - { - if (!LogDev->Irq[i].Description.Mask) - continue; - - FirstDescriptor = TRUE; - - for (j = 0; j < RTL_BITS_OF(LogDev->Irq[i].Description.Mask); j++) - { - 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++) + 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->Dma[i].Description.Mask) - continue; - - FirstDescriptor = TRUE; - - for (j = 0; j < RTL_BITS_OF(LogDev->Dma[i].Description.Mask); j++) + switch (Resource->Type) { - 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; + case ISAPNP_RESOURCE_TYPE_START_DEPENDENT: + { + if (!IsFirstAltList) + { + /* Add room for the fixed descriptors */ + AltList->Count += LastFixedDescriptors; - IsaConvertMemRangeRequirement(Descriptor++, - &LogDev->MemRange[i].Description); - } - for (i = 0; i < RTL_NUMBER_OF(LogDev->MemRange32); i++) - { - if (!LogDev->MemRange32[i].Description.Length) - continue; + /* Move on to the next list */ + AltList = (PIO_RESOURCE_LIST)(AltList->Descriptors + AltList->Count); + AltList->Version = 1; + AltList->Revision = 1; - 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; + /* Propagate the fixed resources to our new list */ + RtlCopyMemory(&AltList->Descriptors, + RequirementsList->List[0].Descriptors, + sizeof(IO_RESOURCE_DESCRIPTOR) * FirstFixedDescriptors); + AltList->Count += FirstFixedDescriptors; - IsaDetermineBestConfig(BestConfig, Alternatives); + Descriptor = &AltList->Descriptors[FirstFixedDescriptors]; + } - 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 - */ - - /* 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)); + IsFirstAltList = FALSE; + break; } - Descriptor = &NextList->Descriptors[NextList->Count - AltCount]; + case ISAPNP_RESOURCE_TYPE_END_DEPENDENT: + break; - /* - * Append alternatives. - * NOTE: To keep it simple, we append these to the end of the list. - */ - if (HasIoAlternatives(Alternatives)) + case ISAPNP_RESOURCE_TYPE_IO: { - IsaConvertIoRequirement(Descriptor++, - &Alternatives->Io[BestConfig[i]]); + IsaConvertIoRequirement(Descriptor++, &Resource->IoDescription); + + ++AltList->Count; + break; } - if (HasIrqAlternatives(Alternatives)) + + case ISAPNP_RESOURCE_TYPE_IRQ: { - FirstDescriptor = TRUE; + IsFirstDescriptor = TRUE; - for (j = 0; j < RTL_BITS_OF(Alternatives->Irq[BestConfig[i]].Mask); j++) + for (i = 0; i < RTL_BITS_OF(Resource->IrqDescription.Mask); i++) { - if (!(Alternatives->Irq[BestConfig[i]].Mask & (1 << j))) + if (!(Resource->IrqDescription.Mask & (1 << i))) continue; IsaConvertIrqRequirement(Descriptor++, - &Alternatives->Irq[BestConfig[i]], - j, - FirstDescriptor); - - if (FirstDescriptor) - FirstDescriptor = FALSE; - else - NextList->Count++; + &Resource->IrqDescription, + i, + IsFirstDescriptor); + ++AltList->Count; + + IsFirstDescriptor = FALSE; } + + break; } - if (HasDmaAlternatives(Alternatives)) + + case ISAPNP_RESOURCE_TYPE_DMA: { - FirstDescriptor = TRUE; + IsFirstDescriptor = TRUE; - for (j = 0; j < RTL_BITS_OF(Alternatives->Dma[BestConfig[i]].Mask); j++) + for (i = 0; i < RTL_BITS_OF(Resource->DmaDescription.Mask); i++) { - if (!(Alternatives->Dma[BestConfig[i]].Mask & (1 << j))) + if (!(Resource->DmaDescription.Mask & (1 << i))) continue; IsaConvertDmaRequirement(Descriptor++, - &Alternatives->Dma[BestConfig[i]], - j, - FirstDescriptor); - - if (FirstDescriptor) - FirstDescriptor = FALSE; - else - NextList->Count++; + &Resource->DmaDescription, + i, + IsFirstDescriptor); + ++AltList->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,58 +460,42 @@ 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; - - Match = Base ? (Base >= Description->Minimum) && (Base <= Description->Maximum) - : (RangeStart >= Description->Minimum) && - (RangeEnd <= (ULONG)(Description->Maximum + Description->Length - 1)); - - if (Match) + if (Resource->Type == ISAPNP_RESOURCE_TYPE_IO) { - if (Information) - *Information = Description->Information; - if (Length) - *Length = Description->Length; - if (WriteOrder) - *WriteOrder = LogDevice->Io[i].Index; - - return TRUE; - } - } - - if (!LogDevice->Alternatives) - return FALSE; + PISAPNP_IO_DESCRIPTION Description = &Resource->IoDescription; + BOOLEAN Match; - for (i = 0; i < LogDevice->Alternatives->Count; i++) - { - Description = &LogDevice->Alternatives->Io[i]; + if (Base) + { + Match = (Base >= Description->Minimum) && (Base <= Description->Maximum); + } + else + { + Match = (RangeStart >= Description->Minimum) && + (RangeEnd <= (ULONG)(Description->Maximum + Description->Length - 1)); + } - 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 (Match) - { - if (Information) - *Information = Description->Information; - if (Length) - *Length = Description->Length; - if (WriteOrder) - *WriteOrder = LogDevice->Alternatives->IoIndex; - - return TRUE; + 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 (Resource->Type == ISAPNP_RESOURCE_TYPE_IRQ) { - if (Description->Mask & (1 << j)) - { - if (j == Vector) - { - if (WriteOrder) - *WriteOrder = LogDevice->Irq[i].Index; + PISAPNP_IRQ_DESCRIPTION Description = &Resource->IrqDescription; - return TRUE; - } - } + 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 (Resource->Type == ISAPNP_RESOURCE_TYPE_DMA) { - if (Description->Mask & (1 << j)) - { - if (j == Channel) - { - if (WriteOrder) - *WriteOrder = LogDevice->Dma[i].Index; + PISAPNP_DMA_DESCRIPTION Description = &Resource->DmaDescription; - return TRUE; - } - } + 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; - - if ((RangeStart >= (ULONG)(Description->Minimum << 8)) && - (RangeEnd <= (ULONG)((Description->Maximum << 8) + (Description->Length << 8) - 1))) + switch (Resource->Type) { - if (Memory32) - *Memory32 = FALSE; - if (Information) - *Information = Description->Information; - if (WriteOrder) - *WriteOrder = LogDevice->MemRange[i].Index; - - return TRUE; - } - } - for (i = 0; i < RTL_NUMBER_OF(LogDevice->MemRange32); i++) - { - Description32 = &LogDevice->MemRange32[i].Description; + case ISAPNP_RESOURCE_TYPE_MEMRANGE: + { + PISAPNP_MEMRANGE_DESCRIPTION Description; - 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; - } - } + Description = &Resource->MemRangeDescription; - if (!LogDevice->Alternatives) - return FALSE; + if ((RangeStart >= (ULONG)(Description->Minimum << 8)) && + (RangeEnd <= (ULONG)((Description->Maximum << 8) + + (Description->Length << 8) - 1))) + { + if (Information) + *Information = Description->Information; - for (i = 0; i < LogDevice->Alternatives->Count; i++) - { - Description = &LogDevice->Alternatives->MemRange[i]; + return TRUE; + } + break; + } - 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; - } - } - for (i = 0; i < LogDevice->Alternatives->Count; i++) - { - Description32 = &LogDevice->Alternatives->MemRange32[i]; + case ISAPNP_RESOURCE_TYPE_MEMRANGE32: + { + PISAPNP_MEMRANGE32_DESCRIPTION Description32; - 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; + Description32 = &Resource->MemRange32Description; + + if ((RangeStart >= Description32->Minimum) && + (RangeEnd <= (Description32->Maximum + Description32->Length - 1))) + { + if (Information) + *Information = Description32->Information; + + return TRUE; + } + break; + } + + default: + break; } + + ++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); diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h index 17945dbe06a..998c7e766f0 100644 --- a/drivers/bus/isapnp/isapnp.h +++ b/drivers/bus/isapnp/isapnp.h @@ -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 diff --git a/drivers/bus/isapnp/isapnpres.h b/drivers/bus/isapnp/isapnpres.h index 16c21646a0f..a21299a1710 100644 --- a/drivers/bus/isapnp/isapnpres.h +++ b/drivers/bus/isapnp/isapnpres.h @@ -9,10 +9,7 @@ #pragma once /** @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 +#define ISAPNP_MAX_RESOURCEDATA 0x1000 typedef struct _ISAPNP_IO { @@ -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 +{ + dfNotStarted, + dfStarted, + dfDone +} ISAPNP_DEPENDENT_FUNCTION_STATE; + +typedef struct _ISAPNP_RESOURCE { - 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; - - _Field_range_(0, ISAPNP_MAX_ALTERNATIVES) - UCHAR Count; -} ISAPNP_ALTERNATIVES, *PISAPNP_ALTERNATIVES; + 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); -} diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c index 5e8979ad274..26d4cfc8a94 100644 --- a/drivers/bus/isapnp/pdo.c +++ b/drivers/bus/isapnp/pdo.c @@ -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);
4 months, 3 weeks
1
0
0
0
[reactos] 06/10: [ISAPNP] Fix the reported length of the memory I/O ranges
by Dmitry Borisov
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c1d7087352bdc91c469c4…
commit c1d7087352bdc91c469c49d6d7bc624aab803ebb Author: Dmitry Borisov <di.sean(a)protonmail.com> AuthorDate: Fri May 3 20:08:33 2024 +0600 Commit: Dmitry Borisov <di.sean(a)protonmail.com> CommitDate: Sat Aug 3 17:08:43 2024 +0600 [ISAPNP] Fix the reported length of the memory I/O ranges CORE-18562 --- drivers/bus/isapnp/isapnp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c index 116b035ac35..7126166b092 100644 --- a/drivers/bus/isapnp/isapnp.c +++ b/drivers/bus/isapnp/isapnp.c @@ -945,7 +945,7 @@ IsaPnpCreateLogicalDeviceResources( Descriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; else Descriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; - Descriptor->u.Memory.Length = LogDev->MemRange[i].Description.Length; + Descriptor->u.Memory.Length = LogDev->MemRange[i].CurrentLength; Descriptor->u.Memory.Start.QuadPart = LogDev->MemRange[i].CurrentBase; } for (i = 0; i < RTL_NUMBER_OF(LogDev->MemRange32); i++) @@ -971,7 +971,7 @@ IsaPnpCreateLogicalDeviceResources( Descriptor->Flags |= CM_RESOURCE_MEMORY_READ_ONLY; else Descriptor->Flags |= CM_RESOURCE_MEMORY_READ_WRITE; - Descriptor->u.Memory.Length = LogDev->MemRange32[i].Description.Length; + Descriptor->u.Memory.Length = LogDev->MemRange32[i].CurrentLength; Descriptor->u.Memory.Start.QuadPart = LogDev->MemRange32[i].CurrentBase; }
4 months, 3 weeks
1
0
0
0
[reactos] 05/10: [ISAPNP] Force clear the upper reserved bits on fixed I/O descriptors
by Dmitry Borisov
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9b7f34601a1310c0e9fa7…
commit 9b7f34601a1310c0e9fa7e6d11649acd78439cd0 Author: Dmitry Borisov <di.sean(a)protonmail.com> AuthorDate: Fri May 3 20:01:47 2024 +0600 Commit: Dmitry Borisov <di.sean(a)protonmail.com> CommitDate: Sat Aug 3 17:08:43 2024 +0600 [ISAPNP] Force clear the upper reserved bits on fixed I/O descriptors CORE-18562 --- drivers/bus/isapnp/hardware.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/bus/isapnp/hardware.c b/drivers/bus/isapnp/hardware.c index a42598e3e6c..135ab574a16 100644 --- a/drivers/bus/isapnp/hardware.c +++ b/drivers/bus/isapnp/hardware.c @@ -888,6 +888,9 @@ ParseTags( PeekCached(ResourceData, &Temp, TagLen); ResourceData += TagLen; + /* Save the address bits [0:9] */ + Temp.IoBase &= ((1 << 10) - 1); + Description->Information = 0; Description->Minimum = Description->Maximum = Temp.IoBase;
4 months, 3 weeks
1
0
0
0
[reactos] 04/10: [ISAPNP] Fix the truncation of 32-bit configuration I/O reads
by Dmitry Borisov
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=991dbeff5326ae203c6c9…
commit 991dbeff5326ae203c6c9a3ed74e92278c0b37c6 Author: Dmitry Borisov <di.sean(a)protonmail.com> AuthorDate: Fri May 3 20:03:51 2024 +0600 Commit: Dmitry Borisov <di.sean(a)protonmail.com> CommitDate: Sat Aug 3 17:08:43 2024 +0600 [ISAPNP] Fix the truncation of 32-bit configuration I/O reads CORE-18562 --- drivers/bus/isapnp/hardware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bus/isapnp/hardware.c b/drivers/bus/isapnp/hardware.c index 105fa0d8dbb..a42598e3e6c 100644 --- a/drivers/bus/isapnp/hardware.c +++ b/drivers/bus/isapnp/hardware.c @@ -118,7 +118,7 @@ ReadDoubleWord( _In_ PUCHAR ReadDataPort, _In_ UCHAR Address) { - return ((ReadWord(ReadDataPort, Address) << 8) | + return ((ReadWord(ReadDataPort, Address) << 16) | (ReadWord(ReadDataPort, Address + 2))); }
4 months, 3 weeks
1
0
0
0
[reactos] 03/10: [ISAPNP_UNITTEST] Add unit tests exercising device discovery and device resources functionality
by Dmitry Borisov
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b36d9bd9c1e353608a25c…
commit b36d9bd9c1e353608a25c430a78194f137fcf472 Author: Dmitry Borisov <di.sean(a)protonmail.com> AuthorDate: Fri May 3 19:09:23 2024 +0600 Commit: Dmitry Borisov <di.sean(a)protonmail.com> CommitDate: Sat Aug 3 17:08:43 2024 +0600 [ISAPNP_UNITTEST] Add unit tests exercising device discovery and device resources functionality CORE-18562 --- drivers/bus/isapnp/hardware.c | 8 + drivers/bus/isapnp/isapnp.c | 10 + modules/rostests/unittests/CMakeLists.txt | 4 + modules/rostests/unittests/isapnp/CMakeLists.txt | 23 + modules/rostests/unittests/isapnp/empty_card.c | 60 + modules/rostests/unittests/isapnp/isabus.c | 508 ++++++++ modules/rostests/unittests/isapnp/precomp.h | 409 +++++++ modules/rostests/unittests/isapnp/res_card.c | 1338 ++++++++++++++++++++++ modules/rostests/unittests/isapnp/testlist.c | 17 + modules/rostests/unittests/isapnp/tests.c | 486 ++++++++ 10 files changed, 2863 insertions(+) diff --git a/drivers/bus/isapnp/hardware.c b/drivers/bus/isapnp/hardware.c index 26d6b120671..105fa0d8dbb 100644 --- a/drivers/bus/isapnp/hardware.c +++ b/drivers/bus/isapnp/hardware.c @@ -7,6 +7,8 @@ * Copyright 2021 Dmitry Borisov <di.sean(a)protonmail.com> */ +#ifndef UNIT_TEST + #include "isapnp.h" #define NDEBUG @@ -16,6 +18,8 @@ #pragma warning(disable:28138) /* ISA bus always uses hardcoded port addresses */ #endif +#endif /* UNIT_TEST */ + typedef enum { dfNotStarted, @@ -1517,6 +1521,7 @@ IsaHwFillDeviceList( { BOOLEAN IsAlreadyEnumerated = FALSE; +#ifndef UNIT_TEST for (Entry = FdoExt->DeviceListHead.Flink; Entry != &FdoExt->DeviceListHead; Entry = Entry->Flink) @@ -1547,6 +1552,7 @@ IsaHwFillDeviceList( break; } } +#endif /* UNIT_TEST */ if (IsAlreadyEnumerated) continue; @@ -1720,6 +1726,7 @@ IsaHwActivateDevice( ActivateDevice(FdoExt->ReadDataPort, LogicalDevice->LDN); } +#ifndef UNIT_TEST _IRQL_requires_max_(DISPATCH_LEVEL) VOID IsaHwDeactivateDevice( @@ -1727,6 +1734,7 @@ IsaHwDeactivateDevice( { DeactivateDevice(LogicalDevice->LDN); } +#endif /* UNIT_TEST */ _IRQL_requires_max_(DISPATCH_LEVEL) VOID diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c index 0d939a300ea..116b035ac35 100644 --- a/drivers/bus/isapnp/isapnp.c +++ b/drivers/bus/isapnp/isapnp.c @@ -9,10 +9,14 @@ /* INCLUDES *******************************************************************/ +#ifndef UNIT_TEST #include "isapnp.h" +#endif /* UNIT_TEST */ #include <search.h> +#ifndef UNIT_TEST + #define NDEBUG #include <debug.h> @@ -26,6 +30,8 @@ BOOLEAN ReadPortCreated = FALSE; _Guarded_by_(BusSyncEvent) LIST_ENTRY BusListHead; +#endif /* UNIT_TEST */ + static PUCHAR Priority; /* FUNCTIONS ******************************************************************/ @@ -1166,6 +1172,8 @@ IsaPnpCreateReadPortDOResources(VOID) return ResourceList; } +#ifndef UNIT_TEST + static CODE_SEG("PAGE") NTSTATUS @@ -1604,4 +1612,6 @@ DriverEntry( return STATUS_SUCCESS; } +#endif /* UNIT_TEST */ + /* EOF */ diff --git a/modules/rostests/unittests/CMakeLists.txt b/modules/rostests/unittests/CMakeLists.txt index 4578836648e..65ab7eb4c20 100644 --- a/modules/rostests/unittests/CMakeLists.txt +++ b/modules/rostests/unittests/CMakeLists.txt @@ -1 +1,5 @@ + +if(ISAPNP_ENABLE) + add_subdirectory(isapnp) +endif() add_subdirectory(setuplib) diff --git a/modules/rostests/unittests/isapnp/CMakeLists.txt b/modules/rostests/unittests/isapnp/CMakeLists.txt new file mode 100644 index 00000000000..0155440890c --- /dev/null +++ b/modules/rostests/unittests/isapnp/CMakeLists.txt @@ -0,0 +1,23 @@ + +include_directories( + ${REACTOS_SOURCE_DIR}/modules/rostests/apitests/include + ${REACTOS_SOURCE_DIR}/drivers/bus/isapnp) + +list(APPEND SOURCE + empty_card.c + isabus.c + res_card.c + tests.c) + +list(APPEND PCH_SKIP_SOURCE + testlist.c) + +add_executable(isapnp_unittest + ${SOURCE} + ${PCH_SKIP_SOURCE}) + +set_module_type(isapnp_unittest win32cui) +add_importlibs(isapnp_unittest msvcrt kernel32 ntdll) +add_pch(isapnp_unittest precomp.h "${PCH_SKIP_SOURCE}") + +add_rostests_file(TARGET isapnp_unittest) diff --git a/modules/rostests/unittests/isapnp/empty_card.c b/modules/rostests/unittests/isapnp/empty_card.c new file mode 100644 index 00000000000..ac97de7f1bc --- /dev/null +++ b/modules/rostests/unittests/isapnp/empty_card.c @@ -0,0 +1,60 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: LGPL-2.1-or-later (
https://spdx.org/licenses/LGPL-2.1-or-later
) + * PURPOSE: Dummy card resource tests for the ISA PnP bus driver + * COPYRIGHT: Copyright 2024 Dmitry Borisov <di.sean(a)protonmail.com> + */ + +/* INCLUDES *******************************************************************/ + +#include "precomp.h" + +/* GLOBALS ********************************************************************/ + +static UCHAR DrvpTestPnpRom[] = +{ + 0x49, 0xF3, // Vendor ID 0xF349 'ROS' + 0x55, 0x66, // Product ID 0x5566 + 0xFF, 0xFF, 0xFF, 0xFF, // Serial Number + 0xFF, // Checksum (dummy) + + 0x0A, 0x10, 0x10, // PnP version 1.0, vendor version 1.0 + + 0x82, 6, 0x00, // ANSI identifier 'Test 2' + 'T', 'e', 's', 't', ' ', '2', + + /* ********************* DEVICE 1 ********************* */ + + 0x15, // Logical device ID + 0x24, 0x08, // Vendor ID 0x0824 'BAD' + 0x30, 0x00, // Product ID 0x3000 + 0x00, + + 0x82, 0xCC, 0xCC, // Long ANSI identifier to verify resource data bounds checking + + /* **************************************************** */ + + 0x79, // END + 0xFF, // Checksum (dummy) +}; + +/* FUNCTIONS ******************************************************************/ + +VOID +DrvCreateCard2( + _In_ PISAPNP_CARD Card) +{ + PISAPNP_CARD_LOGICAL_DEVICE LogDev; + + IsaBusCreateCard(Card, DrvpTestPnpRom, sizeof(DrvpTestPnpRom), 1); + + /* ********************* DEVICE 1 ********************* */ + LogDev = &Card->LogDev[0]; + + /* Enable decodes */ + LogDev->Registers[0x30] = 0x01; + + /* No DMA is active */ + LogDev->Registers[0x74] = 0x04; + LogDev->Registers[0x75] = 0x04; +} diff --git a/modules/rostests/unittests/isapnp/isabus.c b/modules/rostests/unittests/isapnp/isabus.c new file mode 100644 index 00000000000..82c9d289b33 --- /dev/null +++ b/modules/rostests/unittests/isapnp/isabus.c @@ -0,0 +1,508 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: LGPL-2.1-or-later (
https://spdx.org/licenses/LGPL-2.1-or-later
) + * PURPOSE: ISA PnP bus register access helpers + * COPYRIGHT: Copyright 2024 Dmitry Borisov <di.sean(a)protonmail.com> + */ + +/* INCLUDES *******************************************************************/ + +#include "precomp.h" + +/* GLOBALS ********************************************************************/ + +PISAPNP_CARD IsapCard; + +static PISAPNP_CARD IsapConfigureCard = NULL; +static ULONG IsapCardCount = 0; +static UCHAR IsapAddressLatch = 0; + +/* PRIVATE FUNCTIONS **********************************************************/ + +static +inline +UCHAR +IsaBusNextLFSR( + _In_ UCHAR Lfsr, + _In_ UCHAR InputBit) +{ + UCHAR NextLfsr = Lfsr >> 1; + + NextLfsr |= (((Lfsr ^ NextLfsr) ^ InputBit)) << 7; + + return NextLfsr; +} + +static +VOID +IsaBusWriteAddressRegister( + _In_ UCHAR Value) +{ + ULONG i; + + IsapAddressLatch = Value; + + for (i = 0; i < IsapCardCount; ++i) + { + PISAPNP_CARD Card = &IsapCard[i]; + + if (Card->State != IsaWaitForKey) + continue; + + /* Reset the LFSR contents */ + if (Card->Lfsr != Value) + { + Card->Lfsr = ISAPNP_LFSR_SEED; + Card->LfsrCount = 0; + continue; + } + + /* Generate the next data pattern */ + Card->Lfsr = IsaBusNextLFSR(Card->Lfsr, 0); + + /* 32 bytes of the initiation key compared correctly */ + if (++Card->LfsrCount == 32) + { + Card->State = IsaSleep; + } + } +} + +static +VOID +IsaBusWriteDataRegister( + _In_ UCHAR Value) +{ + ULONG i, j; + + switch (IsapAddressLatch) + { + case ISAPNP_READPORT: + { + /* Update the address of the Read Data Port */ + for (i = 0; i < IsapCardCount; ++i) + { + PISAPNP_CARD Card = &IsapCard[i]; + + if (Card->State != IsaIsolation) + continue; + + Card->ReadDataPort = (PUCHAR)(((ULONG_PTR)Value << 2) | 3); + } + break; + } + + case ISAPNP_CONFIGCONTROL: + { + if (Value & ISAPNP_CONFIG_WAIT_FOR_KEY) + { + IsapConfigureCard = NULL; + } + + for (i = 0; i < IsapCardCount; ++i) + { + PISAPNP_CARD Card = &IsapCard[i]; + + if (Card->State != IsaWaitForKey) + { + if (Value & ISAPNP_CONFIG_RESET) + { + for (j = 0; j < Card->LogicalDevices; ++j) + { + PISAPNP_CARD_LOGICAL_DEVICE LogDev = &Card->LogDev[j]; + + LogDev->Registers[ISAPNP_ACTIVATE] = 0; + } + } + if (Value & ISAPNP_CONFIG_RESET_CSN) + { + Card->SelectNumberReg = 0; + } + } + if (Value & ISAPNP_CONFIG_WAIT_FOR_KEY) + { + Card->State = IsaWaitForKey; + } + } + break; + } + + case ISAPNP_WAKE: + { + for (i = 0; i < IsapCardCount; ++i) + { + PISAPNP_CARD Card = &IsapCard[i]; + + if (Card->State == IsaWaitForKey) + continue; + + if (Card->SelectNumberReg != Value) + { + if (Card->State == IsaConfgure || Card->State == IsaIsolation) + { + Card->State = IsaSleep; + + if (IsapConfigureCard == Card) + { + IsapConfigureCard = NULL; + } + } + + continue; + } + + Card->RomIdx = 0; + Card->SerialIsolationIdx = 0; + + if (Card->State == IsaSleep) + { + if (Value == 0) + { + Card->State = IsaIsolation; + + Card->IsolationRead = 0; + } + else + { + Card->State = IsaConfgure; + + /* Only one card can be in the configure state */ + IsapConfigureCard = Card; + } + } + } + + break; + } + + case ISAPNP_CARDSELECTNUMBER: + { + ULONG CsnAssigned = 0; + + /* Assign the CSN */ + for (i = 0; i < IsapCardCount; ++i) + { + PISAPNP_CARD Card = &IsapCard[i]; + + if (Card->State != IsaIsolation) + continue; + + ok(Value != 0, "The new CSN is zero\n"); + ok(Card->SelectNumberReg != Value, "CSNs must be assigned sequentially"); + + Card->State = IsaConfgure; + Card->SelectNumberReg = Value; + + /* Only one card can be in the configure state */ + IsapConfigureCard = Card; + + ++CsnAssigned; + ok_eq_ulong(CsnAssigned, 1UL); + } + break; + } + + case ISAPNP_LOGICALDEVICENUMBER: + { + ok(IsapConfigureCard != NULL, "Invalid write to a LDN register\n"); + + if (IsapConfigureCard != NULL) + { + ok(IsapConfigureCard->LogicalDevices != 0, "Write to a read-only register\n"); + ok(Value < IsapConfigureCard->LogicalDevices, "Invalid write to a LDN register\n"); + + IsapConfigureCard->DeviceNumberReg = Value; + } + break; + } + + case ISAPNP_ACTIVATE: + { + Value &= 0x01; + goto WriteDeviceRegister; + } + + case ISAPNP_IORANGECHECK: + { + Value &= 0x03; + goto WriteDeviceRegister; + } + + case ISAPNP_SERIALISOLATION: + case ISAPNP_RESOURCEDATA: + case ISAPNP_STATUS: + { + ok(FALSE, "Write to a read-only register %02x\n", IsapAddressLatch); + break; + } + + default: + { + if (IsapAddressLatch >= 0x40) + { + PISAPNP_CARD_LOGICAL_DEVICE LogDev; + +WriteDeviceRegister: + ok(IsapConfigureCard != NULL, "Invalid write to device register\n"); + + if (IsapConfigureCard != NULL) + { + LogDev = &IsapConfigureCard->LogDev[IsapConfigureCard->DeviceNumberReg]; + + LogDev->Registers[IsapAddressLatch] = Value; + } + } + else + { + ok(FALSE, "Unexpected write to register %02x\n", IsapAddressLatch); + } + break; + } + } +} + +static +UCHAR +IsaBusReadSerialIsolationRegister( + _In_ PUCHAR Port) +{ + ULONG i, ResponseMap = 0, ListenMap = 0; + UCHAR Result = 0xFF; + + for (i = 0; i < IsapCardCount; ++i) + { + PISAPNP_CARD Card = &IsapCard[i]; + + if (Card->State != IsaIsolation || Card->ReadDataPort != Port) + continue; + + /* The hardware on each card expects 72 pairs of reads */ + if (Card->SerialIsolationIdx == RTL_BITS_OF(ISAPNP_IDENTIFIER)) + continue; + + Card->IsolationRead ^= 1; + + if (Card->IsolationRead) + { + if (Card->PnpRom[Card->SerialIsolationIdx / 8] & (1 << (Card->SerialIsolationIdx % 8))) + Card->SerialIdResponse = 0x55; + else + Card->SerialIdResponse = 0x00; + + ++Card->RomIdx; + ++Card->SerialIsolationIdx; + } + else + { + Card->SerialIdResponse <<= 1; + + if (Card->SerialIdResponse == 0xAA) + ResponseMap |= (1 << i); + else + ListenMap |= (1 << i); + } + + if ((Card->SerialIdResponse > Result) || (Result == 0xFF)) + Result = Card->SerialIdResponse; + } + + /* Release passive cards from the isolation state */ + if (ResponseMap != 0 && ListenMap != 0) + { + for (i = 0; i < RTL_BITS_OF(ListenMap); ++i) + { + if (ListenMap & (1 << i)) + { + PISAPNP_CARD Card = &IsapCard[i]; + + Card->State = IsaSleep; + } + } + } + + return Result; +} + +static +UCHAR +IsaBusReadDataPortRegister( + _In_ PUCHAR Port) +{ + if (IsapAddressLatch == ISAPNP_SERIALISOLATION) + return IsaBusReadSerialIsolationRegister(Port); + + if (IsapConfigureCard == NULL || IsapConfigureCard->ReadDataPort != Port) + return 0xFF; + + switch (IsapAddressLatch) + { + case ISAPNP_RESOURCEDATA: + { + if (IsapConfigureCard->RomIdx >= IsapConfigureCard->RomSize) + break; + + /* The resource data register may return an invalid identifier checksum byte */ + if (IsapConfigureCard->RomIdx == FIELD_OFFSET(ISAPNP_IDENTIFIER, Checksum)) + { + ++IsapConfigureCard->RomIdx; + break; + } + + return IsapConfigureCard->PnpRom[IsapConfigureCard->RomIdx++]; + } + + case ISAPNP_STATUS: + return 0x01; /* Resource data byte available */ + + case ISAPNP_CARDSELECTNUMBER: + return IsapConfigureCard->SelectNumberReg; + + case ISAPNP_LOGICALDEVICENUMBER: + return IsapConfigureCard->DeviceNumberReg; + + case ISAPNP_ACTIVATE: + case ISAPNP_IORANGECHECK: + goto ReadDeviceRegister; + + default: + { + if (IsapAddressLatch >= 0x40) + { + PISAPNP_CARD_LOGICAL_DEVICE LogDev; + +ReadDeviceRegister: + LogDev = &IsapConfigureCard->LogDev[IsapConfigureCard->DeviceNumberReg]; + + return LogDev->Registers[IsapAddressLatch]; + } + else + { + ok(FALSE, "Unexpected read from register %02x\n", IsapAddressLatch); + } + break; + } + } + + return 0xFF; +} + +static +UCHAR +IsaBusPnpChecksum( + _In_ PISAPNP_IDENTIFIER Identifier) +{ + UCHAR i, j, Lfsr; + + Lfsr = ISAPNP_LFSR_SEED; + for (i = 0; i < FIELD_OFFSET(ISAPNP_IDENTIFIER, Checksum); ++i) + { + UCHAR Byte = ((PUCHAR)Identifier)[i]; + + for (j = 0; j < RTL_BITS_OF(Byte); ++j) + { + Lfsr = IsaBusNextLFSR(Lfsr, Byte); + Byte >>= 1; + } + } + + return Lfsr; +} + +static +UCHAR +IsaBusResourceDataChecksum( + _In_ PUCHAR PnpRom, + _In_ ULONG RomSize) +{ + UNREFERENCED_PARAMETER(PnpRom); + UNREFERENCED_PARAMETER(RomSize); + + /* This means "Checksummed properly" */ + return 0x00; +} + +static +VOID +IsaBusPlugInCard( + _Inout_ PISAPNP_CARD Card) +{ + Card->State = IsaWaitForKey; + Card->Lfsr = ISAPNP_LFSR_SEED; + Card->LfsrCount = 0; + Card->SelectNumberReg = 0; + Card->ReadDataPort = NULL; +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + +VOID +IsaBusCreateCard( + _Inout_ PISAPNP_CARD Card, + _In_ PVOID PnpRom, + _In_ ULONG RomSize, + _In_ ULONG LogicalDevices) +{ + Card->RomSize = RomSize; + Card->PnpRom = PnpRom; + Card->PnpRom[FIELD_OFFSET(ISAPNP_IDENTIFIER, Checksum)] = IsaBusPnpChecksum(PnpRom); + Card->PnpRom[RomSize - 1] = IsaBusResourceDataChecksum(PnpRom, RomSize); + Card->LogicalDevices = LogicalDevices; + + IsaBusPlugInCard(Card); + + ++IsapCardCount; +} + +VOID +NTAPI +WRITE_PORT_UCHAR( + _In_ PUCHAR Port, + _In_ UCHAR Value) +{ + switch ((ULONG_PTR)Port) + { + case 0x279: + IsaBusWriteAddressRegister(Value); + break; + + case 0xA79: + IsaBusWriteDataRegister(Value); + break; + + default: + ok(FALSE, "Unexpected write to port %p %02x\n", Port, Value); + break; + } +} + +UCHAR +NTAPI +READ_PORT_UCHAR( + _In_ PUCHAR Port) +{ + UCHAR Result; + + /* We can write only to NT Read Data Ports */ + switch ((ULONG_PTR)Port) + { + case 0x2F4 | 3: + Result = IsaBusReadDataPortRegister(Port); + break; + + /* Indicate that the Read Data Port is in conflict */ + case 0x274 | 3: + case 0x3E4 | 3: + case 0x204 | 3: + case 0x2E4 | 3: + case 0x354 | 3: + Result = 0x00; + break; + + default: + ok(FALSE, "Unexpected read from port %p\n", Port); + Result = 0xFF; + break; + } + + return Result; +} diff --git a/modules/rostests/unittests/isapnp/precomp.h b/modules/rostests/unittests/isapnp/precomp.h new file mode 100644 index 00000000000..7ba7d4dbbbe --- /dev/null +++ b/modules/rostests/unittests/isapnp/precomp.h @@ -0,0 +1,409 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: LGPL-2.1-or-later (
https://spdx.org/licenses/LGPL-2.1-or-later
) + * PURPOSE: Precompiled header for isapnp_unittest + * COPYRIGHT: Copyright 2024 Dmitry Borisov <di.sean(a)protonmail.com> + */ + +#pragma once + +#include <apitest.h> + +#define WIN32_NO_STATUS +#include <ndk/rtlfuncs.h> + +typedef PVOID PDEVICE_OBJECT; + +#define UNIT_TEST +#include <isapnphw.h> +#include <isapnpres.h> + +/* KERNEL DEFINITIONS (MOCK) **************************************************/ + +#define PAGED_CODE() +#define CODE_SEG(segment) +#define DPRINT(...) do { if (0) { trace(__VA_ARGS__); } } while (0) +#define DPRINT1(...) do { if (0) { trace(__VA_ARGS__); } } while (0) +#define KeStallExecutionProcessor(MicroSeconds) + +FORCEINLINE +PVOID +ExAllocatePoolWithTag(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag) +{ + PULONG_PTR Mem = HeapAlloc(GetProcessHeap(), 0, NumberOfBytes + 2 * sizeof(PVOID)); + if (Mem == NULL) + return NULL; + + Mem[0] = NumberOfBytes; + Mem[1] = Tag; + + return (PVOID)(Mem + 2); +} + +FORCEINLINE +PVOID +ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag) +{ + PVOID Result = ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag); + + if (Result != NULL) + RtlZeroMemory(Result, NumberOfBytes); + + return Result; +} + +FORCEINLINE +VOID +ExFreePoolWithTag(PVOID MemPtr, ULONG Tag) +{ + PULONG_PTR Mem = MemPtr; + + Mem -= 2; + ok(Mem[1] == Tag, "Tag is %lx, expected %lx\n", Tag, Mem[1]); + HeapFree(GetProcessHeap(), 0, Mem); +} + +FORCEINLINE +SIZE_T +GetPoolAllocSize(PVOID MemPtr) +{ + PVOID* Mem = MemPtr; + + Mem -= 2; + return (SIZE_T)Mem[0]; +} + +/* ISAPNP DRIVER DEFINITIONS (MOCK) *******************************************/ + +#define TAG_ISAPNP 'pasI' + +typedef struct _ISAPNP_FDO_EXTENSION +{ + LIST_ENTRY DeviceListHead; + ULONG DeviceCount; + ULONG Cards; + PUCHAR ReadDataPort; +} ISAPNP_FDO_EXTENSION, *PISAPNP_FDO_EXTENSION; + +typedef struct _ISAPNP_PDO_EXTENSION +{ + PISAPNP_LOGICAL_DEVICE IsaPnpDevice; + + PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList; + + PCM_RESOURCE_LIST ResourceList; + ULONG ResourceListSize; +} ISAPNP_PDO_EXTENSION, *PISAPNP_PDO_EXTENSION; + +/* TEST DEFINITIONS ***********************************************************/ + +typedef enum _ISAPNP_STATE +{ + IsaWaitForKey = 0, + IsaSleep = 1, + IsaIsolation = 2, + IsaConfgure = 3 +} ISAPNP_STATE; + +typedef struct _ISAPNP_CARD_LOGICAL_DEVICE +{ + UCHAR Registers[0xFF]; +} ISAPNP_CARD_LOGICAL_DEVICE, *PISAPNP_CARD_LOGICAL_DEVICE; + +#define TEST_MAX_SUPPORTED_DEVICES 7 + +typedef struct _ISAPNP_CARD +{ + ISAPNP_STATE State; + UCHAR LfsrCount; + UCHAR Lfsr; + UCHAR SelectNumberReg; + UCHAR DeviceNumberReg; + UCHAR SerialIsolationIdx; + UCHAR SerialIdResponse; + UCHAR IsolationRead; + PUCHAR PnpRom; + PUCHAR ReadDataPort; + ULONG RomIdx; + ULONG RomSize; + ULONG LogicalDevices; + ISAPNP_CARD_LOGICAL_DEVICE LogDev[TEST_MAX_SUPPORTED_DEVICES]; +} ISAPNP_CARD, *PISAPNP_CARD; + +UCHAR +NTAPI +READ_PORT_UCHAR( + _In_ PUCHAR Port); + +VOID +NTAPI +WRITE_PORT_UCHAR( + _In_ PUCHAR Port, + _In_ UCHAR Value); + +VOID +IsaBusCreateCard( + _Inout_ PISAPNP_CARD Card, + _In_ PVOID PnpRom, + _In_ ULONG RomSize, + _In_ ULONG LogicalDevices); + +VOID +DrvCreateCard1( + _In_ PISAPNP_CARD Card); + +VOID +DrvTestCard1Dev1Resources( + _In_ PCM_RESOURCE_LIST ResourceList, + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList); + +VOID +DrvTestCard1Dev2Resources( + _In_ PCM_RESOURCE_LIST ResourceList, + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList); + +VOID +DrvTestCard1Dev3Resources( + _In_ PCM_RESOURCE_LIST ResourceList, + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList); + +VOID +DrvTestCard1Dev4Resources( + _In_ PCM_RESOURCE_LIST ResourceList, + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList); + +VOID +DrvTestCard1Dev5Resources( + _In_ PCM_RESOURCE_LIST ResourceList, + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList); + +VOID +DrvTestCard1Dev6Resources( + _In_ PCM_RESOURCE_LIST ResourceList, + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList); + +VOID +DrvTestCard1Dev7Resources( + _In_ PCM_RESOURCE_LIST ResourceList, + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList); + +PCM_RESOURCE_LIST +DrvTestCard1Dev6CreateConfigurationResources(VOID); + +VOID +DrvTestCard1Dev6ConfigurationResult( + _In_ PISAPNP_CARD_LOGICAL_DEVICE LogDev); + +VOID +DrvCreateCard2( + _In_ PISAPNP_CARD Card); + +#define expect_resource_list_header(ResourceList, ExpectedIface, ExpectedCount) \ + do { \ + ok_eq_int((ResourceList)->List[0].InterfaceType, (ExpectedIface)); \ + ok_eq_ulong((ResourceList)->List[0].BusNumber, 0UL); \ + ok_eq_int((ResourceList)->List[0].PartialResourceList.Version, 1); /* 0 */ \ + ok_eq_int((ResourceList)->List[0].PartialResourceList.Revision, 1); /* 0x3000 */ \ + ok_eq_ulong((ResourceList)->List[0].PartialResourceList.Count, (ExpectedCount)); \ + } while (0) + +#define expect_requirements_list_header(ReqList, ExpectedIface, ExpectedCount) \ + do { \ + ok_eq_int((ReqList)->InterfaceType, (ExpectedIface)); \ + ok_eq_ulong((ReqList)->BusNumber, 0UL); \ + ok_eq_ulong((ReqList)->SlotNumber, 0UL); \ + ok_eq_ulong((ReqList)->AlternativeLists, (ExpectedCount)); \ + } while (0) + +#define expect_alt_list_header(AltList, ExpectedCount) \ + do { \ + ok_eq_int((AltList)->Version, 1); \ + ok_eq_int((AltList)->Revision, 1); \ + ok_eq_ulong((AltList)->Count, (ExpectedCount)); \ + } while (0) + +#define expect_port_req(Desc, ExpectedOption, ExpectedFlags, ExpectedShare, \ + ExpectedLength, ExpectedAlign, ExpectedMin, ExpectedMax) \ + do { \ + ok((Desc)->Type == CmResourceTypePort, \ + "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypePort); \ + ok((Desc)->Option == (ExpectedOption), \ + "Desc->Option = %u, expected %u\n", (Desc)->Option, (ExpectedOption)); \ + ok((Desc)->Flags == (ExpectedFlags), \ + "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \ + ok((Desc)->ShareDisposition == (ExpectedShare), \ + "Desc->ShareDisposition = %u, expected %u\n", \ + (Desc)->ShareDisposition, (ExpectedShare)); \ + ok((Desc)->u.Port.Length == (ExpectedLength), \ + "Desc->u.Port.Length = %lx, expected %lx\n", \ + (Desc)->u.Port.Length, (ExpectedLength)); \ + ok((Desc)->u.Port.Alignment == (ExpectedAlign), \ + "Desc->u.Port.Alignment = %lu, expected %lu\n", \ + (Desc)->u.Port.Alignment, (ExpectedAlign)); \ + ok((Desc)->u.Port.MinimumAddress.QuadPart == (ExpectedMin), \ + "Desc->u.Port.MinimumAddress = 0x%I64x, expected 0x%I64x\n", \ + (Desc)->u.Port.MinimumAddress.QuadPart, (ExpectedMin)); \ + ok((Desc)->u.Port.MaximumAddress.QuadPart == (ExpectedMax), \ + "Desc->u.Port.MaximumAddress = 0x%I64x, expected 0x%I64x\n", \ + (Desc)->u.Port.MaximumAddress.QuadPart, (ExpectedMax)); \ + } while (0) + +#define expect_irq_req(Desc, ExpectedOption, ExpectedFlags, ExpectedShare, \ + ExpectedMin, ExpectedMax) \ + do { \ + ok((Desc)->Type == CmResourceTypeInterrupt, \ + "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypeInterrupt); \ + ok((Desc)->Option == (ExpectedOption), \ + "Desc->Option = %u, expected %u\n", (Desc)->Option, (ExpectedOption)); \ + ok((Desc)->Flags == (ExpectedFlags), \ + "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \ + ok((Desc)->ShareDisposition == (ExpectedShare), \ + "Desc->ShareDisposition = %u, expected %u\n", \ + (Desc)->ShareDisposition, (ExpectedShare)); \ + ok((Desc)->u.Interrupt.MinimumVector == (ExpectedMin), \ + "Desc->u.Interrupt.MinimumVector = %lu, expected %lu\n", \ + (Desc)->u.Interrupt.MinimumVector, (ExpectedMin)); \ + ok((Desc)->u.Interrupt.MaximumVector == (ExpectedMax), \ + "Desc->u.Interrupt.MaximumVector = %lu, expected %lu\n", \ + (Desc)->u.Interrupt.MaximumVector, (ExpectedMax)); \ + } while (0) + +#define expect_dma_req(Desc, ExpectedOption, ExpectedFlags, ExpectedShare, \ + ExpectedMin, ExpectedMax) \ + do { \ + ok((Desc)->Type == CmResourceTypeDma, \ + "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypeDma); \ + ok((Desc)->Option == (ExpectedOption), \ + "Desc->Option = %u, expected %u\n", (Desc)->Option, (ExpectedOption)); \ + ok((Desc)->Flags == (ExpectedFlags), \ + "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \ + ok((Desc)->ShareDisposition == (ExpectedShare), \ + "Desc->ShareDisposition = %u, expected %u\n", \ + (Desc)->ShareDisposition, (ExpectedShare)); \ + ok((Desc)->u.Dma.MinimumChannel == (ExpectedMin), \ + "Desc->u.Dma.MinimumChannel = %lu, expected %lu\n", \ + (Desc)->u.Dma.MinimumChannel, (ExpectedMin)); \ + ok((Desc)->u.Dma.MaximumChannel == (ExpectedMax), \ + "Desc->u.Dma.MaximumChannel = %lu, expected %lu\n", \ + (Desc)->u.Dma.MaximumChannel, (ExpectedMax)); \ + } while (0) + +#define expect_mem_req(Desc, ExpectedOption, ExpectedFlags, ExpectedShare, \ + ExpectedLength, ExpectedAlign, ExpectedMin, ExpectedMax) \ + do { \ + ok((Desc)->Type == CmResourceTypeMemory, \ + "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypeMemory); \ + ok((Desc)->Option == (ExpectedOption), \ + "Desc->Option = %u, expected %u\n", (Desc)->Option, (ExpectedOption)); \ + ok((Desc)->Flags == (ExpectedFlags), \ + "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \ + ok((Desc)->ShareDisposition == (ExpectedShare), \ + "Desc->ShareDisposition = %u, expected %u\n", \ + (Desc)->ShareDisposition, (ExpectedShare)); \ + ok((Desc)->u.Memory.Length == (ExpectedLength), \ + "Desc->u.Memory.Length = %lx, expected %lx\n", \ + (Desc)->u.Memory.Length, (ExpectedLength)); \ + ok((Desc)->u.Memory.Alignment == (ExpectedAlign), \ + "Desc->u.Memory.Alignment = %lx, expected %lx\n", \ + (Desc)->u.Memory.Alignment, (ExpectedAlign)); \ + ok((Desc)->u.Memory.MinimumAddress.QuadPart == (ExpectedMin), \ + "Desc->u.Memory.MinimumAddress = 0x%I64x, expected 0x%I64x\n", \ + (Desc)->u.Memory.MinimumAddress.QuadPart, (ExpectedMin)); \ + ok((Desc)->u.Memory.MaximumAddress.QuadPart == (ExpectedMax), \ + "Desc->u.Memory.MaximumAddress = 0x%I64x, expected 0x%I64x\n", \ + (Desc)->u.Memory.MaximumAddress.QuadPart, (ExpectedMax)); \ + } while (0) + +#define expect_cfg_req(Desc, ExpectedOption, ExpectedFlags, ExpectedShare, \ + ExpectedPriority, ExpectedRes1, ExpectedRes2) \ + do { \ + ok((Desc)->Type == CmResourceTypeConfigData, \ + "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypeConfigData); \ + ok((Desc)->Option == (ExpectedOption), \ + "Desc->Option = %u, expected %u\n", (Desc)->Option, (ExpectedOption)); \ + ok((Desc)->Flags == (ExpectedFlags), \ + "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \ + ok((Desc)->ShareDisposition == (ExpectedShare), \ + "Desc->ShareDisposition = %u, expected %u\n", \ + (Desc)->ShareDisposition, (ExpectedShare)); \ + ok((Desc)->u.ConfigData.Priority == (ExpectedPriority), \ + "Desc->u.ConfigData.Priority = %lx, expected %lx\n", \ + (Desc)->u.ConfigData.Priority, (ExpectedPriority)); \ + ok((Desc)->u.ConfigData.Reserved1 == (ExpectedRes1), \ + "Desc->u.ConfigData.Reserved1 = %lx, expected %lx\n", \ + (Desc)->u.ConfigData.Reserved2, (ExpectedRes1)); \ + ok((Desc)->u.ConfigData.Reserved2 == (ExpectedRes2), \ + "Desc->u.ConfigData.Reserved2 = %lx, expected %lx\n", \ + (Desc)->u.ConfigData.Reserved2, (ExpectedRes2)); \ + } while (0) + +#define expect_port_res(Desc, ExpectedFlags, ExpectedShare, ExpectedLength, ExpectedStart) \ + do { \ + ok((Desc)->Type == CmResourceTypePort, \ + "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypePort); \ + ok((Desc)->Flags == (ExpectedFlags), \ + "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \ + ok((Desc)->ShareDisposition == (ExpectedShare), \ + "Desc->ShareDisposition = %u, expected %u\n", \ + (Desc)->ShareDisposition, (ExpectedShare)); \ + ok((Desc)->u.Port.Length == (ExpectedLength), \ + "Desc->u.Port.Length = %lx, expected %lx\n", \ + (Desc)->u.Port.Length, (ExpectedLength)); \ + ok((Desc)->u.Port.Start.QuadPart == (ExpectedStart), \ + "Desc->u.Port.Start = 0x%I64x, expected 0x%I64x\n", \ + (Desc)->u.Port.Start.QuadPart, (ExpectedStart)); \ + } while (0) + +#define expect_irq_res(Desc, ExpectedFlags, ExpectedShare, \ + ExpectedLevel, ExpectedVector, ExpectedAffinity) \ + do { \ + ok((Desc)->Type == CmResourceTypeInterrupt, \ + "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypeInterrupt); \ + ok((Desc)->Flags == (ExpectedFlags), \ + "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \ + ok((Desc)->ShareDisposition == (ExpectedShare), \ + "Desc->ShareDisposition = %u, expected %u\n", \ + (Desc)->ShareDisposition, (ExpectedShare)); \ + ok((Desc)->u.Interrupt.Level == (ExpectedLevel), \ + "Desc->u.Interrupt.Level = %lu\n", (Desc)->u.Interrupt.Level); \ + ok((Desc)->u.Interrupt.Vector == (ExpectedVector), \ + "Desc->u.Interrupt.Vector = %lu\n", (Desc)->u.Interrupt.Vector); \ + ok((Desc)->u.Interrupt.Affinity == (ExpectedAffinity), \ + "Desc->u.Interrupt.Affinity = %Ix\n", (Desc)->u.Interrupt.Affinity); \ + } while (0) + +#define expect_dma_res(Desc, ExpectedFlags, ExpectedShare, ExpectedChannel) \ + do { \ + ok((Desc)->Type == CmResourceTypeDma, \ + "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypeDma); \ + ok((Desc)->Flags == (ExpectedFlags), \ + "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \ + ok((Desc)->ShareDisposition == (ExpectedShare), \ + "Desc->ShareDisposition = %u, expected %u\n", \ + (Desc)->ShareDisposition, (ExpectedShare)); \ + ok((Desc)->u.Dma.Channel == (ExpectedChannel), \ + "Desc->u.Dma.Channel = %lu, expected %lu\n", \ + (Desc)->u.Dma.Channel, (ExpectedChannel)); \ + ok((Desc)->u.Dma.Port == 0ul, \ + "Desc->u.Dma.Port = %lu, expected %lu\n", \ + (Desc)->u.Dma.Port, 0ul); \ + ok((Desc)->u.Dma.Reserved1 == 0ul, \ + "Desc->u.Dma.Reserved1 = %lx, expected 0\n", (Desc)->u.Dma.Reserved1); \ + } while (0) + +#define expect_mem_res(Desc, ExpectedFlags, ExpectedShare, ExpectedLength, ExpectedStart) \ + do { \ + ok((Desc)->Type == CmResourceTypeMemory, \ + "Desc->Type = %u, expected %u\n", (Desc)->Type, CmResourceTypeMemory); \ + ok((Desc)->Flags == (ExpectedFlags), \ + "Desc->Flags = %x, expected %x\n", (Desc)->Flags, (ExpectedFlags)); \ + ok((Desc)->ShareDisposition == (ExpectedShare), \ + "Desc->ShareDisposition = %u, expected %u\n", \ + (Desc)->ShareDisposition, (ExpectedShare)); \ + ok((Desc)->u.Memory.Length == (ExpectedLength), \ + "Desc->u.Memory.Length = %lx, expected %lx\n", \ + (Desc)->u.Memory.Length, (ExpectedLength)); \ + ok((Desc)->u.Memory.Start.QuadPart == (ExpectedStart), \ + "Desc->u.Memory.Start = 0x%I64x, expected 0x%I64x\n", \ + (Desc)->u.Memory.Start.QuadPart, (ExpectedStart)); \ + } while (0) diff --git a/modules/rostests/unittests/isapnp/res_card.c b/modules/rostests/unittests/isapnp/res_card.c new file mode 100644 index 00000000000..96c7bfd50bb --- /dev/null +++ b/modules/rostests/unittests/isapnp/res_card.c @@ -0,0 +1,1338 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: LGPL-2.1-or-later (
https://spdx.org/licenses/LGPL-2.1-or-later
) + * PURPOSE: Dummy card resource tests for the ISA PnP bus driver + * COPYRIGHT: Copyright 2024 Dmitry Borisov <di.sean(a)protonmail.com> + */ + +/* INCLUDES *******************************************************************/ + +#include "precomp.h" + +/* GLOBALS ********************************************************************/ + +static UCHAR DrvpTestPnpRom[] = +{ + 0x49, 0xF3, // Vendor ID 0xF349 'ROS' + 0x12, 0x34, // Product ID 0x1234 + 0xFF, 0xFF, 0xFF, 0xFF, // Serial Number + 0xFF, // Checksum (dummy) + + 0x0A, 0x10, 0x10, // PnP version 1.0, vendor version 1.0 + + 0x82, 6, 0x00, // ANSI identifier 'Test 1' + 'T', 'e', 's', 't', ' ', '1', + + /* ********************* DEVICE 1 ********************* */ + + 0x15, // Logical device ID + 0xC9, 0xF3, // Vendor ID 0xF3C9 'ROS' + 0x12, 0x34, // Product ID 0x1234 + 0x00, + + 0x82, 12, 0x00, // ANSI identifier 'Test 1 Dev 1' + 'T', 'e', 's', 't', ' ', '1', ' ', + 'D', 'e', 'v', ' ', '1', + + // (A) Fixed + // (B) Dependent + // (C) Fixed + // (D) End + + 0x47, 0x01, 0x30, 0x03, 0x40, 0x03, 0x04, 0x02, // I/O Base 16-bit 0x330-0x340, len 2, align 4 + + 0x30, // Start dependent Function + + 0x47, 0x00, 0x00, 0x06, 0x80, 0x07, 0x01, 0x08, // I/O Base 10-bit 0x600-0x780, len 8, align 1 + 0x4B, 0x16, 0xFC, 0x0C, // Fixed I/O 0x16, length 12 (NOTE: We fill byte 2 with garbage) + + 0x22, 0x20, 0x00, // IRQ 5 positive edge triggered + 0x23, 0x1C, 0x00, 0x08, // IRQ 2, 3, 4 active low, level-sensitive + + 0x31, 0x02, // Start dependent Function + + 0x81, 0x09, 0x00, // Memory Range + 0x1B, // Writeable, read-cacheable, write-through, supports range length, 32-bit memory only + 0x80, 0x0C, // Range minimum 0xC8000 + 0xC0, 0x0D, // Range maximum 0xDC000 + 0x40, 0xFF, // Base alignment 0xFF40 + 0x40, 0x00, // Range length 0x4000 + + 0x81, 0x09, 0x00, // Memory Range + 0x66, // Non-writeable, read-cacheable, write-through, + // supports high address, 8-bit, shadowable, expansion ROM + 0x40, 0x0D, // Range minimum 0xD4000 + 0x80, 0x0D, // Range maximum 0xD8000 + 0x00, 0x00, // Base alignment 0x10000 (NOTE: Special case) + 0x40, 0x00, // Range length 0x4000 + + 0x2A, 0x03, 0x04, // DMA 0 or 1. 8-bit only, ISA Master, not use count by byte/word, ISA compat + + 0x38, // End dependent Function + + 0x2A, 0x04, 0x41, // DMA 3. 8- and 16-bit, not use count by byte/word, Type B + + /* ********************* DEVICE 2 ********************* */ + + 0x15, // Logical device ID + 0xC9, 0xF3, // Vendor ID 0xF3C9 'ROS' + 0x12, 0x35, // Product ID 0x1235 + 0x00, + + // (A) Fixed + // (B) Dependent + // (C) End + + 0x47, 0x01, 0x00, 0x05, 0x06, 0x05, 0x01, 0x01, // I/O Base 16-bit 0x500-0x506, len 1, align 1 + + 0x30, // Start dependent Function + + 0x47, 0x01, 0x00, 0x06, 0x07, 0x06, 0x01, 0x01, // I/O Base 16-bit 0x600-0x607, len 1, align 1 + + 0x30, // Start dependent Function + + 0x47, 0x01, 0x00, 0x07, 0x08, 0x07, 0x01, 0x01, // I/O Base 16-bit 0x700-0x708, len 1, align 1 + + 0x38, // End dependent Function + + /* ********************* DEVICE 3 ********************* */ + + 0x15, // Logical device ID + 0xC9, 0xF3, // Vendor ID 0xF3C9 'ROS' + 0x12, 0x36, // Product ID 0x1236 + 0x00, + + // (A) Dependent + // (B) Fixed + // (C) End + + 0x30, // Start dependent Function + + 0x47, 0x01, 0x00, 0x06, 0x07, 0x06, 0x01, 0x01, // I/O Base 16-bit 0x600-0x607, len 1, align 1 + + 0x30, // Start dependent Function + + 0x47, 0x01, 0x00, 0x07, 0x08, 0x07, 0x01, 0x01, // I/O Base 16-bit 0x700-0x708, len 1, align 1 + + 0x38, // End dependent Function + + 0x47, 0x01, 0x00, 0x05, 0x06, 0x05, 0x01, 0x01, // I/O Base 16-bit 0x500-0x506, len 1, align 1 + + /* ********************* DEVICE 4 ********************* */ + + 0x15, // Logical device ID + 0xC9, 0xF3, // Vendor ID 0xF3C9 'ROS' + 0x12, 0x36, // Product ID 0x1236 + 0x00, + + // (A) Dependent + // (B) End + + 0x30, // Start dependent Function + + 0x47, 0x01, 0x00, 0x06, 0x07, 0x06, 0x01, 0x01, // I/O Base 16-bit 0x600-0x607, len 1, align 1 + + 0x30, // Start dependent Function + + 0x47, 0x01, 0x00, 0x07, 0x08, 0x07, 0x01, 0x01, // I/O Base 16-bit 0x700-0x708, len 1, align 1 + + 0x38, // End dependent Function + + /* ********************* DEVICE 5 ********************* */ + + // We cannot mix 24- and 32-bit memory descriptors, so create a separate logical device + + 0x15, // Logical device ID + 0xC9, 0xF3, // Vendor ID 0xF3C9 'ROS' + 0xAB, 0xCD, // Product ID 0xABCD + 0x00, + + 0x1C, // Compatible device ID + 0xAD, 0x34, // Vendor ID 0x34AD 'MEM' + 0x56, 0x78, // Product ID 0x5678 + + 0x82, 12, 0x00, // ANSI identifier 'Test 1 Dev 2' + 'T', 'e', 's', 't', ' ', '1', ' ', + 'D', 'e', 'v', ' ', '2', + + // (A) Fixed + // (B) End + + 0x85, 0x11, 0x00, // 32-bit Memory Range + 0x66, // Non-writeable, read-cacheable, write-through, + // supports high address, 8-bit, shadowable, expansion ROM + 0x00, 0x00, 0x0D, 0x00, // Range minimum 0xD0000 + 0x00, 0x00, 0x0E, 0x00, // Range maximum 0xE0000 + 0x00, 0x01, 0x00, 0x00, // Base alignment 0x100 + 0x00, 0x80, 0x00, 0x00, // Range length 0x8000 + + 0x86, 0x09, 0x00, // 32-bit Fixed Memory Range + 0x66, // Non-writeable, read-cacheable, write-through, + // supports high address, 8-bit, shadowable, expansion ROM + 0x00, 0x80, 0x0C, 0x00, // Range base address 0xC8000 + 0x00, 0x80, 0x00, 0x00, // Length 0x008000 + + /* ********************* DEVICE 6 ********************* */ + + 0x15, // Logical device ID + 0xC9, 0xF3, // Vendor ID 0xF3C9 'ROS' + 0xA0, 0x01, // Product ID 0xA001 + 0x00, + + // NOTE: We don't supply any ANSI identifiers here + + 0x81, 0x09, 0x00, // Memory Range + 0x6E, // Non-writeable, read-cacheable, write-through, + // supports high address, 16-bit, shadowable, expansion ROM + 0x00, 0x0A, // Range minimum 0xA0000 + 0x40, 0x0A, // Range maximum 0xA4000 + 0x04, 0x00, // Base alignment 4 + 0x10, 0x00, // Range length 0x1000 + + 0x81, 0x09, 0x00, // Memory Range + 0x66, // Non-writeable, read-cacheable, write-through, + // supports high address, 8-bit, shadowable, expansion ROM + 0x00, 0x08, // Range minimum 0x8000 + 0x00, 0x09, // Range maximum 0x9000 + 0x04, 0x00, // Base alignment 4 + 0x01, 0x00, // Range length 0x100 + + 0x2A, 0x40, 0x04, // DMA 6 + + 0x22, 0x20, 0x00, // IRQ 5 positive edge triggered + + 0x4B, 0x80, 0x00, 0x08, // Fixed I/O 0x80, length 8 + + /* ********************* DEVICE 7 ********************* */ + + 0x15, // Logical device ID + 0xB0, 0x15, // Vendor ID 0x15B0 'EMP' + 0x20, 0x00, // Product ID 0x2000 + 0x00, + + // No resource requirements for this device + + 0x73, '1', '2', '3', // Vendor defined valid tag + + /* **************************************************** */ + + 0x79, // END + 0xFF, // Checksum (dummy) +}; + +/* FUNCTIONS ******************************************************************/ + +VOID +DrvCreateCard1( + _In_ PISAPNP_CARD Card) +{ + PISAPNP_CARD_LOGICAL_DEVICE LogDev; + + IsaBusCreateCard(Card, DrvpTestPnpRom, sizeof(DrvpTestPnpRom), 7); + + /* NOTE: Boot resources of the devices should be made from the requirements */ + + /* ********************* DEVICE 1 ********************* */ + LogDev = &Card->LogDev[0]; + + /* + * Assign some I/O base but don't enable decodes. + * The driver will ignore such I/O configuration. + */ + LogDev->Registers[0x60] = 0x03; + LogDev->Registers[0x61] = 0x90; + + /* ******************* DEVICE 2, 3, 4 ***************** */ + LogDev++; + LogDev++; + LogDev++; + + /* ********************* DEVICE 5 ********************* */ + LogDev++; + + /* Enable decodes */ + LogDev->Registers[0x30] = 0x01; + + /* No DMA is active */ + LogDev->Registers[0x74] = 0x04; + LogDev->Registers[0x75] = 0x04; + + /* Memory 32 Base #0 0xD6000 */ + LogDev->Registers[0x76] = 0x00; + LogDev->Registers[0x77] = 0x0D; + LogDev->Registers[0x78] = 0x60; + LogDev->Registers[0x79] = 0x00; + /* Memory 32 Control #0 - enable range length, 8-bit memory */ + LogDev->Registers[0x7A] = 0x00; + /* Memory 32 Range length #0 0xFFFF8000 (32kB) */ + LogDev->Registers[0x7B] = 0xFF; + LogDev->Registers[0x7C] = 0xFF; + LogDev->Registers[0x7D] = 0x80; + LogDev->Registers[0x7E] = 0x00; + + /* Memory 32 Base #1 0xC8000 */ + LogDev->Registers[0x80] = 0x00; + LogDev->Registers[0x81] = 0x0C; + LogDev->Registers[0x82] = 0x80; + LogDev->Registers[0x83] = 0x00; + /* Memory 32 Control #1 - enable upper limit, 8-bit memory */ + LogDev->Registers[0x84] = 0x01; + /* Memory 32 Limit #1 0xD0000 (0xC8000 + 0x8000 = 0xD0000) */ + LogDev->Registers[0x85] = 0x00; + LogDev->Registers[0x86] = 0x0D; + LogDev->Registers[0x87] = 0x00; + LogDev->Registers[0x88] = 0x00; + + /* ********************* DEVICE 6 ********************* */ + LogDev++; + + /* Enable decodes */ + LogDev->Registers[0x30] = 0x01; + + /* Memory Base #0 0xA0000 */ + LogDev->Registers[0x40] = 0x0A; + LogDev->Registers[0x41] = 0x00; + /* + * Memory Control #0 - enable upper limit, 8-bit memory. + * The resource descriptor is 16-bit, + * so we can test the configuration code that touches this register. + */ + LogDev->Registers[0x42] = 0x01; + /* Memory Limit #0 0xA4000 (0xA0000 + 0x4000 = 0xA4000) */ + LogDev->Registers[0x43] = 0x0A; + LogDev->Registers[0x44] = 0x40; + + /* Memory Control #1 - enable range length, 8-bit memory */ + LogDev->Registers[0x4A] = 0x00; + /* Memory Base #1 is disabled */ + + /* I/O Base 80 */ + LogDev->Registers[0x60] = 0x00; + LogDev->Registers[0x61] = 0x80; + + /* IRQ 5 low-to-high transition */ + LogDev->Registers[0x70] = 0x05 | 0xF0; // We add some garbage, must be ignored by the driver + LogDev->Registers[0x71] = 0x02; + + /* DMA 6 */ + LogDev->Registers[0x74] = 0x06 | 0xF8; // Ditto + + /* No DMA is active */ + LogDev->Registers[0x75] = 0x04; + + /* ********************* DEVICE 7 ********************* */ + + /* No resources on purpose */ +} + +/* No boot resources */ +static +VOID +DrvTestCard1Dev1QueryResources( + _In_ PCM_RESOURCE_LIST ResourceList) +{ + ok_eq_pointer(ResourceList, NULL); +} + +/* + * Interface 1 Bus 0 Slot 0 AlternativeLists 2 + * + * AltList 0, AltList->Count 8 Ver.1 Rev.30 + * [0:1:11] IO: Min 0:330, Max 0:341, Align 4 Len 2 + * [0:1:5] IO: Min 0:600, Max 0:787, Align 1 Len 8 + * [0:1:5] IO: Min 0:16, Max 0:21, Align 1 Len C + * [0:1:1] INT: Min 5 Max 5 + * [0:1:1] INT: Min 2 Max 2 + * [8:1:1] INT: Min 3 Max 3 + * [8:1:1] INT: Min 4 Max 4 + * [0:0:0] DMA: Min 2 Max 2 + * + * AltList 1, AltList->Count 6 Ver.1 Rev.31 + * [0:1:11] IO: Min 0:330, Max 0:341, Align 4 Len 2 + * [0:1:10] MEM: Min 0:C8000, Max 0:DFFFF, Align FF40 Len 4000 + * [0:1:10] MEM: Min 0:D4000, Max 0:DBFFF, Align 10000 Len 4000 + * [0:0:0] DMA: Min 0 Max 0 + * [8:0:0] DMA: Min 1 Max 1 + * [0:0:0] DMA: Min 2 Max 2 + */ +static +VOID +DrvTestCard1Dev1QueryResourceRequirements( + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList) +{ + PIO_RESOURCE_DESCRIPTOR Descriptor; + PIO_RESOURCE_LIST AltList; + + ok(ReqList != NULL, "ReqList is NULL\n"); + if (ReqList == NULL) + { + skip("No ReqList\n"); + return; + } + expect_requirements_list_header(ReqList, Isa, 2UL); + + /************************* LIST 0 ************************/ + + AltList = &ReqList->List[0]; + Descriptor = &AltList->Descriptors[0]; + + expect_alt_list_header(AltList, 8UL); + + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 2ul, + 4ul, + 0x330ull, + 0x341ull); + Descriptor++; + + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_10_BIT_DECODE, + CmResourceShareDeviceExclusive, + 8ul, + 1ul, + 0x600ull, + 0x787ull); + Descriptor++; + + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_10_BIT_DECODE, + CmResourceShareDeviceExclusive, + 12ul, + 1ul, + 0x16ull, + 0x21ull); + Descriptor++; + + expect_irq_req(Descriptor, + 0, + CM_RESOURCE_INTERRUPT_LATCHED, + CmResourceShareDeviceExclusive, + 5ul, + 5ul); + Descriptor++; + + // NOTE: The native driver returns CM_RESOURCE_INTERRUPT_LATCHED + // and CmResourceShareDeviceExclusive for some reason +#if 0 + expect_irq_req(Descriptor, + 0, + CM_RESOURCE_INTERRUPT_LATCHED, + CmResourceShareDeviceExclusive, + 2ul, + 2ul); +#else + expect_irq_req(Descriptor, + 0, + CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE, + CmResourceShareShared, + 2ul, + 2ul); +#endif + Descriptor++; + +#if 0 + expect_irq_req(Descriptor, + IO_RESOURCE_ALTERNATIVE, + CM_RESOURCE_INTERRUPT_LATCHED, + CmResourceShareDeviceExclusive, + 3ul, + 3ul); +#else + expect_irq_req(Descriptor, + IO_RESOURCE_ALTERNATIVE, + CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE, + CmResourceShareShared, + 3ul, + 3ul); +#endif + Descriptor++; + +#if 0 + expect_irq_req(Descriptor, + IO_RESOURCE_ALTERNATIVE, + CM_RESOURCE_INTERRUPT_LATCHED, + CmResourceShareDeviceExclusive, + 4ul, + 4ul); +#else + expect_irq_req(Descriptor, + IO_RESOURCE_ALTERNATIVE, + CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE, + CmResourceShareShared, + 4ul, + 4ul); +#endif + Descriptor++; + + expect_dma_req(Descriptor, + 0, + CM_RESOURCE_DMA_8, + CmResourceShareUndetermined, + 2ul, + 2ul); + Descriptor++; + + /************************* LIST 1 ************************/ + + AltList = (PIO_RESOURCE_LIST)(AltList->Descriptors + AltList->Count); + Descriptor = &AltList->Descriptors[0]; + + expect_alt_list_header(AltList, 6UL); + + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 2ul, + 4ul, + 0x330ull, + 0x341ull); + Descriptor++; + + expect_mem_req(Descriptor, + 0, + CM_RESOURCE_MEMORY_24, + CmResourceShareDeviceExclusive, + 0x4000ul, + 0xFF40ul, + 0xC8000ull, + 0xDFFFFull); + Descriptor++; + + // NOTE: The native driver returns CM_RESOURCE_MEMORY_24 only for some reason +#if 0 + expect_mem_req(Descriptor, + 0, + CM_RESOURCE_MEMORY_24, + CmResourceShareDeviceExclusive, + 0x4000ul, + 0x10000ul, + 0xD4000ull, + 0xDBFFFull); +#else + expect_mem_req(Descriptor, + 0, + CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY, + CmResourceShareDeviceExclusive, + 0x4000ul, + 0x10000ul, + 0xD4000ull, + 0xDBFFFull); +#endif + Descriptor++; + + expect_dma_req(Descriptor, + 0, + CM_RESOURCE_DMA_8, + CmResourceShareUndetermined, + 0ul, + 0ul); + Descriptor++; + + expect_dma_req(Descriptor, + IO_RESOURCE_ALTERNATIVE, + CM_RESOURCE_DMA_8, + CmResourceShareUndetermined, + 1ul, + 1ul); + Descriptor++; + + expect_dma_req(Descriptor, + 0, + CM_RESOURCE_DMA_8, + CmResourceShareUndetermined, + 2ul, + 2ul); + Descriptor++; + + /*********************************************************/ + + ok_int(ReqList->ListSize, GetPoolAllocSize(ReqList)); + ok_int(ReqList->ListSize, (ULONG_PTR)Descriptor - (ULONG_PTR)ReqList); +} + +VOID +DrvTestCard1Dev1Resources( + _In_ PCM_RESOURCE_LIST ResourceList, + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList) +{ + DrvTestCard1Dev1QueryResources(ResourceList); + DrvTestCard1Dev1QueryResourceRequirements(ReqList); +} + +/* No boot resources */ +static +VOID +DrvTestCard1Dev2QueryResources( + _In_ PCM_RESOURCE_LIST ResourceList) +{ + ok_eq_pointer(ResourceList, NULL); +} + +/* + * Interface 1 Bus 0 Slot 0 AlternativeLists 2 + * + * AltList 0, AltList->Count 2 Ver.1 Rev.30 + * [0:1:11] IO: Min 0:500, Max 0:506, Align 1 Len 1 + * [0:1:11] IO: Min 0:600, Max 0:607, Align 1 Len 1 + * + * AltList 1, AltList->Count 2 Ver.1 Rev.31 + * [0:1:11] IO: Min 0:500, Max 0:506, Align 1 Len 1 + * [0:1:11] IO: Min 0:700, Max 0:708, Align 1 Len 1 + */ +static +VOID +DrvTestCard1Dev2QueryResourceRequirements( + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList) +{ + PIO_RESOURCE_DESCRIPTOR Descriptor; + PIO_RESOURCE_LIST AltList; + + ok(ReqList != NULL, "ReqList is NULL\n"); + if (ReqList == NULL) + { + skip("No ReqList\n"); + return; + } + expect_requirements_list_header(ReqList, Isa, 2UL); + + /************************* LIST 0 ************************/ + + AltList = &ReqList->List[0]; + Descriptor = &AltList->Descriptors[0]; + + expect_alt_list_header(AltList, 2UL); + + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 1ul, + 1ul, + 0x500ull, + 0x506ull); + Descriptor++; + + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 1ul, + 1ul, + 0x600ull, + 0x607ull); + Descriptor++; + + /************************* LIST 1 ************************/ + + AltList = (PIO_RESOURCE_LIST)(AltList->Descriptors + AltList->Count); + Descriptor = &AltList->Descriptors[0]; + + expect_alt_list_header(AltList, 2UL); + + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 1ul, + 1ul, + 0x500ull, + 0x506ull); + Descriptor++; + + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 1ul, + 1ul, + 0x700ull, + 0x708ull); + Descriptor++; +} + +VOID +DrvTestCard1Dev2Resources( + _In_ PCM_RESOURCE_LIST ResourceList, + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList) +{ + DrvTestCard1Dev2QueryResources(ResourceList); + DrvTestCard1Dev2QueryResourceRequirements(ReqList); +} + +/* No boot resources */ +static +VOID +DrvTestCard1Dev3QueryResources( + _In_ PCM_RESOURCE_LIST ResourceList) +{ + ok_eq_pointer(ResourceList, NULL); +} + +/* + * Interface 1 Bus 0 Slot 0 AlternativeLists 2 + * + * AltList 0, AltList->Count 2 Ver.1 Rev.30 + * [0:1:11] IO: Min 0:600, Max 0:607, Align 1 Len 1 + * [0:1:11] IO: Min 0:500, Max 0:506, Align 1 Len 1 + * + * AltList 1, AltList->Count 2 Ver.1 Rev.31 + * [0:1:11] IO: Min 0:700, Max 0:708, Align 1 Len 1 + * [0:1:11] IO: Min 0:500, Max 0:506, Align 1 Len 1 + */ +static +VOID +DrvTestCard1Dev3QueryResourceRequirements( + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList) +{ + PIO_RESOURCE_DESCRIPTOR Descriptor; + PIO_RESOURCE_LIST AltList; + + ok(ReqList != NULL, "ReqList is NULL\n"); + if (ReqList == NULL) + { + skip("No ReqList\n"); + return; + } + expect_requirements_list_header(ReqList, Isa, 2UL); + + /************************* LIST 0 ************************/ + + AltList = &ReqList->List[0]; + Descriptor = &AltList->Descriptors[0]; + + expect_alt_list_header(AltList, 2UL); + + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 1ul, + 1ul, + 0x600ull, + 0x607ull); + Descriptor++; + + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 1ul, + 1ul, + 0x500ull, + 0x506ull); + Descriptor++; + + /************************* LIST 1 ************************/ + + AltList = (PIO_RESOURCE_LIST)(AltList->Descriptors + AltList->Count); + Descriptor = &AltList->Descriptors[0]; + + expect_alt_list_header(AltList, 2UL); + + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 1ul, + 1ul, + 0x700ull, + 0x708ull); + Descriptor++; + + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 1ul, + 1ul, + 0x500ull, + 0x506ull); + Descriptor++; +} + +VOID +DrvTestCard1Dev3Resources( + _In_ PCM_RESOURCE_LIST ResourceList, + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList) +{ + DrvTestCard1Dev3QueryResources(ResourceList); + DrvTestCard1Dev3QueryResourceRequirements(ReqList); +} + +/* No boot resources */ +static +VOID +DrvTestCard1Dev4QueryResources( + _In_ PCM_RESOURCE_LIST ResourceList) +{ + ok_eq_pointer(ResourceList, NULL); +} + +/* + * Interface 1 Bus 0 Slot 0 AlternativeLists 2 + * + * AltList 0, AltList->Count 1 Ver.1 Rev.30 + * [0:1:11] IO: Min 0:600, Max 0:607, Align 1 Len 1 + * + * AltList 1, AltList->Count 1 Ver.1 Rev.31 + * [0:1:11] IO: Min 0:700, Max 0:708, Align 1 Len 1 + */ +static +VOID +DrvTestCard1Dev4QueryResourceRequirements( + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList) +{ + PIO_RESOURCE_DESCRIPTOR Descriptor; + PIO_RESOURCE_LIST AltList; + + ok(ReqList != NULL, "ReqList is NULL\n"); + if (ReqList == NULL) + { + skip("No ReqList\n"); + return; + } + expect_requirements_list_header(ReqList, Isa, 2UL); + + /************************* LIST 0 ************************/ + + AltList = &ReqList->List[0]; + Descriptor = &AltList->Descriptors[0]; + + expect_alt_list_header(AltList, 1UL); + + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 1ul, + 1ul, + 0x600ull, + 0x607ull); + Descriptor++; + + /************************* LIST 1 ************************/ + + AltList = (PIO_RESOURCE_LIST)(AltList->Descriptors + AltList->Count); + Descriptor = &AltList->Descriptors[0]; + + expect_alt_list_header(AltList, 1UL); + + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 1ul, + 1ul, + 0x700ull, + 0x708ull); + Descriptor++; +} + +VOID +DrvTestCard1Dev4Resources( + _In_ PCM_RESOURCE_LIST ResourceList, + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList) +{ + DrvTestCard1Dev4QueryResources(ResourceList); + DrvTestCard1Dev4QueryResourceRequirements(ReqList); +} + +/* + * FullList Count 1 + * List #0 Iface 1 Bus #0 Ver.0 Rev.3000 Count 2 + * [1:11] MEM: 0:D6000 Len 8000 + * [1:11] MEM: 0:C8000 Len 8000 + */ +static +VOID +DrvTestCard1Dev5QueryResources( + _In_ PCM_RESOURCE_LIST ResourceList) +{ + PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor; + + ok(ResourceList != NULL, "ResourceList is NULL\n"); + if (ResourceList == NULL) + { + skip("No ResourceList\n"); + return; + } + expect_resource_list_header(ResourceList, Isa, 2UL); + + Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[0]; + + expect_mem_res(Descriptor, + CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY, + CmResourceShareDeviceExclusive, + 0x8000ul, + 0xD6000ull); + Descriptor++; + + expect_mem_res(Descriptor, + CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY, + CmResourceShareDeviceExclusive, + 0x8000ul, + 0xC8000ull); + Descriptor++; + + /*********************************************************/ + + ok_eq_size(GetPoolAllocSize(ResourceList), (ULONG_PTR)Descriptor - (ULONG_PTR)ResourceList); +} + +/* + * Interface 1 Bus 0 Slot 0 AlternativeLists 1 + * + * AltList 0, AltList->Count 3 Ver.1 Rev.30 + * [1:3:0] CFG: Priority 2000 Res1 720075 Res2 650072 + * [1:1:11] MEM: Min 0:D6000, Max 0:DDFFF, Align 1 Len 8000 + * [1:1:11] MEM: Min 0:C8000, Max 0:CFFFF, Align 1 Len 8000 + * + * OR (decodes disabled) + * + * AltList 0, AltList->Count 2 Ver.1 Rev.30 + * [0:1:10] MEM: Min 0:D0000, Max 0:E7FFF, Align 100 Len 8000 + * [0:1:10] MEM: Min 0:C8000, Max 0:CFFFF, Align 1 Len 8000 + */ +static +VOID +DrvTestCard1Dev5QueryResourceRequirements( + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList) +{ + PIO_RESOURCE_DESCRIPTOR Descriptor; + PIO_RESOURCE_LIST AltList; + ULONG Count; + + ok(ReqList != NULL, "ReqList is NULL\n"); + if (ReqList == NULL) + { + skip("No ReqList\n"); + return; + } + expect_requirements_list_header(ReqList, Isa, 1UL); + + /************************* LIST 0 ************************/ + + AltList = &ReqList->List[0]; + Descriptor = &AltList->Descriptors[0]; + + if (Descriptor->Type == CmResourceTypeConfigData) + Count = 3; + else + Count = 2; + expect_alt_list_header(AltList, Count); + + /* TODO: Should we support this? */ + if (Descriptor->Type == CmResourceTypeConfigData) + { + expect_cfg_req(Descriptor, + IO_RESOURCE_PREFERRED, + 0, + CmResourceShareShared, + 0x2000ul, + 0ul, + 0ul); + Descriptor++; + } + + expect_mem_req(Descriptor, + 0, + CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY, + CmResourceShareDeviceExclusive, + 0x8000ul, + 0x100ul, + 0xD0000ull, + 0xE7FFFull); + Descriptor++; + + expect_mem_req(Descriptor, + 0, + CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY, + CmResourceShareDeviceExclusive, + 0x8000ul, + 0x1ul, + 0xC8000ull, + 0xCFFFFull); + Descriptor++; + + /*********************************************************/ + + ok_int(ReqList->ListSize, GetPoolAllocSize(ReqList)); + ok_int(ReqList->ListSize, (ULONG_PTR)Descriptor - (ULONG_PTR)ReqList); +} + +VOID +DrvTestCard1Dev5Resources( + _In_ PCM_RESOURCE_LIST ResourceList, + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList) +{ + DrvTestCard1Dev5QueryResources(ResourceList); + DrvTestCard1Dev5QueryResourceRequirements(ReqList); +} + +/* + * FullList Count 1 + * List #0 Iface 1 Bus #0 Ver.0 Rev.3000 Count 4 + * [1:11] MEM: 0:A0000 Len 4000 + * [1:5] IO: Start 0:80, Len 8 + * [1:0] DMA: Channel 6 Port 0 Res 0 + * [1:1] INT: Lev 5 Vec 5 Aff FFFFFFFF + */ +static +VOID +DrvTestCard1Dev6QueryResources( + _In_ PCM_RESOURCE_LIST ResourceList) +{ + PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor; + + ok(ResourceList != NULL, "ResourceList is NULL\n"); + if (ResourceList == NULL) + { + skip("No ResourceList\n"); + return; + } + expect_resource_list_header(ResourceList, Isa, 4UL); + + Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[0]; + + expect_port_res(Descriptor, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_10_BIT_DECODE, + CmResourceShareDeviceExclusive, + 8ul, + 0x80ull); + Descriptor++; + + expect_irq_res(Descriptor, + CM_RESOURCE_INTERRUPT_LATCHED, + CmResourceShareDeviceExclusive, + 5ul, + 5ul, + (KAFFINITY)-1); + Descriptor++; + + expect_dma_res(Descriptor, + 0, + CmResourceShareDeviceExclusive, + 6ul); + Descriptor++; + + expect_mem_res(Descriptor, + CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY, + CmResourceShareDeviceExclusive, + 0x4000ul, + 0xA0000ull); + Descriptor++; + + /*********************************************************/ + + ok_eq_size(GetPoolAllocSize(ResourceList), (ULONG_PTR)Descriptor - (ULONG_PTR)ResourceList); +} + +/* + * Interface 1 Bus 0 Slot 0 AlternativeLists 1 + * + * AltList 0, AltList->Count 6 Ver.1 Rev.30 + * [1:3:0] CFG: Priority 2000 Res1 7 Res2 0 + * [1:1:11] MEM: Min 0:A0000, Max 0:A3FFF, Align 1 Len 4000 + * [0:1:10] MEM: Min 0:80000, Max 0:900FF, Align 4 Len 100 + * [1:0:0] DMA: Min 6 Max 6 + * [1:1:1] INT: Min 5 Max 5 + * [1:1:5] IO: Min 0:80, Max 0:87, Align 1 Len 8 + * + * OR (decodes disabled) + * + * AltList 0, AltList->Count 5 Ver.1 Rev.30 + * [0:1:10] MEM: Min 0:A0000, Max 0:A4FFF, Align 4 Len 1000 + * [0:1:10] MEM: Min 0:80000, Max 0:900FF, Align 4 Len 100 + * [0:0:0] DMA: Min 6 Max 6 + * [0:1:1] INT: Min 5 Max 5 + * [0:1:5] IO: Min 0:80, Max 0:87, Align 1 Len 8 + */ +static +VOID +DrvTestCard1Dev6QueryResourceRequirements( + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList) +{ + PIO_RESOURCE_DESCRIPTOR Descriptor; + PIO_RESOURCE_LIST AltList; + ULONG Count; + + ok(ReqList != NULL, "ReqList is NULL\n"); + if (ReqList == NULL) + { + skip("No ReqList\n"); + return; + } + expect_requirements_list_header(ReqList, Isa, 1UL); + + /************************* LIST 0 ************************/ + + AltList = &ReqList->List[0]; + Descriptor = &AltList->Descriptors[0]; + + if (Descriptor->Type == CmResourceTypeConfigData) + Count = 6; + else + Count = 5; + expect_alt_list_header(AltList, Count); + + /* TODO: Should we support this? */ + if (Descriptor->Type == CmResourceTypeConfigData) + { + expect_cfg_req(Descriptor, + IO_RESOURCE_PREFERRED, + 0, + CmResourceShareShared, + 0x2000ul, + 0ul, + 0ul); + Descriptor++; + } + + expect_mem_req(Descriptor, + 0, + CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY, + CmResourceShareDeviceExclusive, + 0x1000ul, + 0x4ul, + 0xA0000ull, + 0xA4FFFull); + Descriptor++; + + // NOTE: The native driver returns CM_RESOURCE_MEMORY_24 only for some reason +#if 0 + expect_mem_req(Descriptor, + 0, + CM_RESOURCE_MEMORY_24, + CmResourceShareDeviceExclusive, + 0x100ul, + 0x4ul, + 0x80000ull, + 0x900FFull); +#else + expect_mem_req(Descriptor, + 0, + CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY, + CmResourceShareDeviceExclusive, + 0x100ul, + 0x4ul, + 0x80000ull, + 0x900FFull); +#endif + Descriptor++; + + expect_dma_req(Descriptor, + 0, + CM_RESOURCE_DMA_8, + CmResourceShareUndetermined, + 6ul, + 6ul); + Descriptor++; + + expect_irq_req(Descriptor, + 0, + CM_RESOURCE_INTERRUPT_LATCHED, + CmResourceShareDeviceExclusive, + 5ul, + 5ul); + Descriptor++; + + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_10_BIT_DECODE, + CmResourceShareDeviceExclusive, + 8ul, + 1ul, + 0x80ull, + 0x87ull); + Descriptor++; + + /*********************************************************/ + + ok_int(ReqList->ListSize, GetPoolAllocSize(ReqList)); + ok_int(ReqList->ListSize, (ULONG_PTR)Descriptor - (ULONG_PTR)ReqList); +} + +VOID +DrvTestCard1Dev6Resources( + _In_ PCM_RESOURCE_LIST ResourceList, + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList) +{ + DrvTestCard1Dev6QueryResources(ResourceList); + DrvTestCard1Dev6QueryResourceRequirements(ReqList); +} + +VOID +DrvTestCard1Dev6ConfigurationResult( + _In_ PISAPNP_CARD_LOGICAL_DEVICE LogDev) +{ + ULONG i, Offset; + + /* Memory Base #0 = 0xA2000 */ + ok_eq_int(LogDev->Registers[0x40], 0x0A); + ok_eq_int(LogDev->Registers[0x41], 0x20); + /* Memory Control #0 = upper limit enabled, 16-bit memory */ + ok_eq_int(LogDev->Registers[0x42], 0x03); + /* Memory Upper limit #0 = 0xA3000 (0xA2000 + 0x1000) */ + ok_eq_int(LogDev->Registers[0x43], 0x0A); + ok_eq_int(LogDev->Registers[0x44], 0x30); + + /* Memory Base #1 = 0x89000 */ + ok_eq_int(LogDev->Registers[0x48], 0x08); + ok_eq_int(LogDev->Registers[0x49], 0x90); + /* Memory Control #1 = range length enabled, 8-bit memory */ + ok_eq_int(LogDev->Registers[0x4A], 0x00); + /* Memory Upper limit #1 = 0xFFFF00 (0x100) */ + ok_eq_int(LogDev->Registers[0x4B], 0xFF); + ok_eq_int(LogDev->Registers[0x4C], 0xFF); + + /* Memory #2-3 should be disabled */ + for (i = 2; i < 4; ++i) + { + Offset = 0x40 + i * 8; + + /* Memory Base */ + ok_eq_int(LogDev->Registers[Offset ], 0x00); + ok_eq_int(LogDev->Registers[Offset + 1], 0x00); + /* Memory Control */ + ok_eq_int(LogDev->Registers[Offset + 2], 0x00); + /* Memory Upper limit or range length */ + ok_eq_int(LogDev->Registers[Offset + 3], 0x00); + ok_eq_int(LogDev->Registers[Offset + 4], 0x00); + } + + /* Memory 32 #0-3 should be disabled */ + for (i = 0; i < 4; ++i) + { + if (i == 0) + Offset = 0x76; + else + Offset = 0x70 + i * 16; + + /* Memory 32 Base */ + ok_eq_int(LogDev->Registers[Offset ], 0x00); + ok_eq_int(LogDev->Registers[Offset + 1], 0x00); + ok_eq_int(LogDev->Registers[Offset + 2], 0x00); + ok_eq_int(LogDev->Registers[Offset + 3], 0x00); + /* Memory 32 Control */ + ok_eq_int(LogDev->Registers[Offset + 4], 0x00); + /* Memory 32 Upper limit or range length */ + ok_eq_int(LogDev->Registers[Offset + 5], 0x00); + ok_eq_int(LogDev->Registers[Offset + 6], 0x00); + ok_eq_int(LogDev->Registers[Offset + 7], 0x00); + ok_eq_int(LogDev->Registers[Offset + 8], 0x00); + } + + /* I/O Base #0 = 0x80 */ + ok_eq_int(LogDev->Registers[0x60], 0x00); + ok_eq_int(LogDev->Registers[0x61], 0x80); + + /* I/O Base #1-6 should be disabled */ + for (i = 1; i < 6; ++i) + { + Offset = 0x60 + i * 2; + + ok_eq_int(LogDev->Registers[Offset ], 0x00); + ok_eq_int(LogDev->Registers[Offset + 1], 0x00); + } + + /* IRQ select #0 = IRQ 5 low-to-high transition */ + ok_eq_int(LogDev->Registers[0x70], 0x05); + ok_eq_int(LogDev->Registers[0x71], 0x02); + + /* IRQ select #1 should be disabled */ + ok_eq_int(LogDev->Registers[0x72], 0x00); + ok_eq_int(LogDev->Registers[0x73], 0x00); + + /* DMA select #0 = DMA 6 */ + ok_eq_int(LogDev->Registers[0x74], 0x06); + + /* DMA select #1 = No DMA is active */ + ok_eq_int(LogDev->Registers[0x75], 0x04); +} + +PCM_RESOURCE_LIST +DrvTestCard1Dev6CreateConfigurationResources(VOID) +{ + PCM_RESOURCE_LIST ResourceList; + PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor; + ULONG ListSize; + +#define RESOURCE_COUNT 5 + /* + * Make the following resources from the requirements: + * + * FullList Count 1 + * List #0 Iface 1 Bus #0 Ver.1 Rev.1 Count 5 + * [1:11] MEM: 0:A2000 Len 1000 + * [1:11] MEM: 0:89000 Len 100 + * [0:0] DMA: Channel 6 Port 0 Res 0 + * [1:1] INT: Lev 5 Vec 3F Aff FFFFFFFF + * [1:5] IO: Start 0:80, Len 8 + */ + ListSize = FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.PartialDescriptors) + + sizeof(*Descriptor) * RESOURCE_COUNT; + + ResourceList = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ListSize); + if (ResourceList == NULL) + return NULL; + ResourceList->Count = 1; + ResourceList->List[0].InterfaceType = Isa; + ResourceList->List[0].BusNumber = 0; + ResourceList->List[0].PartialResourceList.Version = 1; + ResourceList->List[0].PartialResourceList.Revision = 1; + ResourceList->List[0].PartialResourceList.Count = RESOURCE_COUNT; + + Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[0]; + + Descriptor->Type = CmResourceTypeMemory; + Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; + Descriptor->Flags = CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY; + Descriptor->u.Memory.Start.LowPart = 0xA2000; + Descriptor->u.Memory.Length = 0x1000; + ++Descriptor; + + Descriptor->Type = CmResourceTypeMemory; + Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; + Descriptor->Flags = CM_RESOURCE_MEMORY_24 | CM_RESOURCE_MEMORY_READ_ONLY; + Descriptor->u.Memory.Start.LowPart = 0x89000; + Descriptor->u.Memory.Length = 0x100; + ++Descriptor; + + Descriptor->Type = CmResourceTypeDma; + Descriptor->ShareDisposition = CmResourceShareUndetermined; + Descriptor->Flags = CM_RESOURCE_DMA_8; + Descriptor->u.Dma.Channel = 6; + ++Descriptor; + + Descriptor->Type = CmResourceTypeInterrupt; + Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; + Descriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED; + Descriptor->u.Interrupt.Level = 5; + Descriptor->u.Interrupt.Vector = 0x3F; + Descriptor->u.Interrupt.Affinity = (KAFFINITY)-1; + ++Descriptor; + + Descriptor->Type = CmResourceTypePort; + Descriptor->ShareDisposition = CmResourceShareDeviceExclusive; + Descriptor->Flags = CM_RESOURCE_PORT_IO | CM_RESOURCE_PORT_10_BIT_DECODE; + Descriptor->u.Memory.Start.LowPart = 0x80; + Descriptor->u.Memory.Length = 8; + + return ResourceList; +} + +VOID +DrvTestCard1Dev7Resources( + _In_ PCM_RESOURCE_LIST ResourceList, + _In_ PIO_RESOURCE_REQUIREMENTS_LIST ReqList) +{ + /* No resources */ + ok_eq_pointer(ResourceList, NULL); + ok_eq_pointer(ReqList, NULL); +} diff --git a/modules/rostests/unittests/isapnp/testlist.c b/modules/rostests/unittests/isapnp/testlist.c new file mode 100644 index 00000000000..95ebd627f23 --- /dev/null +++ b/modules/rostests/unittests/isapnp/testlist.c @@ -0,0 +1,17 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: LGPL-2.1-or-later (
https://spdx.org/licenses/LGPL-2.1-or-later
) + * PURPOSE: Test list for the ISA PnP bus driver + * COPYRIGHT: Copyright 2024 Dmitry Borisov <di.sean(a)protonmail.com> + */ + +#define STANDALONE +#include <apitest.h> + +extern void func_Resources(void); + +const struct test winetest_testlist[] = +{ + { "Resources", func_Resources }, + { 0, 0 } +}; diff --git a/modules/rostests/unittests/isapnp/tests.c b/modules/rostests/unittests/isapnp/tests.c new file mode 100644 index 00000000000..eb5e595e6f6 --- /dev/null +++ b/modules/rostests/unittests/isapnp/tests.c @@ -0,0 +1,486 @@ +/* + * PROJECT: ReactOS API Tests + * LICENSE: LGPL-2.1-or-later (
https://spdx.org/licenses/LGPL-2.1-or-later
) + * PURPOSE: Unit Tests for the ISA PnP bus driver (device discovery and resource tests) + * COPYRIGHT: Copyright 2024 Dmitry Borisov <di.sean(a)protonmail.com> + */ + +/* INCLUDES *******************************************************************/ + +#include "precomp.h" + +#include "../../../../drivers/bus/isapnp/isapnp.c" +#include "../../../../drivers/bus/isapnp/hardware.c" + +/* GLOBALS ********************************************************************/ + +static const ULONG DrvpIsaBusPorts[] = { 0xA79, 0x279 }; +static const ULONG DrvpIsaBusReadDataPorts[] = { 0x274, 0x3E4, 0x204, 0x2E4, 0x354, 0x2F4 }; + +extern PISAPNP_CARD IsapCard; + +#define TEST_RDP_IO_BASE ((PUCHAR)(0x2F4 | 3)) + +/* FUNCTIONS ******************************************************************/ + +static +VOID +DrvFlushDeviceConfig( + _In_ PISAPNP_CARD_LOGICAL_DEVICE LogDev) +{ + UCHAR MemControl[8]; + + /* + * Save the memory control registers + * since we would need the correct values for the configuration process. + */ + MemControl[0] = LogDev->Registers[0x42]; + MemControl[1] = LogDev->Registers[0x4A]; + MemControl[2] = LogDev->Registers[0x52]; + MemControl[3] = LogDev->Registers[0x5A]; + MemControl[4] = LogDev->Registers[0x7A]; + MemControl[5] = LogDev->Registers[0x84]; + MemControl[6] = LogDev->Registers[0x94]; + MemControl[7] = LogDev->Registers[0xA4]; + + /* Fill the whole configuration area with 0xCC for testing purposes */ + RtlFillMemory(&LogDev->Registers[0x40], sizeof(LogDev->Registers) - 0x40, 0xCC); + + /* Restore saved registers */ + LogDev->Registers[0x42] = MemControl[0]; + LogDev->Registers[0x4A] = MemControl[1]; + LogDev->Registers[0x52] = MemControl[2]; + LogDev->Registers[0x5A] = MemControl[3]; + LogDev->Registers[0x7A] = MemControl[4]; + LogDev->Registers[0x84] = MemControl[5]; + LogDev->Registers[0x94] = MemControl[6]; + LogDev->Registers[0xA4] = MemControl[7]; +} + +static +BOOLEAN +DrvCreateCards(VOID) +{ + PISAPNP_CARD Card; + + /* Create 2 cards */ + IsapCard = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*IsapCard) * 2); + if (!IsapCard) + return FALSE; + + Card = IsapCard; + DrvCreateCard1(Card++); + DrvCreateCard2(Card++); + + return TRUE; +} + +static +BOOLEAN +DrvTestIsolation(VOID) +{ + UCHAR Cards; + + /* Run the isolation protocol on an empty bus */ + Cards = IsaHwTryReadDataPort(TEST_RDP_IO_BASE); + ok_eq_int(Cards, 0); + IsaHwWaitForKey(); + + if (!DrvCreateCards()) + { + skip("No memory\n"); + return FALSE; + } + + /* Another bus that contains 2 cards */ + Cards = IsaHwTryReadDataPort(TEST_RDP_IO_BASE); + ok_eq_int(Cards, 2); + + return TRUE; +} + +static +VOID +DrvTestResources(VOID) +{ + ISAPNP_FDO_EXTENSION FdoExt = { 0 }; + PISAPNP_CARD_LOGICAL_DEVICE LogDev; + PLIST_ENTRY Entry; + ULONG i; + + /* Our cards were isolated via DrvTestIsolation() */ + FdoExt.Cards = 2; + FdoExt.ReadDataPort = TEST_RDP_IO_BASE; + InitializeListHead(&FdoExt.DeviceListHead); + + /* Enumerate all logical devices on the bus */ + IsaHwFillDeviceList(&FdoExt); + IsaHwWaitForKey(); + + for (Entry = FdoExt.DeviceListHead.Flink, i = 0; + Entry != &FdoExt.DeviceListHead; + Entry = Entry->Flink) + { + ISAPNP_PDO_EXTENSION PdoExt = { 0 }; + PCM_RESOURCE_LIST ResourceList; + PIO_RESOURCE_REQUIREMENTS_LIST ReqList; + + PdoExt.IsaPnpDevice = CONTAINING_RECORD(Entry, ISAPNP_LOGICAL_DEVICE, DeviceLink); + + /* Create the resource lists */ + IsaPnpCreateLogicalDeviceRequirements(&PdoExt); + IsaPnpCreateLogicalDeviceResources(&PdoExt); + + ReqList = PdoExt.RequirementsList; + ResourceList = PdoExt.ResourceList; + + /* Process each discovered logical device */ + switch (i++) + { + case 0: + { + DrvTestCard1Dev1Resources(ResourceList, ReqList); + + LogDev = &IsapCard[0].LogDev[0]; + ok_eq_int(LogDev->Registers[0x30], 0x00); + break; + } + case 1: + { + DrvTestCard1Dev2Resources(ResourceList, ReqList); + + LogDev = &IsapCard[0].LogDev[1]; + ok_eq_int(LogDev->Registers[0x30], 0x00); + break; + } + case 2: + { + DrvTestCard1Dev3Resources(ResourceList, ReqList); + + LogDev = &IsapCard[0].LogDev[2]; + ok_eq_int(LogDev->Registers[0x30], 0x00); + break; + } + case 3: + { + DrvTestCard1Dev4Resources(ResourceList, ReqList); + + LogDev = &IsapCard[0].LogDev[3]; + ok_eq_int(LogDev->Registers[0x30], 0x00); + break; + } + case 4: + { + DrvTestCard1Dev5Resources(ResourceList, ReqList); + + LogDev = &IsapCard[0].LogDev[4]; + ok_eq_int(LogDev->Registers[0x30], 0x00); + break; + } + case 5: + { + DrvTestCard1Dev6Resources(ResourceList, ReqList); + + /* Card 1, logical device 6 */ + LogDev = &IsapCard[0].LogDev[5]; + + /* Should be activated only after configuration */ + ok_eq_int(LogDev->Registers[0x30], 0x00); + + /* I/O configuration test */ + { + NTSTATUS Status; + + DrvFlushDeviceConfig(LogDev); + + /* Assume that this device comes up with I/O range check logic enabled */ + LogDev->Registers[0x31] = 0x02; + + /* Create new resources */ + ResourceList = DrvTestCard1Dev6CreateConfigurationResources(); + if (ResourceList == NULL) + { + skip("No ResourceList\n"); + break; + } + + /* Assign resources to the device */ + { + IsaHwWakeDevice(PdoExt.IsaPnpDevice); + + Status = IsaHwConfigureDevice(&FdoExt, PdoExt.IsaPnpDevice, ResourceList); + ok_eq_hex(Status, STATUS_SUCCESS); + + IsaHwActivateDevice(&FdoExt, PdoExt.IsaPnpDevice); + IsaHwWaitForKey(); + } + + DrvTestCard1Dev6ConfigurationResult(LogDev); + + /* I/O range check must be disabled */ + ok_eq_int(LogDev->Registers[0x31], 0x00); + + /* Verify device activation */ + ok_eq_int(LogDev->Registers[0x30], 0x01); + } + break; + } + case 6: + { + DrvTestCard1Dev7Resources(ResourceList, ReqList); + + LogDev = &IsapCard[0].LogDev[6]; + ok_eq_int(LogDev->Registers[0x30], 0x00); + break; + } + + default: + break; + } + } + + ok(i == 7, "Some devices not tested\n"); +} + +/* + * FullList Count 1 + * List #0 Iface 0 Bus #0 Ver.0 Rev.3000 Count 2 + * [1:10] IO: Start 0:A79, Len 1 + * [1:10] IO: Start 0:279, Len 1 + */ +static +VOID +DrvTestReadDataPortQueryResources(VOID) +{ + PCM_RESOURCE_LIST ResourceList; + PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor; + ULONG i; + + ResourceList = IsaPnpCreateReadPortDOResources(); + + ok(ResourceList != NULL, "ResourceList is NULL\n"); + if (ResourceList == NULL) + { + skip("No ResourceList\n"); + return; + } + expect_resource_list_header(ResourceList, Internal, 2UL); + + Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[0]; + + for (i = 0; i < RTL_NUMBER_OF(DrvpIsaBusPorts); ++i) + { + expect_port_res(Descriptor, + CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 1ul, + (ULONG64)DrvpIsaBusPorts[i]); + Descriptor++; + } + + /*********************************************************/ + + ok_eq_size(GetPoolAllocSize(ResourceList), (ULONG_PTR)Descriptor - (ULONG_PTR)ResourceList); +} + +/* + * Interface 0 Bus 0 Slot 0 AlternativeLists 1 + * + * AltList, AltList->Count 10 Ver.1 Rev.1 + * [0:1:10] IO: Min 0:A79, Max 0:A79, Align 1 Len 1 + * [8:1:10] IO: Min 0:0, Max 0:0, Align 1 Len 0 + * [0:1:10] IO: Min 0:279, Max 0:279, Align 1 Len 1 + * [8:1:10] IO: Min 0:0, Max 0:0, Align 1 Len 0 + * [0:1:10] IO: Min 0:274, Max 0:277, Align 1 Len 4 + * [8:1:10] IO: Min 0:0, Max 0:0, Align 1 Len 0 + * [0:1:10] IO: Min 0:3E4, Max 0:3E7, Align 1 Len 4 + * [8:1:10] IO: Min 0:0, Max 0:0, Align 1 Len 0 + * [0:1:10] IO: Min 0:204, Max 0:207, Align 1 Len 4 + * [8:1:10] IO: Min 0:0, Max 0:0, Align 1 Len 0 + * [0:1:10] IO: Min 0:2E4, Max 0:2E7, Align 1 Len 4 + * [8:1:10] IO: Min 0:0, Max 0:0, Align 1 Len 0 + * [0:1:10] IO: Min 0:354, Max 0:357, Align 1 Len 4 + * [8:1:10] IO: Min 0:0, Max 0:0, Align 1 Len 0 + * [0:1:10] IO: Min 0:2F4, Max 0:2F7, Align 1 Len 4 + * [8:1:10] IO: Min 0:0, Max 0:0, Align 1 Len 0 +*/ +static +VOID +DrvTestReadDataPortQueryResourcesRequirementsForEnum(VOID) +{ + PIO_RESOURCE_REQUIREMENTS_LIST ReqList; + PIO_RESOURCE_DESCRIPTOR Descriptor; + ULONG i; + + ReqList = IsaPnpCreateReadPortDORequirements(0); + + ok(ReqList != NULL, "ReqList is NULL\n"); + if (ReqList == NULL) + { + skip("No ReqList\n"); + return; + } + expect_requirements_list_header(ReqList, Internal, 1UL); + expect_alt_list_header(&ReqList->List[0], 16UL); + + Descriptor = &ReqList->List[0].Descriptors[0]; + + for (i = 0; i < RTL_NUMBER_OF(DrvpIsaBusPorts) * 2; ++i) + { + if ((i % 2) == 0) + { + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 1ul, + 1ul, + (ULONG64)DrvpIsaBusPorts[i / 2], + (ULONG64)DrvpIsaBusPorts[i / 2]); + } + else + { + expect_port_req(Descriptor, + IO_RESOURCE_ALTERNATIVE, + CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 0ul, + 1ul, + 0ull, + 0ull); + } + + Descriptor++; + } + + for (i = 0; i < RTL_NUMBER_OF(DrvpIsaBusReadDataPorts) * 2; ++i) + { + if ((i % 2) == 0) + { + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 4ul, + 1ul, + (ULONG64)DrvpIsaBusReadDataPorts[i / 2], + (ULONG64)(DrvpIsaBusReadDataPorts[i / 2]) + 4 - 1); + } + else + { + expect_port_req(Descriptor, + IO_RESOURCE_ALTERNATIVE, + CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 0ul, + 1ul, + 0ull, + 0ull); + } + + Descriptor++; + } + + /*********************************************************/ + + ok_int(ReqList->ListSize, GetPoolAllocSize(ReqList)); + ok_int(ReqList->ListSize, (ULONG_PTR)Descriptor - (ULONG_PTR)ReqList); +} + +/* + * Interface 0 Bus 0 Slot 0 AlternativeLists 1 + * + * AltList, AltList->Count A Ver.1 Rev.1 + * [0:1:10] IO: Min 0:A79, Max 0:A79, Align 1 Len 1 + * [8:1:10] IO: Min 0:0, Max 0:0, Align 1 Len 0 + * [0:1:10] IO: Min 0:279, Max 0:279, Align 1 Len 1 + * [8:1:10] IO: Min 0:0, Max 0:0, Align 1 Len 0 + * [8:1:10] IO: Min 0:274, Max 0:277, Align 1 Len 4 + * [8:1:10] IO: Min 0:3E4, Max 0:3E7, Align 1 Len 4 + * [8:1:10] IO: Min 0:204, Max 0:207, Align 1 Len 4 + * [8:1:10] IO: Min 0:2E4, Max 0:2E7, Align 1 Len 4 + * [0:1:10] IO: Min 0:354, Max 0:357, Align 1 Len 4 <-- selected (4th range) + * [8:1:10] IO: Min 0:2F4, Max 0:2F7, Align 1 Len 4 + */ +static +VOID +DrvTestReadDataPortQueryResourcesRequirementsForRebalance(VOID) +{ + PIO_RESOURCE_REQUIREMENTS_LIST ReqList; + PIO_RESOURCE_DESCRIPTOR Descriptor; + ULONG i; + + /* Select the 4th I/O range in the list */ +#define RDP_INDEX 4 + ReqList = IsaPnpCreateReadPortDORequirements(DrvpIsaBusReadDataPorts[RDP_INDEX]); + + ok(ReqList != NULL, "ReqList is NULL\n"); + if (ReqList == NULL) + { + skip("No ReqList\n"); + return; + } + expect_requirements_list_header(ReqList, Internal, 1UL); + expect_alt_list_header(&ReqList->List[0], 10UL); + + Descriptor = &ReqList->List[0].Descriptors[0]; + + for (i = 0; i < RTL_NUMBER_OF(DrvpIsaBusPorts) * 2; ++i) + { + if ((i % 2) == 0) + { + expect_port_req(Descriptor, + 0, + CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 1ul, + 1ul, + (ULONG64)DrvpIsaBusPorts[i / 2], + (ULONG64)DrvpIsaBusPorts[i / 2]); + } + else + { + expect_port_req(Descriptor, + IO_RESOURCE_ALTERNATIVE, + CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 0ul, + 1ul, + 0ull, + 0ull); + } + + Descriptor++; + } + + for (i = 0; i < RTL_NUMBER_OF(DrvpIsaBusReadDataPorts); ++i) + { + expect_port_req(Descriptor, + (i == RDP_INDEX) ? 0 : IO_RESOURCE_ALTERNATIVE, + CM_RESOURCE_PORT_16_BIT_DECODE, + CmResourceShareDeviceExclusive, + 4ul, + 1ul, + (ULONG64)DrvpIsaBusReadDataPorts[i], + (ULONG64)(DrvpIsaBusReadDataPorts[i]) + 4 - 1); + + Descriptor++; + } + + /*********************************************************/ + + ok_int(ReqList->ListSize, GetPoolAllocSize(ReqList)); + ok_int(ReqList->ListSize, (ULONG_PTR)Descriptor - (ULONG_PTR)ReqList); +} + +START_TEST(Resources) +{ + DrvTestReadDataPortQueryResources(); + DrvTestReadDataPortQueryResourcesRequirementsForEnum(); + DrvTestReadDataPortQueryResourcesRequirementsForRebalance(); + + if (DrvTestIsolation()) + { + DrvTestResources(); + } +}
4 months, 3 weeks
1
0
0
0
[reactos] 02/10: [ISAPNP] Extract resource definitions
by Dmitry Borisov
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=016d01e5d1f7d7817fe6f…
commit 016d01e5d1f7d7817fe6f270a8246e695cd4f13d Author: Dmitry Borisov <di.sean(a)protonmail.com> AuthorDate: Fri May 3 19:08:09 2024 +0600 Commit: Dmitry Borisov <di.sean(a)protonmail.com> CommitDate: Sat Aug 3 17:08:43 2024 +0600 [ISAPNP] Extract resource definitions Prepare the driver for upcoming API tests CORE-18562 --- drivers/bus/isapnp/isapnp.c | 112 ++++++++++++++-------------- drivers/bus/isapnp/isapnp.h | 151 +------------------------------------- drivers/bus/isapnp/isapnpres.h | 162 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 220 insertions(+), 205 deletions(-) diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c index 514322c69c0..0d939a300ea 100644 --- a/drivers/bus/isapnp/isapnp.c +++ b/drivers/bus/isapnp/isapnp.c @@ -981,62 +981,6 @@ InvalidBiosResources: return STATUS_SUCCESS; } -_Dispatch_type_(IRP_MJ_CREATE) -_Dispatch_type_(IRP_MJ_CLOSE) -static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaCreateClose; - -static -CODE_SEG("PAGE") -NTSTATUS -NTAPI -IsaCreateClose( - _In_ PDEVICE_OBJECT DeviceObject, - _Inout_ PIRP Irp) -{ - PAGED_CODE(); - - Irp->IoStatus.Status = STATUS_SUCCESS; - - DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp); - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - - return STATUS_SUCCESS; -} - -_Dispatch_type_(IRP_MJ_DEVICE_CONTROL) -_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL) -static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaForwardOrIgnore; - -static -CODE_SEG("PAGE") -NTSTATUS -NTAPI -IsaForwardOrIgnore( - _In_ PDEVICE_OBJECT DeviceObject, - _Inout_ PIRP Irp) -{ - PISAPNP_COMMON_EXTENSION CommonExt = DeviceObject->DeviceExtension; - - PAGED_CODE(); - - DPRINT("%s(%p, %p) Minor - %X\n", __FUNCTION__, DeviceObject, Irp, - IoGetCurrentIrpStackLocation(Irp)->MinorFunction); - - if (CommonExt->Signature == IsaPnpBus) - { - IoSkipCurrentIrpStackLocation(Irp); - return IoCallDriver(((PISAPNP_FDO_EXTENSION)CommonExt)->Ldo, Irp); - } - else - { - NTSTATUS Status = Irp->IoStatus.Status; - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; - } -} - CODE_SEG("PAGE") PIO_RESOURCE_REQUIREMENTS_LIST IsaPnpCreateReadPortDORequirements( @@ -1571,6 +1515,62 @@ IsaPnp( return IsaPdoPnp((PISAPNP_PDO_EXTENSION)DevExt, Irp, IrpSp); } +_Dispatch_type_(IRP_MJ_CREATE) +_Dispatch_type_(IRP_MJ_CLOSE) +static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaCreateClose; + +static +CODE_SEG("PAGE") +NTSTATUS +NTAPI +IsaCreateClose( + _In_ PDEVICE_OBJECT DeviceObject, + _Inout_ PIRP Irp) +{ + PAGED_CODE(); + + Irp->IoStatus.Status = STATUS_SUCCESS; + + DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp); + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_SUCCESS; +} + +_Dispatch_type_(IRP_MJ_DEVICE_CONTROL) +_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL) +static CODE_SEG("PAGE") DRIVER_DISPATCH_PAGED IsaForwardOrIgnore; + +static +CODE_SEG("PAGE") +NTSTATUS +NTAPI +IsaForwardOrIgnore( + _In_ PDEVICE_OBJECT DeviceObject, + _Inout_ PIRP Irp) +{ + PISAPNP_COMMON_EXTENSION CommonExt = DeviceObject->DeviceExtension; + + PAGED_CODE(); + + DPRINT("%s(%p, %p) Minor - %X\n", __FUNCTION__, DeviceObject, Irp, + IoGetCurrentIrpStackLocation(Irp)->MinorFunction); + + if (CommonExt->Signature == IsaPnpBus) + { + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(((PISAPNP_FDO_EXTENSION)CommonExt)->Ldo, Irp); + } + else + { + NTSTATUS Status = Irp->IoStatus.Status; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } +} + CODE_SEG("INIT") NTSTATUS NTAPI diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h index ea84d2d5148..17945dbe06a 100644 --- a/drivers/bus/isapnp/isapnp.h +++ b/drivers/bus/isapnp/isapnp.h @@ -12,7 +12,9 @@ #include <ntddk.h> #include <ntstrsafe.h> #include <section_attribs.h> + #include "isapnphw.h" +#include "isapnpres.h" #include <initguid.h> #include <wdmguid.h> @@ -23,121 +25,12 @@ extern "C" { #define TAG_ISAPNP 'pasI' -/** @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 enum { dsStopped, dsStarted } ISAPNP_DEVICE_STATE; -typedef struct _ISAPNP_IO -{ - USHORT CurrentBase; - ISAPNP_IO_DESCRIPTION Description; - UCHAR Index; -} ISAPNP_IO, *PISAPNP_IO; - -typedef struct _ISAPNP_IRQ -{ - UCHAR CurrentNo; - UCHAR CurrentType; - ISAPNP_IRQ_DESCRIPTION Description; - UCHAR Index; -} ISAPNP_IRQ, *PISAPNP_IRQ; - -typedef struct _ISAPNP_DMA -{ - UCHAR CurrentChannel; - ISAPNP_DMA_DESCRIPTION Description; - UCHAR Index; -} ISAPNP_DMA, *PISAPNP_DMA; - -typedef struct _ISAPNP_MEMRANGE -{ - ULONG CurrentBase; - ULONG CurrentLength; - ISAPNP_MEMRANGE_DESCRIPTION Description; - UCHAR Index; -} ISAPNP_MEMRANGE, *PISAPNP_MEMRANGE; - -typedef struct _ISAPNP_MEMRANGE32 -{ - ULONG CurrentBase; - ULONG CurrentLength; - ISAPNP_MEMRANGE32_DESCRIPTION Description; - UCHAR Index; -} ISAPNP_MEMRANGE32, *PISAPNP_MEMRANGE32; - -typedef struct _ISAPNP_COMPATIBLE_ID_ENTRY -{ - UCHAR VendorId[3]; - USHORT ProdId; - LIST_ENTRY IdLink; -} ISAPNP_COMPATIBLE_ID_ENTRY, *PISAPNP_COMPATIBLE_ID_ENTRY; - -typedef struct _ISAPNP_ALTERNATIVES -{ - 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; - - _Field_range_(0, ISAPNP_MAX_ALTERNATIVES) - UCHAR Count; -} ISAPNP_ALTERNATIVES, *PISAPNP_ALTERNATIVES; - -typedef struct _ISAPNP_LOGICAL_DEVICE -{ - PDEVICE_OBJECT Pdo; - - /** - * @name The card data. - * @{ - */ - UCHAR CSN; - UCHAR VendorId[3]; - USHORT ProdId; - ULONG SerialNumber; - /**@}*/ - - /** - * @name The logical device data. - * @{ - */ - UCHAR LDN; - UCHAR LogVendorId[3]; - USHORT LogProdId; - LIST_ENTRY CompatibleIdList; - PSTR FriendlyName; - PISAPNP_ALTERNATIVES Alternatives; - - ISAPNP_IO Io[8]; - ISAPNP_IRQ Irq[2]; - ISAPNP_DMA Dma[2]; - ISAPNP_MEMRANGE MemRange[4]; - ISAPNP_MEMRANGE32 MemRange32[4]; - /**@}*/ - - ULONG Flags; -#define ISAPNP_PRESENT 0x00000001 /**< @brief Cleared when the device is physically removed. */ -#define ISAPNP_HAS_MULTIPLE_LOGDEVS 0x00000002 /**< @brief Indicates if the parent card has multiple logical devices. */ -#define ISAPNP_HAS_RESOURCES 0x00000004 /**< @brief Cleared when the device has no boot resources. */ - - LIST_ENTRY DeviceLink; -} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE; - typedef enum _ISAPNP_SIGNATURE { IsaPnpBus = 'odFI', @@ -248,46 +141,6 @@ IsaPnpReleaseDeviceDataLock( KeSetEvent(&FdoExt->DeviceSyncEvent, IO_NO_INCREMENT, FALSE); } -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); -} - /* isapnp.c */ CODE_SEG("PAGE") diff --git a/drivers/bus/isapnp/isapnpres.h b/drivers/bus/isapnp/isapnpres.h new file mode 100644 index 00000000000..16c21646a0f --- /dev/null +++ b/drivers/bus/isapnp/isapnpres.h @@ -0,0 +1,162 @@ +/* + * PROJECT: ReactOS ISA PnP Bus driver + * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later
) + * PURPOSE: Resource management header file + * COPYRIGHT: Copyright 2010 Cameron Gutman <cameron.gutman(a)reactos.org> + * Copyright 2020 Hervé Poussineau <hpoussin(a)reactos.org> + */ + +#pragma once + +/** @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; + ISAPNP_IO_DESCRIPTION Description; + UCHAR Index; +} ISAPNP_IO, *PISAPNP_IO; + +typedef struct _ISAPNP_IRQ +{ + UCHAR CurrentNo; + UCHAR CurrentType; + ISAPNP_IRQ_DESCRIPTION Description; + UCHAR Index; +} ISAPNP_IRQ, *PISAPNP_IRQ; + +typedef struct _ISAPNP_DMA +{ + UCHAR CurrentChannel; + ISAPNP_DMA_DESCRIPTION Description; + UCHAR Index; +} ISAPNP_DMA, *PISAPNP_DMA; + +typedef struct _ISAPNP_MEMRANGE +{ + ULONG CurrentBase; + ULONG CurrentLength; + ISAPNP_MEMRANGE_DESCRIPTION Description; + UCHAR Index; +} ISAPNP_MEMRANGE, *PISAPNP_MEMRANGE; + +typedef struct _ISAPNP_MEMRANGE32 +{ + ULONG CurrentBase; + ULONG CurrentLength; + ISAPNP_MEMRANGE32_DESCRIPTION Description; + UCHAR Index; +} ISAPNP_MEMRANGE32, *PISAPNP_MEMRANGE32; + +typedef struct _ISAPNP_COMPATIBLE_ID_ENTRY +{ + UCHAR VendorId[3]; + USHORT ProdId; + LIST_ENTRY IdLink; +} ISAPNP_COMPATIBLE_ID_ENTRY, *PISAPNP_COMPATIBLE_ID_ENTRY; + +typedef struct _ISAPNP_ALTERNATIVES +{ + 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; + + _Field_range_(0, ISAPNP_MAX_ALTERNATIVES) + UCHAR Count; +} ISAPNP_ALTERNATIVES, *PISAPNP_ALTERNATIVES; + +typedef struct _ISAPNP_LOGICAL_DEVICE +{ + LIST_ENTRY DeviceLink; + PDEVICE_OBJECT Pdo; + + ULONG Flags; +/** Cleared when the device is physically removed */ +#define ISAPNP_PRESENT 0x00000001 + +/** Indicates if the parent card has multiple logical devices */ +#define ISAPNP_HAS_MULTIPLE_LOGDEVS 0x00000002 + +/** Cleared when the device has no boot resources */ +#define ISAPNP_HAS_RESOURCES 0x00000004 + + /** + * @name The card data. + * @{ + */ + UCHAR CSN; + UCHAR VendorId[3]; + USHORT ProdId; + ULONG SerialNumber; + /**@}*/ + + /** + * @name The logical device data. + * @{ + */ + UCHAR LDN; + UCHAR LogVendorId[3]; + USHORT LogProdId; + PISAPNP_ALTERNATIVES Alternatives; + PSTR FriendlyName; + LIST_ENTRY CompatibleIdList; + + ISAPNP_IO Io[8]; + ISAPNP_IRQ Irq[2]; + ISAPNP_DMA Dma[2]; + ISAPNP_MEMRANGE MemRange[4]; + 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); +}
4 months, 3 weeks
1
0
0
0
[reactos] 01/10: [ISAPNP] Allocate the Read Port resources on demand
by Dmitry Borisov
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4ba8a8b59bebabd941e42…
commit 4ba8a8b59bebabd941e42d14493e4cd02a3e5972 Author: Dmitry Borisov <di.sean(a)protonmail.com> AuthorDate: Sun Jan 15 22:41:49 2023 +0600 Commit: Dmitry Borisov <di.sean(a)protonmail.com> CommitDate: Sat Aug 3 17:08:42 2024 +0600 [ISAPNP] Allocate the Read Port resources on demand This will simplify failure paths and reduce memory usage --- drivers/bus/isapnp/isapnp.c | 43 +++++++------------------------------------ drivers/bus/isapnp/isapnp.h | 28 +++++++++++++++++++++------- drivers/bus/isapnp/pdo.c | 35 ++++++++++++++++++++++------------- 3 files changed, 50 insertions(+), 56 deletions(-) diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c index 0ff17876e75..514322c69c0 100644 --- a/drivers/bus/isapnp/isapnp.c +++ b/drivers/bus/isapnp/isapnp.c @@ -1038,9 +1038,8 @@ IsaForwardOrIgnore( } CODE_SEG("PAGE") -NTSTATUS +PIO_RESOURCE_REQUIREMENTS_LIST IsaPnpCreateReadPortDORequirements( - _In_ PISAPNP_PDO_EXTENSION PdoExt, _In_opt_ ULONG SelectedReadPort) { ULONG ResourceCount, ListSize, i; @@ -1087,7 +1086,7 @@ IsaPnpCreateReadPortDORequirements( sizeof(IO_RESOURCE_DESCRIPTOR) * (ResourceCount - 1); RequirementsList = ExAllocatePoolZero(PagedPool, ListSize, TAG_ISAPNP); if (!RequirementsList) - return STATUS_NO_MEMORY; + return NULL; RequirementsList->ListSize = ListSize; RequirementsList->AlternativeLists = 1; @@ -1182,15 +1181,12 @@ IsaPnpCreateReadPortDORequirements( } } - PdoExt->RequirementsList = RequirementsList; - return STATUS_SUCCESS; + return RequirementsList; } -static CODE_SEG("PAGE") -NTSTATUS -IsaPnpCreateReadPortDOResources( - _In_ PISAPNP_PDO_EXTENSION PdoExt) +PCM_RESOURCE_LIST +IsaPnpCreateReadPortDOResources(VOID) { const USHORT Ports[] = { ISAPNP_WRITE_DATA, ISAPNP_ADDRESS }; ULONG ListSize, i; @@ -1203,7 +1199,7 @@ IsaPnpCreateReadPortDOResources( sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (RTL_NUMBER_OF(Ports) - 1); ResourceList = ExAllocatePoolZero(PagedPool, ListSize, TAG_ISAPNP); if (!ResourceList) - return STATUS_NO_MEMORY; + return NULL; ResourceList->Count = 1; ResourceList->List[0].InterfaceType = Internal; @@ -1223,9 +1219,7 @@ IsaPnpCreateReadPortDOResources( Descriptor++; } - PdoExt->ResourceList = ResourceList; - PdoExt->ResourceListSize = ListSize; - return STATUS_SUCCESS; + return ResourceList; } static @@ -1259,23 +1253,8 @@ IsaPnpCreateReadPortDO( PdoExt->Common.State = dsStopped; PdoExt->FdoExt = FdoExt; - Status = IsaPnpCreateReadPortDORequirements(PdoExt, 0); - if (!NT_SUCCESS(Status)) - goto Failure; - - Status = IsaPnpCreateReadPortDOResources(PdoExt); - if (!NT_SUCCESS(Status)) - goto Failure; - FdoExt->ReadPortPdo->Flags &= ~DO_DEVICE_INITIALIZING; - return Status; - -Failure: - IsaPnpRemoveReadPortDO(FdoExt->ReadPortPdo); - - FdoExt->ReadPortPdo = NULL; - return Status; } @@ -1284,18 +1263,10 @@ VOID IsaPnpRemoveReadPortDO( _In_ PDEVICE_OBJECT Pdo) { - PISAPNP_PDO_EXTENSION ReadPortExt = Pdo->DeviceExtension; - PAGED_CODE(); DPRINT("Removing Read Port\n"); - if (ReadPortExt->RequirementsList) - ExFreePoolWithTag(ReadPortExt->RequirementsList, TAG_ISAPNP); - - if (ReadPortExt->ResourceList) - ExFreePoolWithTag(ReadPortExt->ResourceList, TAG_ISAPNP); - IoDeleteDevice(Pdo); } diff --git a/drivers/bus/isapnp/isapnp.h b/drivers/bus/isapnp/isapnp.h index ad48008251f..ea84d2d5148 100644 --- a/drivers/bus/isapnp/isapnp.h +++ b/drivers/bus/isapnp/isapnp.h @@ -176,12 +176,7 @@ typedef struct _ISAPNP_FDO_EXTENSION typedef struct _ISAPNP_PDO_EXTENSION { ISAPNP_COMMON_EXTENSION Common; - PISAPNP_LOGICAL_DEVICE IsaPnpDevice; PISAPNP_FDO_EXTENSION FdoExt; - PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList; - - PCM_RESOURCE_LIST ResourceList; - ULONG ResourceListSize; ULONG Flags; #define ISAPNP_ENUMERATED 0x00000001 /**< @brief Whether the device has been reported to the PnP manager. */ @@ -189,6 +184,22 @@ typedef struct _ISAPNP_PDO_EXTENSION #define ISAPNP_READ_PORT_ALLOW_FDO_SCAN 0x00000004 /**< @brief Allows the active FDO to scan the bus. */ #define ISAPNP_READ_PORT_NEED_REBALANCE 0x00000008 /**< @brief The I/O resource requirements have changed. */ + union + { + /* Data belonging to logical devices */ + struct + { + PISAPNP_LOGICAL_DEVICE IsaPnpDevice; + + PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList; + + PCM_RESOURCE_LIST ResourceList; + ULONG ResourceListSize; + }; + + ULONG SelectedPort; + }; + _Write_guarded_by_(_Global_interlock_) volatile LONG SpecialFiles; } ISAPNP_PDO_EXTENSION, *PISAPNP_PDO_EXTENSION; @@ -315,11 +326,14 @@ FindMemoryDescriptor( _Out_opt_ PUCHAR WriteOrder); CODE_SEG("PAGE") -NTSTATUS +PIO_RESOURCE_REQUIREMENTS_LIST IsaPnpCreateReadPortDORequirements( - _In_ PISAPNP_PDO_EXTENSION PdoExt, _In_opt_ ULONG SelectedReadPort); +CODE_SEG("PAGE") +PCM_RESOURCE_LIST +IsaPnpCreateReadPortDOResources(VOID); + CODE_SEG("PAGE") VOID IsaPnpRemoveReadPortDO( diff --git a/drivers/bus/isapnp/pdo.c b/drivers/bus/isapnp/pdo.c index 3946ce31485..5e8979ad274 100644 --- a/drivers/bus/isapnp/pdo.c +++ b/drivers/bus/isapnp/pdo.c @@ -478,8 +478,17 @@ IsaPdoQueryResources( PAGED_CODE(); - if (PdoExt->Common.Signature == IsaPnpLogicalDevice && - !(PdoExt->IsaPnpDevice->Flags & ISAPNP_HAS_RESOURCES)) + if (PdoExt->Common.Signature == IsaPnpReadDataPort) + { + ResourceList = IsaPnpCreateReadPortDOResources(); + if (!ResourceList) + return STATUS_NO_MEMORY; + + Irp->IoStatus.Information = (ULONG_PTR)ResourceList; + return STATUS_SUCCESS; + } + + if (!(PdoExt->IsaPnpDevice->Flags & ISAPNP_HAS_RESOURCES)) { Irp->IoStatus.Information = 0; return STATUS_SUCCESS; @@ -513,6 +522,16 @@ IsaPdoQueryResourceRequirements( PAGED_CODE(); + if (PdoExt->Common.Signature == IsaPnpReadDataPort) + { + RequirementsList = IsaPnpCreateReadPortDORequirements(PdoExt->SelectedPort); + if (!RequirementsList) + return STATUS_NO_MEMORY; + + Irp->IoStatus.Information = (ULONG_PTR)RequirementsList; + return STATUS_SUCCESS; + } + if (!PdoExt->RequirementsList) return Irp->IoStatus.Status; @@ -593,19 +612,9 @@ IsaPdoStartReadPort( ASSERT(SelectedPort != 0); - if (PdoExt->RequirementsList) - { - ExFreePoolWithTag(PdoExt->RequirementsList, TAG_ISAPNP); - PdoExt->RequirementsList = NULL; - } - /* Discard the Read Ports at conflicting locations */ - Status = IsaPnpCreateReadPortDORequirements(PdoExt, SelectedPort); - if (!NT_SUCCESS(Status)) - return Status; - + PdoExt->SelectedPort = SelectedPort; PdoExt->Flags |= ISAPNP_READ_PORT_NEED_REBALANCE; - IoInvalidateDeviceState(PdoExt->Common.Self); return STATUS_SUCCESS;
4 months, 3 weeks
1
0
0
0
[reactos] 01/01: [SHELL32] shlexec: Simplify parameters parsing (#7207)
by Katayama Hirofumi MZ
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=266e2e5052486412f6130…
commit 266e2e5052486412f6130ea6f61b91d9c9e2144d Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com> AuthorDate: Sat Aug 3 15:46:24 2024 +0900 Commit: GitHub <noreply(a)github.com> CommitDate: Sat Aug 3 15:46:24 2024 +0900 [SHELL32] shlexec: Simplify parameters parsing (#7207) Simplify code logic. JIRA issue: N/A - Use PathGetArgsW, PathRemoveArgsW, and PathUnquoteSpacesW for parsing parameters. --- dll/win32/shell32/shlexec.cpp | 44 ++++++++++++------------------------------- 1 file changed, 12 insertions(+), 32 deletions(-) diff --git a/dll/win32/shell32/shlexec.cpp b/dll/win32/shell32/shlexec.cpp index 6134aaf311b..a74e1ff0f44 100644 --- a/dll/win32/shell32/shlexec.cpp +++ b/dll/win32/shell32/shlexec.cpp @@ -2153,39 +2153,26 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc) TRACE("execute: %s,%s,%s\n", debugstr_w(wszApplicationName), debugstr_w(wszParameters), debugstr_w(wszDir)); /* separate out command line arguments from executable file name */ - LPCWSTR lpFile; - WCHAR wfileName[MAX_PATH]; + LPCWSTR lpFile = sei_tmp.lpFile; if (!*sei_tmp.lpParameters && !appKnownSingular) { /* If the executable path is quoted, handle the rest of the command line as parameters. */ if (sei_tmp.lpFile[0] == L'"') { - LPWSTR src = wszApplicationName/*sei_tmp.lpFile*/ + 1; - LPWSTR dst = wfileName; - LPWSTR end; - - /* copy the unquoted executable path to 'wfileName' */ - while(*src && *src != L'"') - *dst++ = *src++; - - *dst = L'\0'; - - if (*src == L'"') + LPWSTR pszArgs = PathGetArgsW(wszApplicationName); + PathRemoveArgsW(wszApplicationName); + PathUnquoteSpacesW(wszApplicationName); + parametersLen = lstrlenW(pszArgs); + if (parametersLen < _countof(parametersBuffer)) { - end = ++src; - - while(isspaceW(*src)) - ++src; + StringCchCopyW(parametersBuffer, _countof(parametersBuffer), pszArgs); + wszParameters = parametersBuffer; } else - end = src; - - /* copy the parameter string to 'wszParameters' */ - strcpyW(wszParameters, src); - - /* terminate previous command string after the quote character */ - *end = L'\0'; - lpFile = wfileName; + { + wszParamAlloc.Attach(StrDupW(pszArgs)); + wszParameters = wszParamAlloc; + } } /* We have to test sei instead of sei_tmp because sei_tmp had its * input fMask modified above in SHELL_translate_idlist. @@ -2218,15 +2205,8 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc) break; } } - lpFile = sei_tmp.lpFile; - } - else - { - lpFile = sei_tmp.lpFile; } } - else - lpFile = sei_tmp.lpFile; WCHAR wcmdBuffer[1024]; LPWSTR wcmd = wcmdBuffer;
4 months, 3 weeks
1
0
0
0
[reactos] 01/01: [TASKMGR] Allow setting each column alignment independently (#7208)
by Jose Carlos Jesus
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=deccfb8c9fb860c2dcc19…
commit deccfb8c9fb860c2dcc19d28339ab9cbab2bcc8d Author: Jose Carlos Jesus <zecarlos1957(a)hotmail.com> AuthorDate: Fri Aug 2 22:54:41 2024 +0100 Commit: GitHub <noreply(a)github.com> CommitDate: Sat Aug 3 00:54:41 2024 +0300 [TASKMGR] Allow setting each column alignment independently (#7208) Add dwAlign attribute to the PresetColumnEntry structure to make it work. CORE-19280 --- base/applications/taskmgr/column.c | 58 +++++++++++++++++++------------------- base/applications/taskmgr/column.h | 1 + 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/base/applications/taskmgr/column.c b/base/applications/taskmgr/column.c index b6eec0f5ec8..75d106f68e3 100644 --- a/base/applications/taskmgr/column.c +++ b/base/applications/taskmgr/column.c @@ -10,36 +10,36 @@ UINT ColumnDataHints[COLUMN_NMAX]; -#define DECLARE_COLUMN_PRESET(_name, _size, _state) \ - { IDS_TAB_##_name, IDC_##_name, _size, _state }, +#define DECLARE_COLUMN_PRESET(_name, _size, _state, _align) \ + { IDS_TAB_##_name, IDC_##_name, _size, _state, _align }, const PresetColumnEntry ColumnPresets[COLUMN_NMAX] = { - DECLARE_COLUMN_PRESET(IMAGENAME, 105, TRUE) - DECLARE_COLUMN_PRESET(PID, 50, TRUE) - DECLARE_COLUMN_PRESET(USERNAME, 107, FALSE) - DECLARE_COLUMN_PRESET(SESSIONID, 70, FALSE) - DECLARE_COLUMN_PRESET(CPUUSAGE, 35, TRUE) - DECLARE_COLUMN_PRESET(CPUTIME, 70, TRUE) - DECLARE_COLUMN_PRESET(MEMORYUSAGE, 70, TRUE) - DECLARE_COLUMN_PRESET(PEAKMEMORYUSAGE, 100, FALSE) - DECLARE_COLUMN_PRESET(MEMORYUSAGEDELTA, 70, FALSE) - DECLARE_COLUMN_PRESET(PAGEFAULTS, 70, FALSE) - DECLARE_COLUMN_PRESET(PAGEFAULTSDELTA, 70, FALSE) - DECLARE_COLUMN_PRESET(VIRTUALMEMORYSIZE, 70, FALSE) - DECLARE_COLUMN_PRESET(PAGEDPOOL, 70, FALSE) - DECLARE_COLUMN_PRESET(NONPAGEDPOOL, 70, FALSE) - DECLARE_COLUMN_PRESET(BASEPRIORITY, 60, FALSE) - DECLARE_COLUMN_PRESET(HANDLECOUNT, 60, FALSE) - DECLARE_COLUMN_PRESET(THREADCOUNT, 60, FALSE) - DECLARE_COLUMN_PRESET(USEROBJECTS, 60, FALSE) - DECLARE_COLUMN_PRESET(GDIOBJECTS, 60, FALSE) - DECLARE_COLUMN_PRESET(IOREADS, 70, FALSE) - DECLARE_COLUMN_PRESET(IOWRITES, 70, FALSE) - DECLARE_COLUMN_PRESET(IOOTHER, 70, FALSE) - DECLARE_COLUMN_PRESET(IOREADBYTES, 70, FALSE) - DECLARE_COLUMN_PRESET(IOWRITEBYTES, 70, FALSE) - DECLARE_COLUMN_PRESET(IOOTHERBYTES, 70, FALSE) - DECLARE_COLUMN_PRESET(COMMANDLINE, 450, FALSE) + DECLARE_COLUMN_PRESET(IMAGENAME, 105, TRUE, LVCFMT_LEFT) + DECLARE_COLUMN_PRESET(PID, 50, TRUE, LVCFMT_LEFT) + DECLARE_COLUMN_PRESET(USERNAME, 107, FALSE, LVCFMT_LEFT) + DECLARE_COLUMN_PRESET(SESSIONID, 70, FALSE, LVCFMT_LEFT) + DECLARE_COLUMN_PRESET(CPUUSAGE, 35, TRUE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(CPUTIME, 70, TRUE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(MEMORYUSAGE, 70, TRUE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(PEAKMEMORYUSAGE, 100, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(MEMORYUSAGEDELTA, 70, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(PAGEFAULTS, 70, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(PAGEFAULTSDELTA, 70, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(VIRTUALMEMORYSIZE, 70, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(PAGEDPOOL, 70, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(NONPAGEDPOOL, 70, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(BASEPRIORITY, 60, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(HANDLECOUNT, 60, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(THREADCOUNT, 60, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(USEROBJECTS, 60, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(GDIOBJECTS, 60, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(IOREADS, 70, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(IOWRITES, 70, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(IOOTHER, 70, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(IOREADBYTES, 70, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(IOWRITEBYTES, 70, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(IOOTHERBYTES, 70, FALSE, LVCFMT_RIGHT) + DECLARE_COLUMN_PRESET(COMMANDLINE, 450, FALSE, LVCFMT_LEFT) }; static int InsertColumn(int nCol, LPCWSTR lpszColumnHeading, int nFormat, int nWidth, int nSubItem); @@ -54,7 +54,7 @@ void AddColumns(void) for (n=0; n<COLUMN_NMAX; n++) { if (TaskManagerSettings.Columns[n]) { LoadStringW(hInst, ColumnPresets[n].dwIdsName, szTemp, _countof(szTemp)); - InsertColumn(n, szTemp, LVCFMT_LEFT, TaskManagerSettings.ColumnSizeArray[n], -1); + InsertColumn(n, szTemp, ColumnPresets[n].dwAlign, TaskManagerSettings.ColumnSizeArray[n], -1); } } diff --git a/base/applications/taskmgr/column.h b/base/applications/taskmgr/column.h index 4ccdf36d593..de0a1e9e35d 100644 --- a/base/applications/taskmgr/column.h +++ b/base/applications/taskmgr/column.h @@ -60,6 +60,7 @@ typedef struct { DWORD dwIdcCtrl; int size; BOOL bDefaults; + DWORD dwAlign; } PresetColumnEntry;
4 months, 3 weeks
1
0
0
0
← Newer
1
...
10
11
12
13
14
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Results per page:
10
25
50
100
200