ReactOS 0.4.17-dev-966-gf06eace
utils.c File Reference
#include <pci.h>
#include <debug.h>
Include dependency graph for utils.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

BOOLEAN NTAPI PciUnicodeStringStrStr (IN PUNICODE_STRING InputString, IN PCUNICODE_STRING EqualString, IN BOOLEAN CaseInSensitive)
 
BOOLEAN NTAPI PciStringToUSHORT (IN PWCHAR String, OUT PUSHORT Value)
 
BOOLEAN NTAPI PciIsSuiteVersion (IN USHORT SuiteMask)
 
BOOLEAN NTAPI PciIsDatacenter (VOID)
 
BOOLEAN NTAPI PciOpenKey (IN PWCHAR KeyName, IN HANDLE RootKey, IN ACCESS_MASK DesiredAccess, OUT PHANDLE KeyHandle, OUT PNTSTATUS KeyStatus)
 
NTSTATUS NTAPI PciGetRegistryValue (IN PWCHAR ValueName, IN PWCHAR KeyName, IN HANDLE RootHandle, IN ULONG Type, OUT PVOID *OutputBuffer, OUT PULONG OutputLength)
 
NTSTATUS NTAPI PciBuildDefaultExclusionLists (VOID)
 
PPCI_FDO_EXTENSION NTAPI PciFindParentPciFdoExtension (IN PDEVICE_OBJECT DeviceObject, IN PKEVENT Lock)
 
VOID NTAPI PciInsertEntryAtTail (IN PSINGLE_LIST_ENTRY ListHead, IN PPCI_FDO_EXTENSION DeviceExtension, IN PKEVENT Lock)
 
VOID NTAPI PciInsertEntryAtHead (IN PSINGLE_LIST_ENTRY ListHead, IN PSINGLE_LIST_ENTRY Entry, IN PKEVENT Lock)
 
VOID NTAPI PcipLinkSecondaryExtension (IN PSINGLE_LIST_ENTRY List, IN PVOID Lock, IN PPCI_SECONDARY_EXTENSION SecondaryExtension, IN PCI_SIGNATURE ExtensionType, IN PVOID Destructor)
 
NTSTATUS NTAPI PciGetDeviceProperty (IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, OUT PVOID *OutputBuffer)
 
NTSTATUS NTAPI PciSendIoctl (IN PDEVICE_OBJECT DeviceObject, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength)
 
PPCI_SECONDARY_EXTENSION NTAPI PciFindNextSecondaryExtension (IN PSINGLE_LIST_ENTRY ListHead, IN PCI_SIGNATURE ExtensionType)
 
ULONGLONG NTAPI PciGetHackFlags (IN USHORT VendorId, IN USHORT DeviceId, IN USHORT SubVendorId, IN USHORT SubSystemId, IN UCHAR RevisionId)
 
BOOLEAN NTAPI PciIsCriticalDeviceClass (IN UCHAR BaseClass, IN UCHAR SubClass)
 
PPCI_PDO_EXTENSION NTAPI PciFindPdoByFunction (IN PPCI_FDO_EXTENSION DeviceExtension, IN ULONG FunctionNumber, IN PPCI_COMMON_HEADER PciData)
 
BOOLEAN NTAPI PciIsDeviceOnDebugPath (IN PPCI_PDO_EXTENSION DeviceExtension)
 
NTSTATUS NTAPI PciGetBiosConfig (IN PPCI_PDO_EXTENSION DeviceExtension, OUT PPCI_COMMON_HEADER PciData)
 
NTSTATUS NTAPI PciSaveBiosConfig (IN PPCI_PDO_EXTENSION DeviceExtension, IN PPCI_COMMON_HEADER PciData)
 
UCHAR NTAPI PciReadDeviceCapability (IN PPCI_PDO_EXTENSION DeviceExtension, IN UCHAR Offset, IN ULONG CapabilityId, OUT PPCI_CAPABILITIES_HEADER Buffer, IN ULONG Length)
 
BOOLEAN NTAPI PciCanDisableDecodes (IN PPCI_PDO_EXTENSION DeviceExtension, IN PPCI_COMMON_HEADER Config, IN ULONGLONG HackFlags, IN BOOLEAN ForPowerDown)
 
PCI_DEVICE_TYPES NTAPI PciClassifyDeviceType (IN PPCI_PDO_EXTENSION PdoExtension)
 
ULONG_PTR NTAPI PciExecuteCriticalSystemRoutine (IN ULONG_PTR IpiContext)
 
BOOLEAN NTAPI PciIsSlotPresentInParentMethod (IN PPCI_PDO_EXTENSION PdoExtension, IN ULONG Method)
 
BOOLEAN NTAPI PciCreateIoDescriptorFromBarLimit (_Out_ PIO_RESOURCE_DESCRIPTOR ResourceDescriptor, _In_ ULONG Bar, _In_ ULONG NextBar, _In_ BOOLEAN Rom)
 Builds the requirement of a BAR from the value it reads back after all ones were written to it.
 
VOID NTAPI PciDecodeEnable (IN PPCI_PDO_EXTENSION PdoExtension, IN BOOLEAN Enable, OUT PUSHORT Command)
 
NTSTATUS NTAPI PciQueryBusInformation (IN PPCI_PDO_EXTENSION PdoExtension, OUT PPNP_BUS_INFORMATION *Buffer)
 
NTSTATUS NTAPI PciDetermineSlotNumber (IN PPCI_PDO_EXTENSION PdoExtension, OUT PULONG SlotNumber)
 
NTSTATUS NTAPI PciGetDeviceCapabilities (IN PDEVICE_OBJECT DeviceObject, IN OUT PDEVICE_CAPABILITIES DeviceCapability)
 
NTSTATUS NTAPI PciQueryPowerCapabilities (IN PPCI_PDO_EXTENSION PdoExtension, IN PDEVICE_CAPABILITIES DeviceCapability)
 
NTSTATUS NTAPI PciQueryCapabilities (IN PPCI_PDO_EXTENSION PdoExtension, IN OUT PDEVICE_CAPABILITIES DeviceCapability)
 

Variables

ULONG PciDebugPortsCount
 
RTL_RANGE_LIST PciIsaBitExclusionList
 
RTL_RANGE_LIST PciVgaAndIsaBitExclusionList
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file utils.c.

Function Documentation

◆ PciBuildDefaultExclusionLists()

NTSTATUS NTAPI PciBuildDefaultExclusionLists ( VOID  )

Definition at line 275 of file utils.c.

276{
277 ULONG Start;
281
282 /* Initialize the range lists */
285
286 /* Loop x86 I/O ranges */
287 for (Start = 0x100; Start <= 0xFEFF; Start += 0x400)
288 {
289 /* Add the ISA I/O ranges */
291 Start,
292 Start + 0x2FF,
293 0,
295 NULL,
296 NULL);
297 if (!NT_SUCCESS(Status)) break;
298
299 /* Add the ISA I/O ranges */
301 Start,
302 Start + 0x2AF,
303 0,
305 NULL,
306 NULL);
307 if (!NT_SUCCESS(Status)) break;
308
309 /* Add the VGA I/O range for Monochrome Video */
311 Start + 0x2BC,
312 Start + 0x2BF,
313 0,
315 NULL,
316 NULL);
317 if (!NT_SUCCESS(Status)) break;
318
319 /* Add the VGA I/O range for certain CGA adapters */
321 Start + 0x2E0,
322 Start + 0x2FF,
323 0,
325 NULL,
326 NULL);
327 if (!NT_SUCCESS(Status)) break;
328
329 /* Success, ranges added done */
330 };
331
334 return Status;
335}
static _Out_opt_ PULONGLONG Start
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
RTL_RANGE_LIST PciVgaAndIsaBitExclusionList
Definition: utils.c:21
RTL_RANGE_LIST PciIsaBitExclusionList
Definition: utils.c:20
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:44
NTSYSAPI NTSTATUS NTAPI RtlAddRange(_Inout_ PRTL_RANGE_LIST RangeList, _In_ ULONGLONG Start, _In_ ULONGLONG End, _In_ UCHAR Attributes, _In_ ULONG Flags, _In_opt_ PVOID UserData, _In_opt_ PVOID Owner)
NTSYSAPI VOID NTAPI RtlInitializeRangeList(_Out_ PRTL_RANGE_LIST RangeList)
NTSYSAPI VOID NTAPI RtlFreeRangeList(_In_ PRTL_RANGE_LIST RangeList)
#define RTL_RANGE_LIST_ADD_IF_CONFLICT
Definition: rtltypes.h:81
uint32_t ULONG
Definition: typedefs.h:59

Referenced by DriverEntry().

◆ PciCanDisableDecodes()

BOOLEAN NTAPI PciCanDisableDecodes ( IN PPCI_PDO_EXTENSION  DeviceExtension,
IN PPCI_COMMON_HEADER  Config,
IN ULONGLONG  HackFlags,
IN BOOLEAN  ForPowerDown 
)

Definition at line 954 of file utils.c.

