You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2406 lines
60 KiB
2406 lines
60 KiB
/*++
|
|
|
|
Copyright (c) 1996-2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
pcip.h
|
|
|
|
Abstract:
|
|
|
|
This module contains local definitions for PCI.SYS.
|
|
|
|
Author:
|
|
|
|
Andrew Thornton (andrewth) 25-Jan-2000
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#if !defined(_PCIP_H)
|
|
#define _PCIP_H
|
|
|
|
//
|
|
// Disable warnings of features used by the standard headers
|
|
//
|
|
// Disable warning C4214: nonstandard extension used : bit field types other than int
|
|
// Disable warning C4201: nonstandard extension used : nameless struct/union
|
|
// Disable warning C4115: named type definition in parentheses
|
|
// Disable warning C4127: conditional expression is constant
|
|
//
|
|
|
|
#pragma warning(disable:4214 4201 4115 4127)
|
|
|
|
#define _NTDRIVER_
|
|
#define _NTSRV_
|
|
#define _NTDDK_
|
|
|
|
#define InitSafeBootMode TempInitSafeBootMode
|
|
#include "ntos.h"
|
|
#undef InitSafeBootMode
|
|
|
|
#include "strsafe.h"
|
|
#include "pci.h"
|
|
#include "wdmguid.h"
|
|
#include "zwapi.h"
|
|
#include "pciirqmp.h"
|
|
#include "arbiter.h"
|
|
#include "acpiioct.h"
|
|
#include "pciintrf.h"
|
|
#include "pcicodes.h"
|
|
#include "pciverifier.h"
|
|
#include "acpitabl.h"
|
|
|
|
//
|
|
// regstr.h uses things of type WORD, which isn't around in kernel mode.
|
|
//
|
|
|
|
#define _IN_KERNEL_
|
|
#include "regstr.h"
|
|
|
|
//
|
|
// Pragmas to disable /W4 warnings so PCI can be compiled /W4
|
|
//
|
|
// Disable warning C4057; X differs in indirection to slightly different base types from Y
|
|
// Disable warning C4244; '+='/'-=' : conversion from 'int' to 'X', possible loss of data
|
|
// Disable warning C4100: 'X' : unreferenced formal parameter
|
|
#pragma warning(disable: 4057 4244 4100)
|
|
|
|
//
|
|
// It seems that anything to do with the definitions of GUIDs is
|
|
// bogus.
|
|
//
|
|
|
|
typedef const GUID * PGUID;
|
|
|
|
#define PciCompareGuid(a,b) \
|
|
(RtlEqualMemory((PVOID)(a), (PVOID)(b), sizeof(GUID)))
|
|
|
|
//
|
|
// Internal constants.
|
|
//
|
|
|
|
#define PCI_CM_RESOURCE_VERSION 1
|
|
#define PCI_CM_RESOURCE_REVISION 1
|
|
#define PCI_MAX_CONFIG_TYPE (PCI_CARDBUS_BRIDGE_TYPE)
|
|
|
|
//
|
|
// Internal bug codes.
|
|
//
|
|
|
|
#define PCI_BUGCODE_TOO_MANY_CONFIG_GUESSES 0xdead0010
|
|
|
|
//
|
|
// Internal Controls
|
|
//
|
|
|
|
#define PCI_BOOT_CONFIG_PREFERRED 1
|
|
#define PCIIDE_HACKS 1
|
|
#define PCI_NT50_BETA1_HACKS 1
|
|
#define PCI_DISABLE_LAST_CHANCE_INTERFACES 1
|
|
#define MSI_SUPPORTED 0
|
|
#define PCI_NO_MOVE_MODEM_IN_TOSHIBA 1
|
|
|
|
//
|
|
// Systemwide hack flags. These flags are a bitmask that can be set to zero so
|
|
// as to eliminate support for the hack.
|
|
//
|
|
#define PCIFLAG_IGNORE_PREFETCHABLE_MEMORY_AT_ROOT_HACK 0x00000001
|
|
|
|
//
|
|
// Video Hacks
|
|
//
|
|
|
|
#define PCI_S3_HACKS 1
|
|
#define PCI_CIRRUS_54XX_HACK 1
|
|
|
|
|
|
#define PCI_IS_ATI_M1(_PdoExtension) \
|
|
((_PdoExtension)->VendorId == 0x1002 \
|
|
&& ((_PdoExtension)->DeviceId == 0x4C42 \
|
|
|| (_PdoExtension)->DeviceId == 0x4C44 \
|
|
|| (_PdoExtension)->DeviceId == 0x4C49 \
|
|
|| (_PdoExtension)->DeviceId == 0x4C4D \
|
|
|| (_PdoExtension)->DeviceId == 0x4C4E \
|
|
|| (_PdoExtension)->DeviceId == 0x4C50 \
|
|
|| (_PdoExtension)->DeviceId == 0x4C51 \
|
|
|| (_PdoExtension)->DeviceId == 0x4C52 \
|
|
|| (_PdoExtension)->DeviceId == 0x4C53))
|
|
|
|
#define INTEL_ICH_HACKS 1
|
|
|
|
#if INTEL_ICH_HACKS
|
|
|
|
#define PCI_IS_INTEL_ICH(_PdoExtension) \
|
|
((_PdoExtension)->VendorId == 0x8086 \
|
|
&& ((_PdoExtension)->DeviceId == 0x2418 \
|
|
|| (_PdoExtension)->DeviceId == 0x2428 \
|
|
|| (_PdoExtension)->DeviceId == 0x244E \
|
|
|| (_PdoExtension)->DeviceId == 0x2448))
|
|
|
|
#else
|
|
|
|
#define PCI_IS_INTEL_ICH(_PdoExtension) FALSE
|
|
|
|
#endif
|
|
|
|
//
|
|
// Translatable resources
|
|
//
|
|
|
|
#define ADDRESS_SPACE_MEMORY 0x0
|
|
#define ADDRESS_SPACE_PORT 0x1
|
|
#define ADDRESS_SPACE_USER_MEMORY 0x2
|
|
#define ADDRESS_SPACE_USER_PORT 0x3
|
|
#define ADDRESS_SPACE_DENSE_MEMORY 0x4
|
|
#define ADDRESS_SPACE_USER_DENSE_MEMORY 0x6
|
|
|
|
//
|
|
// Add our tag signature
|
|
//
|
|
|
|
#ifdef ExAllocatePool
|
|
|
|
#undef ExAllocatePool
|
|
|
|
#endif
|
|
|
|
#define ExAllocatePool( t, s ) ExAllocatePoolWithTag( (t), (s), 'BicP' )
|
|
|
|
//
|
|
// Lock and Unlock
|
|
//
|
|
|
|
typedef struct _PCI_LOCK {
|
|
KSPIN_LOCK Atom;
|
|
KIRQL OldIrql;
|
|
|
|
#if DBG
|
|
|
|
PUCHAR File;
|
|
ULONG Line;
|
|
|
|
#endif
|
|
|
|
} PCI_LOCK, *PPCI_LOCK;
|
|
|
|
#if DBG
|
|
|
|
#define PCI_LOCK_OBJECT(x) \
|
|
(x)->Lock.File = __FILE__, \
|
|
(x)->Lock.Line = __LINE__, \
|
|
KeAcquireSpinLock(&(x)->Lock.Atom, &(x)->Lock.OldIrql)
|
|
|
|
#else
|
|
|
|
#define PCI_LOCK_OBJECT(x) \
|
|
KeAcquireSpinLock(&(x)->Lock.Atom, &(x)->Lock.OldIrql)
|
|
|
|
#endif
|
|
#define PCI_UNLOCK_OBJECT(x) \
|
|
KeReleaseSpinLock(&(x)->Lock.Atom, (x)->Lock.OldIrql)
|
|
|
|
|
|
|
|
#define PciAcquireGlobalLock() \
|
|
ExAcquireFastMutex(&PciGlobalLock)
|
|
|
|
#define PciReleaseGlobalLock() \
|
|
ExReleaseFastMutex(&PciGlobalLock)
|
|
|
|
|
|
//
|
|
// PCM_PARTIAL_RESOURCE_DESCRIPTOR
|
|
// PciFirstCmResource(
|
|
// PCM_RESOURCE_LIST List
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// Returns the address of the first CM PARTIAL RESOURCE DESCRIPTOR
|
|
// in the given CM RESOURCE LIST.
|
|
//
|
|
|
|
#define PciFirstCmResource(x) \
|
|
(x)->List[0].PartialResourceList.PartialDescriptors
|
|
|
|
|
|
//
|
|
// ULONG
|
|
// PciGetConfigurationType(
|
|
// PPCI_COMMON_CONFIG x
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// Returns the configuration type subfield from the HeaderType
|
|
// field in PCI Configuration Space.
|
|
//
|
|
|
|
#define PciGetConfigurationType(x) PCI_CONFIGURATION_TYPE(x)
|
|
|
|
//
|
|
// PPCI_FDO_EXTENSION
|
|
// PCI_PARENT_FDO(
|
|
// PPCI_PDO_EXTENSION x
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// Returns a pointer to the FDO extension that created PDO x as a result
|
|
// of enumeration. That is, the FDO extension of the bus that owns this
|
|
// device.
|
|
//
|
|
|
|
#define PCI_PARENT_FDOX(x) ((x)->ParentFdoExtension)
|
|
|
|
|
|
//
|
|
// PPCI_FDO_EXTENSION
|
|
// PCI_ROOT_FDOX(
|
|
// PPCI_PDO_EXTENSION x
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// Returns a pointer to the FDO extension for the root bus (CPU-PCI Bridge)
|
|
// that this device is situated under.
|
|
//
|
|
|
|
#define PCI_ROOT_FDOX(x) ((x)->ParentFdoExtension->BusRootFdoExtension)
|
|
|
|
|
|
//
|
|
// PDEVICE_OBJECT
|
|
// PCI_PARENT_PDO(
|
|
// PPCI_PDO_EXTENSION x
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// Returns a pointer to the PDO for the parent bus.
|
|
//
|
|
|
|
#define PCI_PARENT_PDO(x) ((x)->ParentFdoExtension->PhysicalDeviceObject)
|
|
|
|
//
|
|
// PPCI_PDO_EXTENSION
|
|
// PCI_BRIDGE_PDO(
|
|
// PPCI_FDO_EXTENSION x
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// Returns a pointer to the PDO for the bridge given its FDO
|
|
//
|
|
|
|
#define PCI_BRIDGE_PDO(x) ((PPCI_PDO_EXTENSION)((x)->PhysicalDeviceObject->DeviceExtension))
|
|
|
|
|
|
|
|
//
|
|
// PPCI_FDO_EXTENSION
|
|
// PCI_BRIDGE_FDO(
|
|
// PPCI_PDO_EXTENSION x
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// Returns a pointer to the FDO for the bridge given its PDO
|
|
//
|
|
|
|
#define PCI_BRIDGE_FDO(x) ((PPCI_FDO_EXTENSION)((x)->BridgeFdoExtension))
|
|
|
|
//
|
|
// BOOLEAN
|
|
// PCI_IS_ROOT_FDO(
|
|
// PPCI_FDO_EXTENSION x
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// Returns TRUE if x is an FDO for a PCI ROOT bus.
|
|
//
|
|
|
|
#define PCI_IS_ROOT_FDO(x) ((BOOLEAN)((x) == (x)->BusRootFdoExtension))
|
|
|
|
//
|
|
// BOOLEAN
|
|
// PCI_PDO_ON_ROOT(
|
|
// PPCI_PDO_EXTENSION x
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
|
|
#define PCI_PDO_ON_ROOT(x) ((BOOLEAN)PCI_IS_ROOT_FDO(PCI_PARENT_FDOX(x)))
|
|
|
|
//
|
|
// UCHAR
|
|
// PCI_DEVFUNC(
|
|
// PPCI_PDO_EXTENSION x
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// Returns the 5 bit device number and 3 bit function number for this
|
|
// device as a single 8 bit quantity.
|
|
//
|
|
|
|
#define PCI_DEVFUNC(x) (((x)->Slot.u.bits.DeviceNumber << 3) | \
|
|
(x)->Slot.u.bits.FunctionNumber)
|
|
|
|
//
|
|
//
|
|
// VOID
|
|
// PciConstStringToUnicodeString(
|
|
// OUT PUNICODE_STRING u,
|
|
// IN PCWSTR p
|
|
// )
|
|
//
|
|
//
|
|
#define PciConstStringToUnicodeString(u, p) \
|
|
(u)->Length = ((u)->MaximumLength = sizeof((p))) - sizeof(WCHAR); \
|
|
(u)->Buffer = (p)
|
|
|
|
//
|
|
// Name of the volative key under the DeviceParameters key where data that needs
|
|
// to be persistent accross removes, but NOT reboots is stored
|
|
//
|
|
#define BIOS_CONFIG_KEY_NAME L"BiosConfig"
|
|
|
|
|
|
//
|
|
// Assert this is a device object created by PCI
|
|
//
|
|
|
|
#define ASSERT_PCI_DEVICE_OBJECT(_DeviceObject) \
|
|
PCI_ASSERT((_DeviceObject)->DriverObject == PciDriverObject)
|
|
|
|
#define ASSERT_MUTEX_HELD(x)
|
|
|
|
//
|
|
// IRPs can be handled the following ways
|
|
//
|
|
typedef enum _PCI_DISPATCH_STYLE {
|
|
|
|
IRP_COMPLETE, // Complete IRP, adjust status as neccessary
|
|
IRP_DOWNWARD, // Dispatch on the way down, adjust status as neccessary
|
|
IRP_UPWARD, // Dispatch on the way up, adjust status as neccessary
|
|
IRP_DISPATCH // Dispatch downward, don't touch afterwards
|
|
} PCI_DISPATCH_STYLE;
|
|
|
|
//
|
|
// The following routines are dispatched to depending on header type.
|
|
//
|
|
|
|
typedef
|
|
VOID
|
|
(*PMASSAGEHEADERFORLIMITSDETERMINATION)(
|
|
IN struct _PCI_CONFIGURABLE_OBJECT *This
|
|
);
|
|
|
|
typedef
|
|
VOID
|
|
(*PSAVELIMITS)(
|
|
IN struct _PCI_CONFIGURABLE_OBJECT *This
|
|
);
|
|
|
|
typedef
|
|
VOID
|
|
(*PSAVECURRENTSETTINGS)(
|
|
IN struct _PCI_CONFIGURABLE_OBJECT *This
|
|
);
|
|
|
|
typedef
|
|
VOID
|
|
(*PRESTORECURRENT)(
|
|
IN struct _PCI_CONFIGURABLE_OBJECT *This
|
|
);
|
|
|
|
typedef
|
|
VOID
|
|
(*PCHANGERESOURCESETTINGS)(
|
|
IN struct _PCI_PDO_EXTENSION * PdoExtension,
|
|
IN PPCI_COMMON_CONFIG CommonConfig
|
|
);
|
|
|
|
typedef
|
|
VOID
|
|
(*PGETADDITIONALRESOURCEDESCRIPTORS)(
|
|
IN struct _PCI_PDO_EXTENSION * PdoExtension,
|
|
IN PPCI_COMMON_CONFIG CommonConfig,
|
|
IN PIO_RESOURCE_DESCRIPTOR Resource
|
|
);
|
|
|
|
typedef
|
|
NTSTATUS
|
|
(*PRESETDEVICE)(
|
|
IN struct _PCI_PDO_EXTENSION * PdoExtension,
|
|
IN PPCI_COMMON_CONFIG CommonConfig
|
|
);
|
|
|
|
typedef struct {
|
|
PMASSAGEHEADERFORLIMITSDETERMINATION MassageHeaderForLimitsDetermination;
|
|
PRESTORECURRENT RestoreCurrent;
|
|
PSAVELIMITS SaveLimits;
|
|
PSAVECURRENTSETTINGS SaveCurrentSettings;
|
|
PCHANGERESOURCESETTINGS ChangeResourceSettings;
|
|
PGETADDITIONALRESOURCEDESCRIPTORS GetAdditionalResourceDescriptors;
|
|
PRESETDEVICE ResetDevice;
|
|
} PCI_CONFIGURATOR, *PPCI_CONFIGURATOR;
|
|
|
|
//
|
|
// Internal structure definitions follow
|
|
//
|
|
|
|
|
|
typedef enum {
|
|
PciBridgeIo = 0x10,
|
|
PciBridgeMem,
|
|
PciBridgePrefetch,
|
|
PciBridgeMaxPassThru
|
|
} PCI_BRIDGE_PASSTHRU;
|
|
|
|
typedef enum {
|
|
|
|
//
|
|
// Device Object Extension Types
|
|
//
|
|
|
|
PciPdoExtensionType = 'icP0',
|
|
PciFdoExtensionType,
|
|
|
|
//
|
|
// Arbitration Types. (These are also secondary extensions).
|
|
//
|
|
|
|
PciArb_Io,
|
|
PciArb_Memory,
|
|
PciArb_Interrupt,
|
|
PciArb_BusNumber,
|
|
|
|
//
|
|
// Translation Types. (These are also secondary extensions).
|
|
//
|
|
|
|
PciTrans_Interrupt,
|
|
|
|
//
|
|
// Other exposed interfaces.
|
|
//
|
|
|
|
PciInterface_BusHandler,
|
|
PciInterface_IntRouteHandler,
|
|
PciInterface_PciCb,
|
|
PciInterface_LegacyDeviceDetection,
|
|
PciInterface_PmeHandler,
|
|
PciInterface_DevicePresent,
|
|
PciInterface_NativeIde,
|
|
PciInterface_Location,
|
|
PciInterface_AgpTarget
|
|
|
|
} PCI_SIGNATURE;
|
|
|
|
#define PCI_EXTENSIONTYPE_FDO PciFdoExtensionType
|
|
#define PCI_EXTENSIONTYPE_PDO PciPdoExtensionType
|
|
|
|
typedef enum {
|
|
PciTypeUnknown,
|
|
PciTypeHostBridge,
|
|
PciTypePciBridge,
|
|
PciTypeCardbusBridge,
|
|
PciTypeDevice
|
|
} PCI_OBJECT_TYPE;
|
|
|
|
typedef enum {
|
|
PciPrivateUndefined,
|
|
PciPrivateBar,
|
|
PciPrivateIsaBar,
|
|
PciPrivateSkipList
|
|
} PCI_PRIVATE_RESOURCE_TYPES;
|
|
|
|
typedef
|
|
VOID
|
|
(*PSECONDARYEXTENSIONDESTRUCTOR)(
|
|
IN PVOID Extension
|
|
);
|
|
|
|
typedef struct {
|
|
SINGLE_LIST_ENTRY List;
|
|
PCI_SIGNATURE ExtensionType;
|
|
PSECONDARYEXTENSIONDESTRUCTOR Destructor;
|
|
} PCI_SECONDARY_EXTENSION, *PPCI_SECONDARY_EXTENSION;
|
|
|
|
//
|
|
// Define a structure to contain current and limit settings
|
|
// for any (currently defined) PCI header type.
|
|
//
|
|
// Currently type 0 defines the greatest number of possible
|
|
// resources but we shall do it programmatically anyway.
|
|
//
|
|
// Type 0 and type 1 also have a ROM base address, additionally,
|
|
// type 1 has three ranges that aren't included in its address
|
|
// count but should be.
|
|
//
|
|
|
|
#define PCI_TYPE0_RANGE_COUNT ((PCI_TYPE0_ADDRESSES) + 1)
|
|
#define PCI_TYPE1_RANGE_COUNT ((PCI_TYPE1_ADDRESSES) + 4)
|
|
#define PCI_TYPE2_RANGE_COUNT ((PCI_TYPE2_ADDRESSES) + 1)
|
|
|
|
#if PCI_TYPE0_RANGE_COUNT > PCI_TYPE1_RANGE_COUNT
|
|
|
|
#if PCI_TYPE0_RANGE_COUNT > PCI_TYPE2_RANGE_COUNT
|
|
|
|
#define PCI_MAX_RANGE_COUNT PCI_TYPE0_RANGE_COUNT
|
|
|
|
#else
|
|
|
|
#define PCI_MAX_RANGE_COUNT PCI_TYPE2_RANGE_COUNT
|
|
|
|
#endif
|
|
|
|
#else
|
|
|
|
#if PCI_TYPE1_RANGE_COUNT > PCI_TYPE2_RANGE_COUNT
|
|
|
|
#define PCI_MAX_RANGE_COUNT PCI_TYPE1_RANGE_COUNT
|
|
|
|
#else
|
|
|
|
#define PCI_MAX_RANGE_COUNT PCI_TYPE2_RANGE_COUNT
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
typedef union {
|
|
struct {
|
|
UCHAR Spare[4];
|
|
} type0;
|
|
|
|
struct {
|
|
UCHAR PrimaryBus;
|
|
UCHAR SecondaryBus;
|
|
UCHAR SubordinateBus;
|
|
BOOLEAN SubtractiveDecode:1;
|
|
BOOLEAN IsaBitSet:1;
|
|
BOOLEAN VgaBitSet:1;
|
|
BOOLEAN WeChangedBusNumbers:1;
|
|
BOOLEAN IsaBitRequired:1;
|
|
} type1;
|
|
|
|
struct {
|
|
UCHAR PrimaryBus;
|
|
UCHAR SecondaryBus;
|
|
UCHAR SubordinateBus;
|
|
BOOLEAN SubtractiveDecode:1;
|
|
BOOLEAN IsaBitSet:1;
|
|
BOOLEAN VgaBitSet:1;
|
|
BOOLEAN WeChangedBusNumbers:1;
|
|
BOOLEAN IsaBitRequired:1;
|
|
} type2;
|
|
|
|
} PCI_HEADER_TYPE_DEPENDENT;
|
|
|
|
typedef struct {
|
|
IO_RESOURCE_DESCRIPTOR Limit[PCI_MAX_RANGE_COUNT];
|
|
CM_PARTIAL_RESOURCE_DESCRIPTOR Current[PCI_MAX_RANGE_COUNT];
|
|
} PCI_FUNCTION_RESOURCES, *PPCI_FUNCTION_RESOURCES;
|
|
|
|
//
|
|
// Indices for the PCI_FUNCTION_RESOURCES arrays for different header types
|
|
//
|
|
|
|
#define PCI_DEVICE_BAR_0 0
|
|
#define PCI_DEVICE_BAR_1 1
|
|
#define PCI_DEVICE_BAR_2 2
|
|
#define PCI_DEVICE_BAR_3 3
|
|
#define PCI_DEVICE_BAR_4 4
|
|
#define PCI_DEVICE_BAR_5 5
|
|
#define PCI_DEVICE_BAR_ROM 6
|
|
|
|
#define PCI_BRIDGE_BAR_0 0
|
|
#define PCI_BRIDGE_BAR_1 1
|
|
#define PCI_BRIDGE_IO_WINDOW 2
|
|
#define PCI_BRIDGE_MEMORY_WINDOW 3
|
|
#define PCI_BRIDGE_PREFETCH_WINDOW 4
|
|
#define PCI_BRIDGE_BAR_ROM 5
|
|
|
|
#define PCI_CARDBUS_SOCKET_BAR 0
|
|
#define PCI_CARDBUS_MEMORY_WINDOW_0 1
|
|
#define PCI_CARDBUS_MEMORY_WINDOW_1 2
|
|
#define PCI_CARDBUS_IO_WINDOW_0 3
|
|
#define PCI_CARDBUS_IO_WINDOW_1 4
|
|
#define PCI_CARDBUS_LEGACY_BAR 5 // Not used
|
|
|
|
|
|
|
|
typedef struct {
|
|
ULONGLONG Total;
|
|
ULONG Alignment;
|
|
} PCI_RESOURCE_ACCUMULATOR, *PPCI_RESOURCE_ACCUMULATOR;
|
|
|
|
typedef struct {
|
|
|
|
SYSTEM_POWER_STATE CurrentSystemState;
|
|
DEVICE_POWER_STATE CurrentDeviceState;
|
|
SYSTEM_POWER_STATE SystemWakeLevel;
|
|
DEVICE_POWER_STATE DeviceWakeLevel;
|
|
DEVICE_POWER_STATE SystemStateMapping[PowerSystemMaximum];
|
|
|
|
PIRP WaitWakeIrp;
|
|
PDRIVER_CANCEL SavedCancelRoutine;
|
|
|
|
// device usage...
|
|
LONG Paging;
|
|
LONG Hibernate;
|
|
LONG CrashDump;
|
|
|
|
} PCI_POWER_STATE, *PPCI_POWER_STATE;
|
|
|
|
typedef struct _PCI_PDO_EXTENSION *PPCI_PDO_EXTENSION;
|
|
typedef struct _PCI_FDO_EXTENSION *PPCI_FDO_EXTENSION;
|
|
typedef struct _PCI_COMMON_EXTENSION *PPCI_COMMON_EXTENSION;
|
|
|
|
|
|
//
|
|
// This is an Irp Dispatch Handler for PCI
|
|
//
|
|
typedef NTSTATUS (*PCI_MN_DISPATCH_FUNCTION) (
|
|
IN PIRP Irp,
|
|
IN PIO_STACK_LOCATION IrpSp,
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension
|
|
);
|
|
|
|
typedef struct _PCI_MN_DISPATCH_TABLE {
|
|
|
|
PCI_DISPATCH_STYLE DispatchStyle;
|
|
PCI_MN_DISPATCH_FUNCTION DispatchFunction;
|
|
|
|
} PCI_MN_DISPATCH_TABLE, *PPCI_MN_DISPATCH_TABLE;
|
|
|
|
//
|
|
// This is a table that contains everything neccessary to handle Power, PnP,
|
|
// and other IRPs.
|
|
//
|
|
typedef struct _PCI_MJ_DISPATCH_TABLE {
|
|
|
|
ULONG PnpIrpMaximumMinorFunction;
|
|
PPCI_MN_DISPATCH_TABLE PnpIrpDispatchTable;
|
|
ULONG PowerIrpMaximumMinorFunction;
|
|
PPCI_MN_DISPATCH_TABLE PowerIrpDispatchTable;
|
|
PCI_DISPATCH_STYLE SystemControlIrpDispatchStyle;
|
|
PCI_MN_DISPATCH_FUNCTION SystemControlIrpDispatchFunction;
|
|
PCI_DISPATCH_STYLE OtherIrpDispatchStyle;
|
|
PCI_MN_DISPATCH_FUNCTION OtherIrpDispatchFunction;
|
|
|
|
} PCI_MJ_DISPATCH_TABLE, *PPCI_MJ_DISPATCH_TABLE;
|
|
|
|
typedef
|
|
VOID
|
|
(*PCRITICALROUTINE)(
|
|
IN PVOID Extension,
|
|
IN PVOID Context
|
|
);
|
|
|
|
typedef struct _PCI_CRITICAL_ROUTINE_CONTEXT {
|
|
|
|
volatile LONG Gate;
|
|
volatile LONG Barrier;
|
|
|
|
PCRITICALROUTINE Routine;
|
|
PVOID Extension;
|
|
PVOID Context;
|
|
|
|
} PCI_CRITICAL_ROUTINE_CONTEXT, *PPCI_CRITICAL_ROUTINE_CONTEXT;
|
|
|
|
//
|
|
// Structure used for storing MSI routing info
|
|
// in the PDO extention.
|
|
//
|
|
|
|
typedef struct _PCI_MSI_INFO {
|
|
ULONG_PTR MessageAddress;
|
|
UCHAR CapabilityOffset;
|
|
USHORT MessageData;
|
|
} PCI_MSI_INFO, *PPCI_MSI_INFO;
|
|
|
|
//
|
|
// This much must be common to both the PDO and FDO extensions.
|
|
//
|
|
typedef struct _PCI_COMMON_EXTENSION {
|
|
PVOID Next;
|
|
PCI_SIGNATURE ExtensionType;
|
|
PPCI_MJ_DISPATCH_TABLE IrpDispatchTable;
|
|
UCHAR DeviceState;
|
|
UCHAR TentativeNextState;
|
|
FAST_MUTEX SecondaryExtMutex;
|
|
} PCI_COMMON_EXTENSION;
|
|
|
|
typedef struct _PCI_PDO_EXTENSION{
|
|
PPCI_PDO_EXTENSION Next;
|
|
PCI_SIGNATURE ExtensionType;
|
|
PPCI_MJ_DISPATCH_TABLE IrpDispatchTable;
|
|
UCHAR DeviceState;
|
|
UCHAR TentativeNextState;
|
|
FAST_MUTEX SecondaryExtMutex;
|
|
PCI_SLOT_NUMBER Slot;
|
|
PDEVICE_OBJECT PhysicalDeviceObject;
|
|
PPCI_FDO_EXTENSION ParentFdoExtension;
|
|
SINGLE_LIST_ENTRY SecondaryExtension;
|
|
ULONG BusInterfaceReferenceCount;
|
|
ULONG AgpInterfaceReferenceCount;
|
|
USHORT VendorId;
|
|
USHORT DeviceId;
|
|
USHORT SubsystemVendorId;
|
|
USHORT SubsystemId;
|
|
UCHAR RevisionId;
|
|
UCHAR ProgIf;
|
|
UCHAR SubClass;
|
|
UCHAR BaseClass;
|
|
UCHAR AdditionalResourceCount;
|
|
UCHAR AdjustedInterruptLine;
|
|
UCHAR InterruptPin;
|
|
UCHAR RawInterruptLine;
|
|
UCHAR CapabilitiesPtr;
|
|
UCHAR SavedLatencyTimer;
|
|
UCHAR SavedCacheLineSize;
|
|
UCHAR HeaderType;
|
|
|
|
BOOLEAN NotPresent;
|
|
BOOLEAN ReportedMissing;
|
|
BOOLEAN ExpectedWritebackFailure;
|
|
BOOLEAN NoTouchPmeEnable;
|
|
BOOLEAN LegacyDriver;
|
|
BOOLEAN UpdateHardware;
|
|
BOOLEAN MovedDevice;
|
|
BOOLEAN DisablePowerDown;
|
|
BOOLEAN NeedsHotPlugConfiguration;
|
|
BOOLEAN IDEInNativeMode;
|
|
BOOLEAN BIOSAllowsIDESwitchToNativeMode; // NATA method said it was OK
|
|
BOOLEAN IoSpaceUnderNativeIdeControl;
|
|
BOOLEAN OnDebugPath; // Includes headless port
|
|
|
|
#if MSI_SUPPORTED
|
|
BOOLEAN CapableMSI;
|
|
PCI_MSI_INFO MsiInfo;
|
|
#endif // MSI_SUPPORTED
|
|
|
|
PCI_POWER_STATE PowerState;
|
|
|
|
PCI_HEADER_TYPE_DEPENDENT Dependent;
|
|
ULONGLONG HackFlags;
|
|
PPCI_FUNCTION_RESOURCES Resources;
|
|
PPCI_FDO_EXTENSION BridgeFdoExtension;
|
|
PPCI_PDO_EXTENSION NextBridge;
|
|
PPCI_PDO_EXTENSION NextHashEntry;
|
|
PCI_LOCK Lock;
|
|
PCI_PMC PowerCapabilities;
|
|
UCHAR TargetAgpCapabilityId;
|
|
USHORT CommandEnables; // What we want to enable for this device
|
|
USHORT InitialCommand; // How we found the command register
|
|
} PCI_PDO_EXTENSION;
|
|
|
|
#define ASSERT_PCI_PDO_EXTENSION(x) \
|
|
PCI_ASSERT((x)->ExtensionType == PciPdoExtensionType)
|
|
|
|
typedef struct _PCI_FDO_EXTENSION{
|
|
SINGLE_LIST_ENTRY List; // List of pci.sys's FDOs
|
|
PCI_SIGNATURE ExtensionType; // PciFdoExtensionType
|
|
PPCI_MJ_DISPATCH_TABLE IrpDispatchTable; // Irp Dispatch Table to use.
|
|
UCHAR DeviceState;
|
|
UCHAR TentativeNextState;
|
|
FAST_MUTEX SecondaryExtMutex;
|
|
PDEVICE_OBJECT PhysicalDeviceObject; // PDO passed into AddDevice()
|
|
PDEVICE_OBJECT FunctionalDeviceObject;// FDO that points here
|
|
PDEVICE_OBJECT AttachedDeviceObject; // next DO in chain.
|
|
FAST_MUTEX ChildListMutex;
|
|
PPCI_PDO_EXTENSION ChildPdoList;
|
|
PPCI_FDO_EXTENSION BusRootFdoExtension; // points to top of this tree
|
|
PPCI_FDO_EXTENSION ParentFdoExtension; // points to the parent bridge
|
|
PPCI_PDO_EXTENSION ChildBridgePdoList;
|
|
PPCI_BUS_INTERFACE_STANDARD PciBusInterface; // Only for a root
|
|
UCHAR MaxSubordinateBus; // Only for a root
|
|
PBUS_HANDLER BusHandler;
|
|
UCHAR BaseBus; // Bus number for THIS bus
|
|
BOOLEAN Fake; // True if not a real FDOx
|
|
BOOLEAN Scanned; // True is bus enumerated
|
|
BOOLEAN ArbitersInitialized;
|
|
BOOLEAN BrokenVideoHackApplied;
|
|
BOOLEAN Hibernated;
|
|
PCI_POWER_STATE PowerState;
|
|
SINGLE_LIST_ENTRY SecondaryExtension;
|
|
ULONG ChildWaitWakeCount;
|
|
#if INTEL_ICH_HACKS
|
|
PPCI_COMMON_CONFIG IchHackConfig;
|
|
#endif
|
|
PCI_LOCK Lock;
|
|
|
|
//
|
|
// Information from ACPI _HPP to apply to hot plugged cards,
|
|
// Acquired indicates the rest are valid.
|
|
//
|
|
struct {
|
|
BOOLEAN Acquired;
|
|
UCHAR CacheLineSize;
|
|
UCHAR LatencyTimer;
|
|
BOOLEAN EnablePERR;
|
|
BOOLEAN EnableSERR;
|
|
} HotPlugParameters;
|
|
|
|
ULONG BusHackFlags; // see PCI_BUS_HACK_*
|
|
} PCI_FDO_EXTENSION;
|
|
|
|
|
|
#define ASSERT_PCI_FDO_EXTENSION(x) \
|
|
PCI_ASSERT((x)->ExtensionType == PciFdoExtensionType)
|
|
|
|
typedef struct _PCI_CONFIGURABLE_OBJECT {
|
|
PPCI_PDO_EXTENSION PdoExtension;
|
|
PPCI_COMMON_CONFIG Current;
|
|
PPCI_COMMON_CONFIG Working;
|
|
PPCI_CONFIGURATOR Configurator;
|
|
ULONG PrivateData;
|
|
USHORT Status;
|
|
USHORT Command;
|
|
} PCI_CONFIGURABLE_OBJECT, *PPCI_CONFIGURABLE_OBJECT;
|
|
|
|
typedef struct _PCI_ASSIGNED_RESOURCE_EXTENSION {
|
|
ULONG ResourceIdentifier;
|
|
} PCI_ASSIGNED_RESOURCE_EXTENSION, *PPCI_ASSIGNED_RESOURCE_EXTENSION;
|
|
|
|
//
|
|
// The PCI_COMMON_CONFIG includes the 192 bytes of device specific
|
|
// data. The following structure is used to get only the first 64
|
|
// bytes which is all we care about most of the time anyway. We cast
|
|
// to PCI_COMMON_CONFIG to get at the actual fields.
|
|
//
|
|
|
|
typedef struct {
|
|
ULONG Reserved[PCI_COMMON_HDR_LENGTH/sizeof(ULONG)];
|
|
} PCI_COMMON_HEADER, *PPCI_COMMON_HEADER;
|
|
|
|
//
|
|
// In order to be able to arbitrate interrupts for device with
|
|
// legacy drivers, we have to do some bookkeeping.
|
|
//
|
|
|
|
typedef struct {
|
|
SINGLE_LIST_ENTRY List;
|
|
PDEVICE_OBJECT LegacyDeviceObject;
|
|
ULONG Bus;
|
|
ULONG PciSlot;
|
|
UCHAR InterruptLine;
|
|
UCHAR InterruptPin;
|
|
UCHAR ClassCode;
|
|
UCHAR SubClassCode;
|
|
PDEVICE_OBJECT ParentPdo;
|
|
ROUTING_TOKEN RoutingToken;
|
|
PPCI_PDO_EXTENSION PdoExtension;
|
|
} LEGACY_DEVICE, *PLEGACY_DEVICE;
|
|
|
|
extern PLEGACY_DEVICE PciLegacyDeviceHead;
|
|
|
|
|
|
#define PCI_HACK_FLAG_SUBSYSTEM 0x01
|
|
#define PCI_HACK_FLAG_REVISION 0x02
|
|
|
|
typedef struct _PCI_HACK_TABLE_ENTRY {
|
|
USHORT VendorID;
|
|
USHORT DeviceID;
|
|
USHORT SubVendorID;
|
|
USHORT SubSystemID;
|
|
ULONGLONG HackFlags;
|
|
UCHAR RevisionID;
|
|
UCHAR Flags;
|
|
} PCI_HACK_TABLE_ENTRY, *PPCI_HACK_TABLE_ENTRY;
|
|
|
|
typedef struct _ARBITER_MEMORY_EXTENSION {
|
|
|
|
//
|
|
// Indicates that this arbiter will arbitrate prefetchable memory
|
|
//
|
|
BOOLEAN PrefetchablePresent;
|
|
|
|
//
|
|
// Indicates that this arbiter has been initialized
|
|
//
|
|
BOOLEAN Initialized;
|
|
|
|
//
|
|
// The number of prefetchable ranges
|
|
//
|
|
USHORT PrefetchableCount;
|
|
|
|
//
|
|
// The allocation ordering list to be used for prefetchable memory
|
|
//
|
|
ARBITER_ORDERING_LIST PrefetchableOrdering;
|
|
|
|
//
|
|
// The allocation ordering list to be used for standard memory
|
|
//
|
|
ARBITER_ORDERING_LIST NonprefetchableOrdering;
|
|
|
|
//
|
|
// The original memory allocation ordering (from the registry)
|
|
//
|
|
ARBITER_ORDERING_LIST OriginalOrdering;
|
|
|
|
} ARBITER_MEMORY_EXTENSION, *PARBITER_MEMORY_EXTENSION;
|
|
|
|
|
|
|
|
NTSTATUS
|
|
PciCacheLegacyDeviceRouting(
|
|
IN PDEVICE_OBJECT LegacyDO,
|
|
IN ULONG Bus,
|
|
IN ULONG PciSlot,
|
|
IN UCHAR InterruptLine,
|
|
IN UCHAR InterruptPin,
|
|
IN UCHAR ClassCode,
|
|
IN UCHAR SubClassCode,
|
|
IN PDEVICE_OBJECT ParentPdo,
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
OUT PDEVICE_OBJECT *OldLegacyDO
|
|
);
|
|
|
|
|
|
//
|
|
// Global data declarations follow
|
|
//
|
|
|
|
extern PDRIVER_OBJECT PciDriverObject;
|
|
extern UNICODE_STRING PciServiceRegistryPath;
|
|
extern SINGLE_LIST_ENTRY PciFdoExtensionListHead;
|
|
extern FAST_MUTEX PciGlobalLock;
|
|
extern FAST_MUTEX PciBusLock;
|
|
extern LONG PciRootBusCount;
|
|
extern BOOLEAN PciAssignBusNumbers;
|
|
extern PPCI_FDO_EXTENSION PciRootExtensions;
|
|
extern RTL_RANGE_LIST PciIsaBitExclusionList;
|
|
extern RTL_RANGE_LIST PciVgaAndIsaBitExclusionList;
|
|
extern ULONG PciSystemWideHackFlags;
|
|
extern ULONG PciEnableNativeModeATA;
|
|
extern PPCI_HACK_TABLE_ENTRY PciHackTable;
|
|
extern BOOLEAN PciRunningDatacenter;
|
|
|
|
//
|
|
// Watchdog timer resource table
|
|
//
|
|
extern PWATCHDOG_TIMER_RESOURCE_TABLE WdTable;
|
|
|
|
|
|
// arb_comn.h
|
|
|
|
#define INSTANCE_NAME_LENGTH 24
|
|
|
|
typedef struct _PCI_ARBITER_INSTANCE {
|
|
|
|
//
|
|
// Standard secondary extension header
|
|
//
|
|
|
|
PCI_SECONDARY_EXTENSION Header;
|
|
|
|
//
|
|
// Back pointer to the interface we are a context of
|
|
//
|
|
|
|
struct _PCI_INTERFACE *Interface;
|
|
|
|
//
|
|
// Pointer to owning device object (extension).
|
|
//
|
|
|
|
PPCI_FDO_EXTENSION BusFdoExtension;
|
|
|
|
//
|
|
// Arbiter description.
|
|
//
|
|
|
|
WCHAR InstanceName[INSTANCE_NAME_LENGTH];
|
|
|
|
//
|
|
// The common instance data
|
|
//
|
|
|
|
ARBITER_INSTANCE CommonInstance;
|
|
|
|
} PCI_ARBITER_INSTANCE, *PPCI_ARBITER_INSTANCE;
|
|
|
|
|
|
|
|
NTSTATUS
|
|
PciArbiterInitializeInterface(
|
|
IN PVOID DeviceExtension,
|
|
IN PCI_SIGNATURE DesiredInterface,
|
|
IN OUT PARBITER_INTERFACE ArbiterInterface
|
|
);
|
|
|
|
NTSTATUS
|
|
PciInitializeArbiterRanges(
|
|
IN PPCI_FDO_EXTENSION FdoExtension,
|
|
IN PCM_RESOURCE_LIST ResourceList
|
|
);
|
|
|
|
NTSTATUS
|
|
PciInitializeArbiters(
|
|
IN PVOID DeviceExtension
|
|
);
|
|
|
|
VOID
|
|
PciReferenceArbiter(
|
|
IN PVOID Context
|
|
);
|
|
|
|
VOID
|
|
PciDereferenceArbiter(
|
|
IN PVOID Context
|
|
);
|
|
|
|
VOID
|
|
ario_ApplyBrokenVideoHack(
|
|
IN PPCI_FDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
|
|
// busno.h
|
|
|
|
BOOLEAN
|
|
PciAreBusNumbersConfigured(
|
|
IN PPCI_PDO_EXTENSION Bridge
|
|
);
|
|
|
|
|
|
VOID
|
|
PciConfigureBusNumbers(
|
|
PPCI_FDO_EXTENSION Parent
|
|
);
|
|
|
|
VOID
|
|
PciSetBusNumbers(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN UCHAR Primary,
|
|
IN UCHAR Secondary,
|
|
IN UCHAR Subordinate
|
|
);
|
|
|
|
// cardbus.h
|
|
|
|
VOID
|
|
Cardbus_MassageHeaderForLimitsDetermination(
|
|
IN PPCI_CONFIGURABLE_OBJECT This
|
|
);
|
|
|
|
VOID
|
|
Cardbus_RestoreCurrent(
|
|
IN PPCI_CONFIGURABLE_OBJECT This
|
|
);
|
|
|
|
VOID
|
|
Cardbus_SaveLimits(
|
|
IN PPCI_CONFIGURABLE_OBJECT This
|
|
);
|
|
|
|
VOID
|
|
Cardbus_SaveCurrentSettings(
|
|
IN PPCI_CONFIGURABLE_OBJECT This
|
|
);
|
|
|
|
VOID
|
|
Cardbus_ChangeResourceSettings(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPCI_COMMON_CONFIG CommonConfig
|
|
);
|
|
|
|
VOID
|
|
Cardbus_GetAdditionalResourceDescriptors(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPCI_COMMON_CONFIG CommonConfig,
|
|
IN PIO_RESOURCE_DESCRIPTOR Resource
|
|
);
|
|
|
|
NTSTATUS
|
|
Cardbus_ResetDevice(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPCI_COMMON_CONFIG CommonConfig
|
|
);
|
|
|
|
// config.h
|
|
|
|
VOID
|
|
PciReadDeviceConfig(
|
|
IN PPCI_PDO_EXTENSION Pdo,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
);
|
|
|
|
VOID
|
|
PciWriteDeviceConfig(
|
|
IN PPCI_PDO_EXTENSION Pdo,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
);
|
|
|
|
VOID
|
|
PciReadSlotConfig(
|
|
IN PPCI_FDO_EXTENSION ParentFdo,
|
|
IN PCI_SLOT_NUMBER SlotNumber,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
);
|
|
|
|
VOID
|
|
PciWriteSlotConfig(
|
|
IN PPCI_FDO_EXTENSION ParentFdo,
|
|
IN PCI_SLOT_NUMBER SlotNumber,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
);
|
|
|
|
UCHAR
|
|
PciGetAdjustedInterruptLine(
|
|
IN PPCI_PDO_EXTENSION Pdo
|
|
);
|
|
|
|
NTSTATUS
|
|
PciExternalReadDeviceConfig(
|
|
IN PPCI_PDO_EXTENSION Pdo,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
);
|
|
|
|
NTSTATUS
|
|
PciExternalWriteDeviceConfig(
|
|
IN PPCI_PDO_EXTENSION Pdo,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length
|
|
);
|
|
|
|
NTSTATUS
|
|
PciGetConfigHandlers(
|
|
IN PPCI_FDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
//
|
|
// Macros to access common registers in config space
|
|
//
|
|
|
|
//
|
|
// VOID
|
|
// PciGetCommandRegister(
|
|
// PPCI_PDO_EXTENSION _PdoExt,
|
|
// PUSHORT _Command
|
|
// );
|
|
//
|
|
#define PciGetCommandRegister(_PdoExt, _Command) \
|
|
PciReadDeviceConfig((_PdoExt), \
|
|
(_Command), \
|
|
FIELD_OFFSET(PCI_COMMON_CONFIG, Command), \
|
|
sizeof(USHORT) \
|
|
);
|
|
|
|
//
|
|
// VOID
|
|
// PciSetCommandRegister(
|
|
// PPCI_PDO_EXTENSION _PdoExt,
|
|
// USHORT _Command
|
|
// );
|
|
//
|
|
#define PciSetCommandRegister(_PdoExt, _Command) \
|
|
PciWriteDeviceConfig((_PdoExt), \
|
|
&(_Command), \
|
|
FIELD_OFFSET(PCI_COMMON_CONFIG, Command), \
|
|
sizeof(USHORT) \
|
|
);
|
|
|
|
// BOOLEAN
|
|
// BITS_SET(
|
|
// IN USHORT C
|
|
// IN USHORT F
|
|
// )
|
|
//
|
|
#define BITS_SET(C,F) ((BOOLEAN)(((C) & (F)) == (F)))
|
|
|
|
// BOOLEAN
|
|
// ANY_BITS_SET(
|
|
// IN USHORT C
|
|
// IN USHORT F
|
|
// )
|
|
//
|
|
#define ANY_BITS_SET(C,F) ((BOOLEAN)(((C) & (F)) != 0))
|
|
|
|
|
|
//
|
|
// VOID
|
|
// PciGetConfigData(
|
|
// IN PPCI_PDO_EXTENSION PdoExtension,
|
|
// OUT PPCI_COMMON_CONFIG PciConfig
|
|
// )
|
|
//
|
|
|
|
#define PciGetConfigData(_PdoExtension, _PciConfig) \
|
|
PciReadDeviceConfig((_PdoExtension), \
|
|
(_PciConfig), \
|
|
0, \
|
|
PCI_COMMON_HDR_LENGTH \
|
|
);
|
|
//
|
|
// VOID
|
|
// PciSetConfigData(
|
|
// IN PPCI_PDO_EXTENSION PdoExtension,
|
|
// OUT PPCI_COMMON_CONFIG PciConfig
|
|
// )
|
|
//
|
|
|
|
#define PciSetConfigData(_PdoExtension, _PciConfig) \
|
|
PciWriteDeviceConfig((_PdoExtension), \
|
|
(_PciConfig), \
|
|
0, \
|
|
PCI_COMMON_HDR_LENGTH \
|
|
);
|
|
|
|
// debug.c
|
|
|
|
typedef enum {
|
|
PciDbgAlways = 0x00000000, // unconditionally
|
|
PciDbgInformative = 0x00000001,
|
|
PciDbgVerbose = 0x00000003,
|
|
PciDbgPrattling = 0x00000007,
|
|
|
|
PciDbgPnpIrpsFdo = 0x00000100, // PnP IRPs at FDO
|
|
PciDbgPnpIrpsPdo = 0x00000200, // PnP IRPs at PDO
|
|
PciDbgPoIrpsFdo = 0x00000400, // PO IRPs at FDO
|
|
PciDbgPoIrpsPdo = 0x00000800, // PO IRPs at PDO
|
|
|
|
PciDbgAddDevice = 0x00001000, // AddDevice info
|
|
PciDbgAddDeviceRes = 0x00002000, // bus initial resource info
|
|
|
|
PciDbgWaitWake = 0x00008000, // noisy debug for wait wake
|
|
PciDbgQueryCap = 0x00010000, // Dump QueryCapabilities
|
|
PciDbgCardBus = 0x00020000, // CardBus FDOish behavior
|
|
PciDbgROM = 0x00040000, // access to device ROM
|
|
PciDbgConfigParam = 0x00080000, // Setting config parameters
|
|
|
|
PciDbgBusNumbers = 0x00100000, // checking and assigning bus numbers
|
|
|
|
PciDbgResReqList = 0x01000000, // generated resource requirements
|
|
PciDbgCmResList = 0x02000000, // generated CM Resource lists
|
|
PciDbgSetResChange = 0x04000000, // SetResources iff changing
|
|
PciDbgSetRes = 0x08000000, // SetResources
|
|
|
|
|
|
PciDbgObnoxious = 0x7fffffff // anything
|
|
} PCI_DEBUG_LEVEL;
|
|
|
|
#if DBG
|
|
|
|
#define PCI_DEBUGGING_OKAY() \
|
|
(KeGetCurrentIrql() < IPI_LEVEL)
|
|
|
|
#define PCI_ASSERT \
|
|
if (PCI_DEBUGGING_OKAY()) ASSERT
|
|
|
|
#define PCI_ASSERTMSG \
|
|
if (PCI_DEBUGGING_OKAY()) ASSERTMSG
|
|
|
|
extern PCI_DEBUG_LEVEL PciDebug;
|
|
|
|
#define PCI_DEBUG_BUFFER_SIZE 256
|
|
|
|
#define PciDebugPrint PciDebugPrintIfLevel
|
|
|
|
#else
|
|
|
|
#define PciDebugPrint if(0)
|
|
|
|
#define PCI_ASSERT(exp)
|
|
#define PCI_ASSERTMSG(msg,exp)
|
|
|
|
#endif
|
|
|
|
VOID
|
|
PciDebugDumpCommonConfig(
|
|
IN PPCI_COMMON_CONFIG CommonConfig
|
|
);
|
|
|
|
VOID
|
|
PciDebugDumpQueryCapabilities(
|
|
IN PDEVICE_CAPABILITIES C
|
|
);
|
|
|
|
VOID
|
|
PciDebugHit(
|
|
ULONG StopOnBit
|
|
);
|
|
|
|
PUCHAR
|
|
PciDebugPnpIrpTypeToText(
|
|
ULONG IrpMinorCode
|
|
);
|
|
|
|
PUCHAR
|
|
PciDebugPoIrpTypeToText(
|
|
ULONG IrpMinorCode
|
|
);
|
|
|
|
VOID
|
|
PciDebugPrintIfLevel(
|
|
PCI_DEBUG_LEVEL DebugPrintLevel,
|
|
PCCHAR DebugMessage,
|
|
...
|
|
);
|
|
|
|
VOID
|
|
PciDebugPrintf(
|
|
PCCHAR DebugMessage,
|
|
...
|
|
);
|
|
|
|
VOID
|
|
PciDebugPrintCmResList(
|
|
PCI_DEBUG_LEVEL DebugPrintLevel,
|
|
IN PCM_RESOURCE_LIST ResourceList
|
|
);
|
|
|
|
VOID
|
|
PciDebugPrintIoResource(
|
|
IN PIO_RESOURCE_DESCRIPTOR Descriptor
|
|
);
|
|
|
|
VOID
|
|
PciDebugPrintIoResReqList(
|
|
IN PIO_RESOURCE_REQUIREMENTS_LIST List
|
|
);
|
|
|
|
VOID
|
|
PciDebugPrintPartialResource(
|
|
PCI_DEBUG_LEVEL DebugPrintLevel,
|
|
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR D
|
|
);
|
|
|
|
|
|
// device.h
|
|
|
|
VOID
|
|
Device_MassageHeaderForLimitsDetermination(
|
|
IN PPCI_CONFIGURABLE_OBJECT This
|
|
);
|
|
|
|
VOID
|
|
Device_RestoreCurrent(
|
|
IN PPCI_CONFIGURABLE_OBJECT This
|
|
);
|
|
|
|
VOID
|
|
Device_SaveLimits(
|
|
IN PPCI_CONFIGURABLE_OBJECT This
|
|
);
|
|
|
|
VOID
|
|
Device_SaveCurrentSettings(
|
|
IN PPCI_CONFIGURABLE_OBJECT This
|
|
);
|
|
|
|
VOID
|
|
Device_ChangeResourceSettings(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPCI_COMMON_CONFIG CommonConfig
|
|
);
|
|
|
|
VOID
|
|
Device_GetAdditionalResourceDescriptors(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPCI_COMMON_CONFIG CommonConfig,
|
|
IN PIO_RESOURCE_DESCRIPTOR Resource
|
|
);
|
|
|
|
NTSTATUS
|
|
Device_ResetDevice(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPCI_COMMON_CONFIG CommonConfig
|
|
);
|
|
|
|
|
|
// dispatch.h
|
|
|
|
//
|
|
// This is the dispatch table for normal PDO's.
|
|
//
|
|
extern PCI_MJ_DISPATCH_TABLE PciPdoDispatchTable;
|
|
|
|
NTSTATUS
|
|
PciDispatchIrp(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
|
|
NTSTATUS
|
|
PciPassIrpFromFdoToPdo(
|
|
PPCI_COMMON_EXTENSION DeviceExtension,
|
|
PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
PciCallDownIrpStack(
|
|
PPCI_COMMON_EXTENSION DeviceExtension,
|
|
PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
PciIrpNotSupported(
|
|
IN PIRP Irp,
|
|
IN PIO_STACK_LOCATION IrpSp,
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension
|
|
);
|
|
|
|
NTSTATUS
|
|
PciIrpInvalidDeviceRequest(
|
|
IN PIRP Irp,
|
|
IN PIO_STACK_LOCATION IrpSp,
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension
|
|
);
|
|
|
|
// enum.h
|
|
|
|
PIO_RESOURCE_REQUIREMENTS_LIST
|
|
PciAllocateIoRequirementsList(
|
|
IN ULONG ResourceCount,
|
|
IN ULONG BusNumber,
|
|
IN ULONG SlotNumber
|
|
);
|
|
|
|
BOOLEAN
|
|
PciComputeNewCurrentSettings(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PCM_RESOURCE_LIST ResourceList
|
|
);
|
|
|
|
NTSTATUS
|
|
PciQueryDeviceRelations(
|
|
IN PPCI_FDO_EXTENSION FdoExtension,
|
|
OUT PDEVICE_RELATIONS *DeviceRelations
|
|
);
|
|
|
|
NTSTATUS
|
|
PciQueryRequirements(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
OUT PIO_RESOURCE_REQUIREMENTS_LIST *RequirementsList
|
|
);
|
|
|
|
NTSTATUS
|
|
PciQueryResources(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
OUT PCM_RESOURCE_LIST *ResourceList
|
|
);
|
|
|
|
NTSTATUS
|
|
PciQueryTargetDeviceRelations(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN OUT PDEVICE_RELATIONS *PDeviceRelations
|
|
);
|
|
|
|
NTSTATUS
|
|
PciQueryEjectionRelations(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN OUT PDEVICE_RELATIONS *PDeviceRelations
|
|
);
|
|
|
|
NTSTATUS
|
|
PciScanHibernatedBus(
|
|
IN PPCI_FDO_EXTENSION FdoExtension
|
|
);
|
|
|
|
NTSTATUS
|
|
PciSetResources(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN BOOLEAN PowerOn,
|
|
IN BOOLEAN StartDeviceIrp
|
|
);
|
|
|
|
VOID
|
|
PciUpdateHardware(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPCI_COMMON_CONFIG Config
|
|
);
|
|
|
|
BOOLEAN
|
|
PciIsSameDevice(
|
|
IN PPCI_PDO_EXTENSION PdoExtension
|
|
);
|
|
|
|
NTSTATUS
|
|
PciBuildRequirementsList(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPCI_COMMON_CONFIG CurrentConfig,
|
|
OUT PIO_RESOURCE_REQUIREMENTS_LIST *FinalReqList
|
|
);
|
|
|
|
|
|
// fdo.h
|
|
|
|
|
|
NTSTATUS
|
|
PciFdoIrpQueryDeviceRelations(
|
|
IN PIRP Irp,
|
|
IN PIO_STACK_LOCATION IrpSp,
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension
|
|
);
|
|
|
|
NTSTATUS
|
|
PciAddDevice(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PDEVICE_OBJECT PhysicalDeviceObject
|
|
);
|
|
|
|
VOID
|
|
PciInitializeFdoExtensionCommonFields(
|
|
IN PPCI_FDO_EXTENSION FdoExtension,
|
|
IN PDEVICE_OBJECT Fdo,
|
|
IN PDEVICE_OBJECT Pdo
|
|
);
|
|
|
|
|
|
// hookhal.c
|
|
|
|
VOID
|
|
PciHookHal(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
PciUnhookHal(
|
|
VOID
|
|
);
|
|
|
|
// id.h
|
|
|
|
PWSTR
|
|
PciGetDeviceDescriptionMessage(
|
|
IN UCHAR BaseClass,
|
|
IN UCHAR SubClass
|
|
);
|
|
|
|
NTSTATUS
|
|
PciQueryId(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN BUS_QUERY_ID_TYPE IdType,
|
|
IN OUT PWSTR *BusQueryId
|
|
);
|
|
|
|
NTSTATUS
|
|
PciQueryDeviceText(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN DEVICE_TEXT_TYPE TextType,
|
|
IN LCID LocaleId,
|
|
IN OUT PWSTR *DeviceText
|
|
);
|
|
|
|
// interface.h
|
|
|
|
#define PCIIF_PDO 0x01 // Interface can be used by a PDO
|
|
#define PCIIF_FDO 0x02 // Interface can be used by an FDO
|
|
#define PCIIF_ROOT 0x04 // Interface can be used only at by the root.
|
|
|
|
typedef
|
|
NTSTATUS
|
|
(*PPCI_INTERFACE_CONSTRUCTOR)(
|
|
PVOID DeviceExtension,
|
|
PVOID PciInterface,
|
|
PVOID InterfaceSpecificData,
|
|
USHORT Version,
|
|
USHORT Size,
|
|
PINTERFACE InterfaceReturn
|
|
);
|
|
|
|
typedef
|
|
NTSTATUS
|
|
(*PPCI_INTERFACE_INITIALIZER)(
|
|
PPCI_ARBITER_INSTANCE Instance
|
|
);
|
|
|
|
typedef struct _PCI_INTERFACE {
|
|
PGUID InterfaceType;
|
|
USHORT MinSize;
|
|
USHORT MinVersion;
|
|
USHORT MaxVersion;
|
|
USHORT Flags;
|
|
LONG ReferenceCount;
|
|
PCI_SIGNATURE Signature;
|
|
PPCI_INTERFACE_CONSTRUCTOR Constructor;
|
|
PPCI_INTERFACE_INITIALIZER Initializer;
|
|
} PCI_INTERFACE, *PPCI_INTERFACE;
|
|
|
|
NTSTATUS
|
|
PciQueryInterface(
|
|
IN PVOID DeviceExtension,
|
|
IN PGUID InterfaceType,
|
|
IN USHORT Size,
|
|
IN USHORT Version,
|
|
IN PVOID InterfaceSpecificData,
|
|
IN OUT PINTERFACE Interface,
|
|
IN BOOLEAN LastChance
|
|
);
|
|
|
|
|
|
extern PPCI_INTERFACE PciInterfaces[];
|
|
|
|
// pdo.h
|
|
|
|
NTSTATUS
|
|
PciPdoCreate(
|
|
IN PPCI_FDO_EXTENSION FdoExtension,
|
|
IN PCI_SLOT_NUMBER Slot,
|
|
OUT PDEVICE_OBJECT *PhysicalDeviceObject
|
|
);
|
|
|
|
VOID
|
|
PciPdoDestroy(
|
|
IN PDEVICE_OBJECT PhysicalDeviceObject
|
|
);
|
|
|
|
|
|
// pmeintf.h
|
|
|
|
VOID
|
|
PciPmeAdjustPmeEnable(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN BOOLEAN Enable,
|
|
IN BOOLEAN ClearStatusOnly
|
|
);
|
|
|
|
VOID
|
|
PciPmeGetInformation(
|
|
IN PDEVICE_OBJECT Pdo,
|
|
OUT PBOOLEAN PmeCapable,
|
|
OUT PBOOLEAN PmeStatus,
|
|
OUT PBOOLEAN PmeEnable
|
|
);
|
|
|
|
|
|
|
|
// power.h
|
|
|
|
NTSTATUS
|
|
PciPdoIrpQueryPower(
|
|
IN PIRP Irp,
|
|
IN PIO_STACK_LOCATION IrpSp,
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension
|
|
);
|
|
|
|
NTSTATUS
|
|
PciPdoSetPowerState (
|
|
IN PIRP Irp,
|
|
IN PIO_STACK_LOCATION IrpStack,
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension
|
|
);
|
|
|
|
NTSTATUS
|
|
PciPdoWaitWake (
|
|
IN PIRP Irp,
|
|
IN PIO_STACK_LOCATION IrpSp,
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension
|
|
);
|
|
|
|
|
|
VOID
|
|
PciPdoWaitWakeCancelRoutine(
|
|
IN PDEVICE_OBJECT DeviceObject,
|
|
IN OUT PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
PciFdoIrpQueryPower(
|
|
IN PIRP Irp,
|
|
IN PIO_STACK_LOCATION IrpSp,
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension
|
|
);
|
|
|
|
NTSTATUS
|
|
PciFdoSetPowerState(
|
|
IN PIRP Irp,
|
|
IN PIO_STACK_LOCATION IrpSp,
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension
|
|
);
|
|
|
|
NTSTATUS
|
|
PciFdoWaitWake(
|
|
IN PIRP Irp,
|
|
IN PIO_STACK_LOCATION IrpSp,
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension
|
|
);
|
|
|
|
NTSTATUS
|
|
PciSetPowerManagedDevicePowerState(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN DEVICE_POWER_STATE DeviceState,
|
|
IN BOOLEAN RefreshConfigSpace
|
|
);
|
|
|
|
// ppbridge.h
|
|
|
|
VOID
|
|
PPBridge_MassageHeaderForLimitsDetermination(
|
|
IN PPCI_CONFIGURABLE_OBJECT This
|
|
);
|
|
|
|
VOID
|
|
PPBridge_RestoreCurrent(
|
|
IN PPCI_CONFIGURABLE_OBJECT This
|
|
);
|
|
|
|
VOID
|
|
PPBridge_SaveLimits(
|
|
IN PPCI_CONFIGURABLE_OBJECT This
|
|
);
|
|
|
|
VOID
|
|
PPBridge_SaveCurrentSettings(
|
|
IN PPCI_CONFIGURABLE_OBJECT This
|
|
);
|
|
|
|
VOID
|
|
PPBridge_ChangeResourceSettings(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPCI_COMMON_CONFIG CommonConfig
|
|
);
|
|
|
|
VOID
|
|
PPBridge_GetAdditionalResourceDescriptors(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPCI_COMMON_CONFIG CommonConfig,
|
|
IN PIO_RESOURCE_DESCRIPTOR Resource
|
|
);
|
|
|
|
NTSTATUS
|
|
PPBridge_ResetDevice(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPCI_COMMON_CONFIG CommonConfig
|
|
);
|
|
|
|
// romimage.h
|
|
|
|
NTSTATUS
|
|
PciReadRomImage(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN ULONG WhichSpace,
|
|
OUT PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN OUT PULONG LENGTH
|
|
);
|
|
|
|
// state.h
|
|
|
|
//
|
|
// Note - State.c depends on the order of these.
|
|
//
|
|
typedef enum {
|
|
PciNotStarted = 0,
|
|
PciStarted,
|
|
PciDeleted,
|
|
PciStopped,
|
|
PciSurpriseRemoved,
|
|
PciSynchronizedOperation,
|
|
PciMaxObjectState
|
|
} PCI_OBJECT_STATE;
|
|
|
|
VOID
|
|
PciInitializeState(
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension
|
|
);
|
|
|
|
NTSTATUS
|
|
PciBeginStateTransition(
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension,
|
|
IN PCI_OBJECT_STATE NewState
|
|
);
|
|
|
|
VOID
|
|
PciCommitStateTransition(
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension,
|
|
IN PCI_OBJECT_STATE NewState
|
|
);
|
|
|
|
NTSTATUS
|
|
PciCancelStateTransition(
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension,
|
|
IN PCI_OBJECT_STATE StateNotEntered
|
|
);
|
|
|
|
BOOLEAN
|
|
PciIsInTransitionToState(
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension,
|
|
IN PCI_OBJECT_STATE NextState
|
|
);
|
|
|
|
/*
|
|
NTSTATUS
|
|
PciBeginStateTransitionIfNotBegun(
|
|
IN PPCI_COMMON_EXTENSION DeviceExtension,
|
|
IN PCI_OBJECT_STATE StateToEnter
|
|
);
|
|
*/
|
|
|
|
#define PCI_ACQUIRE_STATE_LOCK(Extension) \
|
|
PciBeginStateTransition((PPCI_COMMON_EXTENSION) (Extension), \
|
|
PciSynchronizedOperation)
|
|
|
|
|
|
#define PCI_RELEASE_STATE_LOCK(Extension) \
|
|
PciCancelStateTransition((PPCI_COMMON_EXTENSION) (Extension), \
|
|
PciSynchronizedOperation)
|
|
|
|
|
|
|
|
// tr_comn.h
|
|
|
|
typedef struct _PCI_TRANSLATOR_INSTANCE {
|
|
PTRANSLATOR_INTERFACE Interface;
|
|
ULONG ReferenceCount;
|
|
PPCI_FDO_EXTENSION FdoExtension;
|
|
} PCI_TRANSLATOR_INSTANCE, *PPCI_TRANSLATOR_INSTANCE;
|
|
|
|
#define PCI_TRANSLATOR_INSTANCE_TO_CONTEXT(x) ((PVOID)(x))
|
|
#define PCI_TRANSLATOR_CONTEXT_TO_INSTANCE(x) ((PPCI_TRANSLATOR_INSTANCE)(x))
|
|
|
|
VOID
|
|
PciReferenceTranslator(
|
|
IN PVOID Context
|
|
);
|
|
|
|
VOID
|
|
PciDereferenceTranslator(
|
|
IN PVOID Context
|
|
);
|
|
|
|
// usage.h
|
|
|
|
NTSTATUS
|
|
PciLocalDeviceUsage (
|
|
IN PPCI_POWER_STATE PowerState,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
NTSTATUS
|
|
PciPdoDeviceUsage (
|
|
IN PPCI_PDO_EXTENSION pdoExtension,
|
|
IN PIRP Irp
|
|
);
|
|
|
|
// utils.h
|
|
|
|
NTSTATUS
|
|
PciAssignSlotResources(
|
|
IN PUNICODE_STRING RegistryPath,
|
|
IN PUNICODE_STRING DriverClassName OPTIONAL,
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PDEVICE_OBJECT DeviceObject OPTIONAL,
|
|
IN INTERFACE_TYPE BusType,
|
|
IN ULONG BusNumber,
|
|
IN ULONG SlotNumber,
|
|
IN OUT PCM_RESOURCE_LIST *AllocatedResources
|
|
);
|
|
|
|
PCI_OBJECT_TYPE
|
|
PciClassifyDeviceType(
|
|
PPCI_PDO_EXTENSION PdoExtension
|
|
);
|
|
|
|
// VOID
|
|
// PciCompleteRequest(
|
|
// IN OUT PIRP Irp,
|
|
// IN NTSTATUS Status
|
|
// );
|
|
|
|
#define PciCompleteRequest(_Irp_,_Status_) \
|
|
{ \
|
|
(_Irp_)->IoStatus.Status = (_Status_); \
|
|
IoCompleteRequest((_Irp_), IO_NO_INCREMENT); \
|
|
}
|
|
|
|
BOOLEAN
|
|
PciCreateIoDescriptorFromBarLimit(
|
|
IN PIO_RESOURCE_DESCRIPTOR Descriptor,
|
|
IN PULONG BaseAddress,
|
|
IN BOOLEAN Rom
|
|
);
|
|
|
|
BOOLEAN
|
|
PciIsCriticalDeviceClass(
|
|
IN UCHAR BaseClass,
|
|
IN UCHAR SubClass
|
|
);
|
|
|
|
#define PCI_CAN_DISABLE_VIDEO_DECODES 0x00000001
|
|
|
|
BOOLEAN
|
|
PciCanDisableDecodes(
|
|
IN PPCI_PDO_EXTENSION PdoExtension OPTIONAL,
|
|
IN PPCI_COMMON_CONFIG Config OPTIONAL,
|
|
IN ULONGLONG HackFlags,
|
|
IN ULONG Flags
|
|
);
|
|
|
|
VOID
|
|
PciDecodeEnable(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN BOOLEAN EnableOperation,
|
|
IN PUSHORT ExistingCommand OPTIONAL
|
|
);
|
|
|
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR
|
|
PciFindDescriptorInCmResourceList(
|
|
IN CM_RESOURCE_TYPE DescriptorType,
|
|
IN PCM_RESOURCE_LIST ResourceList,
|
|
IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PreviousHit
|
|
);
|
|
|
|
PPCI_FDO_EXTENSION
|
|
PciFindParentPciFdoExtension(
|
|
PDEVICE_OBJECT PhysicalDeviceObject,
|
|
IN PFAST_MUTEX Mutex
|
|
);
|
|
|
|
PPCI_PDO_EXTENSION
|
|
PciFindPdoByFunction(
|
|
IN PPCI_FDO_EXTENSION FdoExtension,
|
|
IN PCI_SLOT_NUMBER Slot,
|
|
IN PPCI_COMMON_CONFIG Config
|
|
);
|
|
|
|
PVOID
|
|
PciFindNextSecondaryExtension(
|
|
IN PSINGLE_LIST_ENTRY ListEntry,
|
|
IN PCI_SIGNATURE DesiredType
|
|
);
|
|
|
|
#define PciFindSecondaryExtension(X,TYPE) \
|
|
PciFindNextSecondaryExtension((X)->SecondaryExtension.Next, TYPE)
|
|
|
|
VOID
|
|
PcipLinkSecondaryExtension(
|
|
IN PSINGLE_LIST_ENTRY ListHead,
|
|
IN PFAST_MUTEX Mutex,
|
|
IN PVOID NewExtension,
|
|
IN PCI_SIGNATURE Type,
|
|
IN PSECONDARYEXTENSIONDESTRUCTOR Destructor
|
|
);
|
|
|
|
#define PciLinkSecondaryExtension(X,X2,T,D) \
|
|
PcipLinkSecondaryExtension(&(X)->SecondaryExtension, \
|
|
&(X)->SecondaryExtMutex, \
|
|
X2, \
|
|
T, \
|
|
D)
|
|
|
|
VOID
|
|
PcipDestroySecondaryExtension(
|
|
IN PSINGLE_LIST_ENTRY ListHead,
|
|
IN PFAST_MUTEX Mutex,
|
|
IN PVOID Extension
|
|
);
|
|
|
|
ULONGLONG
|
|
PciGetHackFlags(
|
|
IN USHORT VendorID,
|
|
IN USHORT DeviceID,
|
|
IN USHORT SubVendorID,
|
|
IN USHORT SubSystemID,
|
|
IN UCHAR RevisionID
|
|
);
|
|
|
|
NTSTATUS
|
|
PciGetDeviceProperty(
|
|
IN PDEVICE_OBJECT PhysicalDeviceObject,
|
|
IN DEVICE_REGISTRY_PROPERTY DeviceProperty,
|
|
OUT PVOID *PropertyBuffer
|
|
);
|
|
|
|
NTSTATUS
|
|
PciGetInterruptAssignment(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
OUT ULONG *Minimum,
|
|
OUT ULONG *Maximum
|
|
);
|
|
|
|
ULONG
|
|
PciGetLengthFromBar(
|
|
ULONG BaseAddressRegister
|
|
);
|
|
|
|
NTSTATUS
|
|
PciGetRegistryValue(
|
|
IN PWSTR ValueName,
|
|
IN PWSTR KeyName,
|
|
IN HANDLE ParentHandle,
|
|
IN ULONG Type,
|
|
OUT PVOID *Buffer,
|
|
OUT PULONG Length
|
|
);
|
|
|
|
VOID
|
|
PciInsertEntryAtTail(
|
|
IN PSINGLE_LIST_ENTRY ListHead,
|
|
IN PSINGLE_LIST_ENTRY NewEntry,
|
|
IN PFAST_MUTEX Mutex
|
|
);
|
|
|
|
VOID
|
|
PciInsertEntryAtHead(
|
|
IN PSINGLE_LIST_ENTRY ListHead,
|
|
IN PSINGLE_LIST_ENTRY NewEntry,
|
|
IN PFAST_MUTEX Mutex
|
|
);
|
|
|
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR
|
|
PciNextPartialDescriptor(
|
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor
|
|
);
|
|
|
|
BOOLEAN
|
|
PciOpenKey(
|
|
IN PWSTR KeyName,
|
|
IN HANDLE ParentHandle,
|
|
IN ACCESS_MASK Access,
|
|
OUT PHANDLE ChildHandle,
|
|
OUT PNTSTATUS Status
|
|
);
|
|
|
|
NTSTATUS
|
|
PciQueryBusInformation(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPNP_BUS_INFORMATION *BusInformation
|
|
);
|
|
|
|
NTSTATUS
|
|
PciQueryLegacyBusInformation(
|
|
IN PPCI_FDO_EXTENSION FdoExtension,
|
|
IN PLEGACY_BUS_INFORMATION *BusInformation
|
|
);
|
|
|
|
NTSTATUS
|
|
PciQueryCapabilities(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PDEVICE_CAPABILITIES Capabilities
|
|
);
|
|
|
|
NTSTATUS
|
|
PciRangeListFromResourceList(
|
|
IN PPCI_FDO_EXTENSION FdoExtension,
|
|
IN PCM_RESOURCE_LIST ResourceList,
|
|
IN CM_RESOURCE_TYPE DesiredType,
|
|
IN BOOLEAN Complement,
|
|
IN PRTL_RANGE_LIST ResultRange
|
|
);
|
|
|
|
UCHAR
|
|
PciReadDeviceCapability(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN UCHAR Offset,
|
|
IN UCHAR Id,
|
|
IN OUT PVOID Buffer,
|
|
IN ULONG Length
|
|
);
|
|
|
|
VOID
|
|
PciRemoveEntryFromList(
|
|
IN PSINGLE_LIST_ENTRY ListHead,
|
|
IN PSINGLE_LIST_ENTRY OldEntry,
|
|
IN PFAST_MUTEX Mutex
|
|
);
|
|
|
|
PPCI_PDO_EXTENSION
|
|
PciFindPdoByLocation(
|
|
IN ULONG BusNumber,
|
|
IN PCI_SLOT_NUMBER Slot
|
|
);
|
|
|
|
NTSTATUS
|
|
PciBuildDefaultExclusionLists(
|
|
VOID
|
|
);
|
|
|
|
NTSTATUS
|
|
PciExcludeRangesFromWindow(
|
|
IN ULONGLONG Start,
|
|
IN ULONGLONG End,
|
|
IN PRTL_RANGE_LIST ArbiterRanges,
|
|
IN PRTL_RANGE_LIST ExclusionRanges
|
|
);
|
|
|
|
NTSTATUS
|
|
PciSaveBiosConfig(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPCI_COMMON_CONFIG Config
|
|
);
|
|
|
|
NTSTATUS
|
|
PciGetBiosConfig(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN PPCI_COMMON_CONFIG Config
|
|
);
|
|
|
|
BOOLEAN
|
|
PciStringToUSHORT(
|
|
IN PWCHAR String,
|
|
OUT PUSHORT Result
|
|
);
|
|
|
|
NTSTATUS
|
|
PciSendIoctl(
|
|
IN PDEVICE_OBJECT Device,
|
|
IN ULONG IoctlCode,
|
|
IN PVOID InputBuffer OPTIONAL,
|
|
IN ULONG InputBufferLength,
|
|
IN PVOID OutputBuffer OPTIONAL,
|
|
IN ULONG OutputBufferLength
|
|
);
|
|
|
|
BOOLEAN
|
|
PciIsOnVGAPath(
|
|
IN PPCI_PDO_EXTENSION Pdo
|
|
);
|
|
|
|
BOOLEAN
|
|
PciIsSlotPresentInParentMethod(
|
|
IN PPCI_PDO_EXTENSION Pdo,
|
|
IN ULONG Method
|
|
);
|
|
|
|
NTSTATUS
|
|
PciUpdateLegacyHardwareDescription(
|
|
IN PPCI_FDO_EXTENSION Fdo
|
|
);
|
|
|
|
NTSTATUS
|
|
PciWriteDeviceSpace(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN ULONG WhichSpace,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length,
|
|
OUT PULONG LengthWritten
|
|
);
|
|
|
|
NTSTATUS
|
|
PciReadDeviceSpace(
|
|
IN PPCI_PDO_EXTENSION PdoExtension,
|
|
IN ULONG WhichSpace,
|
|
IN PVOID Buffer,
|
|
IN ULONG Offset,
|
|
IN ULONG Length,
|
|
OUT PULONG LengthRead
|
|
);
|
|
|
|
BOOLEAN
|
|
PciIsSuiteVersion(
|
|
IN USHORT Version
|
|
);
|
|
|
|
BOOLEAN
|
|
PciIsDatacenter(
|
|
);
|
|
|
|
ULONG_PTR
|
|
PciExecuteCriticalSystemRoutine(
|
|
IN ULONG_PTR Context
|
|
);
|
|
|
|
BOOLEAN
|
|
PciUnicodeStringStrStr(
|
|
IN PUNICODE_STRING SearchString,
|
|
IN PUNICODE_STRING SubString,
|
|
IN BOOLEAN CaseInsensitive
|
|
);
|
|
|
|
//
|
|
// Programming Interface encodings for PCI IDE Controllers
|
|
// BaseClass = 1, SubClass = 1
|
|
//
|
|
|
|
|
|
#define PCI_IDE_PRIMARY_NATIVE_MODE 0x01
|
|
#define PCI_IDE_PRIMARY_MODE_CHANGEABLE 0x02
|
|
#define PCI_IDE_SECONDARY_NATIVE_MODE 0x04
|
|
#define PCI_IDE_SECONDARY_MODE_CHANGEABLE 0x08
|
|
|
|
#define PCI_IS_LEGACY_IDE_CONTROLLER(_Config) \
|
|
((_Config)->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR \
|
|
&& (_Config)->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR \
|
|
&& !BITS_SET((_Config)->ProgIf, (PCI_IDE_PRIMARY_NATIVE_MODE \
|
|
| PCI_IDE_SECONDARY_NATIVE_MODE)))
|
|
|
|
#define PCI_IS_NATIVE_IDE_CONTROLLER(_Config) \
|
|
((_Config)->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR \
|
|
&& (_Config)->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR \
|
|
&& BITS_SET((_Config)->ProgIf, (PCI_IDE_PRIMARY_NATIVE_MODE \
|
|
| PCI_IDE_SECONDARY_NATIVE_MODE)))
|
|
|
|
#define PCI_IS_NATIVE_CAPABLE_IDE_CONTROLLER(_Config) \
|
|
((_Config)->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR \
|
|
&& (_Config)->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR \
|
|
&& BITS_SET((_Config)->ProgIf, (PCI_IDE_PRIMARY_MODE_CHANGEABLE \
|
|
| PCI_IDE_SECONDARY_MODE_CHANGEABLE)))
|
|
|
|
|
|
//
|
|
// _HPP method for HotPlugParameters
|
|
//
|
|
// Method (_HPP, 0) {
|
|
// Return (Package(){
|
|
// 0x00000008, // CacheLineSize in DWORDS
|
|
// 0x00000040, // LatencyTimer in PCI clocks
|
|
// 0x00000001, // Enable SERR (Boolean)
|
|
// 0x00000001 // Enable PERR (Boolean)
|
|
// })
|
|
//
|
|
|
|
#define PCI_HPP_CACHE_LINE_SIZE_INDEX 0
|
|
#define PCI_HPP_LATENCY_TIMER_INDEX 1
|
|
#define PCI_HPP_ENABLE_SERR_INDEX 2
|
|
#define PCI_HPP_ENABLE_PERR_INDEX 3
|
|
#define PCI_HPP_PACKAGE_COUNT 4
|
|
|
|
|
|
//
|
|
// Support for kernel debugger and headless ports that can't be turned off
|
|
// This is retrieved from the registry in DriverEntry and thus the bus numbers
|
|
// are how the firmware configured the machine and not necessarily the current
|
|
// settings. Luckily we saved away the BIOS config in the registry.
|
|
//
|
|
|
|
typedef struct _PCI_DEBUG_PORT {
|
|
ULONG Bus;
|
|
PCI_SLOT_NUMBER Slot;
|
|
} PCI_DEBUG_PORT, *PPCI_DEBUG_PORT;
|
|
|
|
extern PCI_DEBUG_PORT PciDebugPorts[];
|
|
extern ULONG PciDebugPortsCount;
|
|
|
|
BOOLEAN
|
|
PciIsDeviceOnDebugPath(
|
|
IN PPCI_PDO_EXTENSION Pdo
|
|
);
|
|
|
|
//
|
|
// Cardbus has extra configuration information beyond the common
|
|
// header.
|
|
//
|
|
|
|
typedef struct _TYPE2EXTRAS {
|
|
USHORT SubVendorID;
|
|
USHORT SubSystemID;
|
|
ULONG LegacyModeBaseAddress;
|
|
} TYPE2EXTRAS;
|
|
|
|
#define CARDBUS_LMBA_OFFSET \
|
|
(ULONG)(FIELD_OFFSET(PCI_COMMON_CONFIG, DeviceSpecific) + \
|
|
FIELD_OFFSET(TYPE2EXTRAS, LegacyModeBaseAddress))
|
|
|
|
|
|
//
|
|
// Hack flags for PCI devices (PDO)
|
|
//
|
|
|
|
#define PCI_HACK_NO_VIDEO_IRQ 0x0000000000000001L
|
|
#define PCI_HACK_PCMCIA_WANT_IRQ 0x0000000000000002L
|
|
#define PCI_HACK_DUAL_IDE 0x0000000000000004L
|
|
#define PCI_HACK_NO_ENUM_AT_ALL 0x0000000000000008L
|
|
#define PCI_HACK_ENUM_NO_RESOURCE 0x0000000000000010L
|
|
#define PCI_HACK_NEED_DWORD_ACCESS 0x0000000000000020L
|
|
#define PCI_HACK_SINGLE_FUNCTION 0x0000000000000040L
|
|
#define PCI_HACK_ALWAYS_ENABLED 0x0000000000000080L
|
|
#define PCI_HACK_IS_IDE 0x0000000000000100L
|
|
#define PCI_HACK_IS_VIDEO 0x0000000000000200L
|
|
#define PCI_HACK_FAIL_START 0x0000000000000400L
|
|
#define PCI_HACK_GHOST 0x0000000000000800L
|
|
#define PCI_HACK_DOUBLE_DECKER 0x0000000000001000L
|
|
#define PCI_HACK_ONE_CHILD 0x0000000000002000L
|
|
#define PCI_HACK_PRESERVE_COMMAND 0x0000000000004000L
|
|
#define PCI_HACK_IS_VGA 0x0000000000008000L
|
|
#define PCI_HACK_CB_SHARE_CMD_BITS 0x0000000000010000L
|
|
#define PCI_HACK_STRAIGHT_IRQ_ROUTING 0x0000000000020000L
|
|
#define PCI_HACK_SUBTRACTIVE_DECODE 0x0000000000040000L
|
|
#define PCI_HACK_FDMA_ISA 0x0000000000080000L
|
|
#define PCI_HACK_EXCLUSIVE 0x0000000000100000L
|
|
#define PCI_HACK_EDGE 0x0000000000200000L
|
|
#define PCI_HACK_NO_SUBSYSTEM 0x0000000000400000L
|
|
#define PCI_HACK_NO_WPE 0x0000000000800000L
|
|
#define PCI_HACK_OLD_ID 0x0000000001000000L
|
|
#define PCI_HACK_DONT_SHRINK_BRIDGE 0x0000000002000000L
|
|
#define PCI_HACK_TURN_OFF_PARITY 0x0000000004000000L
|
|
#define PCI_HACK_NO_NON_PCI_CHILD_BAR 0x0000000008000000L
|
|
#define PCI_HACK_NO_ENUM_WITH_DISABLE 0x0000000010000000L
|
|
#define PCI_HACK_NO_PM_CAPS 0x0000000020000000L
|
|
#define PCI_HACK_NO_DISABLE_DECODES 0x0000000040000000L
|
|
#define PCI_HACK_NO_SUBSYSTEM_AFTER_D3 0x0000000080000000L
|
|
#define PCI_HACK_VIDEO_LEGACY_DECODE 0x0000000100000000L
|
|
#define PCI_HACK_FAKE_CLASS_CODE 0x0000000200000000L
|
|
#define PCI_HACK_RESET_BRIDGE_ON_POWERUP 0x0000000400000000L
|
|
#define PCI_HACK_BAD_NATIVE_IDE 0x0000000800000000L
|
|
#define PCI_HACK_FAIL_QUERY_REMOVE 0x0000001000000000L
|
|
#define PCI_HACK_CRITICAL_DEVICE 0x0000002000000000L
|
|
#define PCI_HACK_OVERRIDE_CRITICAL_DEVICE 0x0000004000000000L
|
|
|
|
//
|
|
// Hack flags for PCI busses (FDO)
|
|
// NB: These are not currently applied to cardbus bridges
|
|
//
|
|
|
|
//
|
|
// PCI_BUS_HACK_LOCK_RESOURCES - prevent devices on *this* bus from
|
|
// being moved. If a BAR are unconfigured it will still be assigned
|
|
// resources from what is available on the bus. If the BAR is
|
|
// configured only those resources if available will be assigned, if
|
|
// not available the the device will fail CM_PROBLEM_RESOURCE_CONFLICT.
|
|
//
|
|
// Putting /PCILOCK in boot.ini applies this to all devices in the system.
|
|
//
|
|
#define PCI_BUS_HACK_LOCK_RESOURCES 0x00000001
|
|
|
|
//
|
|
// Random useful macros
|
|
//
|
|
|
|
#ifndef FIELD_SIZE
|
|
#define FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
|
|
#endif
|
|
|
|
//
|
|
// This macro computes if a range of bytes with configuration
|
|
// space from offset for length bytes will intersect with the
|
|
// any of the fields between field1 and field2 as defined in
|
|
// PCI_COMMON_CONFIG
|
|
//
|
|
|
|
#define INTERSECT_CONFIG_FIELD_RANGE(offset, length, field1, field2) \
|
|
INTERSECT((offset), \
|
|
(offset) + (length) - 1, \
|
|
FIELD_OFFSET(PCI_COMMON_CONFIG, field1), \
|
|
FIELD_OFFSET(PCI_COMMON_CONFIG, field2) \
|
|
+ FIELD_SIZE(PCI_COMMON_CONFIG, field2) - 1 \
|
|
)
|
|
|
|
//
|
|
// This macro computes if a range of bytes with configuration
|
|
// space from offset for length bytes will intersect with
|
|
// field as defined in PCI_COMMON_CONFIG
|
|
//
|
|
|
|
#define INTERSECT_CONFIG_FIELD(offset, length, field) \
|
|
INTERSECT_CONFIG_FIELD_RANGE(offset, length, field, field)
|
|
|
|
#endif
|
|
|
|
|