ReactOS 0.4.16-dev-197-g92996da
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)
 
NTSTATUS NTAPI PciQueryEjectionRelations (IN PPCI_PDO_EXTENSION PdoExtension, IN OUT PDEVICE_RELATIONS *pDeviceRelations)
 
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

◆ PciAllocateCmResourceList()

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

Definition at line 324 of file enum.c.

326{
327 SIZE_T Size;
329
330 /* Calculate the final size of the list, including each descriptor */
331 Size = sizeof(CM_RESOURCE_LIST);
332 if (Count > 1) Size = sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (Count - 1) +
333 sizeof(CM_RESOURCE_LIST);
334
335 /* Allocate the list */
337 if (!ResourceList) return NULL;
338
339 /* Initialize it */
341 ResourceList->Count = 1;
342 ResourceList->List[0].BusNumber = BusNumber;
343 ResourceList->List[0].InterfaceType = PCIBus;
344 ResourceList->List[0].PartialResourceList.Version = 1;
345 ResourceList->List[0].PartialResourceList.Revision = 1;
346 ResourceList->List[0].PartialResourceList.Count = Count;
347
348 /* Return it */
349 return ResourceList;
350}
#define NULL
Definition: types.h:112
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
struct _CM_RESOURCE_LIST CM_RESOURCE_LIST
@ PCIBus
Definition: hwresource.cpp:142
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR CM_PARTIAL_RESOURCE_DESCRIPTOR
int Count
Definition: noreturn.cpp:7
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:4533
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
Definition: wdfresource.h:309
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:160

Referenced by PciQueryResources().

◆ PciAllocateIoRequirementsList()

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

Definition at line 291 of file enum.c.

294{
295 SIZE_T Size;
297
298 /* Calculate the final size of the list, including each descriptor */
300 if (Count > 1) Size = sizeof(IO_RESOURCE_DESCRIPTOR) * (Count - 1) +
302
303 /* Allocate the list */
305 if (!RequirementsList) return NULL;
306
307 /* Initialize it */
309 RequirementsList->AlternativeLists = 1;
310 RequirementsList->BusNumber = BusNumber;
311 RequirementsList->SlotNumber = SlotNumber;
312 RequirementsList->InterfaceType = PCIBus;
313 RequirementsList->ListSize = Size;
314 RequirementsList->List[0].Count = Count;
315 RequirementsList->List[0].Version = 1;
316 RequirementsList->List[0].Revision = 1;
317
318 /* Return it */
319 return RequirementsList;
320}
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 794 of file enum.c.

799{
800 ULONG LegacyBaseAddress;
802 UCHAR RegValue;
803
805
806 /* Check what kind of hack operation this is */
807 switch (OperationType)
808 {
809 /*
810 * This is mostly concerned with fixing up incorrect class data that can
811 * exist on certain PCI hardware before the 2.0 spec was ratified.
812 */
814
815 /* Note that the i82375 PCI/EISA and the i82378 PCI/ISA bridges that
816 * are present on certain DEC/NT Alpha machines are pre-PCI 2.0 devices
817 * and appear as non-classified, so their correct class/subclass data
818 * is written here instead.
819 */
820 if ((PciData->VendorID == 0x8086) &&
821 ((PciData->DeviceID == 0x482) || (PciData->DeviceID == 0x484)))
822 {
823 /* Note that 0x482 is the i82375 (EISA), 0x484 is the i82378 (ISA) */
824 PciData->SubClass = PciData->DeviceID == 0x482 ?
826 PciData->BaseClass = PCI_CLASS_BRIDGE_DEV;
827
828 /*
829 * Because the software is modifying the actual header data from
830 * the BIOS, this flag tells the driver to ignore failures when
831 * comparing the original BIOS data with the PCI data.
832 */
833 if (PdoExtension) PdoExtension->ExpectedWritebackFailure = TRUE;
834 }
835
836 /* Note that in this case, an immediate return is issued */
837 return;
838
839 /*
840 * This is concerned with setting up interrupts correctly for native IDE
841 * mode, but will also handle broken VGA decoding on older bridges as
842 * well as a PAE-specific hack for certain Compaq Hot-Plug Controllers.
843 */
845
846 /* There should always be a PDO extension passed in */
848
849 /*
850 * On the OPTi Viper-M IDE controller, Linux doesn't support IDE-DMA
851 * and FreeBSD bug reports indicate that the system crashes when the
852 * feature is enabled (so it's disabled on that OS as well). In the
853 * NT PCI Bus Driver, it seems Microsoft too, completely disables
854 * Native IDE functionality on this controller, so it would seem OPTi
855 * simply frelled up this controller.
856 */
857 if ((PciData->VendorID == 0x1045) && (PciData->DeviceID != 0xC621))
858 {
859 /* Disable native mode */
860 PciData->ProgIf &= ~5;
861 PciData->u.type0.InterruptPin = 0;
862
863 /*
864 * Because the software is modifying the actual header data from
865 * the BIOS, this flag tells the driver to ignore failures when
866 * comparing the original BIOS data with the PCI data.
867 */
868 PdoExtension->ExpectedWritebackFailure = TRUE;
869 }
870 else if ((PciData->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
871 (PciData->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR))
872 {
873 /* For other IDE controllers, start out in compatible mode */
874 PdoExtension->BIOSAllowsIDESwitchToNativeMode = FALSE;
875
876 /*
877 * Registry must have enabled native mode (typically as a result
878 * of an INF file directive part of the IDE controller's driver)
879 * and the system must not be booted in Safe Mode. If that checks
880 * out, then evaluate the ACPI NATA method to see if the platform
881 * supports this. See the section "BIOS and Platform Prerequisites
882 * for Switching a Native-Mode-Capable Controller" in the Storage
883 * section of the Windows Driver Kit for more details:
884 *
885 * 5. For each ATA controller enumerated, the PCI bus driver checks
886 * the Programming Interface register of the IDE controller to
887 * see if it supports switching both channels to native mode.
888 * 6. The PCI bus driver checks whether the BIOS/platform supports
889 * switching the controller by checking the NATA method described
890 * earlier in this article.
891 *
892 * If an ATA controller does not indicate that it is native
893 * mode-capable, or if the BIOS NATA control method is missing
894 * or does not list that device, the PCI bus driver does not
895 * switch the controller and it is assigned legacy resources.
896 *
897 * If both the controller and the BIOS indicate that the controller
898 * can be switched, the process of switching the controller begins
899 * with the next step.
900 */
902 !(InitSafeBootMode) &&
904 {
905 /* The platform supports it, remember that */
906 PdoExtension->BIOSAllowsIDESwitchToNativeMode = TRUE;
907
908 /*
909 * Now switch the controller into native mode if both channels
910 * support native IDE mode. See "How Windows Switches an ATA
911 * Controller to Native Mode" in the Storage section of the
912 * Windows Driver Kit for more details.
913 */
914 PdoExtension->IDEInNativeMode =
916 }
917
918 /* Is native mode enabled after all? */
919 if ((PciData->ProgIf & 5) != 5)
920 {
921 /* Compatible mode, so force ISA-style IRQ14 and IRQ 15 */
922 PciData->u.type0.InterruptPin = 0;
923 }
924 }
925
926 /* Is this a PCI device with legacy VGA card decodes on the root bus? */
927 if ((PdoExtension->HackFlags & PCI_HACK_VIDEO_LEGACY_DECODE) &&
928 (PCI_IS_ROOT_FDO(DeviceExtension)) &&
929 !(DeviceExtension->BrokenVideoHackApplied))
930 {
931 /* Tell the arbiter to apply a hack for these older devices */
932 ario_ApplyBrokenVideoHack(DeviceExtension);
933 }
934
935 /* Is this a Compaq PCI Hotplug Controller (r17) on a PAE system ? */
936 if ((PciData->VendorID == 0xE11) &&
937 (PciData->DeviceID == 0xA0F7) &&
938 (PciData->RevisionID == 17) &&
940 {
941 /* Turn off the decodes immediately */
942 PciData->Command &= ~(PCI_ENABLE_IO_SPACE |
946 &PciData->Command,
948 sizeof(USHORT));
949
950 /* Do not EVER turn them on again, this will blow up the system */
951 PdoExtension->CommandEnables &= ~(PCI_ENABLE_IO_SPACE |
955 }
956 break;
957
958 /*
959 * This is called whenever resources are changed and hardware needs to be
960 * updated. It is concerned with two highly specific erratas on an IBM
961 * hot-plug docking bridge used on the Thinkpad 600 Series and on Intel's
962 * ICH PCI Bridges.
963 */
965
966 /* There should always be a PDO extension passed in */
968
969 /* Is this an IBM 20H2999 PCI Docking Bridge, used on Thinkpads? */
970 if ((PdoExtension->VendorId == 0x1014) &&
971 (PdoExtension->DeviceId == 0x95))
972 {
973 /* Read the current command */
975 &Command,
977 sizeof(USHORT));
978
979 /* Turn off the decodes */
981
982 /* Apply the required IBM workaround */
983 PciReadDeviceConfig(PdoExtension, &RegValue, 0xE0, sizeof(UCHAR));
984 RegValue &= ~2;
985 RegValue |= 1;
986 PciWriteDeviceConfig(PdoExtension, &RegValue, 0xE0, sizeof(UCHAR));
987
988 /* Restore the command to its original value */
990 &Command,
992 sizeof(USHORT));
993
994 }
995
996 /*
997 * Check for Intel ICH PCI-to-PCI (i82801) bridges (used on the i810,
998 * i820, i840, i845 Chipsets) that have subtractive decode enabled,
999 * and whose hack flags do not specify that this support is broken.
1000 */
1001 if ((PdoExtension->HeaderType == PCI_BRIDGE_TYPE) &&
1002 (PdoExtension->Dependent.type1.SubtractiveDecode) &&
1003 ((PdoExtension->VendorId == 0x8086) &&
1004 ((PdoExtension->DeviceId == 0x2418) ||
1005 (PdoExtension->DeviceId == 0x2428) ||
1006 (PdoExtension->DeviceId == 0x244E) ||
1007 (PdoExtension->DeviceId == 0x2448))) &&
1009 {
1010 /*
1011 * The positive decode window shouldn't be used, these values are
1012 * normally all read-only or initialized to 0 by the BIOS, but
1013 * it appears Intel doesn't do this, so the PCI Bus Driver will
1014 * do it in software instead. Note that this is used to prevent
1015 * certain non-compliant PCI devices from breaking down due to the
1016 * fact that these ICH bridges have a known "quirk" (which Intel
1017 * documents as a known "erratum", although it's not not really
1018 * an ICH bug since the PCI specification does allow for it) in
1019 * that they will sometimes send non-zero addresses during special
1020 * cycles (ie: non-zero data during the address phase). These
1021 * broken PCI cards will mistakenly attempt to claim the special
1022 * cycle and corrupt their I/O and RAM ranges. Again, in Intel's
1023 * defense, the PCI specification only requires stable data, not
1024 * necessarily zero data, during the address phase.
1025 */
1026 PciData->u.type1.MemoryBase = 0xFFFF;
1027 PciData->u.type1.PrefetchBase = 0xFFFF;
1028 PciData->u.type1.IOBase = 0xFF;
1029 PciData->u.type1.IOLimit = 0;
1030 PciData->u.type1.MemoryLimit = 0;
1031 PciData->u.type1.PrefetchLimit = 0;
1032 PciData->u.type1.PrefetchBaseUpper32 = 0;
1033 PciData->u.type1.PrefetchLimitUpper32 = 0;
1034 PciData->u.type1.IOBaseUpper16 = 0;
1035 PciData->u.type1.IOLimitUpper16 = 0;
1036 }
1037 break;
1038
1039 default:
1040 return;
1041 }
1042
1043 /* Finally, also check if this is this a CardBUS device? */
1045 {
1046 /*
1047 * At offset 44h the LegacyBaseAddress is stored, which is cleared by
1048 * ACPI-aware versions of Windows, to disable legacy-mode I/O access to
1049 * CardBus controllers. For more information, see "Supporting CardBus
1050 * Controllers under ACPI" in the "CardBus Controllers and Windows"
1051 * Whitepaper on WHDC.
1052 */
1053 LegacyBaseAddress = 0;
1055 &LegacyBaseAddress,
1056 sizeof(PCI_COMMON_HEADER) + sizeof(ULONG),
1057 sizeof(ULONG));
1058 }
1059}
VOID NTAPI ario_ApplyBrokenVideoHack(IN PPCI_FDO_EXTENSION FdoExtension)
Definition: ar_memio.c:104
#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:654
BOOLEAN PciEnableNativeModeATA
Definition: init.c:24
NTSYSAPI BOOLEAN InitSafeBootMode
Definition: init.c:71
VOID NTAPI PciWriteDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:91
BOOLEAN NTAPI PciIsSlotPresentInParentMethod(IN PPCI_PDO_EXTENSION PdoExtension, IN ULONG Method)
Definition: utils.c:1094
#define PCI_HACK_FIXUP_BEFORE_UPDATE
Definition: pci.h:72
#define PCI_IS_ROOT_FDO(x)
Definition: pci.h:32
VOID NTAPI PciDecodeEnable(IN PPCI_PDO_EXTENSION PdoExtension, IN BOOLEAN Enable, OUT PUSHORT Command)
Definition: utils.c:1267
#define PCI_HACK_FIXUP_AFTER_CONFIGURATION
Definition: pci.h:71
#define PCI_HACK_FIXUP_BEFORE_CONFIGURATION
Definition: pci.h:70
VOID NTAPI PciReadDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:107
@ PdoExtension
Definition: precomp.h:49
#define ASSERT(a)
Definition: mode.c:44
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
BOOLEAN NTAPI ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature)
Definition: sysinfo.c:363
unsigned short USHORT
Definition: pedump.c:61
#define PCI_HACK_PRESERVE_COMMAND
Definition: pci.h:24
#define PCI_HACK_VIDEO_LEGACY_DECODE
Definition: pci.h:42
#define PCI_HACK_BROKEN_SUBTRACTIVE_DECODE
Definition: pci.h:49
Definition: shell.h:41
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint32_t ULONG
Definition: typedefs.h:59
#define PCI_ENABLE_BUS_MASTER
Definition: iotypes.h:3618
#define PCI_SUBCLASS_BR_EISA
Definition: iotypes.h:4163
#define PCI_ENABLE_IO_SPACE
Definition: iotypes.h:3616
#define PCI_CLASS_MASS_STORAGE_CTLR
Definition: iotypes.h:4104
#define PCI_CONFIGURATION_TYPE(PciData)
Definition: iotypes.h:3609
#define PCI_SUBCLASS_MSC_IDE_CTLR
Definition: iotypes.h:4129
#define PCI_ENABLE_MEMORY_SPACE
Definition: iotypes.h:3617
#define PCI_BRIDGE_TYPE
Definition: iotypes.h:3606
#define PCI_SUBCLASS_BR_ISA
Definition: iotypes.h:4162
#define PCI_CLASS_BRIDGE_DEV
Definition: iotypes.h:4109
#define PCI_CARDBUS_BRIDGE_TYPE
Definition: iotypes.h:3607
#define PF_PAE_ENABLED
Definition: ketypes.h:133
unsigned char UCHAR
Definition: xmlstorage.h:181

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 551 of file enum.c.