958{
959 UCHAR BaseClass, SubClass;
960 BOOLEAN IsVga, KeepPower = FALSE;
961
962 /* Is there a device extension or should the PCI header be used? */
963 if (DeviceExtension)
964 {
965 /* Never disable decodes for a debug PCI Device */
966 if (DeviceExtension->OnDebugPath) return FALSE;
967
968 /* Hack flags will be obtained from the extension, not the caller */
969 ASSERT(HackFlags == 0);
970
971 /* Get hacks and classification from the device extension */
972 HackFlags = DeviceExtension->HackFlags;
973 SubClass = DeviceExtension->SubClass;
974 BaseClass = DeviceExtension->BaseClass;
975 KeepPower = DeviceExtension->DisablePowerDown;
976 }
977 else
978 {
979 /* There must be a PCI header, go read the classification information */
980 ASSERT(Config != NULL);
981 BaseClass = Config->BaseClass;
982 SubClass = Config->SubClass;
983 }
984
985 /* Check for hack flags that prevent disabling the decodes */
990 {
991 /* Don't do it */
992 return FALSE;
993 }
994
995 if (ForPowerDown)
996 {
997 /* IDE controllers, legacy bridges and flagged functions may stop but not power down */
998 if (KeepPower || (HackFlags & PCI_HACK_NEVER_POWER_DOWN))
999 return FALSE;
1000 }
1002 {
1003 /* Flagged functions may power down, but keep decoding while stopped or removed */
1004 return FALSE;
1005 }
1006
1007 /* VGA adapters keep decoding unless they are being powered down */
1008 if (((BaseClass == PCI_CLASS_DISPLAY_CTLR) && (SubClass == PCI_SUBCLASS_VID_VGA_CTLR)) ||
1009 ((BaseClass == PCI_CLASS_PRE_20) && (SubClass == PCI_SUBCLASS_PRE_20_VGA)))
1010 {
1011 return ForPowerDown;
1012 }
1013
1014 if (BaseClass == PCI_CLASS_BRIDGE_DEV)
1015 {
1016 /* Check for legacy bridges */
1017 if ((SubClass == PCI_SUBCLASS_BR_ISA) ||
1018 (SubClass == PCI_SUBCLASS_BR_EISA) ||
1019 (SubClass == PCI_SUBCLASS_BR_MCA) ||
1020 (SubClass == PCI_SUBCLASS_BR_HOST) ||
1021 (SubClass == PCI_SUBCLASS_BR_OTHER))
1022 {
1023 /* Never disable these */
1024 return FALSE;
1025 }
1026 else if ((SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI) ||
1027 (SubClass == PCI_SUBCLASS_BR_CARDBUS))
1028 {
1029 /* This is a supported bridge, but does it have a VGA card? */
1030 if (!DeviceExtension)
1031 {
1032 /* Read the bridge control flag from the PCI header */
1033 IsVga = Config->u.type1.BridgeControl & PCI_ENABLE_BRIDGE_VGA;
1034 }
1035 else
1036 {
1037 /* Read the cached flag in the device extension */
1038 IsVga = DeviceExtension->Dependent.type1.VgaBitSet;
1039 }
1040
1041 /* A bridge forwarding VGA follows the same rule as the adapter behind it */
1042 if (IsVga)
1043 return ForPowerDown;
1044 }
1045 }
1046
1047 /* Nothing else has to keep decoding */
1048 return TRUE;
1049}
unsigned char BOOLEAN
Definition: actypes.h:127
_In_ ULONG_PTR HackFlags
Definition: cdrom.h:983
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define PCI_HACK_PRESERVE_COMMAND
Definition: pci.h:25
#define PCI_ENABLE_BRIDGE_VGA
Definition: pci.h:63
#define PCI_HACK_CB_SHARE_CMD_BITS
Definition: pci.h:27
#define PCI_HACK_NEVER_DISCONNECT
Definition: pci.h:17
#define PCI_HACK_DONT_DISABLE
Definition: pci.h:18
#define PCI_HACK_NEVER_POWER_DOWN
Definition: pci.h:41
#define PCI_HACK_KEEP_DECODES_ON_STOP
Definition: pci.h:12
unsigned char UCHAR
Definition: typedefs.h:53
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:476
#define PCI_SUBCLASS_BR_OTHER
Definition: iotypes.h:4173
#define PCI_SUBCLASS_BR_EISA
Definition: iotypes.h:4166
#define PCI_SUBCLASS_BR_HOST
Definition: iotypes.h:4164
#define PCI_SUBCLASS_BR_PCI_TO_PCI
Definition: iotypes.h:4168
#define PCI_SUBCLASS_BR_MCA
Definition: iotypes.h:4167
#define PCI_SUBCLASS_BR_ISA
Definition: iotypes.h:4165
#define PCI_CLASS_BRIDGE_DEV
Definition: iotypes.h:4111
#define PCI_SUBCLASS_BR_CARDBUS
Definition: iotypes.h:4171
#define PCI_CLASS_PRE_20
Definition: iotypes.h:4105
#define PCI_SUBCLASS_VID_VGA_CTLR
Definition: iotypes.h:4147
#define PCI_SUBCLASS_PRE_20_VGA
Definition: iotypes.h:4127
#define PCI_CLASS_DISPLAY_CTLR
Definition: iotypes.h:4108

Referenced by PciDecodeEnable(), and PciSetPowerManagedDevicePowerState().

◆ PciClassifyDeviceType()

PCI_DEVICE_TYPES NTAPI PciClassifyDeviceType ( IN PPCI_PDO_EXTENSION  PdoExtension)

Definition at line 1053 of file utils.c.

1054{
1055 ASSERT(PdoExtension->ExtensionType == PciPdoExtensionType);
1056
1057 /* Differentiate between devices and bridges */
1058 if (PdoExtension->BaseClass != PCI_CLASS_BRIDGE_DEV) return PciTypeDevice;
1059
1060 /* The PCI Bus driver handles only CardBus and PCI bridges (plus host) */
1061 if (PdoExtension->SubClass == PCI_SUBCLASS_BR_HOST) return PciTypeHostBridge;
1064
1065 /* Any other kind of bridge is treated like a device */
1066 return PciTypeDevice;
1067}
@ PciTypeHostBridge
Definition: pci.h:128
@ PciTypeDevice
Definition: pci.h:131
@ PciTypePciBridge
Definition: pci.h:129
@ PciTypeCardbusBridge
Definition: pci.h:130
@ PciPdoExtensionType
Definition: pci.h:104
@ PdoExtension
Definition: precomp.h:49

Referenced by PciProcessBus().

◆ PciCreateIoDescriptorFromBarLimit()

BOOLEAN NTAPI PciCreateIoDescriptorFromBarLimit ( _Out_ PIO_RESOURCE_DESCRIPTOR  ResourceDescriptor,
_In_ ULONG  Bar,
_In_ ULONG  NextBar,
_In_ BOOLEAN  Rom 
)

Builds the requirement of a BAR from the value it reads back after all ones were written to it.

Parameters
[out]ResourceDescriptorReceives the requirement, or a null descriptor when the BAR is not implemented.
[in]BarThe probed BAR.
[in]NextBarThe probed BAR after it, which holds the high half of a 64-bit BAR. 0 when there is none.
[in]RomTRUE when Bar is an expansion ROM BAR.
Returns
TRUE when the BAR is 64-bit, so the BAR after it is not a BAR of its own.

Definition at line 1179 of file utils.c.

