ReactOS 0.4.17-dev-923-g4c9a150
express.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS PCI Bus Driver
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: PCI Express Capability Support
5 * COPYRIGHT: Copyright 2026 Justin Miller <justin.miller@reactos.org>
6 */
7
8/* INCLUDES *******************************************************************/
9
10#include <pci.h>
11
12#define NDEBUG
13#include <debug.h>
14
15/* FUNCTIONS ******************************************************************/
16
17static
22{
23 if ((Offset & 3) || (Offset < PCI_LEGACY_CONFIG_LENGTH))
24 return FALSE;
25
28}
29
40 _In_ PPCI_PDO_EXTENSION DeviceExtension,
41 _In_ ULONG CapabilityId,
44{
46 ULONG Offset, EntriesLeft;
47
48 ASSERT(DeviceExtension->ExtensionType == PciPdoExtensionType);
50
51 if (!DeviceExtension->IsExtendedConfigReachable)
52 return 0;
53
54 /* More entries than aligned offsets means the list loops */
56
58 {
60 return 0;
61
62 if (EntriesLeft == 0)
63 {
64 DPRINT1("PCI device %p extended capabilities list is broken\n",
65 DeviceExtension);
66 return 0;
67 }
68 EntriesLeft--;
69
70 PciReadDeviceConfig(DeviceExtension, &Header, Offset, sizeof(Header));
71
72 /* A function that does not decode extended space reads back all ones */
73 if (Header.CapabilityID == 0xFFFF)
74 return 0;
75
76 if (Header.CapabilityID != CapabilityId)
77 continue;
78
80 return 0;
81
82 PciReadDeviceConfig(DeviceExtension, Buffer, Offset, Length);
83 return Offset;
84 }
85
86 return 0;
87}
88
97VOID
101{
103 PPCI_FDO_EXTENSION ParentFdo;
104 PPCI_PDO_EXTENSION ParentBridge;
106 PAGED_CODE();
107
108 PdoExtension->ExpressCapabilityPtr = 0;
109 PdoExtension->ExpressDeviceType = 0;
110 PdoExtension->IsExtendedConfigReachable = FALSE;
111
112 if (!PdoExtension->CapabilitiesPtr)
113 return;
114
115 if (PdoExtension->HackFlags & PCI_HACK_NO_EXPRESS_CAP)
116 return;
117
118 /* Only the capabilities register is needed */
120 PdoExtension->CapabilitiesPtr,
122 &Express.Header,
124 ExpressCapabilities));
125 if (!Offset)
126 return;
127
128 PdoExtension->ExpressCapabilityPtr = Offset;
129 PdoExtension->ExpressDeviceType = (UCHAR)Express.ExpressCapabilities.DeviceType;
130
131 /* Every bridge between the root and this function has to pass extended config cycles */
132 ParentFdo = PdoExtension->ParentFdoExtension;
133 if (PCI_IS_ROOT_FDO(ParentFdo))
134 {
135 PdoExtension->IsExtendedConfigReachable = PciEcamVerified;
136 }
137 else
138 {
139 ParentBridge = (PPCI_PDO_EXTENSION)ParentFdo->PhysicalDeviceObject->DeviceExtension;
140 ASSERT_PDO(ParentBridge);
141 PdoExtension->IsExtendedConfigReachable = ParentBridge->IsExtendedConfigReachable;
142 }
143
144 DPRINT1("PCI - Express capability at 0x%x, port type %u, version %u\n",
145 PdoExtension->ExpressCapabilityPtr,
146 PdoExtension->ExpressDeviceType,
148}
149
150/* EOF */
#define PAGED_CODE()
unsigned char BOOLEAN
Definition: actypes.h:127
#define DPRINT1
Definition: precomp.h:8
Definition: bufpool.h:45
Definition: Header.h:9
#define FALSE
Definition: types.h:117
struct _PCI_PDO_EXTENSION * PPCI_PDO_EXTENSION
#define PCI_IS_ROOT_FDO(x)
Definition: pci.h:32
BOOLEAN PciEcamVerified
Definition: ecam.c:20
#define PCI_LEGACY_CONFIG_LENGTH
Definition: pci.h:77
UCHAR NTAPI PciReadDeviceCapability(IN PPCI_PDO_EXTENSION DeviceExtension, IN UCHAR Offset, IN ULONG CapabilityId, OUT PPCI_CAPABILITIES_HEADER Buffer, IN ULONG Length)
Definition: utils.c:885
#define ASSERT_PDO(x)
Definition: pci.h:38
VOID NTAPI PciReadDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:149
@ PciPdoExtensionType
Definition: pci.h:104
@ PdoExtension
Definition: precomp.h:49
static BOOLEAN NTAPI PciIsExtendedCapabilityOffsetValid(_In_ ULONG Offset)
Definition: express.c:20
VOID NTAPI PciGetExpressCapabilities(_Inout_ PPCI_PDO_EXTENSION PdoExtension)
Records the Express capability of a new function and whether its extended configuration space can be ...
Definition: express.c:99
ULONG NTAPI PciReadDeviceExtendedCapability(_In_ PPCI_PDO_EXTENSION DeviceExtension, _In_ ULONG CapabilityId, _Out_writes_bytes_(Length) PPCI_EXPRESS_ENHANCED_CAPABILITY_HEADER Buffer, _In_ ULONG Length)
Finds an extended capability and reads it into the caller's buffer.
Definition: express.c:39
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:684
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define PCI_HACK_NO_EXPRESS_CAP
Definition: pci.h:30
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PCI_CAPABILITIES_HEADER Header
Definition: iotypes.h:5128
PCI_EXPRESS_CAPABILITIES_REGISTER ExpressCapabilities
Definition: iotypes.h:5129
PDEVICE_OBJECT PhysicalDeviceObject
Definition: pci.h:210
BOOLEAN IsExtendedConfigReachable
Definition: pci.h:333
unsigned char UCHAR
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
uint32_t ULONG
Definition: typedefs.h:59
#define PCI_EXTENDED_CONFIG_LENGTH
Definition: iotypes.h:3598
#define PCI_CAPABILITY_ID_PCI_EXPRESS
Definition: iotypes.h:3664