|
|
/*++
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
#define _NTDRIVER_
#define _NTSRV_
#define _NTDDK_
#include "stdio.h"
#define InitSafeBootMode TempSafeBootMode
#include "ntos.h"
#undef InitSafeBootMode
#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"
//
// regstr.h uses things of type WORD, which isn't around in kernel mode.
//
#define _IN_KERNEL_
#include "regstr.h"
//
// 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) ((x) == (x)->BusRootFdoExtension)
//
// BOOLEAN
// PCI_PDO_ON_ROOT(
// PPCI_PDO_EXTENSION x
// )
//
// Routine Description:
//
#define PCI_PDO_ON_ROOT(x) 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) \
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
} 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;
//
// 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; 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 SwitchedIDEToNativeMode; BOOLEAN BIOSAllowsIDESwitchToNativeMode; // NIDE 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; 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) \
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) \
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;
// arb_comn.h
#define PciWstrToUnicodeString(u, p) \
\ (u)->Length = ((u)->MaximumLength = sizeof((p))) - sizeof(WCHAR); \ (u)->Buffer = (p)
#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) (((C) & (F)) == (F))
//
// 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
extern PCI_DEBUG_LEVEL PciDebug;
#define PCI_DEBUG_BUFFER_SIZE 256
#define PciDebugPrint PciDebugPrintf
#else
#define PciDebugPrint if(0)
#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 PciDebugPrintf( PCI_DEBUG_LEVEL DebugPrintLevel, 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 );
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 );
#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, OUT PVOID *Buffer, OUT ULONG *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 );
VOID PciInvalidateResourceInfoCache( IN PPCI_PDO_EXTENSION PdoExtension );
PCM_PARTIAL_RESOURCE_DESCRIPTOR PciNextPartialDescriptor( PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor );
BOOLEAN PciOpenKey( IN PWSTR KeyName, IN HANDLE ParentHandle, 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 );
//
// 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
//
// 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
|