1184{
1185 ULONGLONG AddressBits, Length, Alignment;
1187 UCHAR Type;
1188 BOOLEAN Is64BitBar = FALSE;
1189
1190 /* Check if the BAR is nor I/O nor memory */
1191 if (!(Bar & ~PCI_ADDRESS_IO_SPACE))
1192 {
1193 /* Fail this descriptor */
1194 ResourceDescriptor->Type = CmResourceTypeNull;
1195 return FALSE;
1196 }
1197
1198 /* Set default flag */
1199 ResourceDescriptor->Flags = 0;
1200
1201 /* Check for ROM AddressBits */
1202 if (Rom)
1203 {
1204 /* Clean up the BAR to get just the address */
1206 if (!Bar)
1207 {
1208 /* Invalid ar, fail this descriptor */
1209 ResourceDescriptor->Type = CmResourceTypeNull;
1210 return FALSE;
1211 }
1212
1213 /* ROM Addresses are always read only */
1214 ResourceDescriptor->Flags = CM_RESOURCE_MEMORY_READ_ONLY;
1215 }
1216
1217 /* Check what kind of BAR this is */
1219 {
1220 /* Set this as an I/O Port descriptor */
1222 ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;
1223 AddressBits = Bar & PCI_ADDRESS_IO_ADDRESS_MASK;
1224 }
1225 else
1226 {
1227 /* Set this as a memory descriptor */
1229 AddressBits = Bar & PCI_ADDRESS_MEMORY_ADDRESS_MASK;
1230
1231 /* A 64-bit BAR takes the high half of its address from the next BAR */
1233 {
1234 AddressBits |= (ULONGLONG)NextBar << 32;
1235 Is64BitBar = TRUE;
1236 }
1237
1238 /* Check if the BAR is listed as prefetchable memory */
1240 {
1241 /* Mark the descriptor in the same way */
1242 ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE;
1243 }
1244 }
1245
1246 /* The probe leaves only the bits the BAR implements, so the lowest one is its length */
1247 Length = AddressBits & (~AddressBits + 1);
1248
1249 /* A BAR that implements no address bits is not there */
1250 if (!Length)
1251 {
1252 ResourceDescriptor->Type = CmResourceTypeNull;
1253 return FALSE;
1254 }
1255
1256 /* A legacy memory BAR can only be placed below 1MB */
1257 if ((Type == CmResourceTypeMemory) &&
1259 {
1260 AddressBits &= 0xFFFFF;
1261 }
1262
1263 /* A BAR aligns to its own length and decodes nothing above the bits it implements */
1264 Alignment = Length;
1265 MinimumAddress = 0;
1266 MaximumAddress = AddressBits | (Length - 1);
1267
1268 /* A length of 4GB or more takes the large memory form */
1269 if (!NT_SUCCESS(RtlIoEncodeMemIoResource(ResourceDescriptor,
1270 Type,
1271 Length,
1272 Alignment,
1275 {
1276 /* Fail this descriptor */
1277 ResourceDescriptor->Type = CmResourceTypeNull;
1278 }
1279
1280 /* Return if this is a 64-bit BAR, so the loop code knows to skip the next one */
1281 return Is64BitBar;
1282}
static _Out_opt_ PULONGLONG _Out_opt_ PULONGLONG MinimumAddress
static _Out_opt_ PULONGLONG _Out_opt_ PULONGLONG _Out_opt_ PULONGLONG MaximumAddress
Type
Definition: Type.h:7
union Alignment_ Alignment
void Bar(void)
Definition: terminate.cpp:70
#define CM_RESOURCE_MEMORY_PREFETCHABLE
Definition: cmtypes.h:125
#define CM_RESOURCE_PORT_IO
Definition: cmtypes.h:109
#define CM_RESOURCE_MEMORY_READ_ONLY
Definition: cmtypes.h:122
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define CmResourceTypeNull
Definition: restypes.h:103
#define CmResourceTypeMemory
Definition: restypes.h:106
#define CmResourceTypePort
Definition: restypes.h:104
uint64_t ULONGLONG
Definition: typedefs.h:67
#define PCI_TYPE_64BIT
Definition: iotypes.h:4242
#define PCI_ADDRESS_IO_ADDRESS_MASK
Definition: iotypes.h:4236
#define PCI_ADDRESS_IO_SPACE
Definition: iotypes.h:4233
#define PCI_TYPE_20BIT
Definition: iotypes.h:4241
#define PCI_ADDRESS_ROM_ADDRESS_MASK
Definition: iotypes.h:4238
#define PCI_ADDRESS_MEMORY_ADDRESS_MASK
Definition: iotypes.h:4237
#define PCI_ADDRESS_MEMORY_PREFETCHABLE
Definition: iotypes.h:4235
#define PCI_ADDRESS_MEMORY_TYPE_MASK
Definition: iotypes.h:4234
NTSYSAPI NTSTATUS NTAPI RtlIoEncodeMemIoResource(_In_ struct _IO_RESOURCE_DESCRIPTOR *Descriptor, _In_ UCHAR Type, _In_ ULONGLONG Length, _In_ ULONGLONG Alignment, _In_ ULONGLONG MinimumAddress, _In_ ULONGLONG MaximumAddress)

Referenced by Device_SaveLimits(), and PPBridge_SaveLimits().

◆ PciDecodeEnable()

VOID NTAPI PciDecodeEnable ( IN PPCI_PDO_EXTENSION  PdoExtension,
IN BOOLEAN  Enable,
OUT PUSHORT  Command 
)

Definition at line 1286 of file utils.c.

1289{
1290 USHORT CommandValue;
1291
1292 /*
1293 * If decodes are being disabled, make sure it's allowed, and in both cases,
1294 * make sure that a hackflag isn't preventing touching the decodes at all.
1295 */
1296 if (((Enable) || (PciCanDisableDecodes(PdoExtension, 0, 0, 0))) &&
1298 {
1299 /* Did the caller already have a command word? */
1300 if (Command)
1301 {
1302 /* Use the caller's */
1303 CommandValue = *Command;
1304 }
1305 else
1306 {
1307 /* Otherwise, read the current command */
1309 &Command,
1311 sizeof(USHORT));
1312 }
1313
1314 /* Turn off decodes by default */
1315 CommandValue &= ~(PCI_ENABLE_IO_SPACE |
1318
1319 /* If requested, enable the decodes that were enabled at init time */
1320 if (Enable) CommandValue |= PdoExtension->CommandEnables &
1324
1325 /* Update the command word */
1327 &CommandValue,
1329 sizeof(USHORT));
1330 }
1331}
VOID NTAPI PciWriteDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:133
VOID NTAPI PciReadDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:149
BOOLEAN NTAPI PciCanDisableDecodes(IN PPCI_PDO_EXTENSION DeviceExtension, IN PPCI_COMMON_HEADER Config, IN ULONGLONG HackFlags, IN BOOLEAN ForPowerDown)
Definition: utils.c:954
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
unsigned short USHORT
Definition: pedump.c:61
Definition: shell.h:41
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define PCI_ENABLE_BUS_MASTER
Definition: iotypes.h:3620
#define PCI_ENABLE_IO_SPACE
Definition: iotypes.h:3618
#define PCI_ENABLE_MEMORY_SPACE
Definition: iotypes.h:3619

Referenced by PciApplyHacks(), PciConfigureIdeController(), and PcipUpdateHardware().

◆ PciDetermineSlotNumber()

NTSTATUS NTAPI PciDetermineSlotNumber ( IN PPCI_PDO_EXTENSION  PdoExtension,
OUT PULONG  SlotNumber 
)

Definition at line 1358 of file utils.c.

1360{
1361 PPCI_FDO_EXTENSION ParentExtension;
1364 PSLOT_INFO SlotInfo;
1365
1366 /* Check if a $PIR from the BIOS is used (legacy IRQ routing) */
1367 ParentExtension = PdoExtension->ParentFdoExtension;
1368 DPRINT1("Slot lookup for %d.%u.%u\n",
1369 ParentExtension ? ParentExtension->BaseBus : -1,
1370 PdoExtension->Slot.u.bits.DeviceNumber,
1371 PdoExtension->Slot.u.bits.FunctionNumber);
1372 if ((PciIrqRoutingTable) && (ParentExtension))
1373 {
1374 /* Read every slot information entry */
1375 SlotInfo = &PciIrqRoutingTable->Slot[0];
1376 DPRINT1("$PIR %p is %lx bytes, slot 0 is at: %p\n",
1378 while (SlotInfo < (PSLOT_INFO)((ULONG_PTR)PciIrqRoutingTable +
1380 {
1381 DPRINT1("Slot Info: %u.%u->#%u\n",
1382 SlotInfo->BusNumber,
1383 SlotInfo->DeviceNumber,
1384 SlotInfo->SlotNumber);
1385
1386 /* Check if this slot information matches the PDO being queried */
1387 if ((ParentExtension->BaseBus == SlotInfo->BusNumber) &&
1388 (PdoExtension->Slot.u.bits.DeviceNumber == SlotInfo->DeviceNumber >> 3) &&
1389 (SlotInfo->SlotNumber))
1390 {
1391 /* We found it, return it and return success */
1392 *SlotNumber = SlotInfo->SlotNumber;
1393 return STATUS_SUCCESS;
1394 }
1395
1396 /* Try the next slot */
1397 SlotInfo++;
1398 }
1399 }
1400
1401 /* Otherwise, grab the parent FDO and check if it's the root */
1402 if (PCI_IS_ROOT_FDO(ParentExtension))
1403 {
1404 /* The root FDO doesn't have a slot number */
1406 }
1407 else
1408 {
1409 /* Otherwise, query the slot/UI address/number as a device property */
1412 sizeof(ULONG),
1413 SlotNumber,
1414 &ResultLength);
1415 }
1416
1417 /* Return the status of this endeavour */
1418 return Status;
1419}
#define DPRINT1
Definition: precomp.h:8
PPCI_IRQ_ROUTING_TABLE PciIrqRoutingTable
Definition: init.c:26
#define PCI_IS_ROOT_FDO(x)
Definition: pci.h:32
NTSTATUS NTAPI IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength)
Definition: pnpmgr.c:1382
#define STATUS_SUCCESS
Definition: shellext.h:65
PDEVICE_OBJECT PhysicalDeviceObject
Definition: pci.h:210
BOOLEAN BaseBus
Definition: pci.h:221
SLOT_INFO Slot[ANYSIZE_ARRAY]
Definition: pci.h:99
USHORT TableSize
Definition: pci.h:91
Definition: pci.h:79
UCHAR DeviceNumber
Definition: pci.h:81
UCHAR BusNumber
Definition: pci.h:80
UCHAR SlotNumber
Definition: pci.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3782
_In_ WDFIORESREQLIST _In_ ULONG SlotNumber
Definition: wdfresource.h:68
@ DevicePropertyUINumber
Definition: iotypes.h:1212

Referenced by PciQueryCapabilities().

◆ PciExecuteCriticalSystemRoutine()

ULONG_PTR NTAPI PciExecuteCriticalSystemRoutine ( IN ULONG_PTR  IpiContext)

Definition at line 1071 of file utils.c.

1072{
1074
1075 /* Check if the IPI is already running */
1076 if (!InterlockedDecrement(&Context->RunCount))
1077 {
1078 /* Nope, this is the first instance, so execute the IPI function */
1079 Context->Function(Context->DeviceExtension, Context->Context);
1080
1081 /* Notify anyone that was spinning that they can stop now */
1082 Context->Barrier = 0;
1083 }
1084 else
1085 {
1086 /* Spin until it has finished running */
1087 while (Context->Barrier);
1088 }
1089
1090 /* Done */
1091 return 0;
1092}
#define InterlockedDecrement
Definition: armddk.h:52
struct _PCI_IPI_CONTEXT * PPCI_IPI_CONTEXT
_In_ PVOID Context
Definition: storport.h:2269
PCI_IPI_FUNCTION Function
Definition: pci.h:529

◆ PciFindNextSecondaryExtension()

PPCI_SECONDARY_EXTENSION NTAPI PciFindNextSecondaryExtension ( IN PSINGLE_LIST_ENTRY  ListHead,
IN PCI_SIGNATURE  ExtensionType 
)

Definition at line 583 of file utils.c.

585{
586 PSINGLE_LIST_ENTRY NextEntry;
588
589 /* Scan the list */
590 for (NextEntry = ListHead; NextEntry; NextEntry = NextEntry->Next)
591 {
592 /* Grab each extension and check if it's the one requested */
594 if (Extension->ExtensionType == ExtensionType) return Extension;
595 }
596
597 /* Nothing was found */
598 return NULL;
599}
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
Definition: ntbasedef.h:640
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:641
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550

Referenced by ario_ApplyBrokenVideoHack(), PciArbiterConstructor(), and PciInitializeArbiterRanges().

◆ PciFindParentPciFdoExtension()

PPCI_FDO_EXTENSION NTAPI PciFindParentPciFdoExtension ( IN PDEVICE_OBJECT  DeviceObject,
IN PKEVENT  Lock 
)

Definition at line 339 of file utils.c.

341{
342 PPCI_FDO_EXTENSION DeviceExtension;
343 PPCI_PDO_EXTENSION SearchExtension, FoundExtension;
344
345 /* Assume we'll find nothing */
346 SearchExtension = DeviceObject->DeviceExtension;
347 FoundExtension = NULL;
348
349 /* Check if a lock was specified */
350 if (Lock)
351 {
352 /* Wait for the lock to be released */
355 }
356
357 /* Now search for the extension */
359 while (DeviceExtension)
360 {
361 /* Acquire this device's lock */
363 KeWaitForSingleObject(&DeviceExtension->ChildListLock,
364 Executive,
366 FALSE,
367 NULL);
368
369 /* Scan all children PDO, stop when no more PDOs, or found it */
370 for (FoundExtension = DeviceExtension->ChildPdoList;
371 ((FoundExtension) && (FoundExtension != SearchExtension));
372 FoundExtension = FoundExtension->Next);
373
374 /* Release this device's lock */
375 KeSetEvent(&DeviceExtension->ChildListLock, IO_NO_INCREMENT, FALSE);
377
378 /* If we found it, break out */
379 if (FoundExtension) break;
380
381 /* Move to the next device */
382 DeviceExtension = (PPCI_FDO_EXTENSION)DeviceExtension->List.Next;
383 }
384
385 /* Check if we had acquired a lock previously */
386 if (Lock)
387 {
388 /* Release it */
391 }
392
393 /* Return which extension was found, if any */
394 return DeviceExtension;
395}
SINGLE_LIST_ENTRY PciFdoExtensionListHead
Definition: fdo.c:18
while(CdLookupNextInitialFileDirent(IrpContext, Fcb, FileContext))
struct _PCI_FDO_EXTENSION * PPCI_FDO_EXTENSION
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define KernelMode
Definition: asm.h:38
SINGLE_LIST_ENTRY List
Definition: pci.h:204
struct _PCI_PDO_EXTENSION * ChildPdoList
Definition: pci.h:214
KEVENT ChildListLock
Definition: pci.h:213
PVOID Next
Definition: pci.h:276
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWAITLOCK * Lock
Definition: wdfsync.h:127
#define IO_NO_INCREMENT
Definition: iotypes.h:598
@ Executive
Definition: ketypes.h:467

Referenced by PciAddDevice().

◆ PciFindPdoByFunction()

PPCI_PDO_EXTENSION NTAPI PciFindPdoByFunction ( IN PPCI_FDO_EXTENSION  DeviceExtension,
IN ULONG  FunctionNumber,
IN PPCI_COMMON_HEADER  PciData 
)

Definition at line 694 of file utils.c.

697{
698 KIRQL Irql;
700
701 /* Get the current IRQL when this call was made */
703
704 /* Is this a low-IRQL call? */
705 if (Irql < DISPATCH_LEVEL)
706 {
707 /* Acquire this device's lock */
709 KeWaitForSingleObject(&DeviceExtension->ChildListLock,
710 Executive,
712 FALSE,
713 NULL);
714 }
715
716 /* Loop every child PDO */
717 for (PdoExtension = DeviceExtension->ChildPdoList;
720 {
721 /* Find only enumerated PDOs */
722 if (!PdoExtension->ReportedMissing)
723 {
724 /* Check if the function number and header data matches */
725 if ((FunctionNumber == PdoExtension->Slot.u.AsULONG) &&
726 (PdoExtension->VendorId == PciData->VendorID) &&
727 (PdoExtension->DeviceId == PciData->DeviceID) &&
728 (PdoExtension->RevisionId == PciData->RevisionID))
729 {
730 /* This is considered to be the same PDO */
731 break;
732 }
733 }
734 }
735
736 /* Was this a low-IRQL call? */
737 if (Irql < DISPATCH_LEVEL)
738 {
739 /* Release this device's lock */
740 KeSetEvent(&DeviceExtension->ChildListLock, IO_NO_INCREMENT, FALSE);
742 }
743
744 /* If the search found something, this is non-NULL, otherwise it's NULL */
745 return PdoExtension;
746}
_Out_ PKIRQL Irql
Definition: csq.h:179
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696

Referenced by PciScanBus().

◆ PciGetBiosConfig()

NTSTATUS NTAPI PciGetBiosConfig ( IN PPCI_PDO_EXTENSION  DeviceExtension,
OUT PPCI_COMMON_HEADER  PciData 
)

Definition at line 767 of file utils.c.

769{
772 UNICODE_STRING KeyName, KeyValue;
773 WCHAR Buffer[32];
775 PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)DataBuffer;
778 PAGED_CODE();
779
780 /* Open the PCI key */
781 Status = IoOpenDeviceRegistryKey(DeviceExtension->ParentFdoExtension->
783 TRUE,
785 &KeyHandle);
786 if (!NT_SUCCESS(Status)) return Status;
787
788 /* Create a volatile BIOS configuration key */
789 RtlInitUnicodeString(&KeyName, L"BiosConfig");
791 &KeyName,
793 KeyHandle,
794 NULL);
795 Status = ZwCreateKey(&SubKeyHandle,
796 KEY_READ,
798 0,
799 NULL,
801 NULL);
803 if (!NT_SUCCESS(Status)) return Status;
804
805 /* Create the key value based on the device and function number */
807 L"DEV_%02x&FUN_%02x",
808 DeviceExtension->Slot.u.bits.DeviceNumber,
809 DeviceExtension->Slot.u.bits.FunctionNumber);
810 RtlInitUnicodeString(&KeyValue, Buffer);
811
812 /* Query the value information (PCI BIOS configuration header) */
813 Status = ZwQueryValueKey(SubKeyHandle,
814 &KeyValue,
816 PartialInfo,
817 sizeof(DataBuffer),
818 &ResultLength);
820 if (!NT_SUCCESS(Status)) return Status;
821
822 /* If any information was returned, go ahead and copy its data */
823 ASSERT(PartialInfo->DataLength == PCI_COMMON_HDR_LENGTH);
824 RtlCopyMemory(PciData, PartialInfo->Data, PCI_COMMON_HDR_LENGTH);
825 return Status;
826}
#define PAGED_CODE()
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define L(x)
Definition: resources.c:13
#define _swprintf(buf, format,...)
Definition: sprintf.c:56
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING _Out_ PNDIS_HANDLE SubKeyHandle
Definition: ndis.h:4726
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
@ KeyValuePartialInformation
Definition: nt_native.h:1185
#define KEY_ALL_ACCESS
Definition: nt_native.h:1044
#define KEY_READ
Definition: nt_native.h:1026
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1063
short WCHAR
Definition: pedump.c:58
NTSTATUS NTAPI IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey)
Definition: pnpmgr.c:1621
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2705
#define PCI_COMMON_HDR_LENGTH
Definition: iotypes.h:3596

Referenced by PciScanBus(), and PPBridge_SaveCurrentSettings().

◆ PciGetDeviceCapabilities()

NTSTATUS NTAPI PciGetDeviceCapabilities ( IN PDEVICE_OBJECT  DeviceObject,
IN OUT PDEVICE_CAPABILITIES  DeviceCapability 
)

Definition at line 1423 of file utils.c.

1425{
1426 PIRP Irp;
1428 KEVENT Event;
1429 PDEVICE_OBJECT AttachedDevice;
1432 PAGED_CODE();
1433
1434 /* Zero out capabilities and set undefined values to start with */
1435 RtlZeroMemory(DeviceCapability, sizeof(DEVICE_CAPABILITIES));
1436 DeviceCapability->Size = sizeof(DEVICE_CAPABILITIES);
1437 DeviceCapability->Version = 1;
1438 DeviceCapability->Address = -1;
1439 DeviceCapability->UINumber = -1;
1440
1441 /* Build the wait event for the IOCTL */
1443
1444 /* Find the device the PDO is attached to */
1446
1447 /* And build an IRP for it */
1449 AttachedDevice,
1450 NULL,
1451 0,
1452 NULL,
1453 &Event,
1454 &IoStatusBlock);
1455 if (!Irp)
1456 {
1457 /* The IRP failed, fail the request as well */
1458 ObDereferenceObject(AttachedDevice);
1460 }
1461
1462 /* Set default status */
1463 Irp->IoStatus.Information = 0;
1464 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
1465
1466 /* Get a stack location in this IRP */
1469
1470 /* Initialize it as a query capabilities IRP, with no completion routine */
1474 IoStackLocation->Parameters.DeviceCapabilities.Capabilities = DeviceCapability;
1476
1477 /* Send the IOCTL to the driver */
1478 Status = IoCallDriver(AttachedDevice, Irp);
1479 if (Status == STATUS_PENDING)
1480 {
1481 /* Wait for a response and update the actual status */
1483 Executive,
1484 KernelMode,
1485 FALSE,
1486 NULL);
1487 Status = Irp->IoStatus.Status;
1488 }
1489
1490 /* Done, dereference the attached device and return the final result */
1491 ObDereferenceObject(AttachedDevice);
1492 return Status;
1493}
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
_In_ PIO_STATUS_BLOCK IoStatusBlock
Definition: dispmprt.h:608
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
@ SynchronizationEvent
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1414
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1101
#define IoCallDriver
Definition: irp.c:1257
union _IO_STACK_LOCATION::@1803 Parameters
struct _IO_STACK_LOCATION::@4925::@4952 DeviceCapabilities
#define STATUS_PENDING
Definition: telnetd.h:14
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PIO_STACK_LOCATION IoStackLocation
Definition: usbdlib.h:265
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
DEVICE_CAPABILITIES
Definition: iotypes.h:965
#define IRP_MN_QUERY_CAPABILITIES
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by PciQueryPowerCapabilities().

◆ PciGetDeviceProperty()

NTSTATUS NTAPI PciGetDeviceProperty ( IN PDEVICE_OBJECT  DeviceObject,
IN DEVICE_REGISTRY_PROPERTY  DeviceProperty,
OUT PVOID *  OutputBuffer 
)

Definition at line 474 of file utils.c.

477{
481 do
482 {
483 /* Query the requested property size */
486 0,
487 NULL,
488 &BufferLength);
490 {
491 /* Call should've failed with buffer too small! */
492 DPRINT1("PCI - Unexpected status from GetDeviceProperty, saw %08X, expected %08X.\n",
493 Status,
496 ASSERTMSG("PCI Successfully did the impossible!\n", FALSE);
497 break;
498 }
499
500 /* Allocate the required buffer */
502 if (!Buffer)
503 {
504 /* No memory, fail the request */
505 DPRINT1("PCI - Failed to allocate DeviceProperty buffer (%u bytes).\n", BufferLength);
507 break;
508 }
509
510 /* Do the actual property query call */
514 Buffer,
515 &ResultLength);
516 if (!NT_SUCCESS(Status)) break;
517
518 /* Return the buffer to the caller */
521 return STATUS_SUCCESS;
522 } while (FALSE);
523
524 /* Failure path */
525 return STATUS_UNSUCCESSFUL;
526}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY DeviceProperty
Definition: wdfdevice.h:3775
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3777
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863

Referenced by PciAddDevice().

◆ PciGetHackFlags()

ULONGLONG NTAPI PciGetHackFlags ( IN USHORT  VendorId,
IN USHORT  DeviceId,
IN USHORT  SubVendorId,
IN USHORT  SubSystemId,
IN UCHAR  RevisionId 
)

Definition at line 603 of file utils.c.

608{
609 PPCI_HACK_ENTRY HackEntry;
611 ULONG LastWeight, MatchWeight;
612 ULONG EntryFlags;
613
614 /* ReactOS SetupLDR Hack */
615 if (!PciHackTable) return 0;
616
617 /* Initialize the variables before looping */
618 LastWeight = 0;
619 HackFlags = 0;
621
622 /* Scan the hack table */
623 for (HackEntry = PciHackTable;
624 HackEntry->VendorID != PCI_INVALID_VENDORID;
625 ++HackEntry)
626 {
627 /* Check if there's an entry for this device */
628 if ((HackEntry->DeviceID == DeviceId) &&
629 (HackEntry->VendorID == VendorId))
630 {
631 /* This is a basic match */
632 EntryFlags = HackEntry->Flags;
633 MatchWeight = 1;
634
635 /* Does the entry have revision information? */
636 if (EntryFlags & PCI_HACK_HAS_REVISION_INFO)
637 {
638 /* Check if the revision matches, if so, this is a better match */
639 if (HackEntry->RevisionID != RevisionId) continue;
640 MatchWeight = 3;
641 }
642
643 /* Does the netry have subsystem information? */
644 if (EntryFlags & PCI_HACK_HAS_SUBSYSTEM_INFO)
645 {
646 /* Check if it matches, if so, this is the best possible match */
647 if ((HackEntry->SubVendorID != SubVendorId) ||
648 (HackEntry->SubSystemID != SubSystemId))
649 {
650 continue;
651 }
652 MatchWeight += 4;
653 }
654
655 /* Is this the best match yet? */
656 if (MatchWeight > LastWeight)
657 {
658 /* This is the best match for now, use this as the hack flags */
659 HackFlags = HackEntry->HackFlags;
660 LastWeight = MatchWeight;
661 }
662 }
663 }
664
665 /* Return the best match */
666 return HackFlags;
667}
PPCI_HACK_ENTRY PciHackTable
Definition: init.c:28
#define PCI_HACK_HAS_REVISION_INFO
Definition: pci.h:51
#define PCI_HACK_HAS_SUBSYSTEM_INFO
Definition: pci.h:52
Definition: pci.h:163
ULONGLONG HackFlags
Definition: pci.h:168
USHORT SubSystemID
Definition: pci.h:167
USHORT VendorID
Definition: pci.h:164
USHORT RevisionID
Definition: pci.h:169
USHORT DeviceID
Definition: pci.h:165
UCHAR Flags
Definition: pci.h:170
USHORT SubVendorID
Definition: pci.h:166
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3603

Referenced by PciScanBus().

◆ PciGetRegistryValue()

NTSTATUS NTAPI PciGetRegistryValue ( IN PWCHAR  ValueName,
IN PWCHAR  KeyName,
IN HANDLE  RootHandle,
IN ULONG  Type,
OUT PVOID *  OutputBuffer,
OUT PULONG  OutputLength 
)

Definition at line 192 of file utils.c.

198{
201 ULONG NeededLength, ActualLength;
202 UNICODE_STRING ValueString;
205
206 /* So we know what to free at the end of the body */
207 PartialInfo = NULL;
208 KeyHandle = NULL;
209 do
210 {
211 /* Open the key by name, rooted off the handle passed */
213 RootHandle,
215 &KeyHandle,
216 &Status);
217 if (!Result) break;
218
219 /* Query for the size that's needed for the value that was passed in */
220 RtlInitUnicodeString(&ValueString, ValueName);
221 Status = ZwQueryValueKey(KeyHandle,
222 &ValueString,
224 NULL,
225 0,
226 &NeededLength);
228 if (Status != STATUS_BUFFER_TOO_SMALL) break;
229
230 /* Allocate an appropriate buffer for the size that was returned */
231 ASSERT(NeededLength != 0);
233 PartialInfo = ExAllocatePoolWithTag(PagedPool,
234 NeededLength,
236 if (!PartialInfo) break;
237
238 /* Query the actual value information now that the size is known */
239 Status = ZwQueryValueKey(KeyHandle,
240 &ValueString,
242 PartialInfo,
243 NeededLength,
244 &ActualLength);
245 if (!NT_SUCCESS(Status)) break;
246
247 /* Make sure it's of the type that the caller expects */
249 if (PartialInfo->Type != Type) break;
250
251 ASSERT(NeededLength == ActualLength);
252 NeededLength = PartialInfo->DataLength;
253
254 /* Allocate a buffer to hold the data and return it to the caller */
257 NeededLength,
259 if (!*OutputBuffer) break;
260
261 /* Copy the data into the buffer and return its length to the caller */
262 RtlCopyMemory(*OutputBuffer, PartialInfo->Data, NeededLength);
263 if (OutputLength) *OutputLength = NeededLength;
265 } while (0);
266
267 /* Close any opened keys and free temporary allocations */
269 if (PartialInfo) ExFreePoolWithTag(PartialInfo, 0);
270 return Status;
271}
#define PCI_POOL_TAG
Definition: pci.h:27
BOOLEAN NTAPI PciOpenKey(IN PWCHAR KeyName, IN HANDLE RootKey, IN ACCESS_MASK DesiredAccess, OUT PHANDLE KeyHandle, OUT PNTSTATUS KeyStatus)
Definition: utils.c:165
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define KEY_QUERY_VALUE
Definition: nt_native.h:1019
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by DriverEntry(), PciAcpiFindRsdt(), PciGetIrqRoutingTableFromRegistry(), and PciIsDatacenter().

◆ PciInsertEntryAtHead()

VOID NTAPI PciInsertEntryAtHead ( IN PSINGLE_LIST_ENTRY  ListHead,
IN PSINGLE_LIST_ENTRY  Entry,
IN PKEVENT  Lock 
)

Definition at line 429 of file utils.c.

432{
433 PAGED_CODE();
434
435 /* Check if a lock was specified */
436 if (Lock)
437 {
438 /* Wait for the lock to be released */
441 }
442
443 /* Make the entry point to the current head and make the head point to it */
444 Entry->Next = ListHead->Next;
445 ListHead->Next = Entry;
446
447 /* Check if we had acquired a lock previously */
448 if (Lock)
449 {
450 /* Release it */
453 }
454}
Entry
Definition: section.c:5216

Referenced by PcipLinkSecondaryExtension().

◆ PciInsertEntryAtTail()

VOID NTAPI PciInsertEntryAtTail ( IN PSINGLE_LIST_ENTRY  ListHead,
IN PPCI_FDO_EXTENSION  DeviceExtension,
IN PKEVENT  Lock 
)

Definition at line 399 of file utils.c.

402{
403 PSINGLE_LIST_ENTRY NextEntry;
404 PAGED_CODE();
405
406 /* Check if a lock was specified */
407 if (Lock)
408 {
409 /* Wait for the lock to be released */
412 }
413
414 /* Loop the list until we get to the end, then insert this entry there */
415 for (NextEntry = ListHead; NextEntry->Next; NextEntry = NextEntry->Next);
416 NextEntry->Next = &DeviceExtension->List;
417
418 /* Check if we had acquired a lock previously */
419 if (Lock)
420 {
421 /* Release it */
424 }
425}

Referenced by PciAddDevice(), and PciPdoCreate().

◆ PciIsCriticalDeviceClass()

BOOLEAN NTAPI PciIsCriticalDeviceClass ( IN UCHAR  BaseClass,
IN UCHAR  SubClass 
)

Definition at line 671 of file utils.c.

673{
674 /* Check for system or bridge devices */
675 if (BaseClass == PCI_CLASS_BASE_SYSTEM_DEV)
676 {
677 /* Interrupt controllers are critical */
678 return SubClass == PCI_SUBCLASS_SYS_INTERRUPT_CTLR;
679 }
680 else if (BaseClass == PCI_CLASS_BRIDGE_DEV)
681 {
682 /* ISA Bridges are critical */
683 return SubClass == PCI_SUBCLASS_BR_ISA;
684 }
685 else
686 {
687 /* All display controllers are critical */
688 return BaseClass == PCI_CLASS_DISPLAY_CTLR;
689 }
690}
#define PCI_SUBCLASS_SYS_INTERRUPT_CTLR
Definition: iotypes.h:4181
#define PCI_CLASS_BASE_SYSTEM_DEV
Definition: iotypes.h:4113

Referenced by PciScanBus().

◆ PciIsDatacenter()

BOOLEAN NTAPI PciIsDatacenter ( VOID  )

Definition at line 131 of file utils.c.

132{
134 PVOID Value;
137
138 /* Assume this isn't Datacenter */
139 Result = FALSE;
140
141 /* First, try opening the setup key */
143 L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\setupdd",
144 0,
146 &Value,
147 &ResultLength);
148 if (!NT_SUCCESS(Status))
149 {
150 /* This is not an in-progress Setup boot, so query the suite version */
152 }
153 else
154 {
155 /* This scenario shouldn't happen yet, since SetupDD isn't used */
156 UNIMPLEMENTED_FATAL("ReactOS doesn't use SetupDD for its installation program. Therefore this scenario must not happen!\n");
157 }
158
159 /* Return if this is Datacenter or not */
160 return Result;
161}
BOOLEAN NTAPI PciIsSuiteVersion(IN USHORT SuiteMask)
Definition: utils.c:114
NTSTATUS NTAPI PciGetRegistryValue(IN PWCHAR ValueName, IN PWCHAR KeyName, IN HANDLE RootHandle, IN ULONG Type, OUT PVOID *OutputBuffer, OUT PULONG OutputLength)
Definition: utils.c:192
#define REG_BINARY
Definition: nt_native.h:1499
#define VER_SUITE_DATACENTER
#define UNIMPLEMENTED_FATAL(...)
Definition: debug.h:244
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by DriverEntry().

◆ PciIsDeviceOnDebugPath()

BOOLEAN NTAPI PciIsDeviceOnDebugPath ( IN PPCI_PDO_EXTENSION  DeviceExtension)

Definition at line 750 of file utils.c.

751{
752 PAGED_CODE();
753
754 UNREFERENCED_PARAMETER(DeviceExtension);
755
756 /* Check for too many, or no, debug ports */
758 if (!PciDebugPortsCount) return FALSE;
759
760 /* eVb has not been able to test such devices yet */
762 return FALSE;
763}
#define MAX_DEBUGGING_DEVICES_SUPPORTED
Definition: pci.h:87
ULONG PciDebugPortsCount
Definition: utils.c:18
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329

Referenced by PciScanBus().

◆ PciIsSlotPresentInParentMethod()

BOOLEAN NTAPI PciIsSlotPresentInParentMethod ( IN PPCI_PDO_EXTENSION  PdoExtension,
IN ULONG  Method 
)

Definition at line 1096 of file utils.c.

1098{
1099 BOOLEAN FoundSlot;
1103 ULONG i, Length;
1105 PAGED_CODE();
1106
1107 /* Assume slot is not part of the parent method */
1108 FoundSlot = FALSE;
1109
1110 /* Allocate a 2KB buffer for the method return parameters */
1111 Length = sizeof(ACPI_EVAL_OUTPUT_BUFFER) + 2048;
1113 if (OutputBuffer)
1114 {
1115 /* Clear out the output buffer */
1117
1118 /* Initialize the input buffer with the method requested */
1119 InputBuffer.Signature = 0;
1120 *(PULONG)InputBuffer.MethodName = Method;
1122
1123 /* Send it to the ACPI driver */
1124 Status = PciSendIoctl(PdoExtension->ParentFdoExtension->PhysicalDeviceObject,
1126 &InputBuffer,
1127 sizeof(ACPI_EVAL_INPUT_BUFFER),
1129 Length);
1130 if (NT_SUCCESS(Status))
1131 {
1132 /* Scan all output arguments */
1133 for (i = 0; i < OutputBuffer->Count; i++)
1134 {
1135 /* Make sure it's an integer */
1136 Argument = &OutputBuffer->Argument[i];
1137 if (Argument->Type != ACPI_METHOD_ARGUMENT_INTEGER) continue;
1138
1139 /* Check if the argument matches this PCI slot structure */
1140 if (Argument->Argument == ((PdoExtension->Slot.u.bits.DeviceNumber) |
1141 ((PdoExtension->Slot.u.bits.FunctionNumber) << 16)))
1142 {
1143 /* This slot has been found, return it */
1144 FoundSlot = TRUE;
1145 break;
1146 }
1147 }
1148 }
1149
1150 /* Finished with the buffer, free it */
1152 }
1153
1154 /* Return if the slot was found */
1155 return FoundSlot;
1156}
ACPI_METHOD_ARGUMENT UNALIGNED * PACPI_METHOD_ARGUMENT
Definition: acpiioct.h:80
struct _ACPI_EVAL_OUTPUT_BUFFER ACPI_EVAL_OUTPUT_BUFFER
#define ACPI_METHOD_ARGUMENT_INTEGER
Definition: acpiioct.h:30
#define ACPI_EVAL_INPUT_BUFFER_SIGNATURE
Definition: acpiioct.h:12
#define IOCTL_ACPI_EVAL_METHOD
Definition: acpiioct.h:194
ACPI_EVAL_OUTPUT_BUFFER UNALIGNED * PACPI_EVAL_OUTPUT_BUFFER
Definition: acpiioct.h:99
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG _In_ PVOID Argument
Definition: dispmprt.h:1288
NTSTATUS NTAPI PciSendIoctl(IN PDEVICE_OBJECT DeviceObject, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength)
Definition: utils.c:530
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
uint32_t * PULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953

Referenced by PciApplyHacks(), and PciBridgeIsPositiveDecode().

◆ PciIsSuiteVersion()

BOOLEAN NTAPI PciIsSuiteVersion ( IN USHORT  SuiteMask)

Definition at line 114 of file utils.c.

115{
116 ULONGLONG Mask = 0;
118
119 /* Initialize the version information */
122 VersionInfo.wSuiteMask = SuiteMask;
123
124 /* Set the comparison mask and return if the passed suite mask matches */
127}
OSVERSIONINFOW VersionInfo
Definition: wkssvc.c:40
unsigned int Mask
Definition: fpcontrol.c:82
#define VER_AND
Definition: rtltypes.h:252
#define VER_SUITENAME
Definition: rtltypes.h:242
#define VER_SET_CONDITION(ConditionMask, TypeBitMask, ComparisonType)
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:246
NTSYSAPI NTSTATUS WINAPI RtlVerifyVersionInfo(const RTL_OSVERSIONINFOEXW *, DWORD, DWORDLONG)
struct _OSVERSIONINFOEXW RTL_OSVERSIONINFOEXW

Referenced by PciIsDatacenter().

◆ PciOpenKey()

BOOLEAN NTAPI PciOpenKey ( IN PWCHAR  KeyName,
IN HANDLE  RootKey,
IN ACCESS_MASK  DesiredAccess,
OUT PHANDLE  KeyHandle,
OUT PNTSTATUS  KeyStatus 
)

Definition at line 165 of file utils.c.

170{
173 UNICODE_STRING KeyString;
174 PAGED_CODE();
175
176 /* Initialize the object attributes */
177 RtlInitUnicodeString(&KeyString, KeyName);
179 &KeyString,
181 RootKey,
182 NULL);
183
184 /* Open the key, returning a boolean, and the status, if requested */
186 if (KeyStatus) *KeyStatus = Status;
187 return NT_SUCCESS(Status);
188}
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static PMEMKEY RootKey
Definition: registry.c:55
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664

Referenced by DriverEntry(), PciAcpiFindRsdt(), PciEcamQueryWindow(), PciGetIrqRoutingTableFromRegistry(), and PciGetRegistryValue().

◆ PcipLinkSecondaryExtension()

VOID NTAPI PcipLinkSecondaryExtension ( IN PSINGLE_LIST_ENTRY  List,
IN PVOID  Lock,
IN PPCI_SECONDARY_EXTENSION  SecondaryExtension,
IN PCI_SIGNATURE  ExtensionType,
IN PVOID  Destructor 
)

Definition at line 458 of file utils.c.

463{
464 PAGED_CODE();
465
466 /* Setup the extension data, and insert it into the primary's list */
467 SecondaryExtension->ExtensionType = ExtensionType;
468 SecondaryExtension->Destructor = Destructor;
469 PciInsertEntryAtHead(List, &SecondaryExtension->List, Lock);
470}
VOID NTAPI PciInsertEntryAtHead(IN PSINGLE_LIST_ENTRY ListHead, IN PSINGLE_LIST_ENTRY Entry, IN PKEVENT Lock)
Definition: utils.c:429

Referenced by PciInitializeArbiters().

◆ PciQueryBusInformation()

NTSTATUS NTAPI PciQueryBusInformation ( IN PPCI_PDO_EXTENSION  PdoExtension,
OUT PPNP_BUS_INFORMATION *  Buffer 
)

Definition at line 1335 of file utils.c.

1337{
1338 PPNP_BUS_INFORMATION BusInfo;
1339
1340 /* Allocate a structure for the bus information */
1342 sizeof(PNP_BUS_INFORMATION),
1343 'BicP');
1344 if (!BusInfo) return STATUS_INSUFFICIENT_RESOURCES;
1345
1346 /* Write the correct GUID and bus type identifier, and fill the bus number */
1347 BusInfo->BusTypeGuid = GUID_BUS_TYPE_PCI;
1348 BusInfo->LegacyBusType = PCIBus;
1349 BusInfo->BusNumber = PdoExtension->ParentFdoExtension->BaseBus;
1350
1351 *Buffer = BusInfo;
1352
1353 return STATUS_SUCCESS;
1354}
@ PCIBus
Definition: restypes.h:127
INTERFACE_TYPE LegacyBusType
Definition: cmtypes.h:366

Referenced by PciPdoIrpQueryBusInformation().

◆ PciQueryCapabilities()

NTSTATUS NTAPI PciQueryCapabilities ( IN PPCI_PDO_EXTENSION  PdoExtension,
IN OUT PDEVICE_CAPABILITIES  DeviceCapability 
)

Definition at line 1747 of file utils.c.