554{
556
558 UNREFERENCED_PARAMETER(PciData);
559
560 {
561 /* There aren't, so use the zero descriptor */
563
564 /* Does it actually exist yet? */
566 {
567 /* Allocate it, and use it for future use */
571 }
572
573 /* Return the zero requirements list to the caller */
575 DPRINT1("PCI - build resource reqs - early out, 0 resources\n");
576 return STATUS_SUCCESS;
577 }
578 return STATUS_SUCCESS;
579}
#define DPRINT1
Definition: precomp.h:8
Definition: bufpool.h:45
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:291
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

Referenced by PciAssignSlotResources(), 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 BaseResource, CurrentDescriptor;
60 PCM_PARTIAL_RESOURCE_DESCRIPTOR PreviousDescriptor;
61 CM_PARTIAL_RESOURCE_DESCRIPTOR ResourceArray[7];
63 BOOLEAN DrainPartial, RangeChange;
64 ULONG i, j;
65 PPCI_FUNCTION_RESOURCES PciResources;
66 PAGED_CODE();
67
68 /* Make sure we have either no resources, or at least one */
69 ASSERT((ResourceList == NULL) || (ResourceList->Count == 1));
70
71 /* Initialize no partial, interrupt descriptor, or range change */
72 Partial = NULL;
73 InterruptResource = NULL;
74 RangeChange = FALSE;
75
76 /* Check if there's not actually any resources */
77 if (!(ResourceList) || !(ResourceList->Count))
78 {
79 /* Then just return the hardware update state */
80 return PdoExtension->UpdateHardware;
81 }
82
83 /* Print the new specified resource list */
85
86 /* Clear the temporary resource array */
87 for (i = 0; i < 7; i++) ResourceArray[i].Type = CmResourceTypeNull;
88
89 /* Loop the full resource descriptor */
90 FullList = ResourceList->List;
91 for (i = 0; i < ResourceList->Count; i++)
92 {
93 /* Initialize loop variables */
94 DrainPartial = FALSE;
95 BaseResource = NULL;
96
97 /* Loop the partial descriptors */
98 Partial = FullList->PartialResourceList.PartialDescriptors;
99 for (j = 0; j < FullList->PartialResourceList.Count; j++)
100 {
101 /* Check if we were supposed to drain a partial due to device data */
102 if (DrainPartial)
103 {
104 /* Draining complete, move on to the next descriptor then */
105 DrainPartial--;
106 continue;
107 }
108
109 /* Check what kind of descriptor this was */
110 switch (Partial->Type)
111 {
112 /* Base BAR resources */
115
116 /* Set it as the base */
117 ASSERT(BaseResource == NULL);
118 BaseResource = Partial;
119 break;
120
121 /* Interrupt resource */
123
124 /* Make sure it's a compatible (and the only) PCI interrupt */
125 ASSERT(InterruptResource == NULL);
126 ASSERT(Partial->u.Interrupt.Level == Partial->u.Interrupt.Vector);
127 InterruptResource = Partial;
128
129 /* Only 255 interrupts on x86/x64 hardware */
130 if (Partial->u.Interrupt.Level < 256)
131 {
132 /* Use the passed interrupt line */
133 PdoExtension->AdjustedInterruptLine = Partial->u.Interrupt.Level;
134 }
135 else
136 {
137 /* Invalid vector, so ignore it */
138 PdoExtension->AdjustedInterruptLine = 0;
139 }
140
141 break;
142
143 /* Check for specific device data */
145
146 /* Check what kind of data this was */
147 switch (Partial->u.DevicePrivate.Data[0])
148 {
149 /* Not used in the driver yet */
150 case 1:
152 break;
153
154 /* Not used in the driver yet */
155 case 2:
157 break;
158
159 /* A drain request */
160 case 3:
161 /* Shouldn't be a base resource, this is a drain */
162 ASSERT(BaseResource == NULL);
163 DrainPartial = Partial->u.DevicePrivate.Data[1];
164 ASSERT(DrainPartial == TRUE);
165 break;
166 }
167 break;
168 }
169
170 /* Move to the next descriptor */
171 Partial = CmiGetNextPartialDescriptor(Partial);
172 }
173
174 /* We should be starting a new list now */
175 ASSERT(BaseResource == NULL);
176 FullList = (PVOID)Partial;
177 }
178
179 /* Check the current assigned PCI resources */
180 PciResources = PdoExtension->Resources;
181 if (!PciResources) return FALSE;
182
183 //if... // MISSING CODE
185 DPRINT1("Missing sanity checking code!\n");
186
187 /* Loop all the PCI function resources */
188 for (i = 0; i < 7; i++)
189 {
190 /* Get the current function resource descriptor, and the new one */
191 CurrentDescriptor = &PciResources->Current[i];
192 Partial = &ResourceArray[i];
193
194 /* Previous is current during the first loop iteration */
195 PreviousDescriptor = &PciResources->Current[(i == 0) ? (0) : (i - 1)];
196
197 /* Check if this new descriptor is different than the old one */
198 if (((Partial->Type != CurrentDescriptor->Type) ||
199 (Partial->Type != CmResourceTypeNull)) &&
200 ((Partial->u.Generic.Start.QuadPart !=
201 CurrentDescriptor->u.Generic.Start.QuadPart) ||
202 (Partial->u.Generic.Length != CurrentDescriptor->u.Generic.Length)))
203 {
204 /* Record a change */
205 RangeChange = TRUE;
206
207 /* Was there a range before? */
208 if (CurrentDescriptor->Type != CmResourceTypeNull)
209 {
210 /* Print it */
211 DbgPrint(" Old range-\n");
212 PciDebugPrintPartialResource(CurrentDescriptor);
213 }
214 else
215 {
216 /* There was no range */
217 DbgPrint(" Previously unset range\n");
218 }
219
220 /* Print new one */
221 DbgPrint(" changed to\n");
223
224 /* Update to new range */
225 CurrentDescriptor->Type = Partial->Type;
226 PreviousDescriptor->u.Generic.Start = Partial->u.Generic.Start;
227 PreviousDescriptor->u.Generic.Length = Partial->u.Generic.Length;
228 CurrentDescriptor = PreviousDescriptor;
229 }
230 }
231
232 /* Either the hardware was updated, or a resource range changed */
233 return ((RangeChange) || (PdoExtension->UpdateHardware));
234}
#define PAGED_CODE()
unsigned char BOOLEAN
Type
Definition: Type.h:7
#define UNIMPLEMENTED
Definition: debug.h:118
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:348
VOID NTAPI PciDebugPrintCmResList(IN PCM_RESOURCE_LIST PartialList)
Definition: debug.c:364
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
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
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 CmResourceTypeNull
Definition: hwresource.cpp:122
#define CmResourceTypeMemory
Definition: hwresource.cpp:125
#define CmResourceTypeDevicePrivate
Definition: hwresource.cpp:131
#define CmResourceTypePort
Definition: hwresource.cpp:123
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@391::@398 DevicePrivate
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@391 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@391::@394 Interrupt
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@391::@392 Generic
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
CM_PARTIAL_RESOURCE_DESCRIPTOR Current[7]
Definition: pci.h:237
void * PVOID
Definition: typedefs.h:50

Referenced by PciAssignSlotResources(), and PciPdoIrpStartDevice().

◆ PciConfigureIdeController()

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

Definition at line 654 of file enum.c.

657{
658 UCHAR MasterMode, SlaveMode, MasterFixed, SlaveFixed, ProgIf, NewProgIf;
659 BOOLEAN Switched;
661
662 /* Assume it won't work */
663 Switched = FALSE;
664
665 /* Get master and slave current settings, and programmability flag */
666 ProgIf = PciData->ProgIf;
667 MasterMode = (ProgIf & 1) == 1;
668 MasterFixed = (ProgIf & 2) == 0;
669 SlaveMode = (ProgIf & 4) == 4;
670 SlaveFixed = (ProgIf & 8) == 0;
671
672 /*
673 * [..] In order for Windows XP SP1 and Windows Server 2003 to switch an ATA
674 * ATA controller from compatible mode to native mode, the following must be
675 * true:
676 *
677 * - The controller must indicate in its programming interface that both channels
678 * can be switched to native mode. Windows XP SP1 and Windows Server 2003 do
679 * not support switching only one IDE channel to native mode. See the PCI IDE
680 * Controller Specification Revision 1.0 for details.
681 */
682 if ((MasterMode != SlaveMode) || (MasterFixed != SlaveFixed))
683 {
684 /* Windows does not support this configuration, fail */
685 DPRINT1("PCI: Warning unsupported IDE controller configuration for VEN_%04x&DEV_%04x!",
686 PdoExtension->VendorId,
687 PdoExtension->DeviceId);
688 return Switched;
689 }
690
691 /* Check if the controller is already in native mode */
692 if ((MasterMode) && (SlaveMode))
693 {
694 /* Check if I/O decodes should be disabled */
695 if ((Initial) || (PdoExtension->IoSpaceUnderNativeIdeControl))
696 {
697 /* Read the current command */
699 &Command,
701 sizeof(USHORT));
702
703 /* Disable I/O space decode */
704 Command &= ~PCI_ENABLE_IO_SPACE;
705
706 /* Update new command in PCI IDE controller */
708 &Command,
710 sizeof(USHORT));
711
712 /* Save updated command value */
713 PciData->Command = Command;
714 }
715
716 /* The controller is now in native mode */
717 Switched = TRUE;
718 }
719 else if (!(MasterFixed) &&
720 !(SlaveFixed) &&
721 (PdoExtension->BIOSAllowsIDESwitchToNativeMode) &&
723 {
724 /* Turn off decodes */
726
727 /* Update the current command */
729 &PciData->Command,
731 sizeof(USHORT));
732
733 /* Enable native mode */
734 ProgIf = PciData->ProgIf | 5;
736 &ProgIf,
738 sizeof(UCHAR));
739
740 /* Verify the setting "stuck" */
742 &NewProgIf,
744 sizeof(UCHAR));
745 if (NewProgIf == ProgIf)
746 {
747 /* Update the header and PDO data with the new programming mode */
748 PciData->ProgIf = ProgIf;
749 PdoExtension->ProgIf = NewProgIf;
750
751 /* Clear the first four BARs to reset current BAR settings */
752 PciData->u.type0.BaseAddresses[0] = 0;
753 PciData->u.type0.BaseAddresses[1] = 0;
754 PciData->u.type0.BaseAddresses[2] = 0;
755 PciData->u.type0.BaseAddresses[3] = 0;
757 PciData->u.type0.BaseAddresses,
759 u.type0.BaseAddresses),
760 4 * sizeof(ULONG));
761
762 /* Re-read the BARs to have the latest data for native mode IDE */
764 PciData->u.type0.BaseAddresses,
766 u.type0.BaseAddresses),
767 4 * sizeof(ULONG));
768
769 /* Re-read the interrupt pin used for native mode IDE */
771 &PciData->u.type0.InterruptPin,
773 u.type0.InterruptPin),
774 sizeof(UCHAR));
775
776 /* The IDE Controller is now in native mode */
777 Switched = TRUE;
778 }
779 else
780 {
781 /* Settings did not work, fail */
782 DPRINT1("PCI: Warning failed switch to native mode for IDE controller VEN_%04x&DEV_%04x!",
783 PciData->VendorID,
784 PciData->DeviceID);
785 }
786 }
787
788 /* Return whether or not native mode was enabled on the IDE controller */
789 return Switched;
790}
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:45

Referenced by PciApplyHacks(), and PciSetResources().

◆ PciGetEnhancedCapabilities()

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

Definition at line 1171 of file enum.c.

1173{
1174 ULONG HeaderType, CapPtr, TargetAgpCapabilityId;
1175 DEVICE_POWER_STATE WakeLevel;
1176 PCI_CAPABILITIES_HEADER AgpCapability;
1178 PAGED_CODE();
1179
1180 /* Assume no known wake level */
1181 PdoExtension->PowerState.DeviceWakeLevel = PowerDeviceUnspecified;
1182
1183 /* Make sure the device has capabilities */
1184 if (!(PciData->Status & PCI_STATUS_CAPABILITIES_LIST))
1185 {
1186 /* If it doesn't, there will be no power management */
1187 PdoExtension->CapabilitiesPtr = 0;
1188 PdoExtension->HackFlags |= PCI_HACK_NO_PM_CAPS;
1189 }
1190 else
1191 {
1192 /* There's capabilities, need to figure out where to get the offset */
1193 HeaderType = PCI_CONFIGURATION_TYPE(PciData);
1194 if (HeaderType == PCI_CARDBUS_BRIDGE_TYPE)
1195 {
1196 /* Use the bridge's header */
1197 CapPtr = PciData->u.type2.CapabilitiesPtr;
1198 }
1199 else
1200 {
1201 /* Use the device header */
1202 ASSERT(HeaderType <= PCI_CARDBUS_BRIDGE_TYPE);
1203 CapPtr = PciData->u.type0.CapabilitiesPtr;
1204 }
1205
1206 /* Skip garbage capabilities pointer */
1207 if (((CapPtr & 0x3) != 0) || (CapPtr < PCI_COMMON_HDR_LENGTH))
1208 {
1209 /* Report no extended capabilities */
1210 PdoExtension->CapabilitiesPtr = 0;
1211 PdoExtension->HackFlags |= PCI_HACK_NO_PM_CAPS;
1212 }
1213 else
1214 {
1215 DPRINT1("Device has capabilities at: %lx\n", CapPtr);
1216 PdoExtension->CapabilitiesPtr = CapPtr;
1217
1218 /* Check for PCI-to-PCI Bridges and AGP bridges */
1219 if ((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
1220 ((PdoExtension->SubClass == PCI_SUBCLASS_BR_HOST) ||
1222 {
1223 /* Query either the raw AGP capabilitity, or the Target AGP one */
1224 TargetAgpCapabilityId = (PdoExtension->SubClass ==
1229 PdoExtension->CapabilitiesPtr,
1230 TargetAgpCapabilityId,
1231 &AgpCapability,
1232 sizeof(PCI_CAPABILITIES_HEADER)))
1233 {
1234 /* AGP target ID was found, store it */
1235 DPRINT1("AGP ID: %lx\n", TargetAgpCapabilityId);
1236 PdoExtension->TargetAgpCapabilityId = TargetAgpCapabilityId;
1237 }
1238 }
1239
1240 /* Check for devices that are known not to have proper power management */
1241 if (!(PdoExtension->HackFlags & PCI_HACK_NO_PM_CAPS))
1242 {
1243 /* Query if this device supports power management */
1245 PdoExtension->CapabilitiesPtr,
1247 &PowerCapabilities.Header,
1248 sizeof(PCI_PM_CAPABILITY)))
1249 {
1250 /* No power management, so act as if it had the hackflag set */
1251 DPRINT1("No PM caps, disabling PM\n");
1252 PdoExtension->HackFlags |= PCI_HACK_NO_PM_CAPS;
1253 }
1254 else
1255 {
1256 /* Otherwise, pick the highest wake level that is supported */
1257 WakeLevel = PowerDeviceUnspecified;
1258 if (PowerCapabilities.PMC.Capabilities.Support.PMED0)
1259 WakeLevel = PowerDeviceD0;
1260 if (PowerCapabilities.PMC.Capabilities.Support.PMED1)
1261 WakeLevel = PowerDeviceD1;
1262 if (PowerCapabilities.PMC.Capabilities.Support.PMED2)
1263 WakeLevel = PowerDeviceD2;
1264 if (PowerCapabilities.PMC.Capabilities.Support.PMED3Hot)
1265 WakeLevel = PowerDeviceD3;
1266 if (PowerCapabilities.PMC.Capabilities.Support.PMED3Cold)
1267 WakeLevel = PowerDeviceD3;
1268 PdoExtension->PowerState.DeviceWakeLevel = WakeLevel;
1269
1270 /* Convert the PCI power state to the NT power state */
1271 PdoExtension->PowerState.CurrentDeviceState =
1272 PowerCapabilities.PMCSR.ControlStatus.PowerState + 1;
1273
1274 /* Save all the power capabilities */
1275 PdoExtension->PowerCapabilities = PowerCapabilities.PMC.Capabilities;
1276 DPRINT1("PM Caps Found! Wake Level: %d Power State: %d\n",
1277 WakeLevel, PdoExtension->PowerState.CurrentDeviceState);
1278 }
1279 }
1280 }
1281 }
1282
1283 /* At the very end of all this, does this device not have power management? */
1284 if (PdoExtension->HackFlags & PCI_HACK_NO_PM_CAPS)
1285 {
1286 /* Then guess the current state based on whether the decodes are on */
1287 PdoExtension->PowerState.CurrentDeviceState =
1288 PciData->Command & (PCI_ENABLE_IO_SPACE |
1292 DPRINT1("PM is off, so assumed device is: %d based on enables\n",
1293 PdoExtension->PowerState.CurrentDeviceState);
1294 }
1295}
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:886
@ 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:39
_In_ WDFDEVICE _In_ PWDF_DEVICE_POWER_CAPABILITIES PowerCapabilities
Definition: wdfdevice.h:3886
#define PCI_CAPABILITY_ID_AGP
Definition: iotypes.h:3648
#define PCI_SUBCLASS_BR_HOST
Definition: iotypes.h:4161
#define PCI_SUBCLASS_BR_PCI_TO_PCI
Definition: iotypes.h:4165
#define PCI_COMMON_HDR_LENGTH
Definition: iotypes.h:3594
#define PCI_STATUS_CAPABILITIES_LIST
Definition: iotypes.h:3630
#define PCI_CAPABILITY_ID_POWER_MANAGEMENT
Definition: iotypes.h:3647
#define PCI_CAPABILITY_ID_AGP_TARGET
Definition: iotypes.h:3660

Referenced by PciScanBus().

◆ PciGetFunctionLimits()

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

Definition at line 1483 of file enum.c.

1486{
1488 PPCI_COMMON_HEADER PciData;
1490 PAGED_CODE();
1491
1492 /* Do the hackflags indicate this device should be skipped? */
1493 if (PciSkipThisFunction(Current,
1494 PdoExtension->Slot,
1496 HackFlags))
1497 {
1498 /* Do not process its resources */
1499 return STATUS_SUCCESS;
1500 }
1501
1502 /* Allocate a buffer to hold two PCI configuration headers */
1503 PciData = ExAllocatePoolWithTag(0, 2 * PCI_COMMON_HDR_LENGTH, 'BicP');
1504 if (!PciData) return STATUS_INSUFFICIENT_RESOURCES;
1505
1506 /* Set up the context for the resource enumeration, and do it */
1507 Context.Current = Current;
1508 Context.PciData = PciData;
1509 Context.PdoExtension = PdoExtension;
1511
1512 /* Enumeration is completed, free the PCI headers and return the status */
1513 ExFreePoolWithTag(PciData, 0);
1514 return Status;
1515}
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:1097
NTSTATUS NTAPI PcipGetFunctionLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: enum.c:1342
#define PCI_SKIP_RESOURCE_ENUMERATION
Definition: pci.h:65
Status
Definition: gdiplustypes.h:25
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109

Referenced by PciScanBus().

◆ PcipGetFunctionLimits()

NTSTATUS NTAPI PcipGetFunctionLimits ( IN PPCI_CONFIGURATOR_CONTEXT  Context)

Definition at line 1342 of file enum.c.

1343{
1344 PPCI_CONFIGURATOR Configurator;
1345 PPCI_COMMON_HEADER PciData, Current;
1347 PCI_IPI_CONTEXT IpiContext;
1348 PIO_RESOURCE_DESCRIPTOR IoDescriptor;
1349 ULONG Offset;
1350 PAGED_CODE();
1351
1352 /* Grab all parameters from the context */
1353 PdoExtension = Context->PdoExtension;
1354 Current = Context->Current;
1355 PciData = Context->PciData;
1356
1357 /* Save the current PCI Command and Status word */
1358 Context->Status = Current->Status;
1359 Context->Command = Current->Command;
1360
1361 /* Now that they're saved, clear the status, and disable all decodes */
1362 Current->Status = 0;
1363 Current->Command &= ~(PCI_ENABLE_IO_SPACE |
1366
1367 /* Make a copy of the current PCI configuration header (with decodes off) */
1368 RtlCopyMemory(PciData, Current, PCI_COMMON_HDR_LENGTH);
1369
1370 /* Locate the correct resource configurator for this type of device */
1371 Configurator = &PciConfigurators[PdoExtension->HeaderType];
1372 Context->Configurator = Configurator;
1373
1374 /* Initialize it, which will typically setup the BARs for limit discovery */
1375 Configurator->Initialize(Context);
1376
1377 /* Check for critical devices and PCI Debugging devices */
1378 if ((PdoExtension->HackFlags & PCI_HACK_CRITICAL_DEVICE) ||
1379 (PdoExtension->OnDebugPath))
1380 {
1381 /* Specifically check for a PCI Debugging device */
1382 if (PdoExtension->OnDebugPath)
1383 {
1384 /* Was it enabled for bus mastering? */
1385 if (Context->Command & PCI_ENABLE_BUS_MASTER)
1386 {
1387 /* This decode needs to be re-enabled so debugging can work */
1388 PciData->Command |= PCI_ENABLE_BUS_MASTER;
1389 Current->Command |= PCI_ENABLE_BUS_MASTER;
1390 }
1391
1392 /* Disable the debugger while the discovery is happening */
1394 }
1395
1396 /* For these devices, an IPI must be sent to force high-IRQL discovery */
1397 IpiContext.Barrier = 1;
1398 IpiContext.RunCount = 1;
1399 IpiContext.DeviceExtension = PdoExtension;
1401 IpiContext.Context = Context;
1403
1404 /* Re-enable the debugger if this was a PCI Debugging Device */
1405 if (PdoExtension->OnDebugPath) KdEnableDebugger();
1406 }
1407 else
1408 {
1409 /* Otherwise, it's safe to do this in-line at low IRQL */
1411 }
1412
1413 /*
1414 * Check if it's valid to compare the headers to see if limit discovery mode
1415 * has properly exited (the expected case is that the PCI header would now
1416 * be equal to what it was before). In some cases, it is known that this will
1417 * fail, because during PciApplyHacks (among other places), software hacks
1418 * had to be applied to the header, which the hardware-side will not see, and
1419 * thus the headers would appear "different".
1420 */
1421 if (!PdoExtension->ExpectedWritebackFailure)
1422 {
1423 /* Read the current PCI header now, after discovery has completed */
1425
1426 /* Check if the current header at entry, is equal to the header now */
1427 Offset = RtlCompareMemory(PciData + 1, Current, PCI_COMMON_HDR_LENGTH);
1429 {
1430 /* It's not, which means configuration somehow changed, dump this */
1431 DPRINT1("PCI - CFG space write verify failed at offset 0x%x\n", Offset);
1432 PciDebugDumpCommonConfig(PciData + 1);
1433 DPRINT1("----------\n");
1434 PciDebugDumpCommonConfig(Current);
1435 }
1436 }
1437
1438 /* This PDO should not already have resources, since this is only done once */
1439 ASSERT(PdoExtension->Resources == NULL);
1440
1441 /* Allocate the structure that will hold the discovered resources and limits */
1443 sizeof(PCI_FUNCTION_RESOURCES),
1444 'BicP');
1445 if (!PdoExtension->Resources) return STATUS_INSUFFICIENT_RESOURCES;
1446
1447 /* Clear it out for now */
1449
1450 /* Now call the configurator, which will first store the limits... */
1451 Configurator->SaveLimits(Context);
1452
1453 /* ...and then store the current resources being used */
1454 Configurator->SaveCurrentSettings(Context);
1455
1456 /* Loop all the limit descriptors backwards */
1457 IoDescriptor = &PdoExtension->Resources->Limit[PCI_TYPE0_ADDRESSES + 1];
1458 while (TRUE)
1459 {
1460 /* Keep going until a non-null descriptor is found */
1461 IoDescriptor--;
1462 if (IoDescriptor->Type != CmResourceTypeNull) break;
1463
1464 /* This is a null descriptor, is it the last one? */
1465 if (IoDescriptor == &PdoExtension->Resources->Limit[PCI_TYPE0_ADDRESSES + 1])
1466 {
1467 /* This means the descriptor is NULL, which means discovery failed */
1468 DPRINT1("PCI Resources fail!\n");
1469
1470 /* No resources will be assigned for the device */
1471 ExFreePoolWithTag(PdoExtension->Resources, 0);
1472 PdoExtension->Resources = NULL;
1473 break;
1474 }
1475 }
1476
1477 /* Return success here, even if the device has no assigned resources */
1478 return STATUS_SUCCESS;
1479}
VOID NTAPI PciDebugDumpCommonConfig(IN PPCI_COMMON_HEADER PciData)
Definition: debug.c:207
VOID NTAPI PciWriteLimitsAndRestoreCurrent(IN PVOID Reserved, IN PVOID Context2)
Definition: enum.c:1299
PCI_CONFIGURATOR PciConfigurators[]
Definition: enum.c:20
KIPI_BROADCAST_WORKER PciExecuteCriticalSystemRoutine
Definition: pci.h:1132
#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:2172
NTSTATUS NTAPI KdEnableDebugger(VOID)
Definition: kdapi.c:2161
_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:47
PCI_CONFIGURATOR_SAVE_LIMITS SaveLimits
Definition: pci.h:478
PCI_CONFIGURATOR_INITIALIZE Initialize
Definition: pci.h:476
PCI_CONFIGURATOR_SAVE_CURRENT_SETTINGS SaveCurrentSettings
Definition: pci.h:479
LONG RunCount
Definition: pci.h:512
ULONG Barrier
Definition: pci.h:513
PVOID Context
Definition: pci.h:516
PCI_IPI_FUNCTION Function
Definition: pci.h:515
PVOID DeviceExtension
Definition: pci.h:514
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define PCI_TYPE0_ADDRESSES
Definition: iotypes.h:3500

Referenced by PciGetFunctionLimits().

◆ PcipIsSameDevice()

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

Definition at line 1063 of file enum.c.

1065{
1066 BOOLEAN IdMatch, RevMatch, SubsysMatch;
1067 ULONGLONG HackFlags = DeviceExtension->HackFlags;
1068
1069 /* Check if the IDs match */
1070 IdMatch = (PciData->VendorID == DeviceExtension->VendorId) &&
1071 (PciData->DeviceID == DeviceExtension->DeviceId);
1072 if (!IdMatch) return FALSE;
1073
1074 /* If the device has a valid revision, check if it matches */
1076 (PciData->RevisionID == DeviceExtension->RevisionId);
1077 if (!RevMatch) return FALSE;
1078
1079 /* For multifunction devices, this is enough to assume they're the same */
1080 if (PCI_MULTIFUNCTION_DEVICE(PciData)) return TRUE;
1081
1082 /* For bridge devices, there's also nothing else that can be checked */
1083 if (DeviceExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) return TRUE;
1084
1085 /* Devices, on the other hand, have subsystem data that can be compared */
1086 SubsysMatch = (HackFlags & (PCI_HACK_NO_SUBSYSTEM |
1088 ((DeviceExtension->SubsystemVendorId ==
1089 PciData->u.type0.SubVendorID) &&
1090 (DeviceExtension->SubsystemId ==
1091 PciData->u.type0.SubSystemID));
1092 return SubsysMatch;
1093}
#define PCI_HACK_NO_REVISION_AFTER_D3
Definition: pci.h:50
#define PCI_HACK_NO_SUBSYSTEM_AFTER_D3
Definition: pci.h:41
#define PCI_HACK_NO_SUBSYSTEM
Definition: pci.h:32
uint64_t ULONGLONG
Definition: typedefs.h:67
#define PCI_MULTIFUNCTION_DEVICE(PciData)
Definition: iotypes.h:3612

Referenced by PciScanBus(), and PciSetResources().

◆ PciProcessBus()

VOID NTAPI PciProcessBus ( IN PPCI_FDO_EXTENSION  DeviceExtension)

Definition at line 1519 of file enum.c.

1520{
1523 PAGED_CODE();
1524
1525 /* Get the PDO Extension */
1526 PhysicalDeviceObject = DeviceExtension->PhysicalDeviceObject;
1528
1529 /* Cheeck if this is the root bus */
1530 if (!PCI_IS_ROOT_FDO(DeviceExtension))
1531 {
1532 /* Not really handling this year */
1534
1535 /* Check for PCI bridges with the ISA bit set, or required */
1536 if ((PdoExtension) &&
1538 ((PdoExtension->Dependent.type1.IsaBitRequired) ||
1539 (PdoExtension->Dependent.type1.IsaBitSet)))
1540 {
1541 /* We'll need to do some legacy support */
1543 }
1544 }
1545 else
1546 {
1547 /* Scan all of the root bus' children bridges */
1548 for (PdoExtension = DeviceExtension->ChildBridgePdoList;
1550 PdoExtension = PdoExtension->NextBridge)
1551 {
1552 /* Find any that have the VGA decode bit on */
1553 if (PdoExtension->Dependent.type1.VgaBitSet)
1554 {
1555 /* Again, some more legacy support we'll have to do */
1557 }
1558 }
1559 }
1560
1561 /* Check for ACPI systems where the OS assigns bus numbers */
1563 {
1564 /* Not yet supported */
1566 }
1567}
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:1051
@ PciTypePciBridge
Definition: pci.h:119
if(dx< 0)
Definition: linetemp.h:194
PVOID DeviceExtension
Definition: env_spec_w32.h:418

Referenced by PciScanBus().

◆ PcipUpdateHardware()

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

Definition at line 238 of file enum.c.

240{
243
244 /* Check if we're allowed to disable decodes */
245 PciData->Command = PdoExtension->CommandEnables;
246 if (!(PdoExtension->HackFlags & PCI_HACK_PRESERVE_COMMAND))
247 {
248 /* Disable all decodes */
249 PciData->Command &= ~(PCI_ENABLE_IO_SPACE |
253 }
254
255 /* Update the device configuration */
256 PciData->Status = 0;
258
259 /* Turn decodes back on */
260 PciDecodeEnable(PdoExtension, TRUE, &PdoExtension->CommandEnables);
261}
_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:3620

Referenced by PciUpdateHardware().

◆ PciQueryDeviceRelations()

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

Definition at line 2034 of file enum.c.

2036{
2039 ULONG PdoCount = 0;
2040 PDEVICE_RELATIONS DeviceRelations, NewRelations;
2041 SIZE_T Size;
2042 PDEVICE_OBJECT DeviceObject, *ObjectArray;
2043 PAGED_CODE();
2044
2045 /* Make sure the FDO is started */
2046 ASSERT(DeviceExtension->DeviceState == PciStarted);
2047
2048 /* Synchronize while we enumerate the bus */
2050 if (!NT_SUCCESS(Status)) return Status;
2051
2052 /* Scan all children PDO */
2053 for (PdoExtension = DeviceExtension->ChildPdoList;
2055 PdoExtension = PdoExtension->Next)
2056 {
2057 /* Invalidate them */
2058 PdoExtension->NotPresent = TRUE;
2059 }
2060
2061 /* Scan the PCI Bus */
2062 Status = PciScanBus(DeviceExtension);
2064
2065 /* Enumerate all children PDO again */
2066 for (PdoExtension = DeviceExtension->ChildPdoList;
2068 PdoExtension = PdoExtension->Next)
2069 {
2070 /* Check for PDOs that are still invalidated */
2071 if (PdoExtension->NotPresent)
2072 {
2073 /* This means this PDO existed before, but not anymore */
2074 PdoExtension->ReportedMissing = TRUE;
2075 DPRINT1("PCI - Old device (pdox) %p not found on rescan.\n",
2076 PdoExtension);
2077 }
2078 else
2079 {
2080 /* Increase count of detected PDOs */
2081 PdoCount++;
2082 }
2083 }
2084
2085 /* Read the current relations and add the newly discovered relations */
2086 DeviceRelations = *pDeviceRelations;
2087 Size = FIELD_OFFSET(DEVICE_RELATIONS, Objects) +
2088 PdoCount * sizeof(PDEVICE_OBJECT);
2089 if (DeviceRelations) Size += sizeof(PDEVICE_OBJECT) * DeviceRelations->Count;
2090
2091 /* Allocate the device relations */
2092 NewRelations = (PDEVICE_RELATIONS)ExAllocatePoolWithTag(0, Size, 'BicP');
2093 if (!NewRelations)
2094 {
2095 /* Out of space, cancel the operation */
2098 }
2099
2100 /* Check if there were any older relations */
2101 NewRelations->Count = 0;
2102 if (DeviceRelations)
2103 {
2104 /* Copy the old relations into the new buffer, then free the old one */
2105 RtlCopyMemory(NewRelations,
2106 DeviceRelations,
2107 FIELD_OFFSET(DEVICE_RELATIONS, Objects) +
2108 DeviceRelations->Count * sizeof(PDEVICE_OBJECT));
2109 ExFreePoolWithTag(DeviceRelations, 0);
2110 }
2111
2112 /* Print out that we're ready to dump relations */
2113 DPRINT1("PCI QueryDeviceRelations/BusRelations FDOx %p (bus 0x%02x)\n",
2114 DeviceExtension,
2115 DeviceExtension->BaseBus);
2116
2117 /* Loop the current PDO children and the device relation object array */
2118 PdoExtension = DeviceExtension->ChildPdoList;
2119 ObjectArray = &NewRelations->Objects[NewRelations->Count];
2120 while (PdoExtension)
2121 {
2122 /* Dump this relation */
2123 DPRINT1(" QDR PDO %p (x %p)%s\n",
2124 PdoExtension->PhysicalDeviceObject,
2126 PdoExtension->NotPresent ?
2127 "<Omitted, device flaged not present>" : "");
2128
2129 /* Is this PDO present? */
2130 if (!PdoExtension->NotPresent)
2131 {
2132 /* Reference it and add it to the array */
2133 DeviceObject = PdoExtension->PhysicalDeviceObject;
2135 *ObjectArray++ = DeviceObject;
2136 }
2137
2138 /* Go to the next PDO */
2139 PdoExtension = PdoExtension->Next;
2140 }
2141
2142 /* Terminate dumping the relations */
2143 DPRINT1(" QDR Total PDO count = %u (%u already in list)\n",
2144 NewRelations->Count + PdoCount,
2145 NewRelations->Count);
2146
2147 /* Return the final count and the new buffer */
2148 NewRelations->Count += PdoCount;
2149 *pDeviceRelations = NewRelations;
2150 return STATUS_SUCCESS;
2151}
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS NTAPI PciScanBus(IN PPCI_FDO_EXTENSION DeviceExtension)
Definition: enum.c:1571
@ PciStarted
Definition: pci.h:130
@ PciSynchronizedOperation
Definition: pci.h:134
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:2163
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by PciFdoIrpQueryDeviceRelations().

◆ PciQueryEjectionRelations()

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

Definition at line 538 of file enum.c.

540{
542 UNREFERENCED_PARAMETER(pDeviceRelations);
543
544 /* Not yet implemented */
547}
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42

Referenced by PciPdoIrpQueryDeviceRelations().

◆ PciQueryRequirements()

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

Definition at line 583 of file enum.c.

585{
587 PCI_COMMON_HEADER PciHeader;
588 PAGED_CODE();
589
590 /* Check if the PDO has any resources, or at least an interrupt pin */
591 if ((PdoExtension->Resources) || (PdoExtension->InterruptPin))
592 {
593 /* Read the current PCI header */
595
596 /* Use it to build a list of requirements */
598 if (!NT_SUCCESS(Status)) return Status;
599
600 /* Is this a Compaq PCI Hotplug Controller (r17) on a PAE system ? */
601 if ((PciHeader.VendorID == 0xE11) &&
602 (PciHeader.DeviceID == 0xA0F7) &&
603 (PciHeader.RevisionID == 17) &&
605 {
606 /* Have not tested this on eVb's machine yet */
608 }
609
610 /* Check if the requirements are actually the zero list */
612 {
613 /* A simple NULL will suffice for the PnP Manager */
615 DPRINT1("Returning NULL requirements list\n");
616 }
617 else
618 {
619 /* Otherwise, print out the requirements list */
621 }
622 }
623 else
624 {
625 /* There aren't any resources, so simply return NULL */
626 DPRINT1("PciQueryRequirements returning NULL requirements list\n");
628 }
629
630 /* This call always succeeds (but maybe with no requirements) */
631 return STATUS_SUCCESS;
632}
VOID NTAPI PciDebugPrintIoResReqList(IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements)
Definition: debug.c:302
NTSTATUS NTAPI PciBuildRequirementsList(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData, OUT PIO_RESOURCE_REQUIREMENTS_LIST *Buffer)
Definition: enum.c:551

Referenced by PciPdoIrpQueryResourceRequirements().

◆ PciQueryResources()

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

Definition at line 354 of file enum.c.

356{
357 PPCI_FUNCTION_RESOURCES PciResources;
358 BOOLEAN HaveVga, HaveMemSpace, HaveIoSpace;
359 USHORT BridgeControl, PciCommand;
360 ULONG Count, i;
361 PCM_PARTIAL_RESOURCE_DESCRIPTOR Partial, Resource, LastResource;
363 UCHAR InterruptLine;
364 PAGED_CODE();
365
366 /* Assume failure */
367 Count = 0;
368 HaveVga = FALSE;
369 *Buffer = NULL;
370
371 /* Make sure there's some resources to query */
372 PciResources = PdoExtension->Resources;
373 if (!PciResources) return STATUS_SUCCESS;
374
375 /* Read the decodes */
377 &PciCommand,
379 sizeof(USHORT));
380
381 /* Check which ones are turned on */
382 HaveIoSpace = PciCommand & PCI_ENABLE_IO_SPACE;
383 HaveMemSpace = PciCommand & PCI_ENABLE_MEMORY_SPACE;
384
385 /* Loop maximum possible descriptors */
386 for (i = 0; i < 7; i++)
387 {
388 /* Check if the decode for this descriptor is actually turned on */
389 Partial = &PciResources->Current[i];
390 if (((HaveMemSpace) && (Partial->Type == CmResourceTypeMemory)) ||
391 ((HaveIoSpace) && (Partial->Type == CmResourceTypePort)))
392 {
393 /* One more fully active descriptor */
394 Count++;
395 }
396 }
397
398 /* If there's an interrupt pin associated, check at least one decode is on */
399 if ((PdoExtension->InterruptPin) && ((HaveMemSpace) || (HaveIoSpace)))
400 {
401 /* Read the interrupt line for the pin, add a descriptor if it's valid */
402 InterruptLine = PdoExtension->AdjustedInterruptLine;
403 if ((InterruptLine) && (InterruptLine != -1)) Count++;
404 }
405
406 /* Check for PCI bridge */
407 if (PdoExtension->HeaderType == PCI_BRIDGE_TYPE)
408 {
409 /* Read bridge settings, check if VGA is present */
411 &BridgeControl,
412 FIELD_OFFSET(PCI_COMMON_HEADER, u.type1.BridgeControl),
413 sizeof(USHORT));
414 if (BridgeControl & PCI_ENABLE_BRIDGE_VGA)
415 {
416 /* Remember for later */
417 HaveVga = TRUE;
418
419 /* One memory descriptor for 0xA0000, plus the two I/O port ranges */
420 if (HaveMemSpace) Count++;
421 if (HaveIoSpace) Count += 2;
422 }
423 }
424
425 /* If there's no descriptors in use, there's no resources, so return */
426 if (!Count) return STATUS_SUCCESS;
427
428 /* Allocate a resource list to hold the resources */
430 PdoExtension->ParentFdoExtension->BaseBus);
432
433 /* This is where the descriptors will be copied into */
434 Resource = ResourceList->List[0].PartialResourceList.PartialDescriptors;
435 LastResource = Resource + Count + 1;
436
437 /* Loop maximum possible descriptors */
438 for (i = 0; i < 7; i++)
439 {
440 /* Check if the decode for this descriptor is actually turned on */
441 Partial = &PciResources->Current[i];
442 if (((HaveMemSpace) && (Partial->Type == CmResourceTypeMemory)) ||
443 ((HaveIoSpace) && (Partial->Type == CmResourceTypePort)))
444 {
445 /* Copy the descriptor into the resource list */
446 *Resource++ = *Partial;
447 }
448 }
449
450 /* Check if earlier the code detected this was a PCI bridge with VGA on it */
451 if (HaveVga)
452 {
453 /* Are the memory decodes enabled? */
454 if (HaveMemSpace)
455 {
456 /* Build a memory descriptor for a 128KB framebuffer at 0xA0000 */
458 Resource->u.Generic.Start.HighPart = 0;
460 Resource->u.Generic.Start.LowPart = 0xA0000;
461 Resource->u.Generic.Length = 0x20000;
462 Resource++;
463 }
464
465 /* Are the I/O decodes enabled? */
466 if (HaveIoSpace)
467 {
468 /* Build an I/O descriptor for the graphic ports at 0x3B0 */
471 Resource->u.Port.Start.QuadPart = 0x3B0u;
472 Resource->u.Port.Length = 0xC;
473 Resource++;
474
475 /* Build an I/O descriptor for the graphic ports at 0x3C0 */
478 Resource->u.Port.Start.QuadPart = 0x3C0u;
479 Resource->u.Port.Length = 0x20;
480 Resource++;
481 }
482 }
483
484 /* If there's an interrupt pin associated, check at least one decode is on */
485 if ((PdoExtension->InterruptPin) && ((HaveMemSpace) || (HaveIoSpace)))
486 {
487 /* Read the interrupt line for the pin, check if it's valid */
488 InterruptLine = PdoExtension->AdjustedInterruptLine;
489 if ((InterruptLine) && (InterruptLine != -1))
490 {
491 /* Make sure there's still space */
492 ASSERT(Resource < LastResource);
493
494 /* Add the interrupt descriptor */
497 Resource->ShareDisposition = CmResourceShareShared;
498 Resource->u.Interrupt.Affinity = -1;
499 Resource->u.Interrupt.Level = InterruptLine;
500 Resource->u.Interrupt.Vector = InterruptLine;
501 }
502 }
503
504 /* Return the resource list */
506 return STATUS_SUCCESS;
507}
_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:324
#define CM_RESOURCE_PORT_POSITIVE_DECODE
Definition: cmtypes.h:113
#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
Definition: cmtypes.h:143
#define CM_RESOURCE_MEMORY_READ_WRITE
Definition: cmtypes.h:120
#define CM_RESOURCE_PORT_10_BIT_DECODE
Definition: cmtypes.h:110
#define PCI_ENABLE_BRIDGE_VGA
Definition: pci.h:62
@ CmResourceShareShared
Definition: cmtypes.h:243

Referenced by PciPdoIrpQueryResources().

◆ PciQueryTargetDeviceRelations()

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

Definition at line 511 of file enum.c.

513{
514 PDEVICE_RELATIONS DeviceRelations;
515 PAGED_CODE();
516
517 /* If there were existing relations, free them */
518 if (*pDeviceRelations) ExFreePoolWithTag(*pDeviceRelations, 0);
519
520 /* Allocate a new structure for the relations */
521 DeviceRelations = ExAllocatePoolWithTag(NonPagedPool,
522 sizeof(DEVICE_RELATIONS),
523 'BicP');
524 if (!DeviceRelations) return STATUS_INSUFFICIENT_RESOURCES;
525
526 /* Only one relation: the PDO */
527 DeviceRelations->Count = 1;
528 DeviceRelations->Objects[0] = PdoExtension->PhysicalDeviceObject;
529 ObReferenceObject(DeviceRelations->Objects[0]);
530
531 /* Return the new relations */
532 *pDeviceRelations = DeviceRelations;
533 return STATUS_SUCCESS;
534}

Referenced by PciPdoIrpQueryDeviceRelations().

◆ PciScanBus()

NTSTATUS NTAPI PciScanBus ( IN PPCI_FDO_EXTENSION  DeviceExtension)

Definition at line 1571 of file enum.c.

1572{
1573 ULONG MaxDevice = PCI_MAX_DEVICES;
1574 BOOLEAN ProcessFlag = FALSE;
1575 ULONG i, j, k, Size;
1576 USHORT CapOffset, TempOffset;
1580 UCHAR BiosBuffer[PCI_COMMON_HDR_LENGTH];
1581 PPCI_COMMON_HEADER PciData = (PVOID)Buffer;
1582 PPCI_COMMON_HEADER BiosData = (PVOID)BiosBuffer;
1583 PCI_SLOT_NUMBER PciSlot;
1584 PCHAR Name;
1586 PPCI_PDO_EXTENSION PdoExtension, NewExtension;
1587 PPCI_PDO_EXTENSION* BridgeExtension;
1588 PWCHAR DescriptionText;
1589 USHORT SubVendorId, SubSystemId;
1590 PCI_CAPABILITIES_HEADER CapHeader, PcixCapHeader;
1591 UCHAR SecondaryBus;
1592 DPRINT1("PCI Scan Bus: FDO Extension @ 0x%p, Base Bus = 0x%x\n",
1593 DeviceExtension, DeviceExtension->BaseBus);
1594
1595 /* Is this the root FDO? */
1596 if (!PCI_IS_ROOT_FDO(DeviceExtension))
1597 {
1598 /* Get the PDO for the child bus */
1599 PdoExtension = DeviceExtension->PhysicalDeviceObject->DeviceExtension;
1601
1602 /* Check for hack which only allows bus to have one child device */
1603 if (PdoExtension->HackFlags & PCI_HACK_ONE_CHILD) MaxDevice = 1;
1604
1605 /* Check if the secondary bus number has changed */
1607 &SecondaryBus,
1608 FIELD_OFFSET(PCI_COMMON_HEADER, u.type1.SecondaryBus),
1609 sizeof(UCHAR));
1610 if (SecondaryBus != PdoExtension->Dependent.type1.SecondaryBus)
1611 {
1612 UNIMPLEMENTED_DBGBREAK("PCI: Bus numbers have been changed! Restoring originals.\n");
1613 }
1614 }
1615
1616 /* Loop every device on the bus */
1617 PciSlot.u.bits.Reserved = 0;
1618 i = DeviceExtension->BaseBus;
1619 for (j = 0; j < MaxDevice; j++)
1620 {
1621 /* Loop every function of each device */
1622 PciSlot.u.bits.DeviceNumber = j;
1623 for (k = 0; k < PCI_MAX_FUNCTION; k++)
1624 {
1625 /* Build the final slot structure */
1626 PciSlot.u.bits.FunctionNumber = k;
1627
1628 /* Read the vendor for this slot */
1629 PciReadSlotConfig(DeviceExtension,
1630 PciSlot,
1631 PciData,
1632 0,
1633 sizeof(USHORT));
1634
1635 /* Skip invalid device */
1636 if (PciData->VendorID == PCI_INVALID_VENDORID) continue;
1637
1638 /* Now read the whole header */
1639 PciReadSlotConfig(DeviceExtension,
1640 PciSlot,
1641 &PciData->DeviceID,
1642 sizeof(USHORT),
1643 PCI_COMMON_HDR_LENGTH - sizeof(USHORT));
1644
1645 /* Apply any hacks before even analyzing the configuration header */
1646 PciApplyHacks(DeviceExtension,
1647 PciData,
1648 PciSlot,
1650 NULL);
1651
1652 /* Dump device that was found */
1653 DPRINT1("Scan Found Device 0x%x (b=0x%x, d=0x%x, f=0x%x)\n",
1654 PciSlot.u.AsULONG,
1655 i,
1656 j,
1657 k);
1658
1659 /* Dump the device's header */
1660 PciDebugDumpCommonConfig(PciData);
1661
1662 /* Find description for this device for the debugger's sake */
1663 DescriptionText = PciGetDeviceDescriptionMessage(PciData->BaseClass,
1664 PciData->SubClass);
1665 DPRINT1("Device Description \"%S\".\n",
1666 DescriptionText ? DescriptionText : L"(NULL)");
1667 if (DescriptionText) ExFreePoolWithTag(DescriptionText, 0);
1668
1669 /* Check if there is an ACPI Watchdog Table */
1670 if (WdTable)
1671 {
1672 /* Check if this PCI device is the ACPI Watchdog Device... */
1674 }
1675
1676 /* Check for non-simple devices */
1677 if ((PCI_MULTIFUNCTION_DEVICE(PciData)) ||
1678 (PciData->BaseClass == PCI_CLASS_BRIDGE_DEV))
1679 {
1680 /* No subsystem data defined for these kinds of bridges */
1681 SubVendorId = 0;
1682 SubSystemId = 0;
1683 }
1684 else
1685 {
1686 /* Read the subsystem information from the PCI header */
1687 SubVendorId = PciData->u.type0.SubVendorID;
1688 SubSystemId = PciData->u.type0.SubSystemID;
1689 }
1690
1691 /* Get any hack flags for this device */
1692 HackFlags = PciGetHackFlags(PciData->VendorID,
1693 PciData->DeviceID,
1694 SubVendorId,
1695 SubSystemId,
1696 PciData->RevisionID);
1697
1698 /* Check if this device is considered critical by the OS */
1699 if (PciIsCriticalDeviceClass(PciData->BaseClass, PciData->SubClass))
1700 {
1701 /* Check if normally the decodes would be disabled */
1703 {
1704 /* Because this device is critical, don't disable them */
1705 DPRINT1("Not allowing PM Because device is critical\n");
1707 }
1708 }
1709
1710 /* PCI bridges with a VGA card are also considered critical */
1711 if ((PciData->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
1712 (PciData->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI) &&
1713 (PciData->u.type1.BridgeControl & PCI_ENABLE_BRIDGE_VGA) &&
1715 {
1716 /* Do not disable their decodes either */
1717 DPRINT1("Not allowing PM because device is VGA\n");
1719 }
1720
1721 /* Check if the device should be skipped for whatever reason */
1722 if (PciSkipThisFunction(PciData,
1723 PciSlot,
1725 HackFlags))
1726 {
1727 /* Skip this device */
1728 continue;
1729 }
1730
1731 /* Check if a PDO has already been created for this device */
1732 PdoExtension = PciFindPdoByFunction(DeviceExtension,
1733 PciSlot.u.AsULONG,
1734 PciData);
1735 if (PdoExtension)
1736 {
1737 /* Rescan scenarios are not yet implemented */
1739 }
1740
1741 /* Bus processing will need to happen */
1742 ProcessFlag = TRUE;
1743
1744 /* Create the PDO for this device */
1745 Status = PciPdoCreate(DeviceExtension, PciSlot, &DeviceObject);
1747 NewExtension = (PPCI_PDO_EXTENSION)DeviceObject->DeviceExtension;
1748
1749 /* Check for broken devices with wrong/no class codes */
1751 {
1752 /* Setup a default one */
1753 PciData->BaseClass = PCI_CLASS_BASE_SYSTEM_DEV;
1754 PciData->SubClass = PCI_SUBCLASS_SYS_OTHER;
1755
1756 /* Device will behave erratically when reading back data */
1757 NewExtension->ExpectedWritebackFailure = TRUE;
1758 }
1759
1760 /* Clone all the information from the header */
1761 NewExtension->VendorId = PciData->VendorID;
1762 NewExtension->DeviceId = PciData->DeviceID;
1763 NewExtension->RevisionId = PciData->RevisionID;
1764 NewExtension->ProgIf = PciData->ProgIf;
1765 NewExtension->SubClass = PciData->SubClass;
1766 NewExtension->BaseClass = PciData->BaseClass;
1767 NewExtension->HeaderType = PCI_CONFIGURATION_TYPE(PciData);
1768
1769 /* Check for modern bridge types, which are managed by the driver */
1770 if ((NewExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
1771 ((NewExtension->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI) ||
1772 (NewExtension->SubClass == PCI_SUBCLASS_BR_CARDBUS)))
1773 {
1774 /* Acquire this device's lock */
1776 KeWaitForSingleObject(&DeviceExtension->ChildListLock,
1777 Executive,
1778 KernelMode,
1779 FALSE,
1780 NULL);
1781
1782 /* Scan the bridge list until the first free entry */
1783 for (BridgeExtension = &DeviceExtension->ChildBridgePdoList;
1784 *BridgeExtension;
1785 BridgeExtension = &(*BridgeExtension)->NextBridge);
1786
1787 /* Add this PDO as a bridge */
1788 *BridgeExtension = NewExtension;
1789 ASSERT(NewExtension->NextBridge == NULL);
1790
1791 /* Release this device's lock */
1792 KeSetEvent(&DeviceExtension->ChildListLock,
1794 FALSE);
1796 }
1797
1798 /* Get the PCI BIOS configuration saved in the registry */
1799 Status = PciGetBiosConfig(NewExtension, BiosData);
1800 if (NT_SUCCESS(Status))
1801 {
1802 /* This path has not yet been fully tested by eVb */
1803 DPRINT1("Have BIOS configuration!\n");
1805
1806 /* Check if the PCI BIOS configuration has changed */
1807 if (!PcipIsSameDevice(NewExtension, BiosData))
1808 {
1809 /* This is considered failure, and new data will be saved */
1811 }
1812 else
1813 {
1814 /* Data is still correct, check for interrupt line change */
1815 if (BiosData->u.type0.InterruptLine !=
1816 PciData->u.type0.InterruptLine)
1817 {
1818 /* Update the current BIOS with the saved interrupt line */
1819 PciWriteDeviceConfig(NewExtension,
1820 &BiosData->u.type0.InterruptLine,
1822 u.type0.InterruptLine),
1823 sizeof(UCHAR));
1824 }
1825
1826 /* Save the BIOS interrupt line and the initial command */
1827 NewExtension->RawInterruptLine = BiosData->u.type0.InterruptLine;
1828 NewExtension->InitialCommand = BiosData->Command;
1829 }
1830 }
1831
1832 /* Check if no saved data was present or if it was a mismatch */
1833 if (!NT_SUCCESS(Status))
1834 {
1835 /* Save the new data */
1836 Status = PciSaveBiosConfig(NewExtension, PciData);
1838
1839 /* Save the interrupt line and command from the device */
1840 NewExtension->RawInterruptLine = PciData->u.type0.InterruptLine;
1841 NewExtension->InitialCommand = PciData->Command;
1842 }
1843
1844 /* Save original command from the device and hack flags */
1845 NewExtension->CommandEnables = PciData->Command;
1846 NewExtension->HackFlags = HackFlags;
1847
1848 /* Get power, AGP, and other capability data */
1849 PciGetEnhancedCapabilities(NewExtension, PciData);
1850
1851 /* Now configure the BARs */
1852 Status = PciGetFunctionLimits(NewExtension, PciData, HackFlags);
1853
1854 /* Power up the device */
1856
1857 /* Apply any device hacks required for enumeration */
1858 PciApplyHacks(DeviceExtension,
1859 PciData,
1860 PciSlot,
1862 NewExtension);
1863
1864 /* Save interrupt pin */
1865 NewExtension->InterruptPin = PciData->u.type0.InterruptPin;
1866
1867 /*
1868 * Use either this device's actual IRQ line or, if it's connected on
1869 * a master bus whose IRQ line is actually connected to the host, use
1870 * the HAL to query the bus' IRQ line and store that as the adjusted
1871 * interrupt line instead
1872 */
1873 NewExtension->AdjustedInterruptLine = PciGetAdjustedInterruptLine(NewExtension);
1874
1875 /* Check if this device is used for PCI debugger cards */
1876 NewExtension->OnDebugPath = PciIsDeviceOnDebugPath(NewExtension);
1877
1878 /* Check for devices with invalid/bogus subsystem data */
1880 {
1881 /* Set the subsystem information to zero instead */
1882 NewExtension->SubsystemVendorId = 0;
1883 NewExtension->SubsystemId = 0;
1884 }
1885
1886 /* Scan all capabilities */
1887 CapOffset = NewExtension->CapabilitiesPtr;
1888 while (CapOffset)
1889 {
1890 /* Read this header */
1891 TempOffset = PciReadDeviceCapability(NewExtension,
1892 CapOffset,
1893 0,
1894 &CapHeader,
1895 sizeof(PCI_CAPABILITIES_HEADER));
1896 if (TempOffset != CapOffset)
1897 {
1898 /* This is a strange issue that shouldn't happen normally */
1899 DPRINT1("PCI - Failed to read PCI capability at offset 0x%02x\n",
1900 CapOffset);
1901 ASSERT(TempOffset == CapOffset);
1902 }
1903
1904 /* Check for capabilities that this driver cares about */
1905 switch (CapHeader.CapabilityID)
1906 {
1907 /* Power management capability is heavily used by the bus */
1909
1910 /* Dump the capability */
1911 Name = "POWER";
1912 Size = sizeof(PCI_PM_CAPABILITY);
1913 break;
1914
1915 /* AGP capability is required for AGP bus functionality */
1917
1918 /* Dump the capability */
1919 Name = "AGP";
1920 Size = sizeof(PCI_AGP_CAPABILITY);
1921 break;
1922
1923 /* This driver doesn't really use anything other than that */
1924 default:
1925
1926 /* Windows prints this, we could do a translation later */
1927 Name = "UNKNOWN CAPABILITY";
1928 Size = 0;
1929 break;
1930 }
1931
1932 /* Check if this is a capability that should be dumped */
1933 if (Size)
1934 {
1935 /* Read the whole capability data */
1936 TempOffset = PciReadDeviceCapability(NewExtension,
1937 CapOffset,
1938 CapHeader.CapabilityID,
1939 &CapHeader,
1940 Size);
1941
1942 if (TempOffset != CapOffset)
1943 {
1944 /* Again, a strange issue that shouldn't be seen */
1945 DPRINT1("- Failed to read capability data. ***\n");
1946 ASSERT(TempOffset == CapOffset);
1947 }
1948 }
1949
1950 /* Dump this capability */
1951 DPRINT1("CAP @%02x ID %02x (%s)\n",
1952 CapOffset, CapHeader.CapabilityID, Name);
1953 for (i = 0; i < Size; i += 2)
1954 DPRINT1(" %04x\n", *(PUSHORT)((ULONG_PTR)&CapHeader + i));
1955 DPRINT1("\n");
1956
1957 /* Check the next capability */
1958 CapOffset = CapHeader.Next;
1959 }
1960
1961 /* Check for IDE controllers */
1962 if ((NewExtension->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
1963 (NewExtension->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR))
1964 {
1965 /* Do not allow them to power down completely */
1966 NewExtension->DisablePowerDown = TRUE;
1967 }
1968
1969 /*
1970 * Check if this is a legacy bridge. Note that the i82375 PCI/EISA
1971 * bridge that is present on certain NT Alpha machines appears as
1972 * non-classified so detect it manually by scanning for its VID/PID.
1973 */
1974 if (((NewExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
1975 ((NewExtension->SubClass == PCI_SUBCLASS_BR_ISA) ||
1976 (NewExtension->SubClass == PCI_SUBCLASS_BR_EISA) ||
1977 (NewExtension->SubClass == PCI_SUBCLASS_BR_MCA))) ||
1978 ((NewExtension->VendorId == 0x8086) &&
1979 (NewExtension->DeviceId == 0x482)))
1980 {
1981 /* Do not allow these legacy bridges to be powered down */
1982 NewExtension->DisablePowerDown = TRUE;
1983 }
1984
1985 /* Check if the BIOS did not configure a cache line size */
1986 if (!PciData->CacheLineSize)
1987 {
1988 /* Check if the device is disabled */
1989 if (!(NewExtension->CommandEnables & (PCI_ENABLE_IO_SPACE |
1992 {
1993 /* Check if this is a PCI-X device*/
1994 TempOffset = PciReadDeviceCapability(NewExtension,
1995 NewExtension->CapabilitiesPtr,
1997 &PcixCapHeader,
1998 sizeof(PCI_CAPABILITIES_HEADER));
1999
2000 /*
2001 * A device with default cache line size and latency timer
2002 * settings is considered to be unconfigured. Note that on
2003 * PCI-X, the reset value of the latency timer field in the
2004 * header is 64, not 0, hence why the check for PCI-X caps
2005 * was required, and the value used here below.
2006 */
2007 if (!(PciData->LatencyTimer) ||
2008 ((TempOffset) && (PciData->LatencyTimer == 64)))
2009 {
2010 /* Keep track of the fact that it needs configuration */
2011 DPRINT1("PCI - ScanBus, PDOx %p found unconfigured\n",
2012 NewExtension);
2013 NewExtension->NeedsHotPlugConfiguration = TRUE;
2014 }
2015 }
2016 }
2017
2018 /* Save latency and cache size information */
2019 NewExtension->SavedLatencyTimer = PciData->LatencyTimer;
2020 NewExtension->SavedCacheLineSize = PciData->CacheLineSize;
2021
2022 /* The PDO is now ready to go */
2023 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
2024 }
2025 }
2026
2027 /* Enumeration completed, do a final pass now that all devices are found */
2028 if (ProcessFlag) PciProcessBus(DeviceExtension);
2029 return STATUS_SUCCESS;
2030}
struct NameRec_ * Name
Definition: cdprocs.h:460
VOID NTAPI PciGetEnhancedCapabilities(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: enum.c:1171
VOID NTAPI PciProcessBus(IN PPCI_FDO_EXTENSION DeviceExtension)
Definition: enum.c:1519
BOOLEAN NTAPI PcipIsSameDevice(IN PPCI_PDO_EXTENSION DeviceExtension, IN PPCI_COMMON_HEADER PciData)
Definition: enum.c:1063
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:794
NTSTATUS NTAPI PciGetFunctionLimits(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER Current, IN ULONGLONG HackFlags)
Definition: enum.c:1483
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:123
NTSTATUS NTAPI PciPdoCreate(IN PPCI_FDO_EXTENSION DeviceExtension, IN PCI_SLOT_NUMBER Slot, OUT PDEVICE_OBJECT *PdoDeviceObject)
Definition: pdo.c:530
PWCHAR NTAPI PciGetDeviceDescriptionMessage(IN UCHAR BaseClass, IN UCHAR SubClass)
Definition: id.c:88
NTSTATUS NTAPI PciGetBiosConfig(IN PPCI_PDO_EXTENSION DeviceExtension, OUT PPCI_COMMON_HEADER PciData)
Definition: utils.c:768
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)
Definition: utils.c:751
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:121
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:64
#define ASSERT_PDO(x)
Definition: pci.h:38
#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
int k
Definition: mpi.c:3369
#define KernelMode
Definition: asm.h:34
#define L(x)
Definition: ntvdm.h:50
#define PCI_HACK_ONE_CHILD
Definition: pci.h:23
#define PCI_HACK_DONT_DISABLE_DECODES
Definition: pci.h:40
#define PCI_HACK_FAKE_CLASS_CODE
Definition: pci.h:43
BOOLEAN ProgIf
Definition: pci.h:283
BOOLEAN BaseClass
Definition: pci.h:285
ULONGLONG HackFlags
Definition: pci.h:310
BOOLEAN AdjustedInterruptLine
Definition: pci.h:287
BOOLEAN InterruptPin
Definition: pci.h:288
BOOLEAN RawInterruptLine
Definition: pci.h:289
USHORT SubsystemVendorId
Definition: pci.h:280
USHORT SubsystemId
Definition: pci.h:281
USHORT CommandEnables
Definition: pci.h:318
BOOLEAN SavedCacheLineSize
Definition: pci.h:292
BOOLEAN SavedLatencyTimer
Definition: pci.h:291
USHORT DeviceId
Definition: pci.h:279
struct _PCI_PDO_EXTENSION * NextBridge
Definition: pci.h:313
BOOLEAN HeaderType
Definition: pci.h:293
USHORT InitialCommand
Definition: pci.h:319
BOOLEAN NeedsHotPlugConfiguration
Definition: pci.h:302
BOOLEAN SubClass
Definition: pci.h:284
BOOLEAN CapabilitiesPtr
Definition: pci.h:290
USHORT VendorId
Definition: pci.h:278
BOOLEAN OnDebugPath
Definition: pci.h:306
BOOLEAN DisablePowerDown
Definition: pci.h:301
BOOLEAN ExpectedWritebackFailure
Definition: pci.h:296
BOOLEAN RevisionId
Definition: pci.h:282
struct _PCI_SLOT_NUMBER::@4018::@4019 bits
union _PCI_SLOT_NUMBER::@4018 u
PBIOS_DATA BiosData
Definition: bios.c:42
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:3601
#define PCI_CAPABILITY_ID_PCIX
Definition: iotypes.h:3653
#define IO_NO_INCREMENT
Definition: iotypes.h:598
struct _PCI_AGP_CAPABILITY PCI_AGP_CAPABILITY
#define PCI_SUBCLASS_SYS_OTHER
Definition: iotypes.h:4184
#define PCI_SUBCLASS_BR_MCA
Definition: iotypes.h:4164
#define PCI_MAX_FUNCTION
Definition: iotypes.h:3599
struct _PCI_PM_CAPABILITY PCI_PM_CAPABILITY
#define PCI_SUBCLASS_BR_CARDBUS
Definition: iotypes.h:4168
#define PCI_CLASS_BASE_SYSTEM_DEV
Definition: iotypes.h:4111
#define PCI_MAX_DEVICES
Definition: iotypes.h:3598
@ Executive
Definition: ketypes.h:415

Referenced by PciQueryDeviceRelations().

◆ PciSetResources()

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

Definition at line 2155 of file enum.c.

2158{
2160 UCHAR NewCacheLineSize, NewLatencyTimer;
2161 PCI_COMMON_HEADER PciData;
2163 PPCI_CONFIGURATOR Configurator;
2164
2165 UNREFERENCED_PARAMETER(SomethingSomethingDarkSide);
2166
2167 /* Get the FDO and read the configuration data */
2168 FdoExtension = PdoExtension->ParentFdoExtension;
2170
2171 /* Make sure this is still the same device */
2172 if (!PcipIsSameDevice(PdoExtension, &PciData))
2173 {
2174 /* Fail */
2175 ASSERTMSG("PCI Set resources - not same device.\n", FALSE);
2177 }
2178
2179 /* Nothing to set for a host bridge */
2180 if ((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
2181 (PdoExtension->SubClass == PCI_SUBCLASS_BR_HOST))
2182 {
2183 /* Fake success */
2184 return STATUS_SUCCESS;
2185 }
2186
2187 /* Check if an IDE controller is being reset */
2188 if ((DoReset) &&
2189 (PdoExtension->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
2191 {
2192 /* Turn off native mode */
2194 ASSERT(Native == PdoExtension->IDEInNativeMode);
2195 }
2196
2197 /* Check for update of a hotplug device, or first configuration of one */
2198 if ((PdoExtension->NeedsHotPlugConfiguration) &&
2199 (FdoExtension->HotPlugParameters.Acquired))
2200 {
2201 /* Don't have hotplug devices to test with yet, QEMU 0.14 should */
2203 }
2204
2205 /* Locate the correct resource configurator for this type of device */
2206 Configurator = &PciConfigurators[PdoExtension->HeaderType];
2207
2208 /* Apply the settings change */
2209 Configurator->ChangeResourceSettings(PdoExtension, &PciData);
2210
2211 /* Assume no update needed */
2212 PdoExtension->UpdateHardware = FALSE;
2213
2214 /* Check if a reset is needed */
2215 if (DoReset)
2216 {
2217 /* Reset resources */
2218 Configurator->ResetDevice(PdoExtension, &PciData);
2219 PciData.u.type0.InterruptLine = PdoExtension->RawInterruptLine;
2220 }
2221
2222 /* Check if the latency timer changed */
2223 NewLatencyTimer = PdoExtension->SavedLatencyTimer;
2224 if (PciData.LatencyTimer != NewLatencyTimer)
2225 {
2226 /* Debug notification */
2227 DPRINT1("PCI (pdox %p) changing latency from %02x to %02x.\n",
2229 PciData.LatencyTimer,
2230 NewLatencyTimer);
2231 }
2232
2233 /* Check if the cache line changed */
2234 NewCacheLineSize = PdoExtension->SavedCacheLineSize;
2235 if (PciData.CacheLineSize != NewCacheLineSize)
2236 {
2237 /* Debug notification */
2238 DPRINT1("PCI (pdox %p) changing cache line size from %02x to %02x.\n",
2240 PciData.CacheLineSize,
2241 NewCacheLineSize);
2242 }
2243
2244 /* Inherit data from PDO extension */
2245 PciData.LatencyTimer = PdoExtension->SavedLatencyTimer;
2246 PciData.CacheLineSize = PdoExtension->SavedCacheLineSize;
2247 PciData.u.type0.InterruptLine = PdoExtension->RawInterruptLine;
2248
2249 /* Apply any resource hacks required */
2251 &PciData,
2252 PdoExtension->Slot,
2254 PdoExtension);
2255
2256 /* Check if I/O space was disabled by administrator or driver */
2257 if (PdoExtension->IoSpaceNotRequired)
2258 {
2259 /* Don't turn on the decode */
2260 PdoExtension->CommandEnables &= ~PCI_ENABLE_IO_SPACE;
2261 }
2262
2263 /* Update the device with the new settings */
2265
2266 /* Update complete */
2267 PdoExtension->RawInterruptLine = PciData.u.type0.InterruptLine;
2268 PdoExtension->NeedsHotPlugConfiguration = FALSE;
2269 return STATUS_SUCCESS;
2270}
VOID NTAPI PciUpdateHardware(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: enum.c:265
@ FdoExtension
Definition: precomp.h:48
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:428
PCI_CONFIGURATOR_CHANGE_RESOURCE_SETTINGS ChangeResourceSettings
Definition: pci.h:480
PCI_CONFIGURATOR_RESET_DEVICE ResetDevice
Definition: pci.h:482

Referenced by PciAssignSlotResources(), and PciPdoIrpStartDevice().

◆ PciSkipThisFunction()

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

Definition at line 1097 of file enum.c.

1101{
1102 do
1103 {
1104 /* Check if this is device enumeration */
1105 if (OperationType == PCI_SKIP_DEVICE_ENUMERATION)
1106 {
1107 /* Check if there's a hackflag saying not to enumerate this device */
1109
1110 /* Check if this is the high end of a double decker device */
1112 (Slot.u.bits.DeviceNumber >= 16))
1113 {
1114 /* It belongs to the same device, so skip it */
1115 DPRINT1(" Device (Ven %04x Dev %04x (d=0x%x, f=0x%x)) is a ghost.\n",
1116 PciData->VendorID,
1117 PciData->DeviceID,
1118 Slot.u.bits.DeviceNumber,
1119 Slot.u.bits.FunctionNumber);
1120 break;
1121 }
1122 }
1123 else if (OperationType == PCI_SKIP_RESOURCE_ENUMERATION)
1124 {
1125 /* Resource enumeration, check for a hackflag saying not to do it */
1127 }
1128 else
1129 {
1130 /* Logic error in the driver */
1131 ASSERTMSG("PCI Skip Function - Operation type unknown.\n", FALSE);
1132 }
1133
1134 /* Check for legacy bridges during resource enumeration */
1135 if ((PciData->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
1136 (PciData->SubClass <= PCI_SUBCLASS_BR_MCA) &&
1137 (OperationType == PCI_SKIP_RESOURCE_ENUMERATION))
1138 {
1139 /* Their resources are not enumerated, only PCI and Cardbus/PCMCIA */
1140 break;
1141 }
1142 else if (PciData->BaseClass == PCI_CLASS_NOT_DEFINED)
1143 {
1144 /* Undefined base class (usually a PCI BIOS/ROM bug) */
1145 DPRINT1(" Vendor %04x, Device %04x has class code of PCI_CLASS_NOT_DEFINED\n",
1146 PciData->VendorID,
1147 PciData->DeviceID);
1148
1149 /*
1150 * The Alder has an Intel Extended Express System Support Controller
1151 * which presents apparently spurious BARs. When the PCI resource
1152 * code tries to reassign these BARs, the second IO-APIC gets
1153 * disabled (with disastrous consequences). The first BAR is the
1154 * actual IO-APIC, the remaining five bars seem to be spurious
1155 * resources, so ignore this device completely.
1156 */
1157 if ((PciData->VendorID == 0x8086) && (PciData->DeviceID == 8)) break;
1158 }
1159
1160 /* Other normal PCI cards and bridges are enumerated */
1162 } while (FALSE);
1163
1164 /* Hit one of the known bugs/hackflags, or this is a new kind of PCI unit */
1165 DPRINT1(" Device skipped (not enumerated).\n");
1166 return TRUE;
1167}
#define PCI_HACK_ENUM_NO_RESOURCE
Definition: pci.h:14
#define PCI_HACK_NO_ENUM_AT_ALL
Definition: pci.h:13
#define PCI_HACK_DOUBLE_DECKER
Definition: pci.h:22
#define PCI_CLASS_NOT_DEFINED
Definition: iotypes.h:4121

Referenced by PciGetFunctionLimits(), and PciScanBus().

◆ PciUpdateHardware()

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

Definition at line 265 of file enum.c.

267{
269
270 /* Check for critical devices and PCI Debugging devices */
271 if ((PdoExtension->HackFlags & PCI_HACK_CRITICAL_DEVICE) ||
272 (PdoExtension->OnDebugPath))
273 {
274 /* Build the context and send an IPI */
275 Context.RunCount = 1;
276 Context.Barrier = 1;
277 Context.Context = PciData;
278 Context.Function = PcipUpdateHardware;
279 Context.DeviceExtension = PdoExtension;
281 }
282 else
283 {
284 /* Just to the update inline */
286 }
287}
VOID NTAPI PcipUpdateHardware(IN PVOID Context, IN PVOID Context2)
Definition: enum.c:238

Referenced by PciSetResources().

◆ PciWriteLimitsAndRestoreCurrent()

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

Definition at line 1299 of file enum.c.

1301{
1303 PPCI_COMMON_HEADER PciData, Current;
1305
1307
1308 /* Grab all parameters from the context */
1309 PdoExtension = Context->PdoExtension;
1310 Current = Context->Current;
1311 PciData = Context->PciData;
1312
1313 /* Write the limit discovery header */
1315
1316 /* Now read what the device indicated the limits are */
1318
1319 /* Then write back the original configuration header */
1321
1322 /* Copy back the original command that was saved in the context */
1323 Current->Command = Context->Command;
1324 if (Context->Command)
1325 {
1326 /* Program it back into the device */
1328 &Context->Command,
1330 sizeof(USHORT));
1331 }
1332
1333 /* Copy back the original status that was saved as well */
1334 Current->Status = Context->Status;
1335
1336 /* Call the configurator to restore any other data that might've changed */
1337 Context->Configurator->RestoreCurrent(Context);
1338}
_Reserved_ PVOID Reserved
Definition: winddi.h:3974

Referenced by PcipGetFunctionLimits().

Variable Documentation

◆ PciConfigurators

PCI_CONFIGURATOR PciConfigurators[]
Initial value:
=
{
{
},
{
},
{
}
}
VOID NTAPI Cardbus_SaveCurrentSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: cardbus.c:35
VOID NTAPI Cardbus_MassageHeaderForLimitsDetermination(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: cardbus.c:51
VOID NTAPI Cardbus_RestoreCurrent(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: cardbus.c:59
VOID NTAPI Cardbus_ChangeResourceSettings(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: cardbus.c:89
VOID NTAPI Cardbus_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: cardbus.c:43
VOID NTAPI Cardbus_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: cardbus.c:79
VOID NTAPI Cardbus_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context, IN PPCI_COMMON_HEADER PciData, IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
Definition: cardbus.c:67
VOID NTAPI Device_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context, IN PPCI_COMMON_HEADER PciData, IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
Definition: device.c:259
VOID NTAPI Device_ChangeResourceSettings(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: device.c:283
VOID NTAPI Device_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: device.c:118
VOID NTAPI Device_MassageHeaderForLimitsDetermination(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: device.c:218
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:272
VOID NTAPI Device_RestoreCurrent(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: device.c:250
VOID NTAPI PPBridge_SaveCurrentSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:225
VOID NTAPI PPBridge_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context, IN PPCI_COMMON_HEADER PciData, IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
Definition: ppbridge.c:628
VOID NTAPI PPBridge_RestoreCurrent(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:620
VOID NTAPI PPBridge_MassageHeaderForLimitsDetermination(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:582
VOID NTAPI PPBridge_ChangeResourceSettings(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: ppbridge.c:683
VOID NTAPI PPBridge_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:465
VOID NTAPI PPBridge_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: ppbridge.c:673

Definition at line 20 of file enum.c.

Referenced by PcipGetFunctionLimits(), and PciSetResources().

◆ PciZeroIoResourceRequirements

PIO_RESOURCE_REQUIREMENTS_LIST PciZeroIoResourceRequirements

Definition at line 18 of file enum.c.

Referenced by PciBuildRequirementsList(), and PciQueryRequirements().