ReactOS 0.4.17-dev-1190-g4c812f4
enum.c File Reference
#include <pci.h>
#include <debug.h>
Include dependency graph for enum.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

BOOLEAN NTAPI PciComputeNewCurrentSettings (IN PPCI_PDO_EXTENSION PdoExtension, IN PCM_RESOURCE_LIST ResourceList)
 
VOID NTAPI PcipUpdateHardware (IN PVOID Context, IN PVOID Context2)
 
VOID NTAPI PciUpdateHardware (IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
 
PIO_RESOURCE_REQUIREMENTS_LIST NTAPI PciAllocateIoRequirementsList (IN ULONG Count, IN ULONG BusNumber, IN ULONG SlotNumber)
 
PCM_RESOURCE_LIST NTAPI PciAllocateCmResourceList (IN ULONG Count, IN ULONG BusNumber)
 
NTSTATUS NTAPI PciQueryResources (IN PPCI_PDO_EXTENSION PdoExtension, OUT PCM_RESOURCE_LIST *Buffer)
 
NTSTATUS NTAPI PciQueryTargetDeviceRelations (IN PPCI_PDO_EXTENSION PdoExtension, IN OUT PDEVICE_RELATIONS *pDeviceRelations)
 
 _Requires_lock_held_ (PdoExtension->ParentFdoExtension->ChildListLock) static ULONG NTAPI PciGatherOtherFunctions(_In_ PPCI_PDO_EXTENSION PdoExtension
 Finds the other present functions in the same slot as PdoExtension. When Objects is not NULL, each PDO found is referenced and stored there.
 
 _Out_writes_opt_ (_Inexpressible_("function count"))
 
NTSTATUS NTAPI PciQueryEjectionRelations (IN PPCI_PDO_EXTENSION PdoExtension, IN OUT PDEVICE_RELATIONS *pDeviceRelations)
 
BOOLEAN NTAPI PciIsRequirementDescriptor (_In_ PIO_RESOURCE_DESCRIPTOR Limit)
 Tells whether a discovered limit asks the arbiter for a range.
 
static ULONG NTAPI PciAddCurrentPlacementRequirement (_In_ PPCI_PDO_EXTENSION PdoExtension, _In_ USHORT Command, _In_ ULONG BarIndex, _Out_opt_ PIO_RESOURCE_DESCRIPTOR Descriptor)
 Writes a fixed requirement for the range a BAR is decoding now.
 
NTSTATUS NTAPI PciBuildRequirementsList (IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData, OUT PIO_RESOURCE_REQUIREMENTS_LIST *Buffer)
 
NTSTATUS NTAPI PciQueryRequirements (IN PPCI_PDO_EXTENSION PdoExtension, IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *RequirementsList)
 
BOOLEAN NTAPI PciConfigureIdeController (IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData, IN BOOLEAN Initial)
 
VOID NTAPI PciApplyHacks (IN PPCI_FDO_EXTENSION DeviceExtension, IN PPCI_COMMON_HEADER PciData, IN PCI_SLOT_NUMBER SlotNumber, IN ULONG OperationType, PPCI_PDO_EXTENSION PdoExtension)
 
BOOLEAN NTAPI PcipIsSameDevice (IN PPCI_PDO_EXTENSION DeviceExtension, IN PPCI_COMMON_HEADER PciData)
 
BOOLEAN NTAPI PciSkipThisFunction (IN PPCI_COMMON_HEADER PciData, IN PCI_SLOT_NUMBER Slot, IN UCHAR OperationType, IN ULONGLONG HackFlags)
 
VOID NTAPI PciGetEnhancedCapabilities (IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
 
VOID NTAPI PciWriteLimitsAndRestoreCurrent (IN PVOID Reserved, IN PVOID Context2)
 
NTSTATUS NTAPI PcipGetFunctionLimits (IN PPCI_CONFIGURATOR_CONTEXT Context)
 
NTSTATUS NTAPI PciGetFunctionLimits (IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER Current, IN ULONGLONG HackFlags)
 
VOID NTAPI PciProcessBus (IN PPCI_FDO_EXTENSION DeviceExtension)
 
NTSTATUS NTAPI PciScanBus (IN PPCI_FDO_EXTENSION DeviceExtension)
 
NTSTATUS NTAPI PciQueryDeviceRelations (IN PPCI_FDO_EXTENSION DeviceExtension, IN OUT PDEVICE_RELATIONS *pDeviceRelations)
 
NTSTATUS NTAPI PciSetResources (IN PPCI_PDO_EXTENSION PdoExtension, IN BOOLEAN DoReset, IN BOOLEAN SomethingSomethingDarkSide)
 

Variables

PIO_RESOURCE_REQUIREMENTS_LIST PciZeroIoResourceRequirements
 
PCI_CONFIGURATOR PciConfigurators []
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file enum.c.

Function Documentation

◆ _Out_writes_opt_()

_Out_writes_opt_ ( _Inexpressible_("function count")  )

Definition at line 587 of file enum.c.

588{
590 ULONG Found = 0;
591
592 for (Child = PdoExtension->ParentFdoExtension->ChildPdoList; Child; Child = Child->Next)
593 {
594 if ((Child == PdoExtension) ||
595 Child->NotPresent ||
596 (Child->Slot.u.bits.DeviceNumber != PdoExtension->Slot.u.bits.DeviceNumber))
597 {
598 continue;
599 }
600
601 if (Objects)
602 {
603 ObReferenceObject(Child->PhysicalDeviceObject);
604 Objects[Found] = Child->PhysicalDeviceObject;
605 }
606 Found++;
607 }
608
609 return Found;
610}
return Found
Definition: dirsup.c:1270
@ PdoExtension
Definition: precomp.h:61
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFDEVICE Child
Definition: wdffdo.h:536
#define ObReferenceObject
Definition: obfuncs.h:204

◆ _Requires_lock_held_()

_Requires_lock_held_ ( PdoExtension->ParentFdoExtension->  ChildListLock)

Finds the other present functions in the same slot as PdoExtension. When Objects is not NULL, each PDO found is referenced and stored there.

◆ PciAddCurrentPlacementRequirement()

static ULONG NTAPI PciAddCurrentPlacementRequirement ( _In_ PPCI_PDO_EXTENSION  PdoExtension,
_In_ USHORT  Command,
_In_ ULONG  BarIndex,
_Out_opt_ PIO_RESOURCE_DESCRIPTOR  Descriptor 
)
static

Writes a fixed requirement for the range a BAR is decoding now.

Parameters
[in]PdoExtensionThe PDO extension of the function.
[in]CommandThe command register of the function as it reads now.
[in]BarIndexThe BAR to describe.
[out]DescriptorReceives the requirement, or NULL to only count it.
Returns
1 when the BAR has such a range, otherwise 0.

Definition at line 702 of file enum.c.

707{
710 IO_RESOURCE_DESCRIPTOR Placement;
711 ULONGLONG Start, End, Length, Maximum;
712 USHORT DecodeBit;
713 PAGED_CODE();
714
715 Current = &PdoExtension->Resources->Current[BarIndex];
716 Limit = &PdoExtension->Resources->Limit[BarIndex];
717
718 if (Current->Type == CmResourceTypePort)
719 DecodeBit = PCI_ENABLE_IO_SPACE;
720 else if ((Current->Type == CmResourceTypeMemory) ||
721 (Current->Type == CmResourceTypeMemoryLarge))
722 DecodeBit = PCI_ENABLE_MEMORY_SPACE;
723 else
724 return 0;
725
726 /* An address is only a placement while the function decodes it */
727 if ((Limit->Type != Current->Type) || !(Command & DecodeBit))
728 return 0;
729
730 /* The range has to be one this BAR can decode, which also rules out bridge windows */
732 End = Start + Length - 1;
733 if (!Start ||
734 !Length ||
735 (Length != RtlIoDecodeMemIoResource(Limit, NULL, NULL, &Maximum)) ||
736 (End > Maximum))
737 {
738 return 0;
739 }
740
741 /* Built even when only counting, so a range that cannot be described is never counted */
742 Placement = *Limit;
743 Placement.Option = IO_RESOURCE_PREFERRED;
745 if (!NT_SUCCESS(RtlIoEncodeMemIoResource(&Placement, Limit->Type, Length, 1, Start, End)))
746 return 0;
747
748 if (Descriptor)
749 *Descriptor = Placement;
750
751 return 1;
752}
#define PAGED_CODE()
static _Out_opt_ PULONGLONG Start
ULONGLONG NTAPI RtlIoDecodeMemIoResource(_In_ PIO_RESOURCE_DESCRIPTOR Descriptor, _Out_opt_ PULONGLONG Alignment, _Out_opt_ PULONGLONG MinimumAddress, _Out_opt_ PULONGLONG MaximumAddress)
Definition: memres.c:79
ULONGLONG NTAPI RtlCmDecodeMemIoResource(_In_ PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor, _Out_opt_ PULONGLONG Start)
Definition: memres.c:58
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
unsigned short USHORT
Definition: pedump.c:61
#define CmResourceTypeMemory
Definition: restypes.h:106
#define CmResourceTypePort
Definition: restypes.h:104
Definition: shell.h:41
uint64_t ULONGLONG
Definition: typedefs.h:67
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
@ CmResourceShareDeviceExclusive
Definition: cmtypes.h:241
#define CmResourceTypeMemoryLarge
Definition: cmtypes.h:231
#define PCI_ENABLE_IO_SPACE
Definition: iotypes.h:3631
#define PCI_ENABLE_MEMORY_SPACE
Definition: iotypes.h:3632
#define IO_RESOURCE_PREFERRED
_In_ LONG _In_ LONG Limit
Definition: kefuncs.h:304
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 PciBuildRequirementsList().

◆ PciAllocateCmResourceList()

PCM_RESOURCE_LIST NTAPI PciAllocateCmResourceList ( IN ULONG  Count,
IN ULONG  BusNumber 
)

Definition at line 359 of file enum.c.

361{
362 SIZE_T Size;
364
365 /* Calculate the final size of the list, including each descriptor */
366 Size = sizeof(CM_RESOURCE_LIST);
367 if (Count > 1) Size = sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (Count - 1) +
368 sizeof(CM_RESOURCE_LIST);
369
370 /* Allocate the list */
372 if (!ResourceList) return NULL;
373
374 /* Initialize it */
376 ResourceList->Count = 1;
377 ResourceList->List[0].BusNumber = BusNumber;
378 ResourceList->List[0].InterfaceType = PCIBus;
379 ResourceList->List[0].PartialResourceList.Version = 1;
380 ResourceList->List[0].PartialResourceList.Revision = 1;
381 ResourceList->List[0].PartialResourceList.Count = Count;
382
383 /* Return it */
384 return ResourceList;
385}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
int Count
Definition: noreturn.cpp:7
_In_ ULONG BusNumber
Definition: pciidex.h:65
struct _CM_RESOURCE_LIST CM_RESOURCE_LIST
@ PCIBus
Definition: restypes.h:127
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR CM_PARTIAL_RESOURCE_DESCRIPTOR
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
Definition: wdfresource.h:309

Referenced by PciQueryResources().

◆ PciAllocateIoRequirementsList()

PIO_RESOURCE_REQUIREMENTS_LIST NTAPI PciAllocateIoRequirementsList ( IN ULONG  Count,
IN ULONG  BusNumber,
IN ULONG  SlotNumber 
)

Definition at line 326 of file enum.c.

329{
330 SIZE_T Size;
332
333 /* Calculate the final size of the list, including each descriptor */
335 if (Count > 1) Size = sizeof(IO_RESOURCE_DESCRIPTOR) * (Count - 1) +
337
338 /* Allocate the list */
340 if (!RequirementsList) return NULL;
341
342 /* Initialize it */
344 RequirementsList->AlternativeLists = 1;
345 RequirementsList->BusNumber = BusNumber;
346 RequirementsList->SlotNumber = SlotNumber;
347 RequirementsList->InterfaceType = PCIBus;
348 RequirementsList->ListSize = Size;
349 RequirementsList->List[0].Count = Count;
350 RequirementsList->List[0].Version = 1;
351 RequirementsList->List[0].Revision = 1;
352
353 /* Return it */
354 return RequirementsList;
355}
struct _IO_RESOURCE_DESCRIPTOR IO_RESOURCE_DESCRIPTOR
_In_ WDFIORESREQLIST RequirementsList
Definition: wdfresource.h:65
_In_ WDFIORESREQLIST _In_ ULONG SlotNumber
Definition: wdfresource.h:68
struct _IO_RESOURCE_REQUIREMENTS_LIST IO_RESOURCE_REQUIREMENTS_LIST

Referenced by PciBuildRequirementsList().

◆ PciApplyHacks()

VOID NTAPI PciApplyHacks ( IN PPCI_FDO_EXTENSION  DeviceExtension,
IN PPCI_COMMON_HEADER  PciData,
IN PCI_SLOT_NUMBER  SlotNumber,
IN ULONG  OperationType,
PPCI_PDO_EXTENSION  PdoExtension 
)

Definition at line 1081 of file enum.c.

1086{
1087 ULONG LegacyBaseAddress;
1089 UCHAR RegValue;
1090
1092
1093 /* Check what kind of hack operation this is */
1094 switch (OperationType)
1095 {
1096 /*
1097 * This is mostly concerned with fixing up incorrect class data that can
1098 * exist on certain PCI hardware before the 2.0 spec was ratified.
1099 */
1101
1102 /* Note that the i82375 PCI/EISA and the i82378 PCI/ISA bridges that
1103 * are present on certain DEC/NT Alpha machines are pre-PCI 2.0 devices
1104 * and appear as non-classified, so their correct class/subclass data
1105 * is written here instead.
1106 */
1107 if ((PciData->VendorID == 0x8086) &&
1108 ((PciData->DeviceID == 0x482) || (PciData->DeviceID == 0x484)))
1109 {
1110 /* Note that 0x482 is the i82375 (EISA), 0x484 is the i82378 (ISA) */
1111 PciData->SubClass = PciData->DeviceID == 0x482 ?
1113 PciData->BaseClass = PCI_CLASS_BRIDGE_DEV;
1114
1115 /*
1116 * Because the software is modifying the actual header data from
1117 * the BIOS, this flag tells the driver to ignore failures when
1118 * comparing the original BIOS data with the PCI data.
1119 */
1120 if (PdoExtension) PdoExtension->ExpectedWritebackFailure = TRUE;
1121 }
1122
1123 /* Note that in this case, an immediate return is issued */
1124 return;
1125
1126 /*
1127 * This is concerned with setting up interrupts correctly for native IDE
1128 * mode, but will also handle broken VGA decoding on older bridges as
1129 * well as a PAE-specific hack for certain Compaq Hot-Plug Controllers.
1130 */
1132
1133 /* There should always be a PDO extension passed in */
1135
1136 /*
1137 * On the OPTi Viper-M IDE controller, Linux doesn't support IDE-DMA
1138 * and FreeBSD bug reports indicate that the system crashes when the
1139 * feature is enabled (so it's disabled on that OS as well). In the
1140 * NT PCI Bus Driver, it seems Microsoft too, completely disables
1141 * Native IDE functionality on this controller, so it would seem OPTi
1142 * simply frelled up this controller.
1143 */
1144 if ((PciData->VendorID == 0x1045) && (PciData->DeviceID != 0xC621))
1145 {
1146 /* Disable native mode */
1147 PciData->ProgIf &= ~5;
1148 PciData->u.type0.InterruptPin = 0;
1149
1150 /*
1151 * Because the software is modifying the actual header data from
1152 * the BIOS, this flag tells the driver to ignore failures when
1153 * comparing the original BIOS data with the PCI data.
1154 */
1155 PdoExtension->ExpectedWritebackFailure = TRUE;
1156 }
1157 else if ((PciData->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
1158 (PciData->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR))
1159 {
1160 /* For other IDE controllers, start out in compatible mode */
1161 PdoExtension->BIOSAllowsIDESwitchToNativeMode = FALSE;
1162
1163 /*
1164 * Registry must have enabled native mode (typically as a result
1165 * of an INF file directive part of the IDE controller's driver)
1166 * and the system must not be booted in Safe Mode. If that checks
1167 * out, then evaluate the ACPI NATA method to see if the platform
1168 * supports this. See the section "BIOS and Platform Prerequisites
1169 * for Switching a Native-Mode-Capable Controller" in the Storage
1170 * section of the Windows Driver Kit for more details:
1171 *
1172 * 5. For each ATA controller enumerated, the PCI bus driver checks
1173 * the Programming Interface register of the IDE controller to
1174 * see if it supports switching both channels to native mode.
1175 * 6. The PCI bus driver checks whether the BIOS/platform supports
1176 * switching the controller by checking the NATA method described
1177 * earlier in this article.
1178 *
1179 * If an ATA controller does not indicate that it is native
1180 * mode-capable, or if the BIOS NATA control method is missing
1181 * or does not list that device, the PCI bus driver does not
1182 * switch the controller and it is assigned legacy resources.
1183 *
1184 * If both the controller and the BIOS indicate that the controller
1185 * can be switched, the process of switching the controller begins
1186 * with the next step.
1187 */
1188 if ((PciEnableNativeModeATA) &&
1189 !(InitSafeBootMode) &&
1191 {
1192 /* The platform supports it, remember that */
1193 PdoExtension->BIOSAllowsIDESwitchToNativeMode = TRUE;
1194
1195 /*
1196 * Now switch the controller into native mode if both channels
1197 * support native IDE mode. See "How Windows Switches an ATA
1198 * Controller to Native Mode" in the Storage section of the
1199 * Windows Driver Kit for more details.
1200 */
1201 PdoExtension->IDEInNativeMode =
1203 }
1204
1205 /* Is native mode enabled after all? */
1206 if ((PciData->ProgIf & 5) != 5)
1207 {
1208 /* Compatible mode, so force ISA-style IRQ14 and IRQ 15 */
1209 PciData->u.type0.InterruptPin = 0;
1210 }
1211 }
1212
1213 /* Is this a PCI device with legacy VGA card decodes on the root bus? */
1214 if ((PdoExtension->HackFlags & PCI_HACK_VIDEO_LEGACY_DECODE) &&
1215 (PCI_IS_ROOT_FDO(DeviceExtension)) &&
1216 !(DeviceExtension->BrokenVideoHackApplied))
1217 {
1218 /* Tell the arbiter to apply a hack for these older devices */
1219 ario_ApplyBrokenVideoHack(DeviceExtension);
1220 }
1221
1222 /* Is this a Compaq PCI Hotplug Controller (r17) on a PAE system ? */
1223 if ((PciData->VendorID == 0xE11) &&
1224 (PciData->DeviceID == 0xA0F7) &&
1225 (PciData->RevisionID == 17) &&
1227 {
1228 /* Turn off the decodes immediately */
1229 PciData->Command &= ~(PCI_ENABLE_IO_SPACE |
1233 &PciData->Command,
1235 sizeof(USHORT));
1236
1237 /* Do not EVER turn them on again, this will blow up the system */
1238 PdoExtension->CommandEnables &= ~(PCI_ENABLE_IO_SPACE |
1242 }
1243 break;
1244
1245 /*
1246 * This is called whenever resources are changed and hardware needs to be
1247 * updated. It is concerned with two highly specific erratas on an IBM
1248 * hot-plug docking bridge used on the Thinkpad 600 Series and on subtractive
1249 * decode PCI Bridges.
1250 */
1252
1253 /* There should always be a PDO extension passed in */
1255
1256 /* Is this an IBM 20H2999 PCI Docking Bridge, used on Thinkpads? */
1257 if ((PdoExtension->VendorId == 0x1014) &&
1258 (PdoExtension->DeviceId == 0x95))
1259 {
1260 /* Read the current command */
1262 &Command,
1264 sizeof(USHORT));
1265
1266 /* Turn off the decodes */
1268
1269 /* Apply the required IBM workaround */
1270 PciReadDeviceConfig(PdoExtension, &RegValue, 0xE0, sizeof(UCHAR));
1271 RegValue &= ~2;
1272 RegValue |= 1;
1273 PciWriteDeviceConfig(PdoExtension, &RegValue, 0xE0, sizeof(UCHAR));
1274
1275 /* Restore the command to its original value */
1277 &Command,
1279 sizeof(USHORT));
1280
1281 }
1282
1283 /*
1284 * A subtractive bridge needs no positive windows, except Intel ICH (i82801) and
1285 * flagged bridges, which keep the windows their saved header had open.
1286 */
1287 if ((PdoExtension->HeaderType == PCI_BRIDGE_TYPE) &&
1288 (PdoExtension->Dependent.type1.SubtractiveDecode) &&
1289 !((PdoExtension->VendorId == 0x8086) &&
1290 ((PdoExtension->DeviceId == 0x2418) ||
1291 (PdoExtension->DeviceId == 0x2428) ||
1292 (PdoExtension->DeviceId == 0x244E) ||
1293 (PdoExtension->DeviceId == 0x2448))) &&
1295 {
1296 PciData->u.type1.MemoryBase = 0xFFFF;
1297 PciData->u.type1.PrefetchBase = 0xFFFF;
1298 PciData->u.type1.IOBase = 0xFF;
1299 PciData->u.type1.IOLimit = 0;
1300 PciData->u.type1.MemoryLimit = 0;
1301 PciData->u.type1.PrefetchLimit = 0;
1302 PciData->u.type1.PrefetchBaseUpper32 = 0;
1303 PciData->u.type1.PrefetchLimitUpper32 = 0;
1304 PciData->u.type1.IOBaseUpper16 = 0;
1305 PciData->u.type1.IOLimitUpper16 = 0;
1306 }
1307 break;
1308
1309 default:
1310 return;
1311 }
1312
1313 /* Finally, also check if this is this a CardBUS device? */
1315 {
1316 /*
1317 * At offset 44h the LegacyBaseAddress is stored, which is cleared by
1318 * ACPI-aware versions of Windows, to disable legacy-mode I/O access to
1319 * CardBus controllers. For more information, see "Supporting CardBus
1320 * Controllers under ACPI" in the "CardBus Controllers and Windows"
1321 * Whitepaper on WHDC.
1322 */
1323 LegacyBaseAddress = 0;
1325 &LegacyBaseAddress,
1326 sizeof(PCI_COMMON_HEADER) + sizeof(ULONG),
1327 sizeof(ULONG));
1328 }
1329}
VOID NTAPI ario_ApplyBrokenVideoHack(IN PPCI_FDO_EXTENSION FdoExtension)
Definition: ar_memio.c:184
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOLEAN NTAPI PciConfigureIdeController(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData, IN BOOLEAN Initial)
Definition: enum.c:941
BOOLEAN PciEnableNativeModeATA
Definition: init.c:24
VOID NTAPI PciWriteDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:133
BOOLEAN NTAPI PciIsSlotPresentInParentMethod(IN PPCI_PDO_EXTENSION PdoExtension, IN ULONG Method)
Definition: utils.c:1169
#define PCI_HACK_FIXUP_BEFORE_UPDATE
Definition: pci.h:82
#define PCI_IS_ROOT_FDO(x)
Definition: pci.h:42
VOID NTAPI PciDecodeEnable(IN PPCI_PDO_EXTENSION PdoExtension, IN BOOLEAN Enable, OUT PUSHORT Command)
Definition: utils.c:1359
#define PCI_HACK_FIXUP_AFTER_CONFIGURATION
Definition: pci.h:81
#define PCI_HACK_FIXUP_BEFORE_CONFIGURATION
Definition: pci.h:80
VOID NTAPI PciReadDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:149
PULONG InitSafeBootMode
Definition: init.c:75
#define ASSERT(a)
Definition: mode.c:44
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
BOOLEAN NTAPI ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature)
Definition: sysinfo.c:363
#define PCI_HACK_PRESERVE_COMMAND
Definition: pci.h:25
#define PCI_HACK_VIDEO_LEGACY_DECODE
Definition: pci.h:43
#define PCI_HACK_BROKEN_SUBTRACTIVE_DECODE
Definition: pci.h:50
unsigned char UCHAR
Definition: typedefs.h:53
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define PCI_ENABLE_BUS_MASTER
Definition: iotypes.h:3633
#define PCI_SUBCLASS_BR_EISA
Definition: iotypes.h:4179
#define PCI_CLASS_MASS_STORAGE_CTLR
Definition: iotypes.h:4119
#define PCI_CONFIGURATION_TYPE(PciData)
Definition: iotypes.h:3624
#define PCI_SUBCLASS_MSC_IDE_CTLR
Definition: iotypes.h:4144
#define PCI_BRIDGE_TYPE
Definition: iotypes.h:3621
#define PCI_SUBCLASS_BR_ISA
Definition: iotypes.h:4178
#define PCI_CLASS_BRIDGE_DEV
Definition: iotypes.h:4124
#define PCI_CARDBUS_BRIDGE_TYPE
Definition: iotypes.h:3622
#define PF_PAE_ENABLED
Definition: ketypes.h:185

Referenced by PciScanBus(), and PciSetResources().

◆ PciBuildRequirementsList()

NTSTATUS NTAPI PciBuildRequirementsList ( IN PPCI_PDO_EXTENSION  PdoExtension,
IN PPCI_COMMON_HEADER  PciData,
OUT PIO_RESOURCE_REQUIREMENTS_LIST *  Buffer 
)

Definition at line 756 of file enum.c.

759{
763 ULONG Count, i;
764 BOOLEAN HaveInterrupt;
765
766 PAGED_CODE();
767
768 /* Count the BAR limits that resource discovery found for this function */
769 Count = 0;
770 if (PdoExtension->Resources)
771 {
772 for (i = 0; i < (PCI_TYPE0_ADDRESSES + 1); i++)
773 {
774 if (!PciIsRequirementDescriptor(&PdoExtension->Resources->Limit[i]))
775 continue;
776
777 /* A resizable BAR also asks for the larger sizes it can decode */
778 Count++;
780 i,
781 &PdoExtension->Resources->Limit[i],
782 NULL);
783
784 /* And a BAR that already decodes a range also asks to keep it */
786 }
787 }
788
789 /* A device with an interrupt pin also needs a line routed to it */
790 HaveInterrupt = (PdoExtension->InterruptPin) &&
792 if (HaveInterrupt)
793 Count++;
794
795 /* And a bridge with legacy decodes enabled needs those ranges locked down */
796 Count += PdoExtension->AdditionalResourceCount;
797
798 /* Check if the function turned out to need nothing after all */
799 if (!Count)
800 {
801 /* There aren't, so use the zero descriptor */
803
804 /* Does it actually exist yet? */
806 {
807 /* Allocate it, and use it for future use */
811 }
812
814 DPRINT1("PCIX - build resource reqs - early out, 0 resources\n");
815 return STATUS_SUCCESS;
816 }
817
819 PdoExtension->ParentFdoExtension->BaseBus,
820 PdoExtension->Slot.u.AsULONG);
821 if (!RequirementsList)
823
824 Descriptor = RequirementsList->List[0].Descriptors;
825
826 /* Emit the requirements of each BAR that decoded something during discovery */
827 if (PdoExtension->Resources)
828 {
829 Limit = PdoExtension->Resources->Limit;
830 for (i = 0; i < (PCI_TYPE0_ADDRESSES + 1); i++)
831 {
832 /* Skip unimplemented BARs and bridge windows, neither asks for a range */
834 continue;
835
836 /* Larger resizable sizes, then the current placement, then the default size */
840 PciData->Command,
841 i,
842 Descriptor);
843
844 /* A BAR decodes for one function only, so it cannot be shared */
845 *Descriptor = Limit[i];
846 Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
847 Descriptor++;
848
849 /* The first choice for the BAR is preferred and every later one is its alternative */
850 First->Option |= IO_RESOURCE_PREFERRED;
851 for (Next = First + 1; Next < Descriptor; Next++)
852 Next->Option |= IO_RESOURCE_ALTERNATIVE;
853 }
854 }
855
856 if (HaveInterrupt)
857 {
859 Descriptor->ShareDisposition = CmResourceShareShared;
861 Descriptor->u.Interrupt.MinimumVector = 0;
862 Descriptor->u.Interrupt.MaximumVector = MAXULONG;
863 Descriptor++;
864 }
865
866 /* And finally any extra ranges this kind of function decodes on the side */
867 if (PdoExtension->AdditionalResourceCount)
868 {
869 RtlZeroMemory(&Context, sizeof(Context));
870 Context.PdoExtension = PdoExtension;
871 Context.Current = PciData;
872 PciConfigurators[PdoExtension->HeaderType].
873 GetAdditionalResourceDescriptors(&Context, PciData, Descriptor);
874 }
875
877 return STATUS_SUCCESS;
878}
WCHAR First[]
Definition: FormatMessage.c:11
unsigned char BOOLEAN
Definition: actypes.h:127
#define DPRINT1
Definition: precomp.h:8
Definition: bufpool.h:45
BOOLEAN NTAPI PciIsRequirementDescriptor(_In_ PIO_RESOURCE_DESCRIPTOR Limit)
Tells whether a discovered limit asks the arbiter for a range.
Definition: enum.c:671
static ULONG NTAPI PciAddCurrentPlacementRequirement(_In_ PPCI_PDO_EXTENSION PdoExtension, _In_ USHORT Command, _In_ ULONG BarIndex, _Out_opt_ PIO_RESOURCE_DESCRIPTOR Descriptor)
Writes a fixed requirement for the range a BAR is decoding now.
Definition: enum.c:702
PIO_RESOURCE_REQUIREMENTS_LIST PciZeroIoResourceRequirements
Definition: enum.c:18
PIO_RESOURCE_REQUIREMENTS_LIST NTAPI PciAllocateIoRequirementsList(IN ULONG Count, IN ULONG BusNumber, IN ULONG SlotNumber)
Definition: enum.c:326
PCI_CONFIGURATOR PciConfigurators[]
Definition: enum.c:20
ULONG NTAPI PciAddResizableBarRequirements(_In_ PPCI_PDO_EXTENSION PdoExtension, _In_ ULONG BarIndex, _In_ PIO_RESOURCE_DESCRIPTOR Limit, _Out_writes_opt_(2) PIO_RESOURCE_DESCRIPTOR Descriptors)
Writes the requirements for the sizes a resizable BAR can grow to. They go ahead of the default requi...
Definition: rbar.c:142
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
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
Definition: restypes.h:116
#define CmResourceTypeInterrupt
Definition: restypes.h:105
#define PCI_HACK_NO_ENUM_AT_ALL
Definition: pci.h:14
#define STATUS_SUCCESS
Definition: shellext.h:65
STDMETHOD() Next(THIS_ ULONG celt, IAssociationElement *pElement, ULONG *pceltFetched) PURE
#define MAXULONG
Definition: typedefs.h:251
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
@ CmResourceShareShared
Definition: cmtypes.h:243
#define PCI_TYPE0_ADDRESSES
Definition: iotypes.h:3515
#define IO_RESOURCE_ALTERNATIVE

Referenced by PciAssignAndProgramLegacy(), and PciQueryRequirements().

◆ PciComputeNewCurrentSettings()

BOOLEAN NTAPI PciComputeNewCurrentSettings ( IN PPCI_PDO_EXTENSION  PdoExtension,
IN PCM_RESOURCE_LIST  ResourceList 
)

Definition at line 55 of file enum.c.

57{
58 PCM_PARTIAL_RESOURCE_DESCRIPTOR Partial, InterruptResource;
59 PCM_PARTIAL_RESOURCE_DESCRIPTOR CurrentDescriptor;
60 CM_PARTIAL_RESOURCE_DESCRIPTOR ResourceArray[7];
61 ULONG BarIndex;
63 BOOLEAN RangeChange;
64 ULONG DrainPartial;
65 ULONG i, j;
66 PPCI_FUNCTION_RESOURCES PciResources;
67 PAGED_CODE();
68
69 /* Make sure we have either no resources, or at least one */
70 ASSERT((ResourceList == NULL) || (ResourceList->Count == 1));
71
72 /* Initialize no partial, interrupt descriptor, or range change */
73 Partial = NULL;
74 InterruptResource = NULL;
75 RangeChange = FALSE;
76 BarIndex = 0;
77
78 /* The limits say which BARs this function implements, so the walk below
79 * can tell which BAR each assigned descriptor belongs to */
80 PciResources = PdoExtension->Resources;
81
82 /* Check if there's not actually any resources */
83 if (!(ResourceList) || !(ResourceList->Count))
84 {
85 /* Then just return the hardware update state */
86 return PdoExtension->UpdateHardware;
87 }
88
89 /* Print the new specified resource list */
91
92 /* Zero all fields, an unassigned entry still gets copied into the current settings */
93 RtlZeroMemory(ResourceArray, sizeof(ResourceArray));
94
95 /* Loop the full resource descriptor */
96 FullList = ResourceList->List;
97 for (i = 0; i < ResourceList->Count; i++)
98 {
99 /* Initialize loop variables */
100 DrainPartial = 0;
101
102 /* Loop the partial descriptors */
103 Partial = FullList->PartialResourceList.PartialDescriptors;
104 for (j = 0; j < FullList->PartialResourceList.Count; j++)
105 {
106 /* Check if we were supposed to drain a partial due to device data */
107 if (DrainPartial)
108 {
109 DrainPartial--;
110 Partial = CmiGetNextPartialDescriptor(Partial);
111 continue;
112 }
113
114 /* Check what kind of descriptor this was */
115 switch (Partial->Type)
116 {
117 /* Base BAR resources */
121 {
122 /*
123 * Skip legacy/shared resources (e.g., VGA ports 0x3B0-0x3DF, memory 0xA0000).
124 * should not be placed in the ResourceArray.
125 */
127 {
128 break;
129 }
130
131 /*
132 * The assigned descriptors come back in the order the
133 * requirements list asked for them, so walking the limits
134 * in that same order says which BAR this one satisfies.
135 */
136 if (PciResources)
137 {
138 while ((BarIndex < RTL_NUMBER_OF(ResourceArray)) &&
139 !PciIsRequirementDescriptor(&PciResources->Limit[BarIndex]))
140 {
141 BarIndex++;
142 }
143
144 if (BarIndex < RTL_NUMBER_OF(ResourceArray))
145 ResourceArray[BarIndex++] = *Partial;
146 }
147 break;
148 }
149 /* Interrupt resource */
151
152 /* Make sure it's the only PCI interrupt */
153 ASSERT(InterruptResource == NULL);
154 InterruptResource = Partial;
155
156 /* A message grant packs its message count into the level and
157 * has no line to report, it gets programmed at start instead */
159 break;
160
161 /* Make sure it's a compatible line-based interrupt */
162 ASSERT(Partial->u.Interrupt.Level == Partial->u.Interrupt.Vector);
163
164 /* Only 255 interrupts on x86/x64 hardware */
165 if (Partial->u.Interrupt.Level < 256)
166 {
167 /* Use the passed interrupt line */
168 PdoExtension->AdjustedInterruptLine = Partial->u.Interrupt.Level;
169 }
170 else
171 {
172 /* Invalid vector, so ignore it */
173 PdoExtension->AdjustedInterruptLine = 0;
174 }
175
176 break;
177
178 /* Check for specific device data */
180
181 /* Check what kind of data this was */
182 switch (Partial->u.DevicePrivate.Data[0])
183 {
184 /* Not used in the driver yet */
185 case 1:
186 case 2:
187 DPRINT1("PCIX - ignoring device-private data type %u\n",
188 Partial->u.DevicePrivate.Data[0]);
189 break;
190
191 /* A drain request */
192 case 3:
193 DrainPartial = Partial->u.DevicePrivate.Data[1];
194 break;
195 }
196 break;
197 }
198
199 /* Move to the next descriptor */
200 Partial = CmiGetNextPartialDescriptor(Partial);
201 }
202
203 /* We should be starting a new list now */
204 FullList = (PVOID)Partial;
205 }
206
207 /* A function with no discovered resources has nothing to update */
208 if (!PciResources) return FALSE;
209
210 /* Loop all the PCI function resources */
211 for (i = 0; i < RTL_NUMBER_OF(ResourceArray); i++)
212 {
213 /* A bridge window is never asked for, so it keeps the range the firmware gave it */
214 if (!PciIsRequirementDescriptor(&PciResources->Limit[i]))
215 continue;
216
217 /* Get the current function resource descriptor, and the new one */
218 CurrentDescriptor = &PciResources->Current[i];
219 Partial = &ResourceArray[i];
220
221 /* Check if this new descriptor is different than the old one */
222 if ((Partial->Type != CurrentDescriptor->Type) ||
223 ((Partial->Type != CmResourceTypeNull) &&
224 ((Partial->u.Generic.Start.QuadPart !=
225 CurrentDescriptor->u.Generic.Start.QuadPart) ||
226 (RtlCmDecodeMemIoResource(Partial, NULL) !=
227 RtlCmDecodeMemIoResource(CurrentDescriptor, NULL)))))
228 {
229 /* Record a change */
230 RangeChange = TRUE;
231
232 /* Was there a range before? */
233 if (CurrentDescriptor->Type != CmResourceTypeNull)
234 {
235 /* Print it */
236 DbgPrint(" Old range-\n");
237 PciDebugPrintPartialResource(CurrentDescriptor);
238 }
239 else
240 {
241 /* There was no range */
242 DbgPrint(" Previously unset range\n");
243 }
244
245 /* Print new one */
246 DbgPrint(" changed to\n");
248
249 /* Update to new range */
250 CurrentDescriptor->Type = Partial->Type;
251 CurrentDescriptor->Flags = Partial->Flags;
252 CurrentDescriptor->u.Generic.Start = Partial->u.Generic.Start;
253 CurrentDescriptor->u.Generic.Length = Partial->u.Generic.Length;
254 }
255 }
256
257 /* Either the hardware was updated, or a resource range changed */
258 return ((RangeChange) || (PdoExtension->UpdateHardware));
259}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
FORCEINLINE PCM_PARTIAL_RESOURCE_DESCRIPTOR CmiGetNextPartialDescriptor(_In_ const CM_PARTIAL_RESOURCE_DESCRIPTOR *PartialDescriptor)
Definition: cmreslist.h:31
VOID NTAPI PciDebugPrintPartialResource(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource)
Definition: debug.c:349
VOID NTAPI PciDebugPrintCmResList(IN PCM_RESOURCE_LIST PartialList)
Definition: debug.c:365
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 GLint GLint j
Definition: glfuncs.h:250
#define DbgPrint
Definition: hal.h:12
#define CM_RESOURCE_INTERRUPT_MESSAGE
Definition: restypes.h:118
#define CmResourceTypeNull
Definition: restypes.h:103
#define CmResourceTypeDevicePrivate
Definition: restypes.h:112
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: restypes.h:145
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@494 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@494::@501 DevicePrivate
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@494::@497 Interrupt
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@494::@495 Generic
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: restypes.h:100
IO_RESOURCE_DESCRIPTOR Limit[7]
Definition: pci.h:287
CM_PARTIAL_RESOURCE_DESCRIPTOR Current[7]
Definition: pci.h:288
void * PVOID
Definition: typedefs.h:50
@ CmResourceShareDriverExclusive
Definition: cmtypes.h:242

Referenced by PciAssignAndProgramLegacy(), and PciPdoIrpStartDevice().

◆ PciConfigureIdeController()

BOOLEAN NTAPI PciConfigureIdeController ( IN PPCI_PDO_EXTENSION  PdoExtension,
IN PPCI_COMMON_HEADER  PciData,
IN BOOLEAN  Initial 
)

Definition at line 941 of file enum.c.

944{
945 UCHAR MasterMode, SlaveMode, MasterFixed, SlaveFixed, ProgIf, NewProgIf;
946 BOOLEAN Switched;
948
949 /* Assume it won't work */
950 Switched = FALSE;
951
952 /* Get master and slave current settings, and programmability flag */
953 ProgIf = PciData->ProgIf;
954 MasterMode = (ProgIf & 1) == 1;
955 MasterFixed = (ProgIf & 2) == 0;
956 SlaveMode = (ProgIf & 4) == 4;
957 SlaveFixed = (ProgIf & 8) == 0;
958
959 /*
960 * [..] In order for Windows XP SP1 and Windows Server 2003 to switch an ATA
961 * ATA controller from compatible mode to native mode, the following must be
962 * true:
963 *
964 * - The controller must indicate in its programming interface that both channels
965 * can be switched to native mode. Windows XP SP1 and Windows Server 2003 do
966 * not support switching only one IDE channel to native mode. See the PCI IDE
967 * Controller Specification Revision 1.0 for details.
968 */
969 if ((MasterMode != SlaveMode) || (MasterFixed != SlaveFixed))
970 {
971 /* Windows does not support this configuration, fail */
972 DPRINT1("PCIX - Warning unsupported IDE controller configuration for VEN_%04x&DEV_%04x!",
973 PdoExtension->VendorId,
974 PdoExtension->DeviceId);
975 return Switched;
976 }
977
978 /* Check if the controller is already in native mode */
979 if ((MasterMode) && (SlaveMode))
980 {
981 /* Check if I/O decodes should be disabled */
982 if ((Initial) || (PdoExtension->IoSpaceUnderNativeIdeControl))
983 {
984 /* Read the current command */
986 &Command,
988 sizeof(USHORT));
989
990 /* Disable I/O space decode */
991 Command &= ~PCI_ENABLE_IO_SPACE;
992
993 /* Update new command in PCI IDE controller */
995 &Command,
997 sizeof(USHORT));
998
999 /* Save updated command value */
1000 PciData->Command = Command;
1001 }
1002
1003 /* The controller is now in native mode */
1004 Switched = TRUE;
1005 }
1006 else if (!(MasterFixed) &&
1007 !(SlaveFixed) &&
1008 (PdoExtension->BIOSAllowsIDESwitchToNativeMode) &&
1010 {
1011 /* Turn off decodes */
1013
1014 /* Update the current command */
1016 &PciData->Command,
1018 sizeof(USHORT));
1019
1020 /* Enable native mode */
1021 ProgIf = PciData->ProgIf | 5;
1023 &ProgIf,
1025 sizeof(UCHAR));
1026
1027 /* Verify the setting "stuck" */
1029 &NewProgIf,
1031 sizeof(UCHAR));
1032 if (NewProgIf == ProgIf)
1033 {
1034 /* Update the header and PDO data with the new programming mode */
1035 PciData->ProgIf = ProgIf;
1036 PdoExtension->ProgIf = NewProgIf;
1037
1038 /* Clear the first four BARs to reset current BAR settings */
1039 PciData->u.type0.BaseAddresses[0] = 0;
1040 PciData->u.type0.BaseAddresses[1] = 0;
1041 PciData->u.type0.BaseAddresses[2] = 0;
1042 PciData->u.type0.BaseAddresses[3] = 0;
1044 PciData->u.type0.BaseAddresses,
1046 u.type0.BaseAddresses),
1047 4 * sizeof(ULONG));
1048
1049 /* Re-read the BARs to have the latest data for native mode IDE */
1051 PciData->u.type0.BaseAddresses,
1053 u.type0.BaseAddresses),
1054 4 * sizeof(ULONG));
1055
1056 /* Re-read the interrupt pin used for native mode IDE */
1058 &PciData->u.type0.InterruptPin,
1060 u.type0.InterruptPin),
1061 sizeof(UCHAR));
1062
1063 /* The IDE Controller is now in native mode */
1064 Switched = TRUE;
1065 }
1066 else
1067 {
1068 /* Settings did not work, fail */
1069 DPRINT1("PCIX - Warning failed switch to native mode for IDE controller VEN_%04x&DEV_%04x!",
1070 PciData->VendorID,
1071 PciData->DeviceID);
1072 }
1073 }
1074
1075 /* Return whether or not native mode was enabled on the IDE controller */
1076 return Switched;
1077}
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 * u
Definition: glfuncs.h:240
#define PCI_HACK_DISABLE_IDE_NATIVE_MODE
Definition: pci.h:46

Referenced by PciApplyHacks(), and PciSetResources().

◆ PciGetEnhancedCapabilities()

VOID NTAPI PciGetEnhancedCapabilities ( IN PPCI_PDO_EXTENSION  PdoExtension,
IN PPCI_COMMON_HEADER  PciData 
)

Definition at line 1441 of file enum.c.

1443{
1444 ULONG HeaderType, CapPtr, TargetAgpCapabilityId;
1445 DEVICE_POWER_STATE WakeLevel;
1446 PCI_CAPABILITIES_HEADER AgpCapability;
1448 PAGED_CODE();
1449
1450 /* Assume no known wake level */
1451 PdoExtension->PowerState.DeviceWakeLevel = PowerDeviceUnspecified;
1452
1453 /* Make sure the device has capabilities */
1454 if (!(PciData->Status & PCI_STATUS_CAPABILITIES_LIST))
1455 {
1456 /* If it doesn't, there will be no power management */
1457 PdoExtension->CapabilitiesPtr = 0;
1458 PdoExtension->HackFlags |= PCI_HACK_NO_PM_CAPS;
1459 }
1460 else
1461 {
1462 /* There's capabilities, need to figure out where to get the offset */
1463 HeaderType = PCI_CONFIGURATION_TYPE(PciData);
1464 if (HeaderType == PCI_CARDBUS_BRIDGE_TYPE)
1465 {
1466 /* Use the bridge's header */
1467 CapPtr = PciData->u.type2.CapabilitiesPtr;
1468 }
1469 else
1470 {
1471 /* Use the device header */
1472 ASSERT(HeaderType <= PCI_CARDBUS_BRIDGE_TYPE);
1473 CapPtr = PciData->u.type0.CapabilitiesPtr;
1474 }
1475
1476 /* Skip garbage capabilities pointer */
1477 if (((CapPtr & 0x3) != 0) || (CapPtr < PCI_COMMON_HDR_LENGTH))
1478 {
1479 /* Report no extended capabilities */
1480 PdoExtension->CapabilitiesPtr = 0;
1481 PdoExtension->HackFlags |= PCI_HACK_NO_PM_CAPS;
1482 }
1483 else
1484 {
1485 DPRINT1("PCIX - Device has capabilities at: %lx\n", CapPtr);
1486 PdoExtension->CapabilitiesPtr = CapPtr;
1487
1488 /* Check for PCI-to-PCI Bridges and AGP bridges */
1489 if ((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
1490 ((PdoExtension->SubClass == PCI_SUBCLASS_BR_HOST) ||
1492 {
1493 /* Query either the raw AGP capabilitity, or the Target AGP one */
1494 TargetAgpCapabilityId = (PdoExtension->SubClass ==
1499 PdoExtension->CapabilitiesPtr,
1500 TargetAgpCapabilityId,
1501 &AgpCapability,
1502 sizeof(PCI_CAPABILITIES_HEADER)))
1503 {
1504 /* AGP target ID was found, store it */
1505 DPRINT1("PCIX - AGP ID: %lx\n", TargetAgpCapabilityId);
1506 PdoExtension->TargetAgpCapabilityId = TargetAgpCapabilityId;
1507 }
1508 }
1509
1510 /* Check for devices that are known not to have proper power management */
1511 if (!(PdoExtension->HackFlags & PCI_HACK_NO_PM_CAPS))
1512 {
1513 /* Query if this device supports power management */
1515 PdoExtension->CapabilitiesPtr,
1517 &PowerCapabilities.Header,
1518 sizeof(PCI_PM_CAPABILITY)))
1519 {
1520 /* No power management, so act as if it had the hackflag set */
1521 DPRINT1("PCIX - No PM caps, disabling PM\n");
1522 PdoExtension->HackFlags |= PCI_HACK_NO_PM_CAPS;
1523 }
1524 else
1525 {
1526 /* Otherwise, pick the highest wake level that is supported */
1527 WakeLevel = PowerDeviceUnspecified;
1528 if (PowerCapabilities.PMC.Capabilities.Support.PMED0)
1529 WakeLevel = PowerDeviceD0;
1530 if (PowerCapabilities.PMC.Capabilities.Support.PMED1)
1531 WakeLevel = PowerDeviceD1;
1532 if (PowerCapabilities.PMC.Capabilities.Support.PMED2)
1533 WakeLevel = PowerDeviceD2;
1534 if (PowerCapabilities.PMC.Capabilities.Support.PMED3Hot)
1535 WakeLevel = PowerDeviceD3;
1536 if (PowerCapabilities.PMC.Capabilities.Support.PMED3Cold)
1537 WakeLevel = PowerDeviceD3;
1538 PdoExtension->PowerState.DeviceWakeLevel = WakeLevel;
1539
1540 /* Convert the PCI power state to the NT power state */
1541 PdoExtension->PowerState.CurrentDeviceState =
1542 PowerCapabilities.PMCSR.ControlStatus.PowerState + 1;
1543
1544 /* Save all the power capabilities */
1545 PdoExtension->PowerCapabilities = PowerCapabilities.PMC.Capabilities;
1546 DPRINT1("PCIX - PM Caps Found! Wake Level: %d Power State: %d\n",
1547 WakeLevel, PdoExtension->PowerState.CurrentDeviceState);
1548 }
1549 }
1550 }
1551 }
1552
1553 /* Now find out whether this is an Express function, and what kind */
1555
1556 /* And whether any of its BARs can be resized */
1558
1559 /* At the very end of all this, does this device not have power management? */
1560 if (PdoExtension->HackFlags & PCI_HACK_NO_PM_CAPS)
1561 {
1562 /* Then guess the current state based on whether the decodes are on */
1563 PdoExtension->PowerState.CurrentDeviceState =
1564 PciData->Command & (PCI_ENABLE_IO_SPACE |
1568 DPRINT1("PCIX - PM is off, so assumed device is: %d based on enables\n",
1569 PdoExtension->PowerState.CurrentDeviceState);
1570 }
1571}
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
VOID NTAPI PciGetResizableBarCapability(_Inout_ PPCI_PDO_EXTENSION PdoExtension)
Records which BARs of a new function can be resized and the sizes each of them supports.
Definition: rbar.c:31
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:958
@ 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
#define PCI_HACK_NO_PM_CAPS
Definition: pci.h:40
_In_ WDFDEVICE _In_ PWDF_DEVICE_POWER_CAPABILITIES PowerCapabilities
Definition: wdfdevice.h:3892
#define PCI_CAPABILITY_ID_AGP
Definition: iotypes.h:3663
#define PCI_SUBCLASS_BR_HOST
Definition: iotypes.h:4177
#define PCI_SUBCLASS_BR_PCI_TO_PCI
Definition: iotypes.h:4181
#define PCI_COMMON_HDR_LENGTH
Definition: iotypes.h:3609
#define PCI_STATUS_CAPABILITIES_LIST
Definition: iotypes.h:3645
#define PCI_CAPABILITY_ID_POWER_MANAGEMENT
Definition: iotypes.h:3662
#define PCI_CAPABILITY_ID_AGP_TARGET
Definition: iotypes.h:3675

Referenced by PciScanBus().

◆ PciGetFunctionLimits()

NTSTATUS NTAPI PciGetFunctionLimits ( IN PPCI_PDO_EXTENSION  PdoExtension,
IN PPCI_COMMON_HEADER  Current,
IN ULONGLONG  HackFlags 
)

Definition at line 1759 of file enum.c.

1762{
1764 PPCI_COMMON_HEADER PciData;
1766 PAGED_CODE();
1767
1768 /* Do the hackflags indicate this device should be skipped? */
1769 if (PciSkipThisFunction(Current,
1770 PdoExtension->Slot,
1772 HackFlags))
1773 {
1774 /* Do not process its resources */
1775 return STATUS_SUCCESS;
1776 }
1777
1778 /* Allocate a buffer to hold two PCI configuration headers */
1779 PciData = ExAllocatePoolWithTag(0, 2 * PCI_COMMON_HDR_LENGTH, 'BicP');
1780 if (!PciData) return STATUS_INSUFFICIENT_RESOURCES;
1781
1782 /* Set up the context for the resource enumeration, and do it */
1783 Context.Current = Current;
1784 Context.PciData = PciData;
1785 Context.PdoExtension = PdoExtension;
1787
1788 /* Enumeration is completed, free the PCI headers and return the status */
1789 ExFreePoolWithTag(PciData, 0);
1790 return Status;
1791}
LONG NTSTATUS
Definition: precomp.h:26
_In_ ULONG_PTR HackFlags
Definition: cdrom.h:983
BOOLEAN NTAPI PciSkipThisFunction(IN PPCI_COMMON_HEADER PciData, IN PCI_SLOT_NUMBER Slot, IN UCHAR OperationType, IN ULONGLONG HackFlags)
Definition: enum.c:1367
NTSTATUS NTAPI PcipGetFunctionLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: enum.c:1618
#define PCI_SKIP_RESOURCE_ENUMERATION
Definition: pci.h:75
Status
Definition: gdiplustypes.h:24
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109

Referenced by PciScanBus().

◆ PciIsRequirementDescriptor()

BOOLEAN NTAPI PciIsRequirementDescriptor ( _In_ PIO_RESOURCE_DESCRIPTOR  Limit)

Tells whether a discovered limit asks the arbiter for a range.

Parameters
[in]LimitThe limit of one BAR or bridge window.
Returns
TRUE when the limit has a type and a length. A bridge window has no length of its own.

Definition at line 671 of file enum.c.

673{
674 if (Limit->Type == CmResourceTypeNull)
675 return FALSE;
676
677 return (Limit->u.Generic.Length != 0);
678}

Referenced by Device_ChangeResourceSettings(), PciBuildRequirementsList(), and PciComputeNewCurrentSettings().

◆ PcipGetFunctionLimits()

NTSTATUS NTAPI PcipGetFunctionLimits ( IN PPCI_CONFIGURATOR_CONTEXT  Context)

Definition at line 1618 of file enum.c.

1619{
1620 PPCI_CONFIGURATOR Configurator;
1621 PPCI_COMMON_HEADER PciData, Current;
1623 PCI_IPI_CONTEXT IpiContext;
1624 PIO_RESOURCE_DESCRIPTOR IoDescriptor;
1625 ULONG Offset;
1626 PAGED_CODE();
1627
1628 /* Grab all parameters from the context */
1629 PdoExtension = Context->PdoExtension;
1630 Current = Context->Current;
1631 PciData = Context->PciData;
1632
1633 /* Save the current PCI Command and Status word */
1634 Context->Status = Current->Status;
1635 Context->Command = Current->Command;
1636
1637 /* Now that they're saved, clear the status, and disable all decodes */
1638 Current->Status = 0;
1639 Current->Command &= ~(PCI_ENABLE_IO_SPACE |
1642
1643 /* Make a copy of the current PCI configuration header (with decodes off) */
1644 RtlCopyMemory(PciData, Current, PCI_COMMON_HDR_LENGTH);
1645
1646 /* Locate the correct resource configurator for this type of device */
1647 Configurator = &PciConfigurators[PdoExtension->HeaderType];
1648 Context->Configurator = Configurator;
1649
1650 /* Initialize it, which will typically setup the BARs for limit discovery */
1651 Configurator->Initialize(Context);
1652
1653 /* Check for critical devices and PCI Debugging devices */
1654 if ((PdoExtension->HackFlags & PCI_HACK_CRITICAL_DEVICE) ||
1655 (PdoExtension->OnDebugPath))
1656 {
1657 /* Specifically check for a PCI Debugging device */
1658 if (PdoExtension->OnDebugPath)
1659 {
1660 /* Was it enabled for bus mastering? */
1661 if (Context->Command & PCI_ENABLE_BUS_MASTER)
1662 {
1663 /* This decode needs to be re-enabled so debugging can work */
1664 PciData->Command |= PCI_ENABLE_BUS_MASTER;
1665 Current->Command |= PCI_ENABLE_BUS_MASTER;
1666 }
1667
1668 /* Disable the debugger while the discovery is happening */
1670 }
1671
1672 /* For these devices, an IPI must be sent to force high-IRQL discovery */
1673 IpiContext.Barrier = 1;
1674 IpiContext.RunCount = 1;
1675 IpiContext.DeviceExtension = PdoExtension;
1677 IpiContext.Context = Context;
1679
1680 /* Re-enable the debugger if this was a PCI Debugging Device */
1681 if (PdoExtension->OnDebugPath) KdEnableDebugger();
1682 }
1683 else
1684 {
1685 /* Otherwise, it's safe to do this inline at low IRQL */
1687 }
1688
1689 /*
1690 * Check if it's valid to compare the headers to see if limit discovery mode
1691 * has properly exited (the expected case is that the PCI header would now
1692 * be equal to what it was before). In some cases, it is known that this will
1693 * fail, because during PciApplyHacks (among other places), software hacks
1694 * had to be applied to the header, which the hardware-side will not see, and
1695 * thus the headers would appear "different".
1696 */
1697 if (!PdoExtension->ExpectedWritebackFailure)
1698 {
1699 /* Read the current PCI header now, after discovery has completed */
1701
1702 /* Check if the current header at entry, is equal to the header now */
1703 Offset = RtlCompareMemory(PciData + 1, Current, PCI_COMMON_HDR_LENGTH);
1705 {
1706 /* It's not, which means configuration somehow changed, dump this */
1707 DPRINT1("PCIX - CFG space write verify failed at offset 0x%x\n", Offset);
1708 PciDebugDumpCommonConfig(PciData + 1);
1709 DPRINT1("----------\n");
1710 PciDebugDumpCommonConfig(Current);
1711 }
1712 }
1713
1714 /* This PDO should not already have resources, since this is only done once */
1715 ASSERT(PdoExtension->Resources == NULL);
1716
1717 /* Allocate the structure that will hold the discovered resources and limits */
1719 sizeof(PCI_FUNCTION_RESOURCES),
1720 'BicP');
1721 if (!PdoExtension->Resources) return STATUS_INSUFFICIENT_RESOURCES;
1722
1723 /* Clear it out for now */
1725
1726 /* Now call the configurator, which will first store the limits... */
1727 Configurator->SaveLimits(Context);
1728
1729 /* ...and then store the current resources being used */
1730 Configurator->SaveCurrentSettings(Context);
1731
1732 /* Loop all the limit descriptors backwards */
1733 IoDescriptor = &PdoExtension->Resources->Limit[PCI_TYPE0_ADDRESSES + 1];
1734 while (TRUE)
1735 {
1736 /* Keep going until a non-null descriptor is found */
1737 IoDescriptor--;
1738 if (IoDescriptor->Type != CmResourceTypeNull) break;
1739
1740 /* This is a null descriptor, have all of them been scanned now? */
1741 if (IoDescriptor == &PdoExtension->Resources->Limit[0])
1742 {
1743 /* Every limit is null, so the function decodes no BAR, which is not an error */
1744 DPRINT("PCIX - Function %p decodes no BAR\n", PdoExtension);
1745
1746 /* No resources will be assigned for the device */
1747 ExFreePoolWithTag(PdoExtension->Resources, 0);
1748 PdoExtension->Resources = NULL;
1749 break;
1750 }
1751 }
1752
1753 /* Return success here, even if the device has no assigned resources */
1754 return STATUS_SUCCESS;
1755}
VOID NTAPI PciDebugDumpCommonConfig(IN PPCI_COMMON_HEADER PciData)
Definition: debug.c:207
VOID NTAPI PciWriteLimitsAndRestoreCurrent(IN PVOID Reserved, IN PVOID Context2)
Definition: enum.c:1575
KIPI_BROADCAST_WORKER PciExecuteCriticalSystemRoutine
Definition: pci.h:1204
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define NonPagedPool
Definition: env_spec_w32.h:307
NTSTATUS NTAPI KdDisableDebugger(VOID)
Definition: kdapi.c:2169
NTSTATUS NTAPI KdEnableDebugger(VOID)
Definition: kdapi.c:2158
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG_PTR NTAPI KeIpiGenericCall(_In_ PKIPI_BROADCAST_WORKER Function, _In_ ULONG_PTR Argument)
Definition: ipi.c:44
#define PCI_HACK_CRITICAL_DEVICE
Definition: pci.h:48
#define DPRINT
Definition: sndvol32.h:73
PCI_CONFIGURATOR_SAVE_LIMITS SaveLimits
Definition: pci.h:542
PCI_CONFIGURATOR_INITIALIZE Initialize
Definition: pci.h:540
PCI_CONFIGURATOR_SAVE_CURRENT_SETTINGS SaveCurrentSettings
Definition: pci.h:543
LONG RunCount
Definition: pci.h:576
ULONG Barrier
Definition: pci.h:577
PVOID Context
Definition: pci.h:580
PCI_IPI_FUNCTION Function
Definition: pci.h:579
PVOID DeviceExtension
Definition: pci.h:578
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by PciGetFunctionLimits().

◆ PcipIsSameDevice()

BOOLEAN NTAPI PcipIsSameDevice ( IN PPCI_PDO_EXTENSION  DeviceExtension,
IN PPCI_COMMON_HEADER  PciData 
)

Definition at line 1333 of file enum.c.

1335{
1336 BOOLEAN IdMatch, RevMatch, SubsysMatch;
1337 ULONGLONG HackFlags = DeviceExtension->HackFlags;
1338
1339 /* Check if the IDs match */
1340 IdMatch = (PciData->VendorID == DeviceExtension->VendorId) &&
1341 (PciData->DeviceID == DeviceExtension->DeviceId);
1342 if (!IdMatch) return FALSE;
1343
1344 /* If the device has a valid revision, check if it matches */
1346 (PciData->RevisionID == DeviceExtension->RevisionId);
1347 if (!RevMatch) return FALSE;
1348
1349 /* For multifunction devices, this is enough to assume they're the same */
1350 if (PCI_MULTIFUNCTION_DEVICE(PciData)) return TRUE;
1351
1352 /* For bridge devices, there's also nothing else that can be checked */
1353 if (DeviceExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) return TRUE;
1354
1355 /* Devices, on the other hand, have subsystem data that can be compared */
1356 SubsysMatch = (HackFlags & (PCI_HACK_NO_SUBSYSTEM |
1358 ((DeviceExtension->SubsystemVendorId ==
1359 PciData->u.type0.SubVendorID) &&
1360 (DeviceExtension->SubsystemId ==
1361 PciData->u.type0.SubSystemID));
1362 return SubsysMatch;
1363}
#define PCI_HACK_NO_REVISION_AFTER_D3
Definition: pci.h:51
#define PCI_HACK_NO_SUBSYSTEM_AFTER_D3
Definition: pci.h:42
#define PCI_HACK_NO_SUBSYSTEM
Definition: pci.h:33
#define PCI_MULTIFUNCTION_DEVICE(PciData)
Definition: iotypes.h:3627

Referenced by PciFindPdoByFunction(), PciPdoIsPresent(), PciScanBus(), and PciSetResources().

◆ PciProcessBus()

VOID NTAPI PciProcessBus ( IN PPCI_FDO_EXTENSION  DeviceExtension)

Definition at line 1795 of file enum.c.

1796{
1798 PPCI_PDO_EXTENSION VgaDecoder;
1800 BOOLEAN ParentDecodesIsa;
1801 PAGED_CODE();
1802
1803 /* The root bus FDO sits on a PDO this driver does not own */
1805 if (!PCI_IS_ROOT_FDO(DeviceExtension))
1806 {
1807 PhysicalDeviceObject = DeviceExtension->PhysicalDeviceObject;
1810 }
1811
1812 /* Check if the bridge above this bus has the ISA bit set, or required */
1813 ParentDecodesIsa = (PdoExtension &&
1815 ((PdoExtension->Dependent.type1.IsaBitRequired) ||
1816 (PdoExtension->Dependent.type1.IsaBitSet)));
1817
1819 KeWaitForSingleObject(&DeviceExtension->ChildListLock,
1820 Executive,
1821 KernelMode,
1822 FALSE,
1823 NULL);
1824
1825 /* Without an ISA parent, a VGA decoding bridge forces the ISA bit onto its siblings */
1826 VgaDecoder = NULL;
1827 if (!ParentDecodesIsa)
1828 {
1829 for (PdoExtension = DeviceExtension->ChildBridgePdoList;
1831 PdoExtension = PdoExtension->NextBridge)
1832 {
1833 if (PdoExtension->Dependent.type1.VgaBitSet)
1834 {
1835 VgaDecoder = PdoExtension;
1836 break;
1837 }
1838 }
1839 }
1840
1841 /* The I/O arbiter does not avoid the ISA aliases yet, so only report these bridges */
1842 if (ParentDecodesIsa || VgaDecoder)
1843 {
1844 for (PdoExtension = DeviceExtension->ChildBridgePdoList;
1846 PdoExtension = PdoExtension->NextBridge)
1847 {
1848 if ((PdoExtension != VgaDecoder) &&
1849 !(PdoExtension->Dependent.type1.IsaBitSet))
1850 {
1851 DPRINT1("PCIX - bridge PDO ext 0x%p needs the ISA bit, which is not applied\n",
1852 PdoExtension);
1853 }
1854 }
1855 }
1856
1857 /* Bridges the firmware left unnumbered are not renumbered yet, so report them */
1859 {
1860 for (PdoExtension = DeviceExtension->ChildBridgePdoList;
1862 PdoExtension = PdoExtension->NextBridge)
1863 {
1866 {
1867 DPRINT1("PCIX - bridge PDO ext 0x%p has no bus numbers assigned\n",
1868 PdoExtension);
1869 }
1870 }
1871 }
1872
1873 KeSetEvent(&DeviceExtension->ChildListLock, IO_NO_INCREMENT, FALSE);
1875}
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
BOOLEAN PciAssignBusNumbers
Definition: config.c:18
struct _PCI_PDO_EXTENSION * PPCI_PDO_EXTENSION
PCI_DEVICE_TYPES NTAPI PciClassifyDeviceType(IN PPCI_PDO_EXTENSION PdoExtension)
Definition: utils.c:1126
BOOLEAN NTAPI PciAreBusNumbersConfigured(IN PPCI_PDO_EXTENSION PdoExtension)
Definition: busno.c:20
@ PciTypePciBridge
Definition: pci.h:158
#define ASSERT_PDO(x)
Definition: pci.h:48
#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
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define IO_NO_INCREMENT
Definition: iotypes.h:598
@ Executive
Definition: ketypes.h:467

Referenced by PciScanBus().

◆ PcipUpdateHardware()

VOID NTAPI PcipUpdateHardware ( IN PVOID  Context,
IN PVOID  Context2 
)

Definition at line 263 of file enum.c.

265{
268
269 /* Check if we're allowed to disable decodes */
270 PciData->Command = PdoExtension->CommandEnables;
271 if (!(PdoExtension->HackFlags & PCI_HACK_PRESERVE_COMMAND))
272 {
273 /* Disable all decodes */
274 PciData->Command &= ~(PCI_ENABLE_IO_SPACE |
278
279 /* A BAR size can only change with the decodes off, before the BAR gets its address */
280 if (PdoExtension->ResizableBarState.CapabilityPtr)
281 {
283 &PciData->Command,
285 sizeof(PciData->Command));
287 }
288 }
289
290 /* Update the device configuration */
291 PciData->Status = 0;
293
294 /* Turn decodes back on */
295 PciDecodeEnable(PdoExtension, TRUE, &PdoExtension->CommandEnables);
296}
VOID NTAPI PciApplyResizableBarSizes(_In_ PPCI_PDO_EXTENSION PdoExtension)
Sets every resizable BAR to the length it was assigned. The memory decode has to be off,...
Definition: rbar.c:229
_In_ PNET_PNP_EVENT _In_ PTDI_PNP_CONTEXT _In_ PTDI_PNP_CONTEXT Context2
Definition: tdikrnl.h:1096
#define PCI_ENABLE_WRITE_AND_INVALIDATE
Definition: iotypes.h:3635

Referenced by PciUpdateHardware().

◆ PciQueryDeviceRelations()

NTSTATUS NTAPI PciQueryDeviceRelations ( IN PPCI_FDO_EXTENSION  DeviceExtension,
IN OUT PDEVICE_RELATIONS *  pDeviceRelations 
)

Definition at line 2366 of file enum.c.

2368{
2371 ULONG PdoCount = 0;
2372 PDEVICE_RELATIONS DeviceRelations, NewRelations;
2373 SIZE_T Size;
2374 PDEVICE_OBJECT DeviceObject, *ObjectArray;
2375 PAGED_CODE();
2376
2377 /* Make sure the FDO is started */
2378 ASSERT(DeviceExtension->DeviceState == PciStarted);
2379
2380 /* Synchronize while we enumerate the bus */
2382 if (!NT_SUCCESS(Status)) return Status;
2383
2384 /* Scan all children PDO */
2385 for (PdoExtension = DeviceExtension->ChildPdoList;
2387 PdoExtension = PdoExtension->Next)
2388 {
2389 /* Invalidate them */
2390 PdoExtension->NotPresent = TRUE;
2391 }
2392
2393 /* Scan the PCI Bus */
2394 Status = PciScanBus(DeviceExtension);
2396
2397 /* Enumerate all children PDO again */
2398 for (PdoExtension = DeviceExtension->ChildPdoList;
2400 PdoExtension = PdoExtension->Next)
2401 {
2402 /* Check for PDOs that are still invalidated */
2403 if (PdoExtension->NotPresent)
2404 {
2405 /* This means this PDO existed before, but not anymore */
2406 PdoExtension->ReportedMissing = TRUE;
2407 DPRINT1("PCIX - Old device (pdox) %p not found on rescan.\n",
2408 PdoExtension);
2409 }
2410 else
2411 {
2412 /* Increase count of detected PDOs */
2413 PdoCount++;
2414 }
2415 }
2416
2417 /* Read the current relations and add the newly discovered relations */
2418 DeviceRelations = *pDeviceRelations;
2419 Size = FIELD_OFFSET(DEVICE_RELATIONS, Objects) +
2420 PdoCount * sizeof(PDEVICE_OBJECT);
2421 if (DeviceRelations) Size += sizeof(PDEVICE_OBJECT) * DeviceRelations->Count;
2422
2423 /* Allocate the device relations */
2424 NewRelations = (PDEVICE_RELATIONS)ExAllocatePoolWithTag(0, Size, 'BicP');
2425 if (!NewRelations)
2426 {
2427 /* Out of space, cancel the operation */
2430 }
2431
2432 /* Check if there were any older relations */
2433 NewRelations->Count = 0;
2434 if (DeviceRelations)
2435 {
2436 /* Copy the old relations into the new buffer, then free the old one */
2437 RtlCopyMemory(NewRelations,
2438 DeviceRelations,
2439 FIELD_OFFSET(DEVICE_RELATIONS, Objects) +
2440 DeviceRelations->Count * sizeof(PDEVICE_OBJECT));
2441 ExFreePoolWithTag(DeviceRelations, 0);
2442 }
2443
2444 /* Print out that we're ready to dump relations */
2445 DPRINT("PCIX - QueryDeviceRelations/BusRelations FDOx %p (bus 0x%02x)\n",
2446 DeviceExtension,
2447 DeviceExtension->BaseBus);
2448
2449 /* Loop the current PDO children and the device relation object array */
2450 PdoExtension = DeviceExtension->ChildPdoList;
2451 ObjectArray = &NewRelations->Objects[NewRelations->Count];
2452 while (PdoExtension)
2453 {
2454 /* Dump this relation */
2455 DPRINT(" QDR PDO %p (x %p)%s\n",
2456 PdoExtension->PhysicalDeviceObject,
2458 PdoExtension->NotPresent ?
2459 "<Omitted, device flaged not present>" : "");
2460
2461 /* Is this PDO present? */
2462 if (!PdoExtension->NotPresent)
2463 {
2464 /* Reference it and add it to the array */
2465 DeviceObject = PdoExtension->PhysicalDeviceObject;
2467 *ObjectArray++ = DeviceObject;
2468 }
2469
2470 /* Go to the next PDO */
2471 PdoExtension = PdoExtension->Next;
2472 }
2473
2474 /* Terminate dumping the relations */
2475 DPRINT(" QDR Total PDO count = %u (%u already in list)\n",
2476 NewRelations->Count + PdoCount,
2477 NewRelations->Count);
2478
2479 /* Return the final count and the new buffer */
2480 NewRelations->Count += PdoCount;
2481 *pDeviceRelations = NewRelations;
2482
2483 /* Let later rescans and PnP state changes begin their own transitions */
2485 return STATUS_SUCCESS;
2486}
NTSTATUS NTAPI PciScanBus(IN PPCI_FDO_EXTENSION DeviceExtension)
Definition: enum.c:1879
@ PciStarted
Definition: pci.h:169
@ PciSynchronizedOperation
Definition: pci.h:173
NTSTATUS NTAPI PciCancelStateTransition(IN PPCI_FDO_EXTENSION DeviceExtension, IN PCI_STATE NewState)
Definition: state.c:145
NTSTATUS NTAPI PciBeginStateTransition(IN PPCI_FDO_EXTENSION DeviceExtension, IN PCI_STATE NewState)
Definition: state.c:97
struct _DEVICE_OBJECT * PDEVICE_OBJECT
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2165
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061

Referenced by PciFdoIrpQueryDeviceRelations().

◆ PciQueryEjectionRelations()

NTSTATUS NTAPI PciQueryEjectionRelations ( IN PPCI_PDO_EXTENSION  PdoExtension,
IN OUT PDEVICE_RELATIONS *  pDeviceRelations 
)

Definition at line 614 of file enum.c.

616{
617 PPCI_FDO_EXTENSION FdoExtension = PdoExtension->ParentFdoExtension;
618 PDEVICE_RELATIONS OldRelations = *pDeviceRelations;
619 PDEVICE_RELATIONS NewRelations = NULL;
620 ULONG OldCount = OldRelations ? OldRelations->Count : 0;
621 ULONG FunctionCount;
622 PAGED_CODE();
623
626
627 /* The other functions of the same device leave the machine with this one */
628 FunctionCount = PciGatherOtherFunctions(PdoExtension, NULL);
629 if (FunctionCount)
630 {
631 NewRelations = ExAllocatePoolWithTag(NonPagedPool,
633 (OldCount + FunctionCount) * sizeof(*NewRelations->Objects),
635 }
636
637 /* Without memory the list from above is kept as it is */
638 if (NewRelations)
639 {
640 if (OldRelations)
641 {
642 RtlCopyMemory(NewRelations->Objects,
643 OldRelations->Objects,
644 OldCount * sizeof(*OldRelations->Objects));
645 ExFreePoolWithTag(OldRelations, 0);
646 }
647
648 NewRelations->Count = OldCount +
649 PciGatherOtherFunctions(PdoExtension, &NewRelations->Objects[OldCount]);
650 ASSERT(NewRelations->Count == OldCount + FunctionCount);
651 *pDeviceRelations = NewRelations;
652 }
653
654 KeSetEvent(&FdoExtension->ChildListLock, IO_NO_INCREMENT, FALSE);
656 return STATUS_SUCCESS;
657}
#define PCI_POOL_TAG
Definition: pci.h:27
@ FdoExtension
Definition: precomp.h:60

Referenced by PciPdoIrpQueryDeviceRelations().

◆ PciQueryRequirements()

NTSTATUS NTAPI PciQueryRequirements ( IN PPCI_PDO_EXTENSION  PdoExtension,
IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *  RequirementsList 
)

Definition at line 882 of file enum.c.

884{
886 PCI_COMMON_HEADER PciHeader;
887 PAGED_CODE();
888
889 /* Build even without a BAR or a pin, bridge legacy decodes need ranges too */
892 if (!NT_SUCCESS(Status))
893 return Status;
894
895 /* Is this a Compaq PCI Hotplug Controller (r17) on a PAE system ? */
896 if ((PciHeader.VendorID == 0xE11) &&
897 (PciHeader.DeviceID == 0xA0F7) &&
898 (PciHeader.RevisionID == 17) &&
900 {
901 /* No fixup is applied for this controller under PAE */
902 DPRINT1("PCIX - Compaq hotplug controller PDO ext 0x%p has an unhandled PAE quirk\n",
904 }
905
906 /* The shared zero list must never reach PnP, which frees what it is given */
908 {
910 DPRINT("PCIX - Returning NULL requirements list\n");
911 }
912 else
913 {
915 }
916
917 /* This call always succeeds (but maybe with no requirements) */
918 return STATUS_SUCCESS;
919}
VOID NTAPI PciDebugPrintIoResReqList(IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements)
Definition: debug.c:303
NTSTATUS NTAPI PciBuildRequirementsList(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData, OUT PIO_RESOURCE_REQUIREMENTS_LIST *Buffer)
Definition: enum.c:756

Referenced by PciPdoIrpQueryResourceRequirements().

◆ PciQueryResources()

NTSTATUS NTAPI PciQueryResources ( IN PPCI_PDO_EXTENSION  PdoExtension,
OUT PCM_RESOURCE_LIST *  Buffer 
)

Definition at line 389 of file enum.c.

391{
392 PPCI_FUNCTION_RESOURCES PciResources;
393 BOOLEAN HaveVga, HaveMemSpace, HaveIoSpace;
394 USHORT BridgeControl, PciCommand;
395 ULONG Count, i;
396 PCM_PARTIAL_RESOURCE_DESCRIPTOR Partial, Resource, LastResource;
398 UCHAR InterruptLine;
399 PAGED_CODE();
400
401 /* Assume failure */
402 Count = 0;
403 HaveVga = FALSE;
404 *Buffer = NULL;
405
406 /* Make sure there's some resources to query */
407 PciResources = PdoExtension->Resources;
408 if (!PciResources) return STATUS_SUCCESS;
409
410 /* Read the decodes */
412 &PciCommand,
414 sizeof(USHORT));
415
416 /* Check which ones are turned on */
417 HaveIoSpace = PciCommand & PCI_ENABLE_IO_SPACE;
418 HaveMemSpace = PciCommand & PCI_ENABLE_MEMORY_SPACE;
419
420 /* Loop maximum possible descriptors */
421 for (i = 0; i < 7; i++)
422 {
423 /* Check if the decode for this descriptor is actually turned on */
424 Partial = &PciResources->Current[i];
425 if ((HaveMemSpace &&
426 ((Partial->Type == CmResourceTypeMemory) ||
427 (Partial->Type == CmResourceTypeMemoryLarge))) ||
428 (HaveIoSpace && (Partial->Type == CmResourceTypePort)))
429 {
430 /* One more fully active descriptor */
431 Count++;
432 }
433 }
434
435 /* If there's an interrupt pin associated, check at least one decode is on */
436 if ((PdoExtension->InterruptPin) && ((HaveMemSpace) || (HaveIoSpace)))
437 {
438 /* Read the interrupt line for the pin, add a descriptor if it's valid */
439 InterruptLine = PdoExtension->AdjustedInterruptLine;
440 if ((InterruptLine) && (InterruptLine != PCI_INTERRUPT_LINE_UNKNOWN))
441 Count++;
442 }
443
444 /* Check for a PCI-to-PCI or CardBus bridge, both keep the VGA enable at the same place */
445 if ((PdoExtension->HeaderType == PCI_BRIDGE_TYPE) ||
446 (PdoExtension->HeaderType == PCI_CARDBUS_BRIDGE_TYPE))
447 {
448 /* Read bridge settings, check if VGA is present */
450 &BridgeControl,
451 FIELD_OFFSET(PCI_COMMON_HEADER, u.type1.BridgeControl),
452 sizeof(USHORT));
453 if (BridgeControl & PCI_ENABLE_BRIDGE_VGA)
454 {
455 /* Remember for later */
456 HaveVga = TRUE;
457
458 /* One memory descriptor for 0xA0000, plus the two I/O port ranges */
459 if (HaveMemSpace) Count++;
460 if (HaveIoSpace) Count += 2;
461 }
462 }
463
464 /* If there's no descriptors in use, there's no resources, so return */
465 if (!Count) return STATUS_SUCCESS;
466
467 /* Allocate a resource list to hold the resources */
469 PdoExtension->ParentFdoExtension->BaseBus);
471
472 /* This is where the descriptors will be copied into */
473 Resource = ResourceList->List[0].PartialResourceList.PartialDescriptors;
474 LastResource = Resource + Count + 1;
475
476 /* Loop maximum possible descriptors */
477 for (i = 0; i < 7; i++)
478 {
479 /* Check if the decode for this descriptor is actually turned on */
480 Partial = &PciResources->Current[i];
481 if ((HaveMemSpace &&
482 ((Partial->Type == CmResourceTypeMemory) ||
483 (Partial->Type == CmResourceTypeMemoryLarge))) ||
484 (HaveIoSpace && (Partial->Type == CmResourceTypePort)))
485 {
486 /* Copy the descriptor into the resource list */
487 *Resource++ = *Partial;
488 }
489 }
490
491 /* Check if earlier the code detected this was a PCI bridge with VGA on it */
492 if (HaveVga)
493 {
494 /* Are the memory decodes enabled? */
495 if (HaveMemSpace)
496 {
497 /* Build a memory descriptor for a 128KB framebuffer at 0xA0000 */
499 Resource->u.Generic.Start.HighPart = 0;
501 Resource->u.Generic.Start.LowPart = 0xA0000;
502 Resource->u.Generic.Length = 0x20000;
503 Resource++;
504 }
505
506 /* Are the I/O decodes enabled? */
507 if (HaveIoSpace)
508 {
509 /* Build an I/O descriptor for the graphic ports at 0x3B0 */
512 Resource->u.Port.Start.QuadPart = 0x3B0u;
513 Resource->u.Port.Length = 0xC;
514 Resource++;
515
516 /* Build an I/O descriptor for the graphic ports at 0x3C0 */
519 Resource->u.Port.Start.QuadPart = 0x3C0u;
520 Resource->u.Port.Length = 0x20;
521 Resource++;
522 }
523 }
524
525 /* If there's an interrupt pin associated, check at least one decode is on */
526 if ((PdoExtension->InterruptPin) && ((HaveMemSpace) || (HaveIoSpace)))
527 {
528 /* Read the interrupt line for the pin, check if it's valid */
529 InterruptLine = PdoExtension->AdjustedInterruptLine;
530 if ((InterruptLine) && (InterruptLine != PCI_INTERRUPT_LINE_UNKNOWN))
531 {
532 /* Make sure there's still space */
533 ASSERT(Resource < LastResource);
534
535 /* Add the interrupt descriptor */
538 Resource->ShareDisposition = CmResourceShareShared;
539 Resource->u.Interrupt.Affinity = -1;
540 Resource->u.Interrupt.Level = InterruptLine;
541 Resource->u.Interrupt.Vector = InterruptLine;
542 }
543 }
544
545 /* Return the resource list */
547 return STATUS_SUCCESS;
548}
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:843
PCM_RESOURCE_LIST NTAPI PciAllocateCmResourceList(IN ULONG Count, IN ULONG BusNumber)
Definition: enum.c:359
#define PCI_INTERRUPT_LINE_UNKNOWN
Definition: pci.h:92
#define CM_RESOURCE_PORT_POSITIVE_DECODE
Definition: cmtypes.h:113
#define CM_RESOURCE_MEMORY_READ_WRITE
Definition: cmtypes.h:121
#define CM_RESOURCE_PORT_10_BIT_DECODE
Definition: cmtypes.h:110
#define PCI_ENABLE_BRIDGE_VGA
Definition: pci.h:63

Referenced by PciPdoIrpQueryResources().

◆ PciQueryTargetDeviceRelations()

NTSTATUS NTAPI PciQueryTargetDeviceRelations ( IN PPCI_PDO_EXTENSION  PdoExtension,
IN OUT PDEVICE_RELATIONS *  pDeviceRelations 
)

Definition at line 552 of file enum.c.

554{
555 PDEVICE_RELATIONS DeviceRelations;
556 PAGED_CODE();
557
558 /* If there were existing relations, free them */
559 if (*pDeviceRelations) ExFreePoolWithTag(*pDeviceRelations, 0);
560
561 /* Allocate a new structure for the relations */
562 DeviceRelations = ExAllocatePoolWithTag(NonPagedPool,
563 sizeof(DEVICE_RELATIONS),
564 'BicP');
565 if (!DeviceRelations) return STATUS_INSUFFICIENT_RESOURCES;
566
567 /* Only one relation: the PDO */
568 DeviceRelations->Count = 1;
569 DeviceRelations->Objects[0] = PdoExtension->PhysicalDeviceObject;
570 ObReferenceObject(DeviceRelations->Objects[0]);
571
572 /* Return the new relations */
573 *pDeviceRelations = DeviceRelations;
574 return STATUS_SUCCESS;
575}

Referenced by PciPdoIrpQueryDeviceRelations().

◆ PciScanBus()

NTSTATUS NTAPI PciScanBus ( IN PPCI_FDO_EXTENSION  DeviceExtension)

Definition at line 1879 of file enum.c.

1880{
1881 ULONG MaxDevice = PCI_MAX_DEVICES;
1882 BOOLEAN ProcessFlag = FALSE;
1883 ULONG i, j, k, Size;
1884 USHORT CapOffset, TempOffset;
1888 UCHAR BiosBuffer[PCI_COMMON_HDR_LENGTH];
1889 PPCI_COMMON_HEADER PciData = (PVOID)Buffer;
1890 PPCI_COMMON_HEADER BiosData = (PVOID)BiosBuffer;
1892 PCHAR Name;
1894 PPCI_PDO_EXTENSION PdoExtension, NewExtension;
1895 PPCI_PDO_EXTENSION* BridgeExtension;
1896 PWCHAR DescriptionText;
1897 USHORT SubVendorId, SubSystemId;
1898 PCI_CAPABILITIES_HEADER PcixCapHeader;
1899 /* Holds the largest capability the dump below reads in full */
1900 UCHAR CapBuffer[max(sizeof(PCI_PM_CAPABILITY), sizeof(PCI_AGP_CAPABILITY))];
1901 PPCI_CAPABILITIES_HEADER CapHeader = (PVOID)CapBuffer;
1902 UCHAR SecondaryBus;
1903 UCHAR BusNumbers[3];
1904 DPRINT1("PCIX - Scan Bus: FDO Extension @ 0x%p, Base Bus = 0x%x\n",
1905 DeviceExtension, DeviceExtension->BaseBus);
1906
1907 /* Is this the root FDO? */
1908 if (!PCI_IS_ROOT_FDO(DeviceExtension))
1909 {
1910 /* Get the PDO for the child bus */
1911 PdoExtension = DeviceExtension->PhysicalDeviceObject->DeviceExtension;
1913
1914 /* Check for hack which only allows bus to have one child device */
1915 if (PdoExtension->HackFlags & PCI_HACK_ONE_CHILD) MaxDevice = 1;
1916
1917 /* Check if the secondary bus number has changed */
1919 &SecondaryBus,
1920 FIELD_OFFSET(PCI_COMMON_HEADER, u.type1.SecondaryBus),
1921 sizeof(UCHAR));
1922 if (SecondaryBus != DeviceExtension->BaseBus)
1923 {
1924 DPRINT1("PCIX - Bus numbers have been changed! Restoring originals.\n");
1925
1926 /* The children were found under these numbers, so the bridge must decode them again */
1927 BusNumbers[0] = PdoExtension->ParentFdoExtension->BaseBus;
1928 BusNumbers[1] = DeviceExtension->BaseBus;
1929 BusNumbers[2] = PdoExtension->Dependent.type1.SubordinateBus;
1931 BusNumbers,
1932 FIELD_OFFSET(PCI_COMMON_HEADER, u.type1.PrimaryBus),
1933 sizeof(BusNumbers));
1934 }
1935 }
1936
1937 /* Loop every device on the bus */
1938 PciSlot.u.bits.Reserved = 0;
1939 i = DeviceExtension->BaseBus;
1940 for (j = 0; j < MaxDevice; j++)
1941 {
1942 /* Loop every function of each device */
1943 PciSlot.u.bits.DeviceNumber = j;
1944 for (k = 0; k < PCI_MAX_FUNCTION; k++)
1945 {
1946 /* Build the final slot structure */
1947 PciSlot.u.bits.FunctionNumber = k;
1948
1949 /* Read the vendor for this slot */
1950 PciReadSlotConfig(DeviceExtension,
1951 PciSlot,
1952 PciData,
1953 0,
1954 sizeof(USHORT));
1955
1956 /* Skip invalid device */
1957 if (PciData->VendorID == PCI_INVALID_VENDORID) continue;
1958
1959 /* Now read the whole header */
1960 PciReadSlotConfig(DeviceExtension,
1961 PciSlot,
1962 &PciData->DeviceID,
1963 sizeof(USHORT),
1964 PCI_COMMON_HDR_LENGTH - sizeof(USHORT));
1965
1966 /* Apply any hacks before even analyzing the configuration header */
1967 PciApplyHacks(DeviceExtension,
1968 PciData,
1969 PciSlot,
1971 NULL);
1972
1973 /* Dump device that was found */
1974 DPRINT("PCIX - Scan Found Device 0x%x (b=0x%x, d=0x%x, f=0x%x)\n",
1976 i,
1977 j,
1978 k);
1979
1980 /* Dump the device's header */
1981 PciDebugDumpCommonConfig(PciData);
1982
1983 /* Find description for this device for the debugger's sake */
1984 DescriptionText = PciGetDeviceDescriptionMessage(PciData->BaseClass,
1985 PciData->SubClass);
1986 DPRINT("PCIX - Device Description \"%S\".\n",
1987 DescriptionText ? DescriptionText : L"(NULL)");
1988 if (DescriptionText) ExFreePoolWithTag(DescriptionText, 0);
1989
1990 /* The hardware watchdog named by the ACPI table on a root bus gets no PDO */
1991 if ((WdTable) &&
1992 (PCI_IS_ROOT_FDO(DeviceExtension)) &&
1993 (WdTable->PciSegment == 0) &&
1994 (WdTable->PciBus == i) &&
1995 (WdTable->PciDevice == j) &&
1996 (WdTable->PciFunction == k) &&
1997 (WdTable->PciVendorId == PciData->VendorID) &&
1998 (WdTable->PciDeviceId == PciData->DeviceID))
1999 {
2000 DPRINT1("PCIX - not enumerating the ACPI watchdog device\n");
2001 continue;
2002 }
2003
2004 /* Check for non-simple devices */
2005 if ((PCI_MULTIFUNCTION_DEVICE(PciData)) ||
2006 (PciData->BaseClass == PCI_CLASS_BRIDGE_DEV))
2007 {
2008 /* No subsystem data defined for these kinds of bridges */
2009 SubVendorId = 0;
2010 SubSystemId = 0;
2011 }
2012 else
2013 {
2014 /* Read the subsystem information from the PCI header */
2015 SubVendorId = PciData->u.type0.SubVendorID;
2016 SubSystemId = PciData->u.type0.SubSystemID;
2017 }
2018
2019 /* Get any hack flags for this device */
2020 HackFlags = PciGetHackFlags(PciData->VendorID,
2021 PciData->DeviceID,
2022 SubVendorId,
2023 SubSystemId,
2024 PciData->RevisionID);
2025
2026 /* Check if this device is considered critical by the OS */
2027 if (PciIsCriticalDeviceClass(PciData->BaseClass, PciData->SubClass))
2028 {
2029 /* The hack database can take a device out of its critical class */
2031 {
2032 DPRINT1("PCIX - Not allowing PM Because device is critical\n");
2033
2034 /* Probe it with the system held, and keep it decoding while stopped */
2036
2037 /* Only the display can still be powered down */
2038 if (PciData->BaseClass != PCI_CLASS_DISPLAY_CTLR)
2040 }
2041 }
2042
2043 /* PCI bridges with a VGA card are also considered critical */
2044 if ((PciData->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
2045 (PciData->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI) &&
2046 (PciData->u.type1.BridgeControl & PCI_ENABLE_BRIDGE_VGA) &&
2048 {
2049 /* They follow the adapter behind them, so they can still be powered down */
2050 DPRINT1("PCIX - Not allowing PM because device is VGA\n");
2052 }
2053
2054 /* Check if the device should be skipped for whatever reason */
2055 if (PciSkipThisFunction(PciData,
2056 PciSlot,
2058 HackFlags))
2059 {
2060 /* Skip this device */
2061 continue;
2062 }
2063
2064 /* Check if a PDO has already been created for this device */
2065 PdoExtension = PciFindPdoByFunction(DeviceExtension,
2067 PciData);
2068 if (PdoExtension)
2069 {
2070 /* Same function as last scan, so its PDO stays and counts as present */
2071 PdoExtension->NotPresent = FALSE;
2072 continue;
2073 }
2074
2075 /* Bus processing will need to happen */
2076 ProcessFlag = TRUE;
2077
2078 /* Create the PDO for this device */
2079 Status = PciPdoCreate(DeviceExtension, PciSlot, &DeviceObject);
2081 NewExtension = (PPCI_PDO_EXTENSION)DeviceObject->DeviceExtension;
2082
2083 /* Check for broken devices with wrong/no class codes */
2085 {
2086 /* Setup a default one */
2087 PciData->BaseClass = PCI_CLASS_BASE_SYSTEM_DEV;
2088 PciData->SubClass = PCI_SUBCLASS_SYS_OTHER;
2089
2090 /* Device will behave erratically when reading back data */
2091 NewExtension->ExpectedWritebackFailure = TRUE;
2092 }
2093
2094 /* Clone all the information from the header */
2095 NewExtension->VendorId = PciData->VendorID;
2096 NewExtension->DeviceId = PciData->DeviceID;
2097 NewExtension->RevisionId = PciData->RevisionID;
2098 NewExtension->ProgIf = PciData->ProgIf;
2099 NewExtension->SubClass = PciData->SubClass;
2100 NewExtension->BaseClass = PciData->BaseClass;
2101 NewExtension->HeaderType = PCI_CONFIGURATION_TYPE(PciData);
2102
2103 /* Check for modern bridge types, which are managed by the driver */
2104 if ((NewExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
2105 ((NewExtension->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI) ||
2106 (NewExtension->SubClass == PCI_SUBCLASS_BR_CARDBUS)))
2107 {
2108 /* Acquire this device's lock */
2110 KeWaitForSingleObject(&DeviceExtension->ChildListLock,
2111 Executive,
2112 KernelMode,
2113 FALSE,
2114 NULL);
2115
2116 /* Scan the bridge list until the first free entry */
2117 for (BridgeExtension = &DeviceExtension->ChildBridgePdoList;
2118 *BridgeExtension;
2119 BridgeExtension = &(*BridgeExtension)->NextBridge);
2120
2121 /* Add this PDO as a bridge */
2122 *BridgeExtension = NewExtension;
2123 ASSERT(NewExtension->NextBridge == NULL);
2124
2125 /* Release this device's lock */
2126 KeSetEvent(&DeviceExtension->ChildListLock,
2128 FALSE);
2130 }
2131
2132 /* Get the PCI BIOS configuration saved in the registry */
2133 Status = PciGetBiosConfig(NewExtension, BiosData);
2134 if (NT_SUCCESS(Status))
2135 {
2136 DPRINT1("PCIX - Have BIOS configuration!\n");
2137
2138 /* Check if the PCI BIOS configuration has changed */
2139 if (!PcipIsSameDevice(NewExtension, BiosData))
2140 {
2141 /* This is considered failure, and new data will be saved */
2143 }
2144 else
2145 {
2146 /* Data is still correct, check for interrupt line change */
2147 if (BiosData->u.type0.InterruptLine !=
2148 PciData->u.type0.InterruptLine)
2149 {
2150 /* Update the current BIOS with the saved interrupt line */
2151 PciWriteDeviceConfig(NewExtension,
2152 &BiosData->u.type0.InterruptLine,
2154 u.type0.InterruptLine),
2155 sizeof(UCHAR));
2156 }
2157
2158 /* Save the BIOS interrupt line and the initial command */
2159 NewExtension->RawInterruptLine = BiosData->u.type0.InterruptLine;
2160 NewExtension->InitialCommand = BiosData->Command;
2161 }
2162 }
2163
2164 /* Check if no saved data was present or if it was a mismatch */
2165 if (!NT_SUCCESS(Status))
2166 {
2167 /* Save the new data */
2168 Status = PciSaveBiosConfig(NewExtension, PciData);
2170
2171 /* Save the interrupt line and command from the device */
2172 NewExtension->RawInterruptLine = PciData->u.type0.InterruptLine;
2173 NewExtension->InitialCommand = PciData->Command;
2174 }
2175
2176 /* Save original command from the device and hack flags */
2177 NewExtension->CommandEnables = PciData->Command;
2178 NewExtension->HackFlags = HackFlags;
2179
2180 /* Get power, AGP, and other capability data */
2181 PciGetEnhancedCapabilities(NewExtension, PciData);
2182
2183 /* Now configure the BARs */
2184 Status = PciGetFunctionLimits(NewExtension, PciData, HackFlags);
2185
2186 /* Power up the device */
2188
2189 /* Apply any device hacks required for enumeration */
2190 PciApplyHacks(DeviceExtension,
2191 PciData,
2192 PciSlot,
2194 NewExtension);
2195
2196 /* Save interrupt pin */
2197 NewExtension->InterruptPin = PciData->u.type0.InterruptPin;
2198
2199 /*
2200 * Use either this device's actual IRQ line or, if it's connected on
2201 * a master bus whose IRQ line is actually connected to the host, use
2202 * the HAL to query the bus' IRQ line and store that as the adjusted
2203 * interrupt line instead
2204 */
2205 NewExtension->AdjustedInterruptLine = PciGetAdjustedInterruptLine(NewExtension);
2206
2207 /* Check if this device is used for PCI debugger cards */
2208 NewExtension->OnDebugPath = PciIsDeviceOnDebugPath(NewExtension);
2209
2210 /* Check for devices with invalid/bogus subsystem data */
2212 {
2213 /* Set the subsystem information to zero instead */
2214 NewExtension->SubsystemVendorId = 0;
2215 NewExtension->SubsystemId = 0;
2216 }
2217
2218 /* Scan all capabilities */
2219 CapOffset = NewExtension->CapabilitiesPtr;
2220 while (CapOffset)
2221 {
2222 /* Read this header */
2223 TempOffset = PciReadDeviceCapability(NewExtension,
2224 CapOffset,
2225 0,
2226 CapHeader,
2227 sizeof(PCI_CAPABILITIES_HEADER));
2228 if (TempOffset != CapOffset)
2229 {
2230 /* This is a strange issue that shouldn't happen normally */
2231 DPRINT1("PCIX - Failed to read PCI capability at offset 0x%02x\n",
2232 CapOffset);
2233 ASSERT(TempOffset == CapOffset);
2234 }
2235
2236 /* Check for capabilities that this driver cares about */
2237 switch (CapHeader->CapabilityID)
2238 {
2239 /* Power management capability is heavily used by the bus */
2241
2242 /* Dump the capability */
2243 Name = "POWER";
2244 Size = sizeof(PCI_PM_CAPABILITY);
2245 break;
2246
2247 /* AGP capability is required for AGP bus functionality */
2249
2250 /* Dump the capability */
2251 Name = "AGP";
2252 Size = sizeof(PCI_AGP_CAPABILITY);
2253 break;
2254
2255 /* This driver doesn't really use anything other than that */
2256 default:
2257
2258 /* Windows prints this, we could do a translation later */
2259 Name = "UNKNOWN CAPABILITY";
2260 Size = 0;
2261 break;
2262 }
2263
2264 /* Check if this is a capability that should be dumped */
2265 if (Size)
2266 {
2267 /* Read the whole capability data */
2268 TempOffset = PciReadDeviceCapability(NewExtension,
2269 CapOffset,
2270 CapHeader->CapabilityID,
2271 CapHeader,
2272 Size);
2273
2274 if (TempOffset != CapOffset)
2275 {
2276 /* Again, a strange issue that shouldn't be seen */
2277 DPRINT1("- Failed to read capability data. ***\n");
2278 ASSERT(TempOffset == CapOffset);
2279 }
2280 }
2281
2282 /* Dump this capability */
2283 DPRINT("PCIX - CAP @%02x ID %02x (%s)\n",
2284 CapOffset, CapHeader->CapabilityID, Name);
2285 for (i = 0; i < Size; i += 2)
2286 DPRINT(" %04x\n", *(PUSHORT)((ULONG_PTR)CapBuffer + i));
2287 DPRINT("\n");
2288
2289 /* Check the next capability */
2290 CapOffset = CapHeader->Next;
2291 }
2292
2293 /* Check for IDE controllers */
2294 if ((NewExtension->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
2295 (NewExtension->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR))
2296 {
2297 /* Do not allow them to power down completely */
2298 NewExtension->DisablePowerDown = TRUE;
2299 }
2300
2301 /*
2302 * Check if this is a legacy bridge. Note that the i82375 PCI/EISA
2303 * bridge that is present on certain NT Alpha machines appears as
2304 * non-classified so detect it manually by scanning for its VID/PID.
2305 */
2306 if (((NewExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
2307 ((NewExtension->SubClass == PCI_SUBCLASS_BR_ISA) ||
2308 (NewExtension->SubClass == PCI_SUBCLASS_BR_EISA) ||
2309 (NewExtension->SubClass == PCI_SUBCLASS_BR_MCA))) ||
2310 ((NewExtension->VendorId == 0x8086) &&
2311 (NewExtension->DeviceId == 0x482)))
2312 {
2313 /* Do not allow these legacy bridges to be powered down */
2314 NewExtension->DisablePowerDown = TRUE;
2315 }
2316
2317 /* Check if the BIOS did not configure a cache line size */
2318 if (!PciData->CacheLineSize)
2319 {
2320 /* Check if the device is disabled */
2321 if (!(NewExtension->CommandEnables & (PCI_ENABLE_IO_SPACE |
2324 {
2325 /* Check if this is a PCI-X device*/
2326 TempOffset = PciReadDeviceCapability(NewExtension,
2327 NewExtension->CapabilitiesPtr,
2329 &PcixCapHeader,
2330 sizeof(PCI_CAPABILITIES_HEADER));
2331
2332 /*
2333 * A device with default cache line size and latency timer
2334 * settings is considered to be unconfigured. Note that on
2335 * PCI-X, the reset value of the latency timer field in the
2336 * header is 64, not 0, hence why the check for PCI-X caps
2337 * was required, and the value used here below.
2338 */
2339 if (!(PciData->LatencyTimer) ||
2340 ((TempOffset) && (PciData->LatencyTimer == 64)))
2341 {
2342 /* Keep track of the fact that it needs configuration */
2343 DPRINT1("PCIX - ScanBus, PDOx %p found unconfigured\n",
2344 NewExtension);
2345 NewExtension->NeedsHotPlugConfiguration = TRUE;
2346 }
2347 }
2348 }
2349
2350 /* Save latency and cache size information */
2351 NewExtension->SavedLatencyTimer = PciData->LatencyTimer;
2352 NewExtension->SavedCacheLineSize = PciData->CacheLineSize;
2353
2354 /* The PDO is now ready to go */
2355 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
2356 }
2357 }
2358
2359 /* Enumeration completed, do a final pass now that all devices are found */
2360 if (ProcessFlag) PciProcessBus(DeviceExtension);
2361 return STATUS_SUCCESS;
2362}
LPWSTR Name
Definition: desk.c:124
#define L(x)
Definition: resources.c:13
VOID NTAPI PciGetEnhancedCapabilities(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: enum.c:1441
VOID NTAPI PciProcessBus(IN PPCI_FDO_EXTENSION DeviceExtension)
Definition: enum.c:1795
BOOLEAN NTAPI PcipIsSameDevice(IN PPCI_PDO_EXTENSION DeviceExtension, IN PPCI_COMMON_HEADER PciData)
Definition: enum.c:1333
VOID NTAPI PciApplyHacks(IN PPCI_FDO_EXTENSION DeviceExtension, IN PPCI_COMMON_HEADER PciData, IN PCI_SLOT_NUMBER SlotNumber, IN ULONG OperationType, PPCI_PDO_EXTENSION PdoExtension)
Definition: enum.c:1081
NTSTATUS NTAPI PciGetFunctionLimits(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER Current, IN ULONGLONG HackFlags)
Definition: enum.c:1759
PWATCHDOG_TABLE WdTable
Definition: init.c:27
VOID NTAPI PciReadSlotConfig(IN PPCI_FDO_EXTENSION DeviceExtension, IN PCI_SLOT_NUMBER Slot, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:165
NTSTATUS NTAPI PciPdoCreate(IN PPCI_FDO_EXTENSION DeviceExtension, IN PCI_SLOT_NUMBER Slot, OUT PDEVICE_OBJECT *PdoDeviceObject)
Definition: pdo.c:1022
PWCHAR NTAPI PciGetDeviceDescriptionMessage(IN UCHAR BaseClass, IN UCHAR SubClass)
Definition: id.c:105
NTSTATUS NTAPI PciGetBiosConfig(IN PPCI_PDO_EXTENSION DeviceExtension, OUT PPCI_COMMON_HEADER PciData)
Definition: utils.c:840
PPCI_PDO_EXTENSION NTAPI PciFindPdoByFunction(IN PPCI_FDO_EXTENSION DeviceExtension, IN ULONG FunctionNumber, IN PPCI_COMMON_HEADER PciData)
Definition: utils.c:695
BOOLEAN NTAPI PciIsDeviceOnDebugPath(IN PPCI_PDO_EXTENSION DeviceExtension)
BOOLEAN NTAPI PciIsCriticalDeviceClass(IN UCHAR BaseClass, IN UCHAR SubClass)
Definition: utils.c:672
NTSTATUS NTAPI PciSetPowerManagedDevicePowerState(IN PPCI_PDO_EXTENSION DeviceExtension, IN DEVICE_POWER_STATE DeviceState, IN BOOLEAN IrpSet)
Definition: power.c:123
ULONGLONG NTAPI PciGetHackFlags(IN USHORT VendorId, IN USHORT DeviceId, IN USHORT SubVendorId, IN USHORT SubSystemId, IN UCHAR RevisionId)
Definition: utils.c:604
NTSTATUS NTAPI PciSaveBiosConfig(IN PPCI_PDO_EXTENSION DeviceExtension, OUT PPCI_COMMON_HEADER PciData)
UCHAR NTAPI PciGetAdjustedInterruptLine(IN PPCI_PDO_EXTENSION PdoExtension)
Definition: config.c:24
#define PCI_SKIP_DEVICE_ENUMERATION
Definition: pci.h:74
static const uint32_t k[]
Definition: sha256.c:24
if(dx< 0)
Definition: linetemp.h:194
_In_ ULONG _In_ PCI_SLOT_NUMBER PciSlot
Definition: pciidex.h:66
#define PCI_HACK_NOT_CRITICAL_DEVICE
Definition: pci.h:49
#define PCI_HACK_ONE_CHILD
Definition: pci.h:24
#define PCI_HACK_FAKE_CLASS_CODE
Definition: pci.h:44
#define PCI_HACK_NEVER_POWER_DOWN
Definition: pci.h:41
#define PCI_HACK_KEEP_DECODES_ON_STOP
Definition: pci.h:12
BOOLEAN ProgIf
Definition: pci.h:343
BOOLEAN BaseClass
Definition: pci.h:345
UCHAR RawInterruptLine
Definition: pci.h:349
ULONGLONG HackFlags
Definition: pci.h:370
BOOLEAN InterruptPin
Definition: pci.h:348
USHORT SubsystemVendorId
Definition: pci.h:340
USHORT SubsystemId
Definition: pci.h:341
USHORT CommandEnables
Definition: pci.h:378
BOOLEAN SavedCacheLineSize
Definition: pci.h:352
BOOLEAN SavedLatencyTimer
Definition: pci.h:351
USHORT DeviceId
Definition: pci.h:339
struct _PCI_PDO_EXTENSION * NextBridge
Definition: pci.h:373
BOOLEAN HeaderType
Definition: pci.h:353
USHORT InitialCommand
Definition: pci.h:379
BOOLEAN NeedsHotPlugConfiguration
Definition: pci.h:362
BOOLEAN SubClass
Definition: pci.h:344
BOOLEAN CapabilitiesPtr
Definition: pci.h:350
USHORT VendorId
Definition: pci.h:338
BOOLEAN OnDebugPath
Definition: pci.h:366
BOOLEAN DisablePowerDown
Definition: pci.h:361
BOOLEAN ExpectedWritebackFailure
Definition: pci.h:356
UCHAR AdjustedInterruptLine
Definition: pci.h:347
BOOLEAN RevisionId
Definition: pci.h:342
struct _PCI_SLOT_NUMBER::@5064::@5065 bits
union _PCI_SLOT_NUMBER::@5064 u
UCHAR PciFunction
Definition: acpi.h:238
USHORT PciDeviceId
Definition: acpi.h:234
UCHAR PciDevice
Definition: acpi.h:237
UCHAR PciBus
Definition: acpi.h:236
USHORT PciVendorId
Definition: acpi.h:235
UCHAR PciSegment
Definition: acpi.h:239
PBIOS_DATA BiosData
Definition: bios.c:42
#define max(a, b)
Definition: svc.c:63
int64_t LONGLONG
Definition: typedefs.h:68
uint16_t * PUSHORT
Definition: typedefs.h:56
uint16_t * PWCHAR
Definition: typedefs.h:56
char * PCHAR
Definition: typedefs.h:51
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3616
#define PCI_CAPABILITY_ID_PCIX
Definition: iotypes.h:3668
struct _PCI_AGP_CAPABILITY PCI_AGP_CAPABILITY
#define PCI_SUBCLASS_SYS_OTHER
Definition: iotypes.h:4200
#define PCI_SUBCLASS_BR_MCA
Definition: iotypes.h:4180
#define PCI_MAX_FUNCTION
Definition: iotypes.h:3614
struct _PCI_PM_CAPABILITY PCI_PM_CAPABILITY
#define PCI_SUBCLASS_BR_CARDBUS
Definition: iotypes.h:4184
#define PCI_CLASS_BASE_SYSTEM_DEV
Definition: iotypes.h:4126
#define PCI_MAX_DEVICES
Definition: iotypes.h:3613
#define PCI_CLASS_DISPLAY_CTLR
Definition: iotypes.h:4121

Referenced by PciQueryDeviceRelations().

◆ PciSetResources()

NTSTATUS NTAPI PciSetResources ( IN PPCI_PDO_EXTENSION  PdoExtension,
IN BOOLEAN  DoReset,
IN BOOLEAN  SomethingSomethingDarkSide 
)

Definition at line 2490 of file enum.c.

2493{
2495 UCHAR NewCacheLineSize, NewLatencyTimer, CacheLineReadBack;
2496 PCI_COMMON_HEADER PciData;
2498 PPCI_CONFIGURATOR Configurator;
2500
2501 UNREFERENCED_PARAMETER(SomethingSomethingDarkSide);
2502
2503 /* Get the FDO and read the configuration data */
2504 FdoExtension = PdoExtension->ParentFdoExtension;
2506
2507 /* Make sure this is still the same device */
2508 if (!PcipIsSameDevice(PdoExtension, &PciData))
2509 {
2510 /* Fail */
2511 ASSERTMSG("PCI Set resources - not same device.\n", FALSE);
2513 }
2514
2515 /* Nothing to set for a host bridge */
2516 if ((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
2517 (PdoExtension->SubClass == PCI_SUBCLASS_BR_HOST))
2518 {
2519 /* Fake success */
2520 return STATUS_SUCCESS;
2521 }
2522
2523 /* Check if an IDE controller is being reset */
2524 if ((DoReset) &&
2525 (PdoExtension->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
2527 {
2528 /* Turn off native mode */
2530 ASSERT(Native == PdoExtension->IDEInNativeMode);
2531 }
2532
2533 /* Check for update of a hotplug device, or first configuration of one */
2534 if ((PdoExtension->NeedsHotPlugConfiguration) &&
2535 (FdoExtension->HotPlugParameters.Acquired))
2536 {
2537 /* The firmware never configured this device, so use what _HPP asks for */
2538 PdoExtension->SavedLatencyTimer = FdoExtension->HotPlugParameters.LatencyTimer;
2539 PdoExtension->SavedCacheLineSize = FdoExtension->HotPlugParameters.CacheLineSize;
2540
2541 PdoExtension->CommandEnables &= ~(PCI_ENABLE_PARITY | PCI_ENABLE_SERR);
2542 if (FdoExtension->HotPlugParameters.EnablePERR)
2543 {
2544 PdoExtension->CommandEnables |= PCI_ENABLE_PARITY;
2545 }
2546
2547 if (FdoExtension->HotPlugParameters.EnableSERR)
2548 {
2549 PdoExtension->CommandEnables |= PCI_ENABLE_SERR;
2550 }
2551
2552 /* Only turn on memory write and invalidate if the device keeps the cache line size */
2554 &PdoExtension->SavedCacheLineSize,
2555 FIELD_OFFSET(PCI_COMMON_HEADER, CacheLineSize),
2556 sizeof(PdoExtension->SavedCacheLineSize));
2558 &CacheLineReadBack,
2559 FIELD_OFFSET(PCI_COMMON_HEADER, CacheLineSize),
2560 sizeof(CacheLineReadBack));
2561 if ((CacheLineReadBack != 0) &&
2562 (CacheLineReadBack == PdoExtension->SavedCacheLineSize))
2563 {
2565 }
2566 else
2567 {
2568 DPRINT1("PCIX - pdox %p cache line size %02x rejected, MWI stays off\n",
2569 PdoExtension, PdoExtension->SavedCacheLineSize);
2570 }
2571 }
2572
2573 /* Locate the correct resource configurator for this type of device */
2574 Configurator = &PciConfigurators[PdoExtension->HeaderType];
2575
2576 /* Apply the settings change, nothing reaches the hardware if it is refused */
2577 Status = Configurator->ChangeResourceSettings(PdoExtension, &PciData);
2578 if (!NT_SUCCESS(Status))
2579 return Status;
2580
2581 /* Assume no update needed */
2582 PdoExtension->UpdateHardware = FALSE;
2583
2584 /* Check if a reset is needed */
2585 if (DoReset)
2586 {
2587 /* Reset resources */
2588 Configurator->ResetDevice(PdoExtension, &PciData);
2589 PciData.u.type0.InterruptLine = PdoExtension->RawInterruptLine;
2590 }
2591
2592 /* Check if the latency timer changed */
2593 NewLatencyTimer = PdoExtension->SavedLatencyTimer;
2594 if (PciData.LatencyTimer != NewLatencyTimer)
2595 {
2596 /* Debug notification */
2597 DPRINT1("PCIX - pdox %p changing latency from %02x to %02x.\n",
2599 PciData.LatencyTimer,
2600 NewLatencyTimer);
2601 }
2602
2603 /* Check if the cache line changed */
2604 NewCacheLineSize = PdoExtension->SavedCacheLineSize;
2605 if (PciData.CacheLineSize != NewCacheLineSize)
2606 {
2607 /* Debug notification */
2608 DPRINT1("PCIX - pdox %p changing cache line size from %02x to %02x.\n",
2610 PciData.CacheLineSize,
2611 NewCacheLineSize);
2612 }
2613
2614 /* Inherit data from PDO extension */
2615 PciData.LatencyTimer = PdoExtension->SavedLatencyTimer;
2616 PciData.CacheLineSize = PdoExtension->SavedCacheLineSize;
2617 PciData.u.type0.InterruptLine = PdoExtension->RawInterruptLine;
2618
2619 /* Apply any resource hacks required */
2621 &PciData,
2622 PdoExtension->Slot,
2624 PdoExtension);
2625
2626 /* Check if I/O space was disabled by administrator or driver */
2627 if (PdoExtension->IoSpaceNotRequired)
2628 {
2629 /* Don't turn on the decode */
2630 PdoExtension->CommandEnables &= ~PCI_ENABLE_IO_SPACE;
2631 }
2632
2633 /* Update the device with the new settings */
2635
2636 /* Update complete */
2637 PdoExtension->RawInterruptLine = PciData.u.type0.InterruptLine;
2638 PdoExtension->NeedsHotPlugConfiguration = FALSE;
2639 return STATUS_SUCCESS;
2640}
VOID NTAPI PciUpdateHardware(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: enum.c:300
unsigned int Native
Definition: fpcontrol.c:84
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:522
PCI_CONFIGURATOR_CHANGE_RESOURCE_SETTINGS ChangeResourceSettings
Definition: pci.h:544
PCI_CONFIGURATOR_RESET_DEVICE ResetDevice
Definition: pci.h:546
#define PCI_ENABLE_PARITY
Definition: iotypes.h:3637
#define PCI_ENABLE_SERR
Definition: iotypes.h:3639

Referenced by PciAssignAndProgramLegacy(), PciPdoIrpStartDevice(), and PciSetPowerManagedDevicePowerState().

◆ PciSkipThisFunction()

BOOLEAN NTAPI PciSkipThisFunction ( IN PPCI_COMMON_HEADER  PciData,
IN PCI_SLOT_NUMBER  Slot,
IN UCHAR  OperationType,
IN ULONGLONG  HackFlags 
)

Definition at line 1367 of file enum.c.

1371{
1372 do
1373 {
1374 /* Check if this is device enumeration */
1375 if (OperationType == PCI_SKIP_DEVICE_ENUMERATION)
1376 {
1377 /* Check if there's a hackflag saying not to enumerate this device */
1379
1380 /* Check if this is the high end of a double decker device */
1382 (Slot.u.bits.DeviceNumber >= 16))
1383 {
1384 /* It belongs to the same device, so skip it */
1385 DPRINT1(" Device (Ven %04x Dev %04x (d=0x%x, f=0x%x)) is a ghost.\n",
1386 PciData->VendorID,
1387 PciData->DeviceID,
1388 Slot.u.bits.DeviceNumber,
1389 Slot.u.bits.FunctionNumber);
1390 break;
1391 }
1392 }
1393 else if (OperationType == PCI_SKIP_RESOURCE_ENUMERATION)
1394 {
1395 /* Resource enumeration, check for a hackflag saying not to do it */
1397 }
1398 else
1399 {
1400 /* Logic error in the driver */
1401 ASSERTMSG("PCI Skip Function - Operation type unknown.\n", FALSE);
1402 }
1403
1404 /* Check for legacy bridges during resource enumeration */
1405 if ((PciData->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
1406 (PciData->SubClass <= PCI_SUBCLASS_BR_MCA) &&
1407 (OperationType == PCI_SKIP_RESOURCE_ENUMERATION))
1408 {
1409 /* Their resources are not enumerated, only PCI and Cardbus/PCMCIA */
1410 break;
1411 }
1412 else if (PciData->BaseClass == PCI_CLASS_NOT_DEFINED)
1413 {
1414 /* Undefined base class (usually a PCI BIOS/ROM bug) */
1415 DPRINT1(" Vendor %04x, Device %04x has class code of PCI_CLASS_NOT_DEFINED\n",
1416 PciData->VendorID,
1417 PciData->DeviceID);
1418
1419 /*
1420 * The Alder has an Intel Extended Express System Support Controller
1421 * which presents apparently spurious BARs. When the PCI resource
1422 * code tries to reassign these BARs, the second IO-APIC gets
1423 * disabled (with disastrous consequences). The first BAR is the
1424 * actual IO-APIC, the remaining five bars seem to be spurious
1425 * resources, so ignore this device completely.
1426 */
1427 if ((PciData->VendorID == 0x8086) && (PciData->DeviceID == 8)) break;
1428 }
1429
1430 /* Other normal PCI cards and bridges are enumerated */
1432 } while (FALSE);
1433
1434 /* Hit one of the known bugs/hackflags, or this is a new kind of PCI unit */
1435 DPRINT1(" Device skipped (not enumerated).\n");
1436 return TRUE;
1437}
#define PCI_HACK_ENUM_NO_RESOURCE
Definition: pci.h:15
#define PCI_HACK_DOUBLE_DECKER
Definition: pci.h:23
#define PCI_CLASS_NOT_DEFINED
Definition: iotypes.h:4136

Referenced by PciGetFunctionLimits(), and PciScanBus().

◆ PciUpdateHardware()

VOID NTAPI PciUpdateHardware ( IN PPCI_PDO_EXTENSION  PdoExtension,
IN PPCI_COMMON_HEADER  PciData 
)

Definition at line 300 of file enum.c.

302{
304
305 /* Check for critical devices and PCI Debugging devices */
306 if ((PdoExtension->HackFlags & PCI_HACK_CRITICAL_DEVICE) ||
307 (PdoExtension->OnDebugPath))
308 {
309 /* Build the context and send an IPI */
310 Context.RunCount = 1;
311 Context.Barrier = 1;
312 Context.Context = PciData;
313 Context.Function = PcipUpdateHardware;
314 Context.DeviceExtension = PdoExtension;
316 }
317 else
318 {
319 /* Just do the update inline */
321 }
322}
VOID NTAPI PcipUpdateHardware(IN PVOID Context, IN PVOID Context2)
Definition: enum.c:263

Referenced by PciSetResources().

◆ PciWriteLimitsAndRestoreCurrent()

VOID NTAPI PciWriteLimitsAndRestoreCurrent ( IN PVOID  Reserved,
IN PVOID  Context2 
)

Definition at line 1575 of file enum.c.

1577{
1579 PPCI_COMMON_HEADER PciData, Current;
1581
1583
1584 /* Grab all parameters from the context */
1585 PdoExtension = Context->PdoExtension;
1586 Current = Context->Current;
1587 PciData = Context->PciData;
1588
1589 /* Write the limit discovery header */
1591
1592 /* Now read what the device indicated the limits are */
1594
1595 /* Then write back the original configuration header */
1597
1598 /* Copy back the original command that was saved in the context */
1599 Current->Command = Context->Command;
1600 if (Context->Command)
1601 {
1602 /* Program it back into the device */
1604 &Context->Command,
1606 sizeof(USHORT));
1607 }
1608
1609 /* Copy back the original status that was saved as well */
1610 Current->Status = Context->Status;
1611
1612 /* Call the configurator to restore any other data that might've changed */
1613 Context->Configurator->RestoreCurrent(Context);
1614}
_Reserved_ PVOID Reserved
Definition: winddi.h:3974

Referenced by PcipGetFunctionLimits().

Variable Documentation

◆ PciConfigurators

PCI_CONFIGURATOR PciConfigurators[]
Initial value:
=
{
{
},
{
},
{
}
}
NTSTATUS NTAPI Cardbus_ChangeResourceSettings(_In_ PPCI_PDO_EXTENSION PdoExtension, _Inout_ PPCI_COMMON_HEADER PciData)
Definition: cardbus.c:149
VOID NTAPI Cardbus_SaveCurrentSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: cardbus.c:39
VOID NTAPI Cardbus_MassageHeaderForLimitsDetermination(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: cardbus.c:102
VOID NTAPI Cardbus_RestoreCurrent(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: cardbus.c:120
VOID NTAPI Cardbus_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: cardbus.c:91
VOID NTAPI Cardbus_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: cardbus.c:138
VOID NTAPI Cardbus_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context, IN PPCI_COMMON_HEADER PciData, IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
Definition: cardbus.c:128
VOID NTAPI Device_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context, IN PPCI_COMMON_HEADER PciData, IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
Definition: device.c:271
VOID NTAPI Device_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: device.c:120
NTSTATUS NTAPI Device_ChangeResourceSettings(_In_ PPCI_PDO_EXTENSION PdoExtension, _Inout_ PPCI_COMMON_HEADER PciData)
Puts the ranges assigned to a function into its BARs and ROM BAR.
Definition: device.c:308
VOID NTAPI Device_MassageHeaderForLimitsDetermination(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: device.c:230
VOID NTAPI Device_SaveCurrentSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: device.c:20
VOID NTAPI Device_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: device.c:284
VOID NTAPI Device_RestoreCurrent(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: device.c:262
VOID NTAPI PPBridge_SaveCurrentSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:227
VOID NTAPI PPBridge_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context, IN PPCI_COMMON_HEADER PciData, IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
Definition: ppbridge.c:657
VOID NTAPI PPBridge_RestoreCurrent(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:649
VOID NTAPI PPBridge_MassageHeaderForLimitsDetermination(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:611
VOID NTAPI PPBridge_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:494
VOID NTAPI PPBridge_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: ppbridge.c:702
NTSTATUS NTAPI PPBridge_ChangeResourceSettings(_In_ PPCI_PDO_EXTENSION PdoExtension, _Inout_ PPCI_COMMON_HEADER PciData)
Definition: ppbridge.c:831

Definition at line 20 of file enum.c.

Referenced by PciBuildRequirementsList(), PcipGetFunctionLimits(), and PciSetResources().

◆ PciZeroIoResourceRequirements

PIO_RESOURCE_REQUIREMENTS_LIST PciZeroIoResourceRequirements