1749{
1751
1752 /* A PDO ID is never unique, and its address is its function and device */
1753 DeviceCapability->UniqueID = FALSE;
1754 DeviceCapability->Address = PdoExtension->Slot.u.bits.FunctionNumber |
1755 (PdoExtension->Slot.u.bits.DeviceNumber << 16);
1756
1757 /* Check for host bridges */
1758 if ((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
1759 (PdoExtension->SubClass == PCI_SUBCLASS_BR_HOST))
1760 {
1761 /* Raw device opens to a host bridge are acceptable */
1762 DeviceCapability->RawDeviceOK = TRUE;
1763 }
1764 else
1765 {
1766 /* Otherwise, other PDOs cannot be directly opened */
1767 DeviceCapability->RawDeviceOK = FALSE;
1768 }
1769
1770 /* PCI PDOs are pretty fixed things */
1771 DeviceCapability->LockSupported = FALSE;
1772 DeviceCapability->EjectSupported = FALSE;
1773 DeviceCapability->Removable = FALSE;
1774 DeviceCapability->DockDevice = FALSE;
1775
1776 /* The slot number is stored as a device property, go query it */
1777 PciDetermineSlotNumber(PdoExtension, &DeviceCapability->UINumber);
1778
1779 /* Finally, query and power capabilities and convert them for PnP usage */
1780 Status = PciQueryPowerCapabilities(PdoExtension, DeviceCapability);
1781
1782 /* Dump the capabilities if it all worked, and return the status */
1783 if (NT_SUCCESS(Status)) PciDebugDumpQueryCapabilities(DeviceCapability);
1784 return Status;
1785}
VOID NTAPI PciDebugDumpQueryCapabilities(IN PDEVICE_CAPABILITIES DeviceCaps)
Definition: debug.c:221
NTSTATUS NTAPI PciQueryPowerCapabilities(IN PPCI_PDO_EXTENSION PdoExtension, IN PDEVICE_CAPABILITIES DeviceCapability)
Definition: utils.c:1497
NTSTATUS NTAPI PciDetermineSlotNumber(IN PPCI_PDO_EXTENSION PdoExtension, OUT PULONG SlotNumber)
Definition: utils.c:1358

Referenced by PciPdoIrpQueryCapabilities().

◆ PciQueryPowerCapabilities()

NTSTATUS NTAPI PciQueryPowerCapabilities ( IN PPCI_PDO_EXTENSION  PdoExtension,
IN PDEVICE_CAPABILITIES  DeviceCapability 
)

Definition at line 1497 of file utils.c.

1499{
1502 DEVICE_CAPABILITIES AttachedCaps;
1503 DEVICE_POWER_STATE NewPowerState, DevicePowerState, DeviceWakeLevel, DeviceWakeState;
1504 SYSTEM_POWER_STATE SystemWakeState, DeepestWakeState, CurrentState;
1505
1506 /* Nothing is known at first */
1507 DeviceWakeState = PowerDeviceUnspecified;
1508 SystemWakeState = DeepestWakeState = PowerSystemUnspecified;
1509
1510 /* Get the PCI capabilities for the parent PDO */
1511 DeviceObject = PdoExtension->ParentFdoExtension->PhysicalDeviceObject;
1514 if (!NT_SUCCESS(Status)) return Status;
1515
1516 /* Check if there's not an existing device state for S0 */
1517 if (!AttachedCaps.DeviceState[PowerSystemWorking])
1518 {
1519 /* Set D0<->S0 mapping */
1520 AttachedCaps.DeviceState[PowerSystemWorking] = PowerDeviceD0;
1521 }
1522
1523 /* Check if there's not an existing device state for S3 */
1524 if (!AttachedCaps.DeviceState[PowerSystemShutdown])
1525 {
1526 /* Set D3<->S3 mapping */
1527 AttachedCaps.DeviceState[PowerSystemShutdown] = PowerDeviceD3;
1528 }
1529
1530 /* Check for a PDO with broken, or no, power capabilities */
1531 if (PdoExtension->HackFlags & PCI_HACK_NO_PM_CAPS)
1532 {
1533 /* Unknown wake device states */
1534 DeviceCapability->DeviceWake = PowerDeviceUnspecified;
1535 DeviceCapability->SystemWake = PowerSystemUnspecified;
1536
1537 /* No device state support */
1538 DeviceCapability->DeviceD1 = FALSE;
1539 DeviceCapability->DeviceD2 = FALSE;
1540
1541 /* No waking from any low-power device state is supported */
1542 DeviceCapability->WakeFromD0 = FALSE;
1543 DeviceCapability->WakeFromD1 = FALSE;
1544 DeviceCapability->WakeFromD2 = FALSE;
1545 DeviceCapability->WakeFromD3 = FALSE;
1546
1547 /* For the rest, copy whatever the parent PDO had */
1548 RtlCopyMemory(DeviceCapability->DeviceState,
1549 AttachedCaps.DeviceState,
1550 sizeof(DeviceCapability->DeviceState));
1551 return STATUS_SUCCESS;
1552 }
1553
1554 /* The PCI Device has power capabilities, so read which ones are supported */
1555 DeviceCapability->DeviceD1 = PdoExtension->PowerCapabilities.Support.D1;
1556 DeviceCapability->DeviceD2 = PdoExtension->PowerCapabilities.Support.D2;
1557 DeviceCapability->WakeFromD0 = PdoExtension->PowerCapabilities.Support.PMED0;
1558 DeviceCapability->WakeFromD1 = PdoExtension->PowerCapabilities.Support.PMED1;
1559 DeviceCapability->WakeFromD2 = PdoExtension->PowerCapabilities.Support.PMED2;
1560
1561 /* Can the attached device wake from D3? */
1562 if (AttachedCaps.DeviceWake != PowerDeviceD3)
1563 {
1564 /* It can't, so check if this PDO supports hot D3 wake */
1565 DeviceCapability->WakeFromD3 = PdoExtension->PowerCapabilities.Support.PMED3Hot;
1566 }
1567 else
1568 {
1569 /* It can, is this the root bus? */
1570 if (PCI_IS_ROOT_FDO(PdoExtension->ParentFdoExtension))
1571 {
1572 /* This is the root bus, so just check if it supports hot D3 wake */
1573 DeviceCapability->WakeFromD3 = PdoExtension->PowerCapabilities.Support.PMED3Hot;
1574 }
1575 else
1576 {
1577 /* Take the minimums? -- need to check with briang at work */
1579 }
1580 }
1581
1582 /* Now loop each system power state to determine its device state mapping */
1585 CurrentState++)
1586 {
1587 /* Read the current mapping from the attached device */
1588 DevicePowerState = AttachedCaps.DeviceState[CurrentState];
1589 NewPowerState = DevicePowerState;
1590
1591 /* The attachee supports D1, but this PDO does not */
1592 if ((NewPowerState == PowerDeviceD1) &&
1593 !(PdoExtension->PowerCapabilities.Support.D1))
1594 {
1595 /* Fall back to D2 */
1596 NewPowerState = PowerDeviceD2;
1597 }
1598
1599 /* The attachee supports D2, but this PDO does not */
1600 if ((NewPowerState == PowerDeviceD2) &&
1601 !(PdoExtension->PowerCapabilities.Support.D2))
1602 {
1603 /* Fall back to D3 */
1604 NewPowerState = PowerDeviceD3;
1605 }
1606
1607 /* Set the mapping based on the best state supported */
1608 DeviceCapability->DeviceState[CurrentState] = NewPowerState;
1609
1610 /* Check if sleep states are being processed, and a mapping was found */
1612 (NewPowerState != PowerDeviceUnspecified))
1613 {
1614 /* Save this state as being the deepest one found until now */
1615 DeepestWakeState = CurrentState;
1616 }
1617
1618 /*
1619 * Finally, check if the computed sleep state is within the states that
1620 * this device can wake the system from, and if it's higher or equal to
1621 * the sleep state mapping that came from the attachee, assuming that it
1622 * had a valid mapping to begin with.
1623 *
1624 * It this is the case, then make sure that the computed sleep state is
1625 * matched by the device's ability to actually wake from that state.
1626 *
1627 * For devices that support D3, the PCI device only needs Hot D3 as long
1628 * as the attachee's state is less than D3. Otherwise, if the attachee
1629 * might also be at D3, this would require a Cold D3 wake, so check that
1630 * the device actually support this.
1631 */
1632 if ((CurrentState < AttachedCaps.SystemWake) &&
1633 (NewPowerState >= DevicePowerState) &&
1635 (((NewPowerState == PowerDeviceD0) && (DeviceCapability->WakeFromD0)) ||
1636 ((NewPowerState == PowerDeviceD1) && (DeviceCapability->WakeFromD1)) ||
1637 ((NewPowerState == PowerDeviceD2) && (DeviceCapability->WakeFromD2)) ||
1638 ((NewPowerState == PowerDeviceD3) &&
1639 (PdoExtension->PowerCapabilities.Support.PMED3Hot) &&
1641 (PdoExtension->PowerCapabilities.Support.PMED3Cold)))))
1642 {
1643 /* The mapping is valid, so this will be the lowest wake state */
1644 SystemWakeState = CurrentState;
1645 DeviceWakeState = NewPowerState;
1646 }
1647 }
1648
1649 /* Read the current wake level */
1650 DeviceWakeLevel = PdoExtension->PowerState.DeviceWakeLevel;
1651
1652 /* Check if the attachee's wake levels are valid, and the PDO's is higher */
1653 if ((AttachedCaps.SystemWake != PowerSystemUnspecified) &&
1654 (AttachedCaps.DeviceWake != PowerDeviceUnspecified) &&
1655 (DeviceWakeLevel != PowerDeviceUnspecified) &&
1656 (DeviceWakeLevel >= AttachedCaps.DeviceWake))
1657 {
1658 /* Inherit the system wake from the attachee, and this PDO's wake level */
1659 DeviceCapability->SystemWake = AttachedCaps.SystemWake;
1660 DeviceCapability->DeviceWake = DeviceWakeLevel;
1661
1662 /* Now check if the wake level is D0, but the PDO doesn't support it */
1663 if ((DeviceCapability->DeviceWake == PowerDeviceD0) &&
1664 !(DeviceCapability->WakeFromD0))
1665 {
1666 /* Bump to D1 */
1667 DeviceCapability->DeviceWake = PowerDeviceD1;
1668 }
1669
1670 /* Now check if the wake level is D1, but the PDO doesn't support it */
1671 if ((DeviceCapability->DeviceWake == PowerDeviceD1) &&
1672 !(DeviceCapability->WakeFromD1))
1673 {
1674 /* Bump to D2 */
1675 DeviceCapability->DeviceWake = PowerDeviceD2;
1676 }
1677
1678 /* Now check if the wake level is D2, but the PDO doesn't support it */
1679 if ((DeviceCapability->DeviceWake == PowerDeviceD2) &&
1680 !(DeviceCapability->WakeFromD2))
1681 {
1682 /* Bump it to D3 */
1683 DeviceCapability->DeviceWake = PowerDeviceD3;
1684 }
1685
1686 /* Now check if the wake level is D3, but the PDO doesn't support it */
1687 if ((DeviceCapability->DeviceWake == PowerDeviceD3) &&
1688 !(DeviceCapability->WakeFromD3))
1689 {
1690 /* Then no valid wake state exists */
1691 DeviceCapability->DeviceWake = PowerDeviceUnspecified;
1692 DeviceCapability->SystemWake = PowerSystemUnspecified;
1693 }
1694
1695 /* Check if no valid wake state was found */
1696 if ((DeviceCapability->DeviceWake == PowerDeviceUnspecified) ||
1697 (DeviceCapability->SystemWake == PowerSystemUnspecified))
1698 {
1699 /* Check if one was computed earlier */
1700 if ((SystemWakeState != PowerSystemUnspecified) &&
1701 (DeviceWakeState != PowerDeviceUnspecified))
1702 {
1703 /* Use the wake state that had been computed earlier */
1704 DeviceCapability->DeviceWake = DeviceWakeState;
1705 DeviceCapability->SystemWake = SystemWakeState;
1706
1707 /* If that state was D3, then the device supports Hot/Cold D3 */
1708 if (DeviceWakeState == PowerDeviceD3) DeviceCapability->WakeFromD3 = TRUE;
1709 }
1710 }
1711
1712 /*
1713 * Finally, check for off states (lower than S3, such as hibernate) and
1714 * make sure that the device both supports waking from D3 as well as
1715 * supports a Cold wake
1716 */
1717 if ((DeviceCapability->SystemWake > PowerSystemSleeping3) &&
1718 ((DeviceCapability->DeviceWake != PowerDeviceD3) ||
1719 !(PdoExtension->PowerCapabilities.Support.PMED3Cold)))
1720 {
1721 /* It doesn't, so pick the computed lowest wake state from earlier */
1722 DeviceCapability->SystemWake = DeepestWakeState;
1723 }
1724
1725 /* Set the PCI Specification mandated maximum latencies for transitions */
1726 DeviceCapability->D1Latency = 0;
1727 DeviceCapability->D2Latency = 2;
1728 DeviceCapability->D3Latency = 100;
1729
1730 /* Sanity check */
1731 ASSERT(DeviceCapability->DeviceState[PowerSystemWorking] == PowerDeviceD0);
1732 }
1733 else
1734 {
1735 /* No valid sleep states, no latencies to worry about */
1736 DeviceCapability->D1Latency = 0;
1737 DeviceCapability->D2Latency = 0;
1738 DeviceCapability->D3Latency = 0;
1739 }
1740
1741 /* This function always succeeds, even without power management support */
1742 return STATUS_SUCCESS;
1743}
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
_Check_return_ _In_ ULONG _In_ DEVICE_POWER_STATE DevicePowerState
Definition: dispmprt.h:1274
NTSTATUS NTAPI PciGetDeviceCapabilities(IN PDEVICE_OBJECT DeviceObject, IN OUT PDEVICE_CAPABILITIES DeviceCapability)
Definition: utils.c:1423
@ PowerSystemMaximum
Definition: ntpoapi.h:42
@ PowerSystemUnspecified
Definition: ntpoapi.h:35
@ PowerSystemSleeping3
Definition: ntpoapi.h:39
@ PowerSystemShutdown
Definition: ntpoapi.h:41
@ PowerSystemWorking
Definition: ntpoapi.h:36
@ PowerSystemHibernate
Definition: ntpoapi.h:40
@ PowerDeviceD1
Definition: ntpoapi.h:50
@ PowerDeviceUnspecified
Definition: ntpoapi.h:48
@ PowerDeviceD0
Definition: ntpoapi.h:49
@ PowerDeviceD2
Definition: ntpoapi.h:51
@ PowerDeviceD3
Definition: ntpoapi.h:52
enum _DEVICE_POWER_STATE DEVICE_POWER_STATE
enum _SYSTEM_POWER_STATE SYSTEM_POWER_STATE
#define PCI_HACK_NO_PM_CAPS
Definition: pci.h:40
_Out_opt_ PBOOLEAN CurrentState
Definition: zwfuncs.h:393

Referenced by PciQueryCapabilities().

◆ PciReadDeviceCapability()

UCHAR NTAPI PciReadDeviceCapability ( IN PPCI_PDO_EXTENSION  DeviceExtension,
IN UCHAR  Offset,
IN ULONG  CapabilityId,
OUT PPCI_CAPABILITIES_HEADER  Buffer,
IN ULONG  Length 
)

Definition at line 885 of file utils.c.

890{
891 ULONG CapabilityCount = 0;
892
893 /* If the device has no capabilility list, fail */
894 if (!Offset) return 0;
895
896 /* Validate a PDO with capabilities, a valid buffer, and a valid length */
897 ASSERT(DeviceExtension->ExtensionType == PciPdoExtensionType);
898 ASSERT(DeviceExtension->CapabilitiesPtr != 0);
899 ASSERT(Buffer);
901
902 /* Loop all capabilities */
903 while (Offset)
904 {
905 /* Make sure the pointer is spec-aligned and spec-sized */
906 ASSERT((Offset >= PCI_COMMON_HDR_LENGTH) && ((Offset & 0x3) == 0));
907
908 /* Read the capability header */
909 PciReadDeviceConfig(DeviceExtension,
910 Buffer,
911 Offset,
913
914 /* Check if this is the capability being looked up */
915 if ((Buffer->CapabilityID == CapabilityId) || !(CapabilityId))
916 {
917 /* Check if was at a valid offset and length */
918 if ((Offset) && (Length > sizeof(PCI_CAPABILITIES_HEADER)))
919 {
920 /* Sanity check */
921 ASSERT(Length <= (sizeof(PCI_COMMON_CONFIG) - Offset));
922
923 /* Now read the whole capability data into the buffer */
924 PciReadDeviceConfig(DeviceExtension,
929 }
930
931 /* Return the offset where the capability was found */
932 return Offset;
933 }
934
935 /* Try the next capability instead */
936 CapabilityCount++;
937 Offset = Buffer->Next;
938
939 /* There can't be more than 48 capabilities (256 bytes max) */
940 if (CapabilityCount > 48)
941 {
942 /* Fail, since this is basically a broken PCI device */
943 DPRINT1("PCI device %p capabilities list is broken.\n", DeviceExtension);
944 return 0;
945 }
946 }
947
948 /* Capability wasn't found, fail */
949 return 0;
950}
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101

Referenced by PciGetEnhancedCapabilities(), PciGetExpressCapabilities(), PciScanBus(), and PciSetPowerManagedDevicePowerState().

◆ PciSaveBiosConfig()

NTSTATUS NTAPI PciSaveBiosConfig ( IN PPCI_PDO_EXTENSION  DeviceExtension,
IN PPCI_COMMON_HEADER  PciData 
)

Definition at line 830 of file utils.c.

832{
835 UNICODE_STRING KeyName, KeyValue;
836 WCHAR Buffer[32];
838 PAGED_CODE();
839
840 /* Open the PCI key */
841 Status = IoOpenDeviceRegistryKey(DeviceExtension->ParentFdoExtension->
843 TRUE,
845 &KeyHandle);
846 if (!NT_SUCCESS(Status)) return Status;
847
848 /* Create a volatile BIOS configuration key */
849 RtlInitUnicodeString(&KeyName, L"BiosConfig");
851 &KeyName,
853 KeyHandle,
854 NULL);
855 Status = ZwCreateKey(&SubKeyHandle,
858 0,
859 NULL,
861 NULL);
863 if (!NT_SUCCESS(Status)) return Status;
864
865 /* Create the key value based on the device and function number */
867 L"DEV_%02x&FUN_%02x",
868 DeviceExtension->Slot.u.bits.DeviceNumber,
869 DeviceExtension->Slot.u.bits.FunctionNumber);
870 RtlInitUnicodeString(&KeyValue, Buffer);
871
872 /* Set the value data (the PCI BIOS configuration header) */
873 Status = ZwSetValueKey(SubKeyHandle,
874 &KeyValue,
875 0,
877 PciData,
880 return Status;
881}
#define KEY_WRITE
Definition: nt_native.h:1034

◆ PciSendIoctl()

NTSTATUS NTAPI PciSendIoctl ( IN PDEVICE_OBJECT  DeviceObject,
IN ULONG  IoControlCode,
IN PVOID  InputBuffer,
IN ULONG  InputBufferLength,
IN PVOID  OutputBuffer,
IN ULONG  OutputBufferLength 
)

Definition at line 530 of file utils.c.

536{
537 PIRP Irp;
541 PDEVICE_OBJECT AttachedDevice;
542 PAGED_CODE();
543
544 /* Initialize the pending IRP event */
546
547 /* Get a reference to the root PDO (ACPI) */
549 if (!AttachedDevice) return STATUS_INVALID_PARAMETER;
550
551 /* Build the requested IOCTL IRP */
553 AttachedDevice,
558 0,
559 &Event,
562
563 /* Send the IOCTL to the driver */
564 Status = IoCallDriver(AttachedDevice, Irp);
565 if (Status == STATUS_PENDING)
566 {
567 /* Wait for a response */
569 Executive,
571 FALSE,
572 NULL);
573 Status = Irp->IoStatus.Status;
574 }
575
576 /* Take away the reference we took and return the result to the caller */
577 ObDereferenceObject(AttachedDevice);
578 return Status;
579}
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:913
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
Definition: wdfio.h:325
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322

Referenced by PciGetHotPlugParameters(), and PciIsSlotPresentInParentMethod().

◆ PciStringToUSHORT()

BOOLEAN NTAPI PciStringToUSHORT ( IN PWCHAR  String,
OUT PUSHORT  Value 
)

Definition at line 61 of file utils.c.

63{
66 WCHAR Char;
67
68 /* Initialize everything to zero */
69 Short = 0;
70 Length = 0;
71 while (TRUE)
72 {
73 /* Get the character and set the high byte based on the previous one */
74 Char = *String++;
75 High = 16 * Short;
76
77 /* Check for numbers */
78 if ( Char >= '0' && Char <= '9' )
79 {
80 /* Convert them to a byte */
81 Low = Char - '0';
82 }
83 else if ( Char >= 'A' && Char <= 'F' )
84 {
85 /* Convert upper-case hex letters into a byte */
86 Low = Char - '7';
87 }
88 else if ( Char >= 'a' && Char <= 'f' )
89 {
90 /* Convert lower-case hex letters into a byte */
91 Low = Char - 'W';
92 }
93 else
94 {
95 /* Invalid string, fail the conversion */
96 return FALSE;
97 }
98
99 /* Combine the high and low byte */
100 Short = High | Low;
101
102 /* If 4 letters have been reached, the 16-bit integer should exist */
103 if (++Length >= 4)
104 {
105 /* Return it to the caller */
106 *Value = Short;
107 return TRUE;
108 }
109 }
110}
short Short
Definition: ftraster.c:309
@ High
Definition: strmini.h:378
@ Low
Definition: strmini.h:380
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2439

Referenced by PciBuildHackTable().

◆ PciUnicodeStringStrStr()

BOOLEAN NTAPI PciUnicodeStringStrStr ( IN PUNICODE_STRING  InputString,
IN PCUNICODE_STRING  EqualString,
IN BOOLEAN  CaseInSensitive 
)

Definition at line 27 of file utils.c.

30{
31 UNICODE_STRING PartialString;
32 LONG EqualChars, TotalChars;
33
34 /* Build a partial string with the smaller substring */
35 PartialString.Length = EqualString->Length;
36 PartialString.MaximumLength = InputString->MaximumLength;
37 PartialString.Buffer = InputString->Buffer;
38
39 /* Check how many characters that need comparing */
40 EqualChars = 0;
41 TotalChars = (InputString->Length - EqualString->Length) / sizeof(WCHAR);
42
43 /* If the substring is bigger, just fail immediately */
44 if (TotalChars < 0) return FALSE;
45
46 /* Keep checking each character */
47 while (!RtlEqualUnicodeString(EqualString, &PartialString, CaseInSensitive))
48 {
49 /* Continue checking until all the required characters are equal */
50 PartialString.Buffer++;
51 PartialString.MaximumLength -= sizeof(WCHAR);
52 if (++EqualChars > TotalChars) return FALSE;
53 }
54
55 /* The string is equal */
56 return TRUE;
57}
_In_ const STRING _In_ BOOLEAN CaseInSensitive
Definition: rtlfuncs.h:2437
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
long LONG
Definition: pedump.c:60
USHORT MaximumLength
Definition: env_spec_w32.h:370

Referenced by DriverEntry().

Variable Documentation

◆ PciDebugPortsCount

ULONG PciDebugPortsCount

Definition at line 18 of file utils.c.

Referenced by PciIsDeviceOnDebugPath().

◆ PciIsaBitExclusionList

RTL_RANGE_LIST PciIsaBitExclusionList

Definition at line 20 of file utils.c.

Referenced by PciBuildDefaultExclusionLists().

◆ PciVgaAndIsaBitExclusionList

RTL_RANGE_LIST PciVgaAndIsaBitExclusionList

Definition at line 21 of file utils.c.

Referenced by PciBuildDefaultExclusionLists().