mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[ISAPNP_UNITTEST] Add unit tests exercising device discovery and device resources functionality
CORE-18562
This commit is contained in:
parent
016d01e5d1
commit
b36d9bd9c1
10 changed files with 2863 additions and 0 deletions
|
@ -7,6 +7,8 @@
|
||||||
* Copyright 2021 Dmitry Borisov <di.sean@protonmail.com>
|
* Copyright 2021 Dmitry Borisov <di.sean@protonmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef UNIT_TEST
|
||||||
|
|
||||||
#include "isapnp.h"
|
#include "isapnp.h"
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
@ -16,6 +18,8 @@
|
||||||
#pragma warning(disable:28138) /* ISA bus always uses hardcoded port addresses */
|
#pragma warning(disable:28138) /* ISA bus always uses hardcoded port addresses */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* UNIT_TEST */
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
dfNotStarted,
|
dfNotStarted,
|
||||||
|
@ -1517,6 +1521,7 @@ IsaHwFillDeviceList(
|
||||||
{
|
{
|
||||||
BOOLEAN IsAlreadyEnumerated = FALSE;
|
BOOLEAN IsAlreadyEnumerated = FALSE;
|
||||||
|
|
||||||
|
#ifndef UNIT_TEST
|
||||||
for (Entry = FdoExt->DeviceListHead.Flink;
|
for (Entry = FdoExt->DeviceListHead.Flink;
|
||||||
Entry != &FdoExt->DeviceListHead;
|
Entry != &FdoExt->DeviceListHead;
|
||||||
Entry = Entry->Flink)
|
Entry = Entry->Flink)
|
||||||
|
@ -1547,6 +1552,7 @@ IsaHwFillDeviceList(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* UNIT_TEST */
|
||||||
|
|
||||||
if (IsAlreadyEnumerated)
|
if (IsAlreadyEnumerated)
|
||||||
continue;
|
continue;
|
||||||
|
@ -1720,6 +1726,7 @@ IsaHwActivateDevice(
|
||||||
ActivateDevice(FdoExt->ReadDataPort, LogicalDevice->LDN);
|
ActivateDevice(FdoExt->ReadDataPort, LogicalDevice->LDN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef UNIT_TEST
|
||||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||||
VOID
|
VOID
|
||||||
IsaHwDeactivateDevice(
|
IsaHwDeactivateDevice(
|
||||||
|
@ -1727,6 +1734,7 @@ IsaHwDeactivateDevice(
|
||||||
{
|
{
|
||||||
DeactivateDevice(LogicalDevice->LDN);
|
DeactivateDevice(LogicalDevice->LDN);
|
||||||
}
|
}
|
||||||
|
#endif /* UNIT_TEST */
|
||||||
|
|
||||||
_IRQL_requires_max_(DISPATCH_LEVEL)
|
_IRQL_requires_max_(DISPATCH_LEVEL)
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -9,10 +9,14 @@
|
||||||
|
|
||||||
/* INCLUDES *******************************************************************/
|
/* INCLUDES *******************************************************************/
|
||||||
|
|
||||||
|
#ifndef UNIT_TEST
|
||||||
#include "isapnp.h"
|
#include "isapnp.h"
|
||||||
|
#endif /* UNIT_TEST */
|
||||||
|
|
||||||
#include <search.h>
|
#include <search.h>
|
||||||
|
|
||||||
|
#ifndef UNIT_TEST
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
@ -26,6 +30,8 @@ BOOLEAN ReadPortCreated = FALSE;
|
||||||
_Guarded_by_(BusSyncEvent)
|
_Guarded_by_(BusSyncEvent)
|
||||||
LIST_ENTRY BusListHead;
|
LIST_ENTRY BusListHead;
|
||||||
|
|
||||||
|
#endif /* UNIT_TEST */
|
||||||
|
|
||||||
static PUCHAR Priority;
|
static PUCHAR Priority;
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
@ -1166,6 +1172,8 @@ IsaPnpCreateReadPortDOResources(VOID)
|
||||||
return ResourceList;
|
return ResourceList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef UNIT_TEST
|
||||||
|
|
||||||
static
|
static
|
||||||
CODE_SEG("PAGE")
|
CODE_SEG("PAGE")
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -1604,4 +1612,6 @@ DriverEntry(
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* UNIT_TEST */
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
|
|
||||||
|
if(ISAPNP_ENABLE)
|
||||||
|
add_subdirectory(isapnp)
|
||||||
|
endif()
|
||||||
add_subdirectory(setuplib)
|
add_subdirectory(setuplib)
|
||||||
|
|
23
modules/rostests/unittests/isapnp/CMakeLists.txt
Normal file
23
modules/rostests/unittests/isapnp/CMakeLists.txt
Normal file
|
@ -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)
|
60
modules/rostests/unittests/isapnp/empty_card.c
Normal file
60
modules/rostests/unittests/isapnp/empty_card.c
Normal file
|
@ -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@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;
|
||||||
|
}
|
508
modules/rostests/unittests/isapnp/isabus.c
Normal file
508
modules/rostests/unittests/isapnp/isabus.c
Normal file
|
@ -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@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;
|
||||||
|
}
|
409
modules/rostests/unittests/isapnp/precomp.h
Normal file
409
modules/rostests/unittests/isapnp/precomp.h
Normal file
|
@ -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@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)
|
1338
modules/rostests/unittests/isapnp/res_card.c
Normal file
1338
modules/rostests/unittests/isapnp/res_card.c
Normal file
File diff suppressed because it is too large
Load diff
17
modules/rostests/unittests/isapnp/testlist.c
Normal file
17
modules/rostests/unittests/isapnp/testlist.c
Normal file
|
@ -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@protonmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define STANDALONE
|
||||||
|
#include <apitest.h>
|
||||||
|
|
||||||
|
extern void func_Resources(void);
|
||||||
|
|
||||||
|
const struct test winetest_testlist[] =
|
||||||
|
{
|
||||||
|
{ "Resources", func_Resources },
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
486
modules/rostests/unittests/isapnp/tests.c
Normal file
486
modules/rostests/unittests/isapnp/tests.c
Normal file
|
@ -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@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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue