/*++ Copyright (c) 2012 Minoca Corp. All Rights Reserved Module Name: pci.h Abstract: This header contains definitions for the PCI (Peripheral Component Interconnect) driver. Author: Evan Green 17-Sep-2012 --*/ // // ------------------------------------------------------------------- Includes // #include #include #include // // --------------------------------------------------------------------- Macros // // // This macro returns the PCI class codes from the 4-byte register. // #define PCI_CLASS_CODE(_Register) (((_Register) >> 24) & 0x000000FF) #define PCI_SUBCLASS_AND_INTERFACE(_Register) (((_Register) >> 8) & 0x0000FFFF) // // ---------------------------------------------------------------- Definitions // #define PCI_ALLOCATION_TAG 0x21696350 // '!icP' #define PCI_BUS_ID "PNP0A03" #define PCI_EXPRESS_BUS_ID "PNP0A08" #define PCI_BRIDGE_CLASS_ID "PCIBridge" #define PCI_SUBTRACTIVE_BRIDGE_CLASS_ID "PCIBridgeSubtractive" #define PCI_DEVICE_ID_FORMAT "VEN_%04X&DEV_%04X" #define PCI_DEVICE_ID_SIZE 18 #define MAX_PCI_FUNCTION 7 #define MAX_PCI_DEVICE 32 #define MAX_PCI_DEVICES ((MAX_PCI_FUNCTION + 1) * (MAX_PCI_DEVICE + 1)) #define PCI_INVALID_VENDOR_ID 0xFFFF #define PCI_INITIAL_CHILD_COUNT 10 #define PCI_ROOT_CONFIG_ADDRESS 0xCF8 #define PCI_ROOT_CONFIG_DATA 0xCFC #define PCI_BRIDGE_CLASS_CODE 0x06040000 #define PCI_SUBTRACTIVE_BRIDGE_CLASS_CODE 0x06040100 // // PCI Configuration Space definitions. // #define PCI_ID_OFFSET 0x00 #define PCI_VENDOR_ID_MASK 0x0000FFFF #define PCI_DEVICE_ID_SHIFT 16 #define PCI_DEVICE_ID_MASK 0xFFFF0000 #define PCI_CONTROL_OFFSET 0x04 #define PCI_STATUS_OFFSET 0x04 #define PCI_STATUS_MASK 0xFFFF0000 #define PCI_STATUS_SHIFT 16 #define PCI_CLASS_CODE_OFFSET 0x08 #define PCI_CLASS_CODE_MASK 0xFFFFFF00 #define PCI_HEADER_TYPE_OFFSET 0x0C #define PCI_HEADER_TYPE_MASK 0x00FF0000 #define PCI_HEADER_TYPE_SHIFT 16 #define PCI_BAR_OFFSET 0x10 #define PCI_BAR_COUNT 6 #define PCI_DEFAULT_CAPABILITIES_POINTER_OFFSET 0x34 #define PCI_ALTERNATE_CAPABILITIES_POINTER_OFFSET 0x14 #define PCI_INTERRUPT_LINE_OFFSET 0x3C #define PCI_BRIDGE_BUS_NUMBERS_OFFSET 0x18 #define PCI_BRIDGE_IO_BAR_OFFSET 0x1C #define PCI_BRIDGE_MEMORY_BAR_OFFSET 0x20 #define PCI_BRIDGE_PREFETCHABLE_MEMORY_BAR_OFFSET 0x24 #define PCI_BRIDGE_PREFETCHABLE_MEMORY_BASE_HIGH_OFFSET 0x28 #define PCI_BRIDGE_PREFETCHABLE_MEMORY_LIMIT_HIGH_OFFSET 0x2C #define PCI_BRIDGE_IO_HIGH_BAR_OFFSET 0x30 #define PCI_BRIDGE_BUS_MASK 0x000000FF #define PCI_BRIDGE_SECONDARY_BUS_SHIFT 8 #define PCI_BRIDGE_SECONDARY_BUS_MASK 0x0000FF00 #define PCI_BRIDGE_SUBORDINATE_BUS_SHIFT 16 #define PCI_BRIDGE_SUBORDINATE_BUS_MASK 0x00FF0000 #define PCI_BRIDGE_SECONDARY_LATENCY_TIMER_MASK 0xFF000000 #define PCI_BRIDGE_IO_BASE_DECODE_MASK 0x000F #define PCI_BRIDGE_IO_BASE_DECODE_32_BIT 0x0001 #define PCI_BRIDGE_IO_BASE_MASK 0x00F0 #define PCI_BRIDGE_IO_LIMIT_DECODE_MASK 0x0F00 #define PCI_BRIDGE_IO_LIMIT_DECODE_32_BIT 0x0100 #define PCI_BRIDGE_IO_LIMIT_MASK 0xF000 #define PCI_BRIDGE_IO_BASE_ADDRESS_SHIFT 8 #define PCI_BRIDGE_IO_BASE_HIGH_MASK 0x0000FFFF #define PCI_BRIDGE_IO_LIMIT_HIGH_MASK 0xFFFF0000 #define PCI_BRIDGE_IO_BASE_HIGH_ADDRESS_SHIFT 16 #define PCI_BRIDGE_MEMORY_BASE_MASK 0x0000FFF0 #define PCI_BRIDGE_MEMORY_BASE_ADDRESS_SHIFT 16 #define PCI_BRIDGE_MEMORY_LIMIT_MASK 0xFFF00000 #define PCI_BRIDGE_PREFETCHABLE_MEMORY_BASE_DECODE_MASK 0x0000000F #define PCI_BRIDGE_PREFETCHABLE_MEMORY_BASE_DECODE_64_BIT 0x00000001 #define PCI_BRIDGE_PREFETCHABLE_MEMORY_BASE_MASK 0x0000FFF0 #define PCI_BRIDGE_PREFETCHABLE_MEMORY_BASE_ADDRESS_SHIFT 16 #define PCI_BRIDGE_PREFETCHABLE_MEMORY_LIMIT_MASK 0xFFF00000 #define PCI_BRIDGE_PREFETCHABLE_MEMORY_LIMIT_DECODE_MASK 0x000F0000 #define PCI_BRIDGE_PREFETCHABLE_MEMORY_LIMIT_DECODE_64_BIT 0x00010000 #define PCI_BRIDGE_PREFETCHABLE_MEMORY_HIGH_ADDRESS_SHIFT 32 #define PCI_BRIDGE_IO_GRANULARITY 4096 #define PCI_BRIDGE_MEMORY_GRANULARITY (1024 * 1024) // // PCI Control register definitions. // #define PCI_CONTROL_IO_DECODE_ENABLED 0x0001 #define PCI_CONTROL_MEMORY_DECODE_ENABLED 0x0002 #define PCI_CONTROL_BUS_MASTER_ENABLED 0x0004 #define PCI_CONTROL_SPECIAL_CYCLES_ENABLED 0x0008 #define PCI_CONTROL_WRITE_INVALIDATE_ENABLED 0x0010 #define PCI_CONTROL_VGA_PALETTE_SNOOP_ENABLED 0x0020 #define PCI_CONTROL_PARITY_ERROR_RESPONSE_ENABLED 0x0040 #define PCI_CONTROL_STEPPING_CONTROL_ENABLED 0x0080 #define PCI_CONTROL_SERR_ENABLED 0x0100 #define PCI_CONTROL_FAST_BACK_TO_BACK_ENABLED 0x0200 #define PCI_CONTROL_INTERRUPT_DISABLE 0x0400 // // PCI Status register definitions. // #define PCI_STATUS_INTERRUPT_ASSERTED 0x0008 #define PCI_STATUS_CAPABILITIES_LIST 0x0010 #define PCI_STATUS_66MHZ_CAPABLE 0x0020 #define PCI_STATUS_FAST_BACK_TO_BACK_CAPABLE 0x0080 #define PCI_STATUS_MASTER_DATA_PARITY_ERROR 0x0100 #define PCI_STATUS_DEVSEL_TIMING_MASK 0x0600 #define PCI_STATUS_DEVSEL_TIMING_SHIFT 9 #define PCI_STATUS_DEVSEL_FAST 0x0 #define PCI_STATUS_DEVSEL_MEDIUM 0x1 #define PCI_STATUS_DEVSEL_SLOW 0x2 #define PCI_STATUS_TARGET_ABORT_SIGNALED 0x0800 #define PCI_STATUS_TARGET_ABORT_RECEIVED 0x1000 #define PCI_STATUS_MASTER_ABORT_RECEIVED 0x2000 #define PCI_STATUS_SYSTEM_ERROR_SIGNALED 0x4000 #define PCI_STATUS_PARITY_ERROR_DETECTED 0x8000 // // PCI Base Address Register bit definitions. // #define PCI_BAR_MEMORY_FLAGS_MASK 0x0000000FULL #define PCI_BAR_IO_FLAGS_MASK 0x00000003 #define PCI_BAR_IO_SPACE 0x00000001 #define PCI_BAR_MEMORY_SIZE_MASK 0x0000006 #define PCI_BAR_MEMORY_32_BIT 0x00000000 #define PCI_BAR_MEMORY_1MB 0x00000002 #define PCI_BAR_MEMORY_64_BIT 0x00000004 #define PCI_BAR_MEMORY_PREFETCHABLE 0x00000008 // // PCI classes. // #define PCI_CLASS_UNKNOWN 0x00 #define PCI_CLASS_MASS_STORAGE 0x01 #define PCI_CLASS_NETWORK 0x02 #define PCI_CLASS_DISPLAY 0x03 #define PCI_CLASS_MULTIMEDIA 0x04 #define PCI_CLASS_MEMORY 0x05 #define PCI_CLASS_BRIDGE 0x06 #define PCI_CLASS_SIMPLE_COMMUNICATION 0x07 #define PCI_CLASS_GENERAL_PERIPHERAL 0x08 #define PCI_CLASS_INPUT 0x09 #define PCI_CLASS_DOCKING_STATION 0x0A #define PCI_CLASS_PROCESSOR 0x0B #define PCI_CLASS_SERIAL_BUS 0x0C #define PCI_CLASS_WIRELESS 0x0D #define PCI_CLASS_INTELLIGENT_IO 0x0E #define PCI_CLASS_SATELLITE_COMMUNICATION 0x0F #define PCI_CLASS_ENCRYPTION 0x10 #define PCI_CLASS_DATA_ACQUISITION 0x11 #define PCI_CLASS_VENDOR 0xFF // // PCI subclasses (and interfaces). // #define PCI_CLASS_UNKNOWN_NON_VGA 0x0000 #define PCI_CLASS_UNKNOWN_VGA 0x0100 #define PCI_CLASS_MASS_STORAGE_IDE_MASK 0xFF00 #define PCI_CLASS_MASS_STORAGE_IDE 0x0100 #define PCI_CLASS_BRIDGE_ISA 0x0100 #define PCI_CLASS_BRIDGE_PCI 0x0400 #define PCI_CLASS_BRIDGE_PCI_SUBTRACTIVE 0x0401 #define PCI_CLASS_SIMPLE_COMMUNICATION_XT_UART 0x0000 #define PCI_CLASS_SIMPLE_COMMUNICATION_16450 0x0001 #define PCI_CLASS_SIMPLE_COMMUNICATION_16550 0x0002 #define PCI_CLASS_SIMPLE_COMMUNICATION_PARALLEL 0x0100 #define PCI_CLASS_SIMPLE_COMMUNICATION_BIDIRECTIONAL_PARALLEL 0x0101 #define PCI_CLASS_SIMPLE_COMMUNICATION_ECP_PARALLEL 0x0102 #define PCI_CLASS_SIMPLE_COMMUNICATION_OTHER 0x8000 #define PCI_CLASS_SERIAL_BUS_USB_UHCI 0x0300 #define PCI_CLASS_SERIAL_BUS_USB_OHCI 0x0310 #define PCI_CLASS_SERIAL_BUS_USB_EHCI 0x0320 #define PCI_CLASS_GENERAL_SD_HOST_NO_DMA 0x0500 #define PCI_CLASS_GENERAL_SD_HOST 0x0501 // // Header type definitions. // #define PCI_HEADER_TYPE_STANDARD 0x00 #define PCI_HEADER_TYPE_PCI_TO_PCI_BRIDGE 0x01 #define PCI_HEADER_TYPE_CARDBUS_BRIDGE 0x02 #define PCI_HEADER_TYPE_VALUE_MASK 0x7F // // Header type flags. // #define PCI_HEADER_TYPE_FLAG_MULTIPLE_FUNCTIONS 0x80 // // Define the PCI capability pointer mask. The bottom two bits are reserved. // #define PCI_CAPABILITY_POINTER_MASK 0xFC // // PCI capability list definitions. // #define PCI_CAPABILITY_LIST_ID_MASK 0x00FF #define PCI_CAPABILITY_LIST_ID_SHIFT 0 #define PCI_CAPABILITY_LIST_NEXT_POINTER_MASK 0xFF00 #define PCI_CAPABILITY_LIST_NEXT_POINTER_SHIFT 8 // // PCI capability definitions. // #define PCI_CAPABILITY_POWER_MANAGEMENT_INTERFACE 0x01 #define PCI_CAPABILITY_ACCELERATED_GRAPHICS_PORT 0x02 #define PCI_CAPABILITY_VITAL_PRODUCT_DATA 0x03 #define PCI_CAPABILITY_SLOT_IDENTIFICATION 0x04 #define PCI_CAPABILITY_MSI 0x05 #define PCI_CAPABILITY_COMPACT_PCI_HOT_SWAP 0x06 #define PCI_CAPABILITY_PCI_X 0x07 #define PCI_CAPABILITY_HYPER_TRANSPORT 0x08 #define PCI_CAPABILITY_VENDOR_SPECIFIC 0x09 #define PCI_CAPABILITY_DEBUG_PORT 0x0A #define PCI_CAPABILITY_COMPACT_PCI_CONTROL 0x0B #define PCI_CAPABILITY_HOT_PLUG 0x0C #define PCI_CAPABILITY_BRIDGE_SUBSYSTEM_VENDOR_ID 0x0D #define PCI_CAPABILITY_ACCELERATED_GRAPHICS_PORT_8X 0x0E #define PCI_CAPABILITY_SECURE_DEVICE 0x0F #define PCI_CAPABILITY_PCI_EXPRESS 0x10 #define PCI_CAPABILITY_MSI_X 0x11 // // Define the PCI MSI flags. // #define PCI_MSI_FLAG_64_BIT_CAPABLE 0x00000001 #define PCI_MSI_FLAG_MASKABLE 0x00000002 // // ------------------------------------------------------ Data Type Definitions // typedef ULONGLONG (*PPCI_READ_CONFIG) ( UCHAR Bus, UCHAR Device, UCHAR Function, ULONG Register, ULONG AccessSize ); /*++ Routine Description: This routine reads from PCI Configuration Space. Arguments: Bus - Supplies the bus number to read from. Device - Supplies the device number to read from. Valid values are 0 to 31. Function - Supplies the PCI function to read from. Valid values are 0 to 7. Register - Supplies the configuration register to read from. AccessSize - Supplies the size of the access to make. Valid values are 1, 2, 4, and 8. Return Value: Returns the value read from the bus, or 0xFFFFFFFF on error. --*/ typedef VOID (*PPCI_WRITE_CONFIG) ( UCHAR Bus, UCHAR Device, UCHAR Function, ULONG Register, ULONG AccessSize, ULONGLONG Value ); /*++ Routine Description: This routine writes to PCI Configuration Space. Arguments: Bus - Supplies the bus number to write to. Device - Supplies the device number to write to. Valid values are 0 to 31. Function - Supplies the PCI function to write to. Valid values are 0 to 7. Register - Supplies the configuration register to write to. AccessSize - Supplies the size of the access to make. Valid values are 1, 2, 4, and 8. Value - Supplies the value to write to the register. Return Value: None. --*/ /*++ Structure Description: This structure defines a PCI child device. Members: DeviceNumber - Stores the device/slot number on the parent bus. Function - Stores the function number on the bus. VendorId - Stores the Vendor ID of the device. DeviceId - Stores the Device ID. --*/ typedef struct _PCI_CHILD { UCHAR DeviceNumber; UCHAR Function; USHORT VendorId; USHORT DeviceId; } PCI_CHILD, *PPCI_CHILD; // // This enum is a touch confusing, in that when the device type is function, // then PCI acts as the bus driver. When the device type is bus or bridge, PCI // is acting as the functional driver. // typedef enum _PCI_DEVICE_TYPE { PciDeviceInvalid, PciDeviceBus, PciDeviceBridge, PciDeviceFunction, } PCI_DEVICE_TYPE, *PPCI_DEVICE_TYPE; /*++ Structure Description: This structure defines the set of PCI Base Address Registers, also known as BARs. Members: U - Stores the union of six 32 bit BARs or three 64 bit BARs. --*/ typedef struct _PCI_BASE_ADDRESS_REGISTER_SET { union { ULONG Bar32[PCI_BAR_COUNT]; ULONGLONG Bar64[PCI_BAR_COUNT / 2]; } U; } PCI_BASE_ADDRESS_REGISTER_SET, *PPCI_BASE_ADDRESS_REGISTER_SET; /*++ Structure Description: This structure defines a PCI device's MSI/MSI-X context. Members: MsiOffset - Stores the offset into configuration space of the MSI capability. A value of 0 indicates that it does not exist. MsiXOffset - Stores the offset into configuration space of the MSI-X capability. A value of 0 indicates that it does not exist. MsiFlags - Stores a bitmask of PCI MSI flags. See PCI_MSI_FLAG_* for definitions. MsiVectorCount - Stores the number of MSI vectors currently in use. MsiMaxVectorCount - Stores the maximum number of MSI vectors supported by the device. MsiXVectorCount - Stores the number of MSI-X vectors currently in use. MsiXMaxVectorCount - Stores the maximum number of MSI-X vectors supported by the device. MsiXTable - Stores a pointer to the mapped MSI-X vector table. MsiXPendingArray - Stores a pointer to the mapped MSI-X pending bit array. MsiXTablePhysicalAddress - Stores the physical address of the MSI-X vector table. MsiXPendingArrayPhysicalAddress - Stores the physical address of the MSI-X pending bit array. Interface - Stores a pointer to the MSI/MSI-X interface. --*/ typedef struct _PCI_MSI_CONTEXT { UCHAR MsiOffset; UCHAR MsiXOffset; ULONG MsiFlags; ULONGLONG MsiVectorCount; ULONGLONG MsiMaxVectorCount; ULONGLONG MsiXVectorCount; ULONGLONG MsiXMaxVectorCount; volatile PVOID MsiXTable; volatile PVOID MsiXPendingArray; PHYSICAL_ADDRESS MsiXTablePhysicalAddress; PHYSICAL_ADDRESS MsiXPendingArrayPhysicalAddress; PINTERFACE_PCI_MSI Interface; } PCI_MSI_CONTEXT, *PPCI_MSI_CONTEXT; typedef struct _PCI_DEVICE PCI_DEVICE, *PPCI_DEVICE; /*++ Structure Description: This structure defines a PCI device. Members: Type - Stores which genre of PCI device this is. BusNumber - Stores the number of this device's PCI bus. DeviceNumber - Stores the slot number of this device. FunctionNumber - Stores the function number of this device. InterruptPin - Stores the interrupt pin that the function uses. This value comes from read-only configuration space. DeviceIsBridge - Stores a boolean indicating whether or not the device is a PCI bridge. ClassCode - Stores the class code of the device. Parent - Stores a pointer to the parent PCI device if there is one. Children - Stores an array allocated in paged pool of the device's children, if this device is a root bus or PCI bridge. ChildrenData - Stores an array allocated in paged pool of information about the device's children. This array parallels the Children array. ChildCount - Stores the number of children in the array. ChildSize - Stores the size of the children array, in elements. ReadConfig - Stores a pointer to a function used to read from configuration space for buses. WriteConfig - Stores a pointer to a function used to write to configuration space for buses. BarsRead - Stores a boolean indicating if the device's BARs have been read yet. BootConfiguration - Stores the state of the BARs as configured by the BIOS. BootControlRegister - Stores the value of the control register when the system was booted. AddressDecodeBits - Stores the values of the BARs after writing all ones to them and reading them back to see which ones stick. BarCount - Stores one higher than the index of the highest valid BAR. PciConfigInterface - Stores a pointer to the config interface. AcpiBusAddressInterface - Stores a pointer to the ACPI interface. SpecificPciConfigInterface - Stores a pointer to the specific PCI config space access interface. MsiContext - Stores a pointer to the MSI/MSI-X context if the device supports message based interrupts. --*/ struct _PCI_DEVICE { PCI_DEVICE_TYPE Type; UCHAR BusNumber; UCHAR DeviceNumber; UCHAR FunctionNumber; UCHAR InterruptPin; BOOL DeviceIsBridge; ULONG ClassCode; PPCI_DEVICE Parent; PDEVICE *Children; PPCI_CHILD *ChildrenData; ULONG ChildCount; ULONG ChildSize; PPCI_READ_CONFIG ReadConfig; PPCI_WRITE_CONFIG WriteConfig; BOOL BarsRead; PCI_BASE_ADDRESS_REGISTER_SET BootConfiguration; USHORT BootControlRegister; PCI_BASE_ADDRESS_REGISTER_SET AddressDecodeBits; ULONG BarCount; PINTERFACE_PCI_CONFIG_ACCESS PciConfigInterface; PINTERFACE_ACPI_BUS_ADDRESS AcpiBusAddressInterface; PINTERFACE_SPECIFIC_PCI_CONFIG_ACCESS SpecificPciConfigInterface; PPCI_MSI_CONTEXT MsiContext; }; /*++ Structure Description: This structure defines the interface for returning a device's PCI bus driver's device structure. This is used internally by PCI to create a complete device tree. Members: BusDevice - Stores a pointer to the bus driver context. --*/ typedef struct _INTERFACE_PCI_BUS_DEVICE { PVOID BusDevice; } INTERFACE_PCI_BUS_DEVICE, *PINTERFACE_PCI_BUS_DEVICE; // // -------------------------------------------------------------------- Globals // extern PDRIVER PciDriver; // // Store the UUID of the PCI MSI and MSI-X access. // extern UUID PciMessageSignaledInterruptsUuid; // // -------------------------------------------------------- Function Prototypes // ULONGLONG PcipRootReadConfig ( UCHAR Bus, UCHAR Device, UCHAR Function, ULONG Register, ULONG AccessSize ); /*++ Routine Description: This routine reads from PCI Configuration Space on the root PCI bus. Arguments: Bus - Supplies the bus number to read from. Device - Supplies the device number to read from. Valid values are 0 to 31. Function - Supplies the PCI function to read from. Valid values are 0 to 7. Register - Supplies the configuration register to read from. AccessSize - Supplies the size of the access to make. Valid values are 1, 2, 4, and 8. Return Value: Returns the value read from the bus, or 0xFFFFFFFF on error. --*/ VOID PcipRootWriteConfig ( UCHAR Bus, UCHAR Device, UCHAR Function, ULONG Register, ULONG AccessSize, ULONGLONG Value ); /*++ Routine Description: This routine writes to PCI Configuration Space on the PCI root bus. Arguments: Bus - Supplies the bus number to write to. Device - Supplies the device number to write to. Valid values are 0 to 31. Function - Supplies the PCI function to write to. Valid values are 0 to 7. Register - Supplies the configuration register to write to. AccessSize - Supplies the size of the access to make. Valid values are 1, 2, 4, and 8. Value - Supplies the value to write to the register. Return Value: None. --*/ KSTATUS PcipMsiCreateContextAndInterface ( PDEVICE Device, PPCI_DEVICE PciDevice ); /*++ Routine Description: This routine initializes the MSI/MSI-X context and interface for the given PCI device. Arguments: Device - Supplies a pointer to the device in need of an MSI/MSI-X context and interface. PciDevice - Supplies a pointer to the PCI device context. Return Value: Status code. --*/ VOID PcipMsiDestroyContextAndInterface ( PDEVICE Device, PPCI_DEVICE PciDevice ); /*++ Routine Description: This routine destroys the given PCI device's MSI context and interface if they exist. Arguments: Device - Supplies a pointer to the device whose MSI/MSI-x context and interface is to be destroyed. PciDevice - Supplies a pointer to the PCI device context. Return Value: None. --*/ VOID PcipGetMsiXBarInformation ( PPCI_DEVICE PciDevice, PULONG TableBarIndex, PULONG TableOffset, PULONG PendingArrayBarIndex, PULONG PendingArrayOffset ); /*++ Routine Description: This routine gets the BAR information for the MSI-X table and pending bit array out of PCI configuration space. Arguments: PciDevice - Supplies a pointer to the PCI device context. TableBarIndex - Supplies a pointer that receives the index of the BAR within which the MSI-X table resides. TableOffset - Supplies a pointer that receives the offset within the BAR of the MSI-X table. PendingArrayBarIndex - Supplies a pointer that receives the index of the BAR within which the MSI-X pending bit array resides. PendingArrayOffset - Supplies a pointer that receives the offset within the BAR of the MSI-X pending bit array. Return Value: None. --*/