938 lines
29 KiB
C
938 lines
29 KiB
C
/*++
|
|
|
|
Copyright (c) 1997-2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
devhere.c
|
|
|
|
Abstract:
|
|
|
|
PCI_DEVICE_PRESENT_INTERFACE lives here
|
|
|
|
Author:
|
|
|
|
Andy Thornton (andrewth) 15-July-1999
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "pcip.h"
|
|
|
|
#define DEVPRESENT_MINSIZE FIELD_OFFSET(PCI_DEVICE_PRESENT_INTERFACE, IsDevicePresentEx)
|
|
|
|
|
|
|
|
BOOLEAN
|
|
devpresent_IsDevicePresent(
|
|
USHORT VendorID,
|
|
USHORT DeviceID,
|
|
UCHAR RevisionID,
|
|
USHORT SubVendorID,
|
|
USHORT SubSystemID,
|
|
ULONG Flags
|
|
);
|
|
|
|
BOOLEAN
|
|
devpresent_IsDevicePresentEx(
|
|
IN PVOID Context,
|
|
IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
|
|
);
|
|
|
|
NTSTATUS
|
|
devpresent_Initializer(
|
|
IN PPCI_ARBITER_INSTANCE Instance
|
|
);
|
|
|
|
NTSTATUS
|
|
devpresent_Constructor(
|
|
PVOID DeviceExtension,
|
|
PVOID PciInterface,
|
|
PVOID InterfaceSpecificData,
|
|
USHORT Version,
|
|
USHORT Size,
|
|
PINTERFACE InterfaceReturn
|
|
);
|
|
|
|
VOID
|
|
PciRefDereferenceNoop(
|
|
IN PVOID Context
|
|
);
|
|
|
|
BOOLEAN
|
|
PcipDevicePresentOnBus(
|
|
IN PPCI_FDO_EXTENSION FdoExtension,
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
|
|
);
|
|
|
|
#ifdef ALLOC_PRAGMA
|
|
|
|
#pragma alloc_text(PAGE, devpresent_IsDevicePresent)
|
|
#pragma alloc_text(PAGE, devpresent_Initializer)
|
|
#pragma alloc_text(PAGE, devpresent_Constructor)
|
|
#pragma alloc_text(PAGE, PciRefDereferenceNoop)
|
|
|
|
#endif
|
|
|
|
|
|
PCI_INTERFACE PciDevicePresentInterface = {
|
|
&GUID_PCI_DEVICE_PRESENT_INTERFACE, // InterfaceType
|
|
DEVPRESENT_MINSIZE, // MinSize
|
|
PCI_DEVICE_PRESENT_INTERFACE_VERSION, // MinVersion
|
|
PCI_DEVICE_PRESENT_INTERFACE_VERSION, // MaxVersion
|
|
PCIIF_PDO, // Flags
|
|
0, // ReferenceCount
|
|
PciInterface_DevicePresent, // Signature
|
|
devpresent_Constructor, // Constructor
|
|
devpresent_Initializer // Instance Initializer
|
|
};
|
|
|
|
|
|
VOID
|
|
PciRefDereferenceNoop(
|
|
IN PVOID Context
|
|
)
|
|
{
|
|
|
|
PAGED_CODE();
|
|
return;
|
|
}
|
|
|
|
NTSTATUS
|
|
devpresent_Initializer(
|
|
IN PPCI_ARBITER_INSTANCE Instance
|
|
)
|
|
{
|
|
PAGED_CODE();
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
devpresent_Constructor(
|
|
PVOID DeviceExtension,
|
|
PVOID PciInterface,
|
|
PVOID InterfaceSpecificData,
|
|
USHORT Version,
|
|
USHORT Size,
|
|
PINTERFACE InterfaceReturn
|
|
)
|
|
{
|
|
|
|
|
|
PPCI_DEVICE_PRESENT_INTERFACE interface;
|
|
|
|
PAGED_CODE();
|
|
|
|
//
|
|
// Have already verified that the InterfaceReturn variable
|
|
// points to an area in memory large enough to contain a
|
|
// PCI_DEVICE_PRESENT_INTERFACE. Fill it in for the caller.
|
|
//
|
|
|
|
interface = (PPCI_DEVICE_PRESENT_INTERFACE) InterfaceReturn;
|
|
|
|
interface->Version = PCI_DEVICE_PRESENT_INTERFACE_VERSION;
|
|
interface->InterfaceReference = PciRefDereferenceNoop;
|
|
interface->InterfaceDereference = PciRefDereferenceNoop;
|
|
interface->Context = DeviceExtension;
|
|
interface->IsDevicePresent = devpresent_IsDevicePresent;
|
|
|
|
//
|
|
// This interface has been extended from the base interface (what was
|
|
// filled in above), to a larger interface. If the buffer provided
|
|
// is large enough to hold the whole thing, fill in the rest. Otherwise
|
|
// don't.
|
|
//
|
|
if (Size >= sizeof(PCI_DEVICE_PRESENT_INTERFACE)) {
|
|
|
|
interface->IsDevicePresentEx = devpresent_IsDevicePresentEx;
|
|
interface->Size = sizeof(PCI_DEVICE_PRESENT_INTERFACE);
|
|
|
|
} else {
|
|
|
|
interface->Size = DEVPRESENT_MINSIZE;
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
devpresent_IsDevicePresent(
|
|
IN USHORT VendorID,
|
|
IN USHORT DeviceID,
|
|
IN UCHAR RevisionID,
|
|
IN USHORT SubVendorID,
|
|
IN USHORT SubSystemID,
|
|
IN ULONG Flags
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine searches the PCI device tree to see if the specific device
|
|
is present in the system. Not devices that are explicitly not enumerated
|
|
(such as PIIX4 power management function) are considered absent.
|
|
|
|
Arguments:
|
|
|
|
VendorID - Required VendorID of the device
|
|
|
|
DeviceID - Required DeviceID of the device
|
|
|
|
RevisionID - Optional Revision ID
|
|
|
|
SubVendorID - Optional Subsystem Vendor ID
|
|
|
|
SubSystemID - Optional Subsystem ID
|
|
|
|
Flags - Bitfield which indicates if Revision and Sub* ID's should be used:
|
|
|
|
PCI_USE_SUBSYSTEM_IDS, PCI_USE_REVISION_ID are valid all other bits
|
|
should be 0
|
|
|
|
|
|
Return Value:
|
|
|
|
TRUE if the device is present in the system, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
PCI_DEVICE_PRESENCE_PARAMETERS parameters;
|
|
|
|
parameters.Size = sizeof(PCI_DEVICE_PRESENCE_PARAMETERS);
|
|
parameters.VendorID = VendorID;
|
|
parameters.DeviceID = DeviceID;
|
|
parameters.RevisionID = RevisionID;
|
|
parameters.SubVendorID = SubVendorID;
|
|
parameters.SubSystemID = SubSystemID;
|
|
|
|
//
|
|
// Clear out flags that this version of the interface didn't use,
|
|
//
|
|
parameters.Flags = Flags & (PCI_USE_SUBSYSTEM_IDS | PCI_USE_REVISION);
|
|
|
|
//
|
|
// This original version of the interface required vendor/device ID
|
|
// matching. The new version doesn't, so set the flag indicating
|
|
// that we do in fact want to do a vendor/device ID match.
|
|
//
|
|
parameters.Flags |= PCI_USE_VENDEV_IDS;
|
|
|
|
return devpresent_IsDevicePresentEx(NULL,
|
|
¶meters
|
|
);
|
|
}
|
|
|
|
BOOLEAN
|
|
devpresent_IsDevicePresentEx(
|
|
IN PVOID Context,
|
|
IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine searches the PCI device tree to see if the specific device
|
|
is present in the system. Note devices that are explicitly not enumerated
|
|
(such as PIIX4 power management function) are considered absent.
|
|
|
|
Arguments:
|
|
|
|
Context - The device extension of the device requesting the search.
|
|
|
|
Parameters - Pointer to a structure containing the parameters of the device search,
|
|
including VendorID, SubSystemID and ClassCode, among others.
|
|
|
|
Return Value:
|
|
|
|
TRUE if the device is present in the system, FALSE otherwise.
|
|
|
|
--*/
|
|
{
|
|
PSINGLE_LIST_ENTRY nextEntry;
|
|
PPCI_FDO_EXTENSION fdoExtension;
|
|
PPCI_PDO_EXTENSION pdoExtension;
|
|
BOOLEAN found = FALSE;
|
|
ULONG flags;
|
|
|
|
PAGED_CODE();
|
|
|
|
//
|
|
// Validate the parameters.
|
|
//
|
|
|
|
if (!ARGUMENT_PRESENT(Parameters)) {
|
|
|
|
ASSERT(ARGUMENT_PRESENT(Parameters));
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Validate the size of the structure passed in.
|
|
//
|
|
if (Parameters->Size < sizeof(PCI_DEVICE_PRESENCE_PARAMETERS)) {
|
|
|
|
ASSERT(Parameters->Size >= sizeof(PCI_DEVICE_PRESENCE_PARAMETERS));
|
|
return FALSE;
|
|
}
|
|
|
|
flags = Parameters->Flags;
|
|
|
|
//
|
|
// We can either do a Vendor/Device ID match, or a Class/SubClass
|
|
// match. If neither of these flags are present, fail.
|
|
//
|
|
if (!(flags & (PCI_USE_VENDEV_IDS | PCI_USE_CLASS_SUBCLASS))) {
|
|
|
|
ASSERT(flags & (PCI_USE_VENDEV_IDS | PCI_USE_CLASS_SUBCLASS));
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// RevisionID, SubVendorID and SubSystemID are more precise flags.
|
|
// They are only valid if we're doing a Vendor/Device ID match.
|
|
//
|
|
if (flags & (PCI_USE_REVISION | PCI_USE_SUBSYSTEM_IDS)) {
|
|
|
|
if (!(flags & PCI_USE_VENDEV_IDS)) {
|
|
|
|
ASSERT(flags & PCI_USE_VENDEV_IDS);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Programming Interface is also a more precise flag.
|
|
// It is only valid if we're doing a class code match.
|
|
//
|
|
if (flags & PCI_USE_PROGIF) {
|
|
|
|
if (!(flags & PCI_USE_CLASS_SUBCLASS)) {
|
|
|
|
ASSERT(flags & PCI_USE_CLASS_SUBCLASS);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Okay, validation complete. Do the search.
|
|
//
|
|
ExAcquireFastMutex(&PciGlobalLock);
|
|
|
|
pdoExtension = (PPCI_PDO_EXTENSION)Context;
|
|
|
|
if (flags & (PCI_USE_LOCAL_BUS | PCI_USE_LOCAL_DEVICE)) {
|
|
|
|
//
|
|
// Limit the search to the same bus as the device that requested
|
|
// the search. This requires a pdoExtension representing the device
|
|
// requesting the search.
|
|
//
|
|
if (pdoExtension == NULL) {
|
|
|
|
ASSERT(pdoExtension != NULL);
|
|
goto cleanup;
|
|
}
|
|
|
|
fdoExtension = pdoExtension->ParentFdoExtension;
|
|
|
|
found = PcipDevicePresentOnBus(fdoExtension,
|
|
pdoExtension,
|
|
Parameters
|
|
);
|
|
} else {
|
|
|
|
//
|
|
// We have not been told to limit the search to
|
|
// the bus on which a particular device lives.
|
|
// Do a global search, iterating over all the buses.
|
|
//
|
|
for ( nextEntry = PciFdoExtensionListHead.Next;
|
|
nextEntry != NULL;
|
|
nextEntry = nextEntry->Next ) {
|
|
|
|
fdoExtension = CONTAINING_RECORD(nextEntry,
|
|
PCI_FDO_EXTENSION,
|
|
List
|
|
);
|
|
|
|
found = PcipDevicePresentOnBus(fdoExtension,
|
|
NULL,
|
|
Parameters
|
|
);
|
|
if (found) {
|
|
break;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
cleanup:
|
|
|
|
ExReleaseFastMutex(&PciGlobalLock);
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
BOOLEAN
|
|
PcipDevicePresentOnBus(
|
|
IN PPCI_FDO_EXTENSION FdoExtension,
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine searches the PCI device tree for a given device
|
|
on the bus represented by the given FdoExtension.
|
|
|
|
Arguments:
|
|
|
|
FdoExtension - A pointer to the device extension of a PCI FDO.
|
|
This represents the bus to be searched for the given device.
|
|
|
|
PdoExtension - A pointer to the device extension of the PCI PDO that requested
|
|
the search. Some device searches are limited to the same bus/device number
|
|
as the requesting device, and this is used to get those numbers.
|
|
|
|
Parameters - The parameters of the search.
|
|
|
|
Flags - A bitfield indicating which fields of the Parameters structure to use for the search.
|
|
|
|
Return Value:
|
|
|
|
TRUE if the requested device is found.
|
|
FALSE if it is not.
|
|
|
|
--*/
|
|
{
|
|
IN PPCI_PDO_EXTENSION currentPdo;
|
|
BOOLEAN found = FALSE;
|
|
ULONG flags = Parameters->Flags;
|
|
|
|
ExAcquireFastMutex(&FdoExtension->ChildListMutex);
|
|
|
|
for (currentPdo = FdoExtension->ChildPdoList;
|
|
currentPdo;
|
|
currentPdo = currentPdo->Next) {
|
|
|
|
//
|
|
// If we're limiting the search to devices with the same
|
|
// device number as the requesting device, make sure this
|
|
// current PDO qualifies.
|
|
//
|
|
if (PdoExtension && (flags & PCI_USE_LOCAL_DEVICE)) {
|
|
|
|
if (PdoExtension->Slot.u.bits.DeviceNumber !=
|
|
currentPdo->Slot.u.bits.DeviceNumber) {
|
|
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (flags & PCI_USE_VENDEV_IDS) {
|
|
|
|
if ((currentPdo->VendorId != Parameters->VendorID)
|
|
|| (currentPdo->DeviceId != Parameters->DeviceID)) {
|
|
|
|
continue;
|
|
}
|
|
|
|
if ((flags & PCI_USE_SUBSYSTEM_IDS)
|
|
&& ((currentPdo->SubsystemVendorId != Parameters->SubVendorID) ||
|
|
(currentPdo->SubsystemId != Parameters->SubSystemID))) {
|
|
|
|
continue;
|
|
}
|
|
|
|
if ((flags & PCI_USE_REVISION)
|
|
&& (currentPdo->RevisionId != Parameters->RevisionID)) {
|
|
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (flags & PCI_USE_CLASS_SUBCLASS) {
|
|
|
|
if ((currentPdo->BaseClass != Parameters->BaseClass) ||
|
|
(currentPdo->SubClass != Parameters->SubClass)) {
|
|
|
|
continue;
|
|
}
|
|
|
|
if ((flags & PCI_USE_PROGIF)
|
|
&& (currentPdo->ProgIf != Parameters->ProgIf)) {
|
|
|
|
continue;
|
|
}
|
|
}
|
|
|
|
found = TRUE;
|
|
break;
|
|
}
|
|
|
|
ExReleaseFastMutex(&FdoExtension->ChildListMutex);
|
|
|
|
return found;
|
|
}
|
|
|
|
#if DEVPRSNT_TESTING
|
|
|
|
NTSTATUS
|
|
PciRunDevicePresentInterfaceTest(
|
|
IN PPCI_PDO_EXTENSION PdoExtension
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
FdoExtension - this PCI bus's FDO extension
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
PCI_DEVICE_PRESENT_INTERFACE interface;
|
|
PDEVICE_OBJECT targetDevice = NULL;
|
|
KEVENT irpCompleted;
|
|
IO_STATUS_BLOCK statusBlock;
|
|
PIRP irp = NULL;
|
|
PIO_STACK_LOCATION irpStack;
|
|
USHORT interfaceSize;
|
|
ULONG pass;
|
|
PCI_DEVICE_PRESENCE_PARAMETERS parameters;
|
|
BOOLEAN result;
|
|
|
|
PAGED_CODE();
|
|
|
|
targetDevice = IoGetAttachedDeviceReference(PdoExtension->PhysicalDeviceObject);
|
|
|
|
for (pass = 0; pass < 2; pass++) {
|
|
|
|
if (pass == 0) {
|
|
|
|
//
|
|
// First pass test the old version.
|
|
//
|
|
interfaceSize = FIELD_OFFSET(PCI_DEVICE_PRESENT_INTERFACE, IsDevicePresentEx);
|
|
|
|
} else {
|
|
|
|
//
|
|
// Second pass test the full new version.
|
|
//
|
|
interfaceSize = sizeof(PCI_DEVICE_PRESENT_INTERFACE);
|
|
}
|
|
|
|
//
|
|
// Get an IRP
|
|
//
|
|
//
|
|
// Find out where we are sending the irp
|
|
//
|
|
|
|
|
|
KeInitializeEvent(&irpCompleted, SynchronizationEvent, FALSE);
|
|
|
|
irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
|
|
targetDevice,
|
|
NULL, // Buffer
|
|
0, // Length
|
|
0, // StartingOffset
|
|
&irpCompleted,
|
|
&statusBlock
|
|
);
|
|
if (!irp) {
|
|
status = STATUS_INSUFFICIENT_RESOURCES;
|
|
goto cleanup;
|
|
}
|
|
|
|
irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
|
|
irp->IoStatus.Information = 0;
|
|
|
|
//
|
|
// Initialize the stack location
|
|
//
|
|
|
|
irpStack = IoGetNextIrpStackLocation(irp);
|
|
|
|
PCI_ASSERT(irpStack->MajorFunction == IRP_MJ_PNP);
|
|
|
|
irpStack->MinorFunction = IRP_MN_QUERY_INTERFACE;
|
|
|
|
irpStack->Parameters.QueryInterface.InterfaceType = (PGUID) &GUID_PCI_DEVICE_PRESENT_INTERFACE;
|
|
irpStack->Parameters.QueryInterface.Version = PCI_DEVICE_PRESENT_INTERFACE_VERSION;
|
|
irpStack->Parameters.QueryInterface.Size = interfaceSize;
|
|
irpStack->Parameters.QueryInterface.Interface = (PINTERFACE)&interface;
|
|
irpStack->Parameters.QueryInterface.InterfaceSpecificData = NULL;
|
|
|
|
//
|
|
// Call the driver and wait for completion
|
|
//
|
|
|
|
status = IoCallDriver(targetDevice, irp);
|
|
|
|
if (status == STATUS_PENDING) {
|
|
|
|
KeWaitForSingleObject(&irpCompleted, Executive, KernelMode, FALSE, NULL);
|
|
status = statusBlock.Status;
|
|
}
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
|
|
PciDebugPrintf("Couldn't successfully retrieve interface\n");
|
|
goto cleanup;
|
|
}
|
|
|
|
PciDebugPrintf("Testing PCI Device Presence Interface\n");
|
|
if (pass==0) {
|
|
PciDebugPrintf("Original Version\n");
|
|
} else {
|
|
PciDebugPrintf("New Version\n");
|
|
}
|
|
|
|
PciDebugPrintf("Interface values:\n");
|
|
PciDebugPrintf("\tSize=%d\n",interface.Size);
|
|
PciDebugPrintf("\tVersion=%d\n",interface.Version);
|
|
PciDebugPrintf("\tContext=%d\n",interface.Context);
|
|
PciDebugPrintf("\tInterfaceReference=%d\n",interface.InterfaceReference);
|
|
PciDebugPrintf("\tInterfaceDereference=%d\n",interface.InterfaceDereference);
|
|
PciDebugPrintf("\tIsDevicePresent=%d\n",interface.IsDevicePresent);
|
|
PciDebugPrintf("\tIsDevicePresentEx=%d\n",interface.IsDevicePresentEx);
|
|
|
|
PciDebugPrintf("Testing IsDevicePresent function\n");
|
|
PciDebugPrintf("\tTesting 8086:7190.03 0000:0000 No flags Should be TRUE, is ");
|
|
result = interface.IsDevicePresent(0x8086,0x7190,3,0,0,0);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:7190.03 0000:0000 PCI_USE_REVISION Should be TRUE, is ");
|
|
result = interface.IsDevicePresent(0x8086,0x7190,3,0,0,PCI_USE_REVISION);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:7190.01 0000:0000 PCI_USE_REVISION Should be FALSE, is ");
|
|
result = interface.IsDevicePresent(0x8086,0x7190,1,0,0,PCI_USE_REVISION);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:1229.05 8086:0009 PCI_USE_SUBSYSTEM_IDS Should be TRUE, is ");
|
|
result = interface.IsDevicePresent(0x8086,0x1229,5,0x8086,9,PCI_USE_SUBSYSTEM_IDS);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:1229.05 8086:0009 PCI_USE_SUBSYSTEM_IDS|PCI_USE_REVISION Should be TRUE, is ");
|
|
result = interface.IsDevicePresent(0x8086,0x1229,5,0x8086,9,PCI_USE_SUBSYSTEM_IDS|PCI_USE_REVISION);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:1229.05 8086:0004 PCI_USE_SUBSYSTEM_IDS Should be FALSE, is ");
|
|
result = interface.IsDevicePresent(0x8086,0x1229,5,0x8086,4,PCI_USE_SUBSYSTEM_IDS);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:1229.05 8084:0009 PCI_USE_SUBSYSTEM_IDS|PCI_USE_REVISION Should be FALSE, is ");
|
|
result = interface.IsDevicePresent(0x8086,0x1229,5,0x8084,9,PCI_USE_SUBSYSTEM_IDS|PCI_USE_REVISION);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 0000:0000.00 0000:0000 No flags Should ASSERT and be FALSE, is ");
|
|
result = interface.IsDevicePresent(0,0,0,0,0,0);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 0000:0000.00 0000:0000 PCI_USE_SUBSYSTEM_IDS Should ASSERT and be FALSE, is ");
|
|
result = interface.IsDevicePresent(0,0,0,0,0,PCI_USE_SUBSYSTEM_IDS);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
if (pass == 1) {
|
|
|
|
PciDebugPrintf("Testing IsDevicePresentEx function\n");
|
|
PciDebugPrintf("Running the same tests as IsDevicePresent, but using new function\n");
|
|
|
|
PciDebugPrintf("\tTesting 8086:7190.03 0000:0000 PCI_USE_VENDEV_IDS Should be TRUE, is ");
|
|
parameters.Size = sizeof(PCI_DEVICE_PRESENCE_PARAMETERS);
|
|
parameters.Flags = PCI_USE_VENDEV_IDS;
|
|
parameters.VendorID = 0x8086;
|
|
parameters.DeviceID = 0x7190;
|
|
parameters.RevisionID = 3;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:7190.03 0000:0000 PCI_USE_REVISION Should be TRUE, is ");
|
|
parameters.Flags |= PCI_USE_REVISION;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:7190.01 0000:0000 PCI_USE_REVISION Should be FALSE, is ");
|
|
parameters.RevisionID = 1;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:1229.05 8086:0009 PCI_USE_SUBSYSTEM_IDS Should be TRUE, is ");
|
|
parameters.DeviceID = 0x1229;
|
|
parameters.RevisionID = 5;
|
|
parameters.SubVendorID = 0x8086;
|
|
parameters.SubSystemID = 9;
|
|
parameters.Flags = PCI_USE_VENDEV_IDS | PCI_USE_SUBSYSTEM_IDS;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:1229.05 8086:0009 PCI_USE_SUBSYSTEM_IDS|PCI_USE_REVISION Should be TRUE, is ");
|
|
parameters.Flags |= PCI_USE_REVISION;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:1229.05 8086:0004 PCI_USE_SUBSYSTEM_IDS Should be FALSE, is ");
|
|
parameters.Flags &= ~PCI_USE_REVISION;
|
|
parameters.SubSystemID = 4;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:1229.05 8084:0009 PCI_USE_SUBSYSTEM_IDS|PCI_USE_REVISION Should be FALSE, is ");
|
|
parameters.SubVendorID = 0x8084;
|
|
parameters.SubSystemID = 9;
|
|
parameters.Flags |= PCI_USE_SUBSYSTEM_IDS;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:1229.05 8084:0009 No flags Should ASSERT and be FALSE, is ");
|
|
parameters.Flags = 0;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:1229.05 8084:0009 PCI_USE_VENDEV_IDS bad Size Should ASSERT and be FALSE, is ");
|
|
parameters.SubVendorID = 0x8086;
|
|
parameters.SubSystemID = 9;
|
|
parameters.Flags = PCI_USE_VENDEV_IDS;
|
|
parameters.Size = 3;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 0000:0000.00 0000:0000 No flags Should ASSERT and be FALSE, is ");
|
|
RtlZeroMemory(¶meters, sizeof(PCI_DEVICE_PRESENCE_PARAMETERS));
|
|
parameters.Size = sizeof(PCI_DEVICE_PRESENCE_PARAMETERS);
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("Running tests on new flags\n");
|
|
PciDebugPrintf("\tTesting Class USB Controller PCI_USE_CLASS_SUBCLASS Should be TRUE, is ");
|
|
parameters.Flags = PCI_USE_CLASS_SUBCLASS;
|
|
parameters.BaseClass = PCI_CLASS_SERIAL_BUS_CTLR;
|
|
parameters.SubClass = PCI_SUBCLASS_SB_USB;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting Class USB Controller (UHCI) PCI_USE_CLASS_SUBCLASS|PCI_USE_PROGIF Should be TRUE, is ");
|
|
parameters.Flags = PCI_USE_CLASS_SUBCLASS|PCI_USE_PROGIF;
|
|
parameters.ProgIf = 0;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting Class USB Controller (OHCI) PCI_USE_CLASS_SUBCLASS|PCI_USE_PROGIF Should be FALSE, is ");
|
|
parameters.ProgIf = 0x10;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting Class Wireless RF PCI_USE_CLASS_SUBCLASS Should be FALSE, is ");
|
|
parameters.BaseClass = PCI_CLASS_WIRELESS_CTLR;
|
|
parameters.SubClass = PCI_SUBCLASS_WIRELESS_RF;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:7112 Class USB Controller PCI_USE_VENDEV|PCI_USE_CLASS_SUBCLASS Should be TRUE, is ");
|
|
parameters.VendorID = 0x8086;
|
|
parameters.DeviceID = 0x7112;
|
|
parameters.BaseClass = PCI_CLASS_SERIAL_BUS_CTLR;
|
|
parameters.SubClass = PCI_SUBCLASS_SB_USB;
|
|
parameters.Flags = PCI_USE_VENDEV_IDS|PCI_USE_CLASS_SUBCLASS;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:7112 Class USB Controller PCI_USE_VENDEV|PCI_USE_CLASS_SUBCLASS|PCI_USE_LOCAL_BUS Should be TRUE, is ");
|
|
parameters.VendorID = 0x8086;
|
|
parameters.DeviceID = 0x7112;
|
|
parameters.BaseClass = PCI_CLASS_SERIAL_BUS_CTLR;
|
|
parameters.SubClass = PCI_SUBCLASS_SB_USB;
|
|
parameters.Flags = PCI_USE_VENDEV_IDS|PCI_USE_CLASS_SUBCLASS|PCI_USE_LOCAL_BUS;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:7112 Class USB Controller PCI_USE_VENDEV|PCI_USE_CLASS_SUBCLASS|PCI_USE_LOCAL_DEVICE Should be ?, is ");
|
|
parameters.VendorID = 0x8086;
|
|
parameters.DeviceID = 0x7112;
|
|
parameters.BaseClass = PCI_CLASS_SERIAL_BUS_CTLR;
|
|
parameters.SubClass = PCI_SUBCLASS_SB_USB;
|
|
parameters.Flags = PCI_USE_VENDEV_IDS|PCI_USE_CLASS_SUBCLASS|PCI_USE_LOCAL_DEVICE;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:7112 Class USB Controller PCI_USE_VENDEV|PCI_USE_CLASS_SUBCLASS|PCI_USE_LOCAL_BUS|PCI_USE_LOCAL_DEVICE Should be ?, is ");
|
|
parameters.VendorID = 0x8086;
|
|
parameters.DeviceID = 0x7112;
|
|
parameters.BaseClass = PCI_CLASS_SERIAL_BUS_CTLR;
|
|
parameters.SubClass = PCI_SUBCLASS_SB_USB;
|
|
parameters.Flags = PCI_USE_VENDEV_IDS|PCI_USE_CLASS_SUBCLASS|PCI_USE_LOCAL_DEVICE|PCI_USE_LOCAL_BUS;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:7190 PCI_USE_VENDEV|PCI_USE_LOCAL_DEVICE Should be FALSE, is ");
|
|
parameters.VendorID = 0x8086;
|
|
parameters.DeviceID = 0x7190;
|
|
parameters.Flags = PCI_USE_VENDEV_IDS|PCI_USE_LOCAL_DEVICE;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
PciDebugPrintf("\tTesting 8086:7190 PCI_USE_VENDEV|PCI_USE_LOCAL_BUS Should be TRUE, is ");
|
|
parameters.VendorID = 0x8086;
|
|
parameters.DeviceID = 0x7190;
|
|
parameters.Flags = PCI_USE_VENDEV_IDS|PCI_USE_LOCAL_BUS;
|
|
result = interface.IsDevicePresentEx(interface.Context,¶meters);
|
|
if (result) {
|
|
PciDebugPrintf("TRUE\n");
|
|
} else {
|
|
PciDebugPrintf("FALSE\n");
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
//
|
|
// Ok we're done with this stack
|
|
//
|
|
|
|
ObDereferenceObject(targetDevice);
|
|
|
|
return status;
|
|
|
|
cleanup:
|
|
|
|
if (targetDevice) {
|
|
ObDereferenceObject(targetDevice);
|
|
}
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
#endif
|