mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +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>
|
||||
*/
|
||||
|
||||
#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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -1 +1,5 @@
|
|||
|
||||
if(ISAPNP_ENABLE)
|
||||
add_subdirectory(isapnp)
|
||||
endif()
|
||||
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