ReactOS 0.4.16-dev-2613-g9533ad7
enum.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS PCI Bus Driver
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/bus/pci/enum.c
5 * PURPOSE: PCI Bus/Device Enumeration
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include <pci.h>
12
13#define NDEBUG
14#include <debug.h>
15
16/* GLOBALS ********************************************************************/
17
19
21{
22 {
30 },
31 {
39 },
40 {
48 }
49};
50
51/* FUNCTIONS ******************************************************************/
52
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 /*
117 * Skip legacy/shared resources (e.g., VGA ports 0x3B0-0x3DF, memory 0xA0000).
118 * should not be placed in the ResourceArray.
119 */
121 {
122 break;
123 }
124
125 /* Set it as the base */
126 ASSERT(BaseResource == NULL);
127 BaseResource = Partial;
128 break;
129 }
130 /* Interrupt resource */
132
133 /* Make sure it's a compatible (and the only) PCI interrupt */
134 ASSERT(InterruptResource == NULL);
135 ASSERT(Partial->u.Interrupt.Level == Partial->u.Interrupt.Vector);
136 InterruptResource = Partial;
137
138 /* Only 255 interrupts on x86/x64 hardware */
139 if (Partial->u.Interrupt.Level < 256)
140 {
141 /* Use the passed interrupt line */
142 PdoExtension->AdjustedInterruptLine = Partial->u.Interrupt.Level;
143 }
144 else
145 {
146 /* Invalid vector, so ignore it */
147 PdoExtension->AdjustedInterruptLine = 0;
148 }
149
150 break;
151
152 /* Check for specific device data */
154
155 /* Check what kind of data this was */
156 switch (Partial->u.DevicePrivate.Data[0])
157 {
158 /* Not used in the driver yet */
159 case 1:
161 break;
162
163 /* Not used in the driver yet */
164 case 2:
166 break;
167
168 /* A drain request */
169 case 3:
170 /* Shouldn't be a base resource, this is a drain */
171 ASSERT(BaseResource == NULL);
172 DrainPartial = Partial->u.DevicePrivate.Data[1];
173 ASSERT(DrainPartial == TRUE);
174 break;
175 }
176 break;
177 }
178
179 /* Move to the next descriptor */
180 Partial = CmiGetNextPartialDescriptor(Partial);
181 }
182
183 /* We should be starting a new list now */
184 ASSERT(BaseResource == NULL);
185 FullList = (PVOID)Partial;
186 }
187
188 /* Check the current assigned PCI resources */
189 PciResources = PdoExtension->Resources;
190 if (!PciResources) return FALSE;
191
192 //if... // MISSING CODE
194 DPRINT1("Missing sanity checking code!\n");
195
196 /* Loop all the PCI function resources */
197 for (i = 0; i < 7; i++)
198 {
199 /* Get the current function resource descriptor, and the new one */
200 CurrentDescriptor = &PciResources->Current[i];
201 Partial = &ResourceArray[i];
202
203 /* Previous is current during the first loop iteration */
204 PreviousDescriptor = &PciResources->Current[(i == 0) ? (0) : (i - 1)];
205
206 /* Check if this new descriptor is different than the old one */
207 if (((Partial->Type != CurrentDescriptor->Type) ||
208 (Partial->Type != CmResourceTypeNull)) &&
209 ((Partial->u.Generic.Start.QuadPart !=
210 CurrentDescriptor->u.Generic.Start.QuadPart) ||
211 (Partial->u.Generic.Length != CurrentDescriptor->u.Generic.Length)))
212 {
213 /* Record a change */
214 RangeChange = TRUE;
215
216 /* Was there a range before? */
217 if (CurrentDescriptor->Type != CmResourceTypeNull)
218 {
219 /* Print it */
220 DbgPrint(" Old range-\n");
221 PciDebugPrintPartialResource(CurrentDescriptor);
222 }
223 else
224 {
225 /* There was no range */
226 DbgPrint(" Previously unset range\n");
227 }
228
229 /* Print new one */
230 DbgPrint(" changed to\n");
232
233 /* Update to new range */
234 CurrentDescriptor->Type = Partial->Type;
235 PreviousDescriptor->u.Generic.Start = Partial->u.Generic.Start;
236 PreviousDescriptor->u.Generic.Length = Partial->u.Generic.Length;
237 CurrentDescriptor = PreviousDescriptor;
238 }
239 }
240
241 /* Either the hardware was updated, or a resource range changed */
242 return ((RangeChange) || (PdoExtension->UpdateHardware));
243}
244
245VOID
246NTAPI
249{
252
253 /* Check if we're allowed to disable decodes */
254 PciData->Command = PdoExtension->CommandEnables;
255 if (!(PdoExtension->HackFlags & PCI_HACK_PRESERVE_COMMAND))
256 {
257 /* Disable all decodes */
258 PciData->Command &= ~(PCI_ENABLE_IO_SPACE |
262 }
263
264 /* Update the device configuration */
265 PciData->Status = 0;
267
268 /* Turn decodes back on */
269 PciDecodeEnable(PdoExtension, TRUE, &PdoExtension->CommandEnables);
270}
271
272VOID
273NTAPI
275 IN PPCI_COMMON_HEADER PciData)
276{
278
279 /* Check for critical devices and PCI Debugging devices */
280 if ((PdoExtension->HackFlags & PCI_HACK_CRITICAL_DEVICE) ||
281 (PdoExtension->OnDebugPath))
282 {
283 /* Build the context and send an IPI */
284 Context.RunCount = 1;
285 Context.Barrier = 1;
286 Context.Context = PciData;
287 Context.Function = PcipUpdateHardware;
288 Context.DeviceExtension = PdoExtension;
290 }
291 else
292 {
293 /* Just to the update inline */
295 }
296}
297
299NTAPI
303{
304 SIZE_T Size;
306
307 /* Calculate the final size of the list, including each descriptor */
309 if (Count > 1) Size = sizeof(IO_RESOURCE_DESCRIPTOR) * (Count - 1) +
311
312 /* Allocate the list */
314 if (!RequirementsList) return NULL;
315
316 /* Initialize it */
318 RequirementsList->AlternativeLists = 1;
319 RequirementsList->BusNumber = BusNumber;
320 RequirementsList->SlotNumber = SlotNumber;
321 RequirementsList->InterfaceType = PCIBus;
322 RequirementsList->ListSize = Size;
323 RequirementsList->List[0].Count = Count;
324 RequirementsList->List[0].Version = 1;
325 RequirementsList->List[0].Revision = 1;
326
327 /* Return it */
328 return RequirementsList;
329}
330
332NTAPI
335{
336 SIZE_T Size;
338
339 /* Calculate the final size of the list, including each descriptor */
340 Size = sizeof(CM_RESOURCE_LIST);
341 if (Count > 1) Size = sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR) * (Count - 1) +
342 sizeof(CM_RESOURCE_LIST);
343
344 /* Allocate the list */
346 if (!ResourceList) return NULL;
347
348 /* Initialize it */
350 ResourceList->Count = 1;
351 ResourceList->List[0].BusNumber = BusNumber;
352 ResourceList->List[0].InterfaceType = PCIBus;
353 ResourceList->List[0].PartialResourceList.Version = 1;
354 ResourceList->List[0].PartialResourceList.Revision = 1;
355 ResourceList->List[0].PartialResourceList.Count = Count;
356
357 /* Return it */
358 return ResourceList;
359}
360
362NTAPI
365{
366 PPCI_FUNCTION_RESOURCES PciResources;
367 BOOLEAN HaveVga, HaveMemSpace, HaveIoSpace;
368 USHORT BridgeControl, PciCommand;
369 ULONG Count, i;
370 PCM_PARTIAL_RESOURCE_DESCRIPTOR Partial, Resource, LastResource;
372 UCHAR InterruptLine;
373 PAGED_CODE();
374
375 /* Assume failure */
376 Count = 0;
377 HaveVga = FALSE;
378 *Buffer = NULL;
379
380 /* Make sure there's some resources to query */
381 PciResources = PdoExtension->Resources;
382 if (!PciResources) return STATUS_SUCCESS;
383
384 /* Read the decodes */
386 &PciCommand,
388 sizeof(USHORT));
389
390 /* Check which ones are turned on */
391 HaveIoSpace = PciCommand & PCI_ENABLE_IO_SPACE;
392 HaveMemSpace = PciCommand & PCI_ENABLE_MEMORY_SPACE;
393
394 /* Loop maximum possible descriptors */
395 for (i = 0; i < 7; i++)
396 {
397 /* Check if the decode for this descriptor is actually turned on */
398 Partial = &PciResources->Current[i];
399 if (((HaveMemSpace) && (Partial->Type == CmResourceTypeMemory)) ||
400 ((HaveIoSpace) && (Partial->Type == CmResourceTypePort)))
401 {
402 /* One more fully active descriptor */
403 Count++;
404 }
405 }
406
407 /* If there's an interrupt pin associated, check at least one decode is on */
408 if ((PdoExtension->InterruptPin) && ((HaveMemSpace) || (HaveIoSpace)))
409 {
410 /* Read the interrupt line for the pin, add a descriptor if it's valid */
411 InterruptLine = PdoExtension->AdjustedInterruptLine;
412 if ((InterruptLine) && (InterruptLine != -1)) Count++;
413 }
414
415 /* Check for PCI bridge */
416 if (PdoExtension->HeaderType == PCI_BRIDGE_TYPE)
417 {
418 /* Read bridge settings, check if VGA is present */
420 &BridgeControl,
421 FIELD_OFFSET(PCI_COMMON_HEADER, u.type1.BridgeControl),
422 sizeof(USHORT));
423 if (BridgeControl & PCI_ENABLE_BRIDGE_VGA)
424 {
425 /* Remember for later */
426 HaveVga = TRUE;
427
428 /* One memory descriptor for 0xA0000, plus the two I/O port ranges */
429 if (HaveMemSpace) Count++;
430 if (HaveIoSpace) Count += 2;
431 }
432 }
433
434 /* If there's no descriptors in use, there's no resources, so return */
435 if (!Count) return STATUS_SUCCESS;
436
437 /* Allocate a resource list to hold the resources */
439 PdoExtension->ParentFdoExtension->BaseBus);
441
442 /* This is where the descriptors will be copied into */
443 Resource = ResourceList->List[0].PartialResourceList.PartialDescriptors;
444 LastResource = Resource + Count + 1;
445
446 /* Loop maximum possible descriptors */
447 for (i = 0; i < 7; i++)
448 {
449 /* Check if the decode for this descriptor is actually turned on */
450 Partial = &PciResources->Current[i];
451 if (((HaveMemSpace) && (Partial->Type == CmResourceTypeMemory)) ||
452 ((HaveIoSpace) && (Partial->Type == CmResourceTypePort)))
453 {
454 /* Copy the descriptor into the resource list */
455 *Resource++ = *Partial;
456 }
457 }
458
459 /* Check if earlier the code detected this was a PCI bridge with VGA on it */
460 if (HaveVga)
461 {
462 /* Are the memory decodes enabled? */
463 if (HaveMemSpace)
464 {
465 /* Build a memory descriptor for a 128KB framebuffer at 0xA0000 */
467 Resource->u.Generic.Start.HighPart = 0;
469 Resource->u.Generic.Start.LowPart = 0xA0000;
470 Resource->u.Generic.Length = 0x20000;
471 Resource++;
472 }
473
474 /* Are the I/O decodes enabled? */
475 if (HaveIoSpace)
476 {
477 /* Build an I/O descriptor for the graphic ports at 0x3B0 */
480 Resource->u.Port.Start.QuadPart = 0x3B0u;
481 Resource->u.Port.Length = 0xC;
482 Resource++;
483
484 /* Build an I/O descriptor for the graphic ports at 0x3C0 */
487 Resource->u.Port.Start.QuadPart = 0x3C0u;
488 Resource->u.Port.Length = 0x20;
489 Resource++;
490 }
491 }
492
493 /* If there's an interrupt pin associated, check at least one decode is on */
494 if ((PdoExtension->InterruptPin) && ((HaveMemSpace) || (HaveIoSpace)))
495 {
496 /* Read the interrupt line for the pin, check if it's valid */
497 InterruptLine = PdoExtension->AdjustedInterruptLine;
498 if ((InterruptLine) && (InterruptLine != -1))
499 {
500 /* Make sure there's still space */
501 ASSERT(Resource < LastResource);
502
503 /* Add the interrupt descriptor */
506 Resource->ShareDisposition = CmResourceShareShared;
507 Resource->u.Interrupt.Affinity = -1;
508 Resource->u.Interrupt.Level = InterruptLine;
509 Resource->u.Interrupt.Vector = InterruptLine;
510 }
511 }
512
513 /* Return the resource list */
515 return STATUS_SUCCESS;
516}
517
519NTAPI
521 IN OUT PDEVICE_RELATIONS *pDeviceRelations)
522{
523 PDEVICE_RELATIONS DeviceRelations;
524 PAGED_CODE();
525
526 /* If there were existing relations, free them */
527 if (*pDeviceRelations) ExFreePoolWithTag(*pDeviceRelations, 0);
528
529 /* Allocate a new structure for the relations */
530 DeviceRelations = ExAllocatePoolWithTag(NonPagedPool,
531 sizeof(DEVICE_RELATIONS),
532 'BicP');
533 if (!DeviceRelations) return STATUS_INSUFFICIENT_RESOURCES;
534
535 /* Only one relation: the PDO */
536 DeviceRelations->Count = 1;
537 DeviceRelations->Objects[0] = PdoExtension->PhysicalDeviceObject;
538 ObReferenceObject(DeviceRelations->Objects[0]);
539
540 /* Return the new relations */
541 *pDeviceRelations = DeviceRelations;
542 return STATUS_SUCCESS;
543}
544
546NTAPI
548 IN OUT PDEVICE_RELATIONS *pDeviceRelations)
549{
551 UNREFERENCED_PARAMETER(pDeviceRelations);
552
553 /* Not yet implemented */
556}
557
559NTAPI
561 IN PPCI_COMMON_HEADER PciData,
563{
565
567 UNREFERENCED_PARAMETER(PciData);
568
569 {
570 /* There aren't, so use the zero descriptor */
572
573 /* Does it actually exist yet? */
575 {
576 /* Allocate it, and use it for future use */
580 }
581
582 /* Return the zero requirements list to the caller */
584 DPRINT1("PCI - build resource reqs - early out, 0 resources\n");
585 return STATUS_SUCCESS;
586 }
587 return STATUS_SUCCESS;
588}
589
591NTAPI
594{
596 PCI_COMMON_HEADER PciHeader;
597 PAGED_CODE();
598
599 /* Check if the PDO has any resources, or at least an interrupt pin */
600 if ((PdoExtension->Resources) || (PdoExtension->InterruptPin))
601 {
602 /* Read the current PCI header */
604
605 /* Use it to build a list of requirements */
607 if (!NT_SUCCESS(Status)) return Status;
608
609 /* Is this a Compaq PCI Hotplug Controller (r17) on a PAE system ? */
610 if ((PciHeader.VendorID == 0xE11) &&
611 (PciHeader.DeviceID == 0xA0F7) &&
612 (PciHeader.RevisionID == 17) &&
614 {
615 /* Have not tested this on eVb's machine yet */
617 }
618
619 /* Check if the requirements are actually the zero list */
621 {
622 /* A simple NULL will suffice for the PnP Manager */
624 DPRINT1("Returning NULL requirements list\n");
625 }
626 else
627 {
628 /* Otherwise, print out the requirements list */
630 }
631 }
632 else
633 {
634 /* There aren't any resources, so simply return NULL */
635 DPRINT1("PciQueryRequirements returning NULL requirements list\n");
637 }
638
639 /* This call always succeeds (but maybe with no requirements) */
640 return STATUS_SUCCESS;
641}
642
643/*
644 * 7. The IO/MEM/Busmaster decodes are disabled for the device.
645 * 8. The PCI bus driver sets the operating mode bits of the Programming
646 * Interface byte to switch the controller to native mode.
647 *
648 * Important: When the controller is set to native mode, it must quiet itself
649 * and must not decode I/O resources or generate interrupts until the operating
650 * system has enabled the ports in the PCI configuration header.
651 * The IO/MEM/BusMaster bits will be disabled before the mode change, but it
652 * is not possible to disable interrupts on the device. The device must not
653 * generate interrupts (either legacy or native mode) while the decodes are
654 * disabled in the command register.
655 *
656 * This operation is expected to be instantaneous and the operating system does
657 * not stall afterward. It is also expected that the interrupt pin register in
658 * the PCI Configuration space for this device is accurate. The operating system
659 * re-reads this data after previously ignoring it.
660 */
662NTAPI
664 IN PPCI_COMMON_HEADER PciData,
665 IN BOOLEAN Initial)
666{
667 UCHAR MasterMode, SlaveMode, MasterFixed, SlaveFixed, ProgIf, NewProgIf;
668 BOOLEAN Switched;
670
671 /* Assume it won't work */
672 Switched = FALSE;
673
674 /* Get master and slave current settings, and programmability flag */
675 ProgIf = PciData->ProgIf;
676 MasterMode = (ProgIf & 1) == 1;
677 MasterFixed = (ProgIf & 2) == 0;
678 SlaveMode = (ProgIf & 4) == 4;
679 SlaveFixed = (ProgIf & 8) == 0;
680
681 /*
682 * [..] In order for Windows XP SP1 and Windows Server 2003 to switch an ATA
683 * ATA controller from compatible mode to native mode, the following must be
684 * true:
685 *
686 * - The controller must indicate in its programming interface that both channels
687 * can be switched to native mode. Windows XP SP1 and Windows Server 2003 do
688 * not support switching only one IDE channel to native mode. See the PCI IDE
689 * Controller Specification Revision 1.0 for details.
690 */
691 if ((MasterMode != SlaveMode) || (MasterFixed != SlaveFixed))
692 {
693 /* Windows does not support this configuration, fail */
694 DPRINT1("PCI: Warning unsupported IDE controller configuration for VEN_%04x&DEV_%04x!",
695 PdoExtension->VendorId,
696 PdoExtension->DeviceId);
697 return Switched;
698 }
699
700 /* Check if the controller is already in native mode */
701 if ((MasterMode) && (SlaveMode))
702 {
703 /* Check if I/O decodes should be disabled */
704 if ((Initial) || (PdoExtension->IoSpaceUnderNativeIdeControl))
705 {
706 /* Read the current command */
708 &Command,
710 sizeof(USHORT));
711
712 /* Disable I/O space decode */
713 Command &= ~PCI_ENABLE_IO_SPACE;
714
715 /* Update new command in PCI IDE controller */
717 &Command,
719 sizeof(USHORT));
720
721 /* Save updated command value */
722 PciData->Command = Command;
723 }
724
725 /* The controller is now in native mode */
726 Switched = TRUE;
727 }
728 else if (!(MasterFixed) &&
729 !(SlaveFixed) &&
730 (PdoExtension->BIOSAllowsIDESwitchToNativeMode) &&
732 {
733 /* Turn off decodes */
735
736 /* Update the current command */
738 &PciData->Command,
740 sizeof(USHORT));
741
742 /* Enable native mode */
743 ProgIf = PciData->ProgIf | 5;
745 &ProgIf,
747 sizeof(UCHAR));
748
749 /* Verify the setting "stuck" */
751 &NewProgIf,
753 sizeof(UCHAR));
754 if (NewProgIf == ProgIf)
755 {
756 /* Update the header and PDO data with the new programming mode */
757 PciData->ProgIf = ProgIf;
758 PdoExtension->ProgIf = NewProgIf;
759
760 /* Clear the first four BARs to reset current BAR settings */
761 PciData->u.type0.BaseAddresses[0] = 0;
762 PciData->u.type0.BaseAddresses[1] = 0;
763 PciData->u.type0.BaseAddresses[2] = 0;
764 PciData->u.type0.BaseAddresses[3] = 0;
766 PciData->u.type0.BaseAddresses,
768 u.type0.BaseAddresses),
769 4 * sizeof(ULONG));
770
771 /* Re-read the BARs to have the latest data for native mode IDE */
773 PciData->u.type0.BaseAddresses,
775 u.type0.BaseAddresses),
776 4 * sizeof(ULONG));
777
778 /* Re-read the interrupt pin used for native mode IDE */
780 &PciData->u.type0.InterruptPin,
782 u.type0.InterruptPin),
783 sizeof(UCHAR));
784
785 /* The IDE Controller is now in native mode */
786 Switched = TRUE;
787 }
788 else
789 {
790 /* Settings did not work, fail */
791 DPRINT1("PCI: Warning failed switch to native mode for IDE controller VEN_%04x&DEV_%04x!",
792 PciData->VendorID,
793 PciData->DeviceID);
794 }
795 }
796
797 /* Return whether or not native mode was enabled on the IDE controller */
798 return Switched;
799}
800
801VOID
802NTAPI
804 IN PPCI_COMMON_HEADER PciData,
806 IN ULONG OperationType,
808{
809 ULONG LegacyBaseAddress;
811 UCHAR RegValue;
812
814
815 /* Check what kind of hack operation this is */
816 switch (OperationType)
817 {
818 /*
819 * This is mostly concerned with fixing up incorrect class data that can
820 * exist on certain PCI hardware before the 2.0 spec was ratified.
821 */
823
824 /* Note that the i82375 PCI/EISA and the i82378 PCI/ISA bridges that
825 * are present on certain DEC/NT Alpha machines are pre-PCI 2.0 devices
826 * and appear as non-classified, so their correct class/subclass data
827 * is written here instead.
828 */
829 if ((PciData->VendorID == 0x8086) &&
830 ((PciData->DeviceID == 0x482) || (PciData->DeviceID == 0x484)))
831 {
832 /* Note that 0x482 is the i82375 (EISA), 0x484 is the i82378 (ISA) */
833 PciData->SubClass = PciData->DeviceID == 0x482 ?
835 PciData->BaseClass = PCI_CLASS_BRIDGE_DEV;
836
837 /*
838 * Because the software is modifying the actual header data from
839 * the BIOS, this flag tells the driver to ignore failures when
840 * comparing the original BIOS data with the PCI data.
841 */
842 if (PdoExtension) PdoExtension->ExpectedWritebackFailure = TRUE;
843 }
844
845 /* Note that in this case, an immediate return is issued */
846 return;
847
848 /*
849 * This is concerned with setting up interrupts correctly for native IDE
850 * mode, but will also handle broken VGA decoding on older bridges as
851 * well as a PAE-specific hack for certain Compaq Hot-Plug Controllers.
852 */
854
855 /* There should always be a PDO extension passed in */
857
858 /*
859 * On the OPTi Viper-M IDE controller, Linux doesn't support IDE-DMA
860 * and FreeBSD bug reports indicate that the system crashes when the
861 * feature is enabled (so it's disabled on that OS as well). In the
862 * NT PCI Bus Driver, it seems Microsoft too, completely disables
863 * Native IDE functionality on this controller, so it would seem OPTi
864 * simply frelled up this controller.
865 */
866 if ((PciData->VendorID == 0x1045) && (PciData->DeviceID != 0xC621))
867 {
868 /* Disable native mode */
869 PciData->ProgIf &= ~5;
870 PciData->u.type0.InterruptPin = 0;
871
872 /*
873 * Because the software is modifying the actual header data from
874 * the BIOS, this flag tells the driver to ignore failures when
875 * comparing the original BIOS data with the PCI data.
876 */
877 PdoExtension->ExpectedWritebackFailure = TRUE;
878 }
879 else if ((PciData->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
880 (PciData->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR))
881 {
882 /* For other IDE controllers, start out in compatible mode */
883 PdoExtension->BIOSAllowsIDESwitchToNativeMode = FALSE;
884
885 /*
886 * Registry must have enabled native mode (typically as a result
887 * of an INF file directive part of the IDE controller's driver)
888 * and the system must not be booted in Safe Mode. If that checks
889 * out, then evaluate the ACPI NATA method to see if the platform
890 * supports this. See the section "BIOS and Platform Prerequisites
891 * for Switching a Native-Mode-Capable Controller" in the Storage
892 * section of the Windows Driver Kit for more details:
893 *
894 * 5. For each ATA controller enumerated, the PCI bus driver checks
895 * the Programming Interface register of the IDE controller to
896 * see if it supports switching both channels to native mode.
897 * 6. The PCI bus driver checks whether the BIOS/platform supports
898 * switching the controller by checking the NATA method described
899 * earlier in this article.
900 *
901 * If an ATA controller does not indicate that it is native
902 * mode-capable, or if the BIOS NATA control method is missing
903 * or does not list that device, the PCI bus driver does not
904 * switch the controller and it is assigned legacy resources.
905 *
906 * If both the controller and the BIOS indicate that the controller
907 * can be switched, the process of switching the controller begins
908 * with the next step.
909 */
911 !(InitSafeBootMode) &&
913 {
914 /* The platform supports it, remember that */
915 PdoExtension->BIOSAllowsIDESwitchToNativeMode = TRUE;
916
917 /*
918 * Now switch the controller into native mode if both channels
919 * support native IDE mode. See "How Windows Switches an ATA
920 * Controller to Native Mode" in the Storage section of the
921 * Windows Driver Kit for more details.
922 */
923 PdoExtension->IDEInNativeMode =
925 }
926
927 /* Is native mode enabled after all? */
928 if ((PciData->ProgIf & 5) != 5)
929 {
930 /* Compatible mode, so force ISA-style IRQ14 and IRQ 15 */
931 PciData->u.type0.InterruptPin = 0;
932 }
933 }
934
935 /* Is this a PCI device with legacy VGA card decodes on the root bus? */
936 if ((PdoExtension->HackFlags & PCI_HACK_VIDEO_LEGACY_DECODE) &&
937 (PCI_IS_ROOT_FDO(DeviceExtension)) &&
938 !(DeviceExtension->BrokenVideoHackApplied))
939 {
940 /* Tell the arbiter to apply a hack for these older devices */
941 ario_ApplyBrokenVideoHack(DeviceExtension);
942 }
943
944 /* Is this a Compaq PCI Hotplug Controller (r17) on a PAE system ? */
945 if ((PciData->VendorID == 0xE11) &&
946 (PciData->DeviceID == 0xA0F7) &&
947 (PciData->RevisionID == 17) &&
949 {
950 /* Turn off the decodes immediately */
951 PciData->Command &= ~(PCI_ENABLE_IO_SPACE |
955 &PciData->Command,
957 sizeof(USHORT));
958
959 /* Do not EVER turn them on again, this will blow up the system */
960 PdoExtension->CommandEnables &= ~(PCI_ENABLE_IO_SPACE |
964 }
965 break;
966
967 /*
968 * This is called whenever resources are changed and hardware needs to be
969 * updated. It is concerned with two highly specific erratas on an IBM
970 * hot-plug docking bridge used on the Thinkpad 600 Series and on Intel's
971 * ICH PCI Bridges.
972 */
974
975 /* There should always be a PDO extension passed in */
977
978 /* Is this an IBM 20H2999 PCI Docking Bridge, used on Thinkpads? */
979 if ((PdoExtension->VendorId == 0x1014) &&
980 (PdoExtension->DeviceId == 0x95))
981 {
982 /* Read the current command */
984 &Command,
986 sizeof(USHORT));
987
988 /* Turn off the decodes */
990
991 /* Apply the required IBM workaround */
992 PciReadDeviceConfig(PdoExtension, &RegValue, 0xE0, sizeof(UCHAR));
993 RegValue &= ~2;
994 RegValue |= 1;
995 PciWriteDeviceConfig(PdoExtension, &RegValue, 0xE0, sizeof(UCHAR));
996
997 /* Restore the command to its original value */
999 &Command,
1001 sizeof(USHORT));
1002
1003 }
1004
1005 /*
1006 * Check for Intel ICH PCI-to-PCI (i82801) bridges (used on the i810,
1007 * i820, i840, i845 Chipsets) that have subtractive decode enabled,
1008 * and whose hack flags do not specify that this support is broken.
1009 */
1010 if ((PdoExtension->HeaderType == PCI_BRIDGE_TYPE) &&
1011 (PdoExtension->Dependent.type1.SubtractiveDecode) &&
1012 ((PdoExtension->VendorId == 0x8086) &&
1013 ((PdoExtension->DeviceId == 0x2418) ||
1014 (PdoExtension->DeviceId == 0x2428) ||
1015 (PdoExtension->DeviceId == 0x244E) ||
1016 (PdoExtension->DeviceId == 0x2448))) &&
1018 {
1019 /*
1020 * The positive decode window shouldn't be used, these values are
1021 * normally all read-only or initialized to 0 by the BIOS, but
1022 * it appears Intel doesn't do this, so the PCI Bus Driver will
1023 * do it in software instead. Note that this is used to prevent
1024 * certain non-compliant PCI devices from breaking down due to the
1025 * fact that these ICH bridges have a known "quirk" (which Intel
1026 * documents as a known "erratum", although it's not not really
1027 * an ICH bug since the PCI specification does allow for it) in
1028 * that they will sometimes send non-zero addresses during special
1029 * cycles (ie: non-zero data during the address phase). These
1030 * broken PCI cards will mistakenly attempt to claim the special
1031 * cycle and corrupt their I/O and RAM ranges. Again, in Intel's
1032 * defense, the PCI specification only requires stable data, not
1033 * necessarily zero data, during the address phase.
1034 */
1035 PciData->u.type1.MemoryBase = 0xFFFF;
1036 PciData->u.type1.PrefetchBase = 0xFFFF;
1037 PciData->u.type1.IOBase = 0xFF;
1038 PciData->u.type1.IOLimit = 0;
1039 PciData->u.type1.MemoryLimit = 0;
1040 PciData->u.type1.PrefetchLimit = 0;
1041 PciData->u.type1.PrefetchBaseUpper32 = 0;
1042 PciData->u.type1.PrefetchLimitUpper32 = 0;
1043 PciData->u.type1.IOBaseUpper16 = 0;
1044 PciData->u.type1.IOLimitUpper16 = 0;
1045 }
1046 break;
1047
1048 default:
1049 return;
1050 }
1051
1052 /* Finally, also check if this is this a CardBUS device? */
1054 {
1055 /*
1056 * At offset 44h the LegacyBaseAddress is stored, which is cleared by
1057 * ACPI-aware versions of Windows, to disable legacy-mode I/O access to
1058 * CardBus controllers. For more information, see "Supporting CardBus
1059 * Controllers under ACPI" in the "CardBus Controllers and Windows"
1060 * Whitepaper on WHDC.
1061 */
1062 LegacyBaseAddress = 0;
1064 &LegacyBaseAddress,
1065 sizeof(PCI_COMMON_HEADER) + sizeof(ULONG),
1066 sizeof(ULONG));
1067 }
1068}
1069
1070BOOLEAN
1071NTAPI
1073 IN PPCI_COMMON_HEADER PciData)
1074{
1075 BOOLEAN IdMatch, RevMatch, SubsysMatch;
1076 ULONGLONG HackFlags = DeviceExtension->HackFlags;
1077
1078 /* Check if the IDs match */
1079 IdMatch = (PciData->VendorID == DeviceExtension->VendorId) &&
1080 (PciData->DeviceID == DeviceExtension->DeviceId);
1081 if (!IdMatch) return FALSE;
1082
1083 /* If the device has a valid revision, check if it matches */
1085 (PciData->RevisionID == DeviceExtension->RevisionId);
1086 if (!RevMatch) return FALSE;
1087
1088 /* For multifunction devices, this is enough to assume they're the same */
1089 if (PCI_MULTIFUNCTION_DEVICE(PciData)) return TRUE;
1090
1091 /* For bridge devices, there's also nothing else that can be checked */
1092 if (DeviceExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) return TRUE;
1093
1094 /* Devices, on the other hand, have subsystem data that can be compared */
1095 SubsysMatch = (HackFlags & (PCI_HACK_NO_SUBSYSTEM |
1097 ((DeviceExtension->SubsystemVendorId ==
1098 PciData->u.type0.SubVendorID) &&
1099 (DeviceExtension->SubsystemId ==
1100 PciData->u.type0.SubSystemID));
1101 return SubsysMatch;
1102}
1103
1104BOOLEAN
1105NTAPI
1107 IN PCI_SLOT_NUMBER Slot,
1108 IN UCHAR OperationType,
1110{
1111 do
1112 {
1113 /* Check if this is device enumeration */
1114 if (OperationType == PCI_SKIP_DEVICE_ENUMERATION)
1115 {
1116 /* Check if there's a hackflag saying not to enumerate this device */
1118
1119 /* Check if this is the high end of a double decker device */
1121 (Slot.u.bits.DeviceNumber >= 16))
1122 {
1123 /* It belongs to the same device, so skip it */
1124 DPRINT1(" Device (Ven %04x Dev %04x (d=0x%x, f=0x%x)) is a ghost.\n",
1125 PciData->VendorID,
1126 PciData->DeviceID,
1127 Slot.u.bits.DeviceNumber,
1128 Slot.u.bits.FunctionNumber);
1129 break;
1130 }
1131 }
1132 else if (OperationType == PCI_SKIP_RESOURCE_ENUMERATION)
1133 {
1134 /* Resource enumeration, check for a hackflag saying not to do it */
1136 }
1137 else
1138 {
1139 /* Logic error in the driver */
1140 ASSERTMSG("PCI Skip Function - Operation type unknown.\n", FALSE);
1141 }
1142
1143 /* Check for legacy bridges during resource enumeration */
1144 if ((PciData->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
1145 (PciData->SubClass <= PCI_SUBCLASS_BR_MCA) &&
1146 (OperationType == PCI_SKIP_RESOURCE_ENUMERATION))
1147 {
1148 /* Their resources are not enumerated, only PCI and Cardbus/PCMCIA */
1149 break;
1150 }
1151 else if (PciData->BaseClass == PCI_CLASS_NOT_DEFINED)
1152 {
1153 /* Undefined base class (usually a PCI BIOS/ROM bug) */
1154 DPRINT1(" Vendor %04x, Device %04x has class code of PCI_CLASS_NOT_DEFINED\n",
1155 PciData->VendorID,
1156 PciData->DeviceID);
1157
1158 /*
1159 * The Alder has an Intel Extended Express System Support Controller
1160 * which presents apparently spurious BARs. When the PCI resource
1161 * code tries to reassign these BARs, the second IO-APIC gets
1162 * disabled (with disastrous consequences). The first BAR is the
1163 * actual IO-APIC, the remaining five bars seem to be spurious
1164 * resources, so ignore this device completely.
1165 */
1166 if ((PciData->VendorID == 0x8086) && (PciData->DeviceID == 8)) break;
1167 }
1168
1169 /* Other normal PCI cards and bridges are enumerated */
1171 } while (FALSE);
1172
1173 /* Hit one of the known bugs/hackflags, or this is a new kind of PCI unit */
1174 DPRINT1(" Device skipped (not enumerated).\n");
1175 return TRUE;
1176}
1177
1178VOID
1179NTAPI
1181 IN PPCI_COMMON_HEADER PciData)
1182{
1183 ULONG HeaderType, CapPtr, TargetAgpCapabilityId;
1184 DEVICE_POWER_STATE WakeLevel;
1185 PCI_CAPABILITIES_HEADER AgpCapability;
1187 PAGED_CODE();
1188
1189 /* Assume no known wake level */
1190 PdoExtension->PowerState.DeviceWakeLevel = PowerDeviceUnspecified;
1191
1192 /* Make sure the device has capabilities */
1193 if (!(PciData->Status & PCI_STATUS_CAPABILITIES_LIST))
1194 {
1195 /* If it doesn't, there will be no power management */
1196 PdoExtension->CapabilitiesPtr = 0;
1197 PdoExtension->HackFlags |= PCI_HACK_NO_PM_CAPS;
1198 }
1199 else
1200 {
1201 /* There's capabilities, need to figure out where to get the offset */
1202 HeaderType = PCI_CONFIGURATION_TYPE(PciData);
1203 if (HeaderType == PCI_CARDBUS_BRIDGE_TYPE)
1204 {
1205 /* Use the bridge's header */
1206 CapPtr = PciData->u.type2.CapabilitiesPtr;
1207 }
1208 else
1209 {
1210 /* Use the device header */
1211 ASSERT(HeaderType <= PCI_CARDBUS_BRIDGE_TYPE);
1212 CapPtr = PciData->u.type0.CapabilitiesPtr;
1213 }
1214
1215 /* Skip garbage capabilities pointer */
1216 if (((CapPtr & 0x3) != 0) || (CapPtr < PCI_COMMON_HDR_LENGTH))
1217 {
1218 /* Report no extended capabilities */
1219 PdoExtension->CapabilitiesPtr = 0;
1220 PdoExtension->HackFlags |= PCI_HACK_NO_PM_CAPS;
1221 }
1222 else
1223 {
1224 DPRINT1("Device has capabilities at: %lx\n", CapPtr);
1225 PdoExtension->CapabilitiesPtr = CapPtr;
1226
1227 /* Check for PCI-to-PCI Bridges and AGP bridges */
1228 if ((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
1229 ((PdoExtension->SubClass == PCI_SUBCLASS_BR_HOST) ||
1231 {
1232 /* Query either the raw AGP capabilitity, or the Target AGP one */
1233 TargetAgpCapabilityId = (PdoExtension->SubClass ==
1238 PdoExtension->CapabilitiesPtr,
1239 TargetAgpCapabilityId,
1240 &AgpCapability,
1241 sizeof(PCI_CAPABILITIES_HEADER)))
1242 {
1243 /* AGP target ID was found, store it */
1244 DPRINT1("AGP ID: %lx\n", TargetAgpCapabilityId);
1245 PdoExtension->TargetAgpCapabilityId = TargetAgpCapabilityId;
1246 }
1247 }
1248
1249 /* Check for devices that are known not to have proper power management */
1250 if (!(PdoExtension->HackFlags & PCI_HACK_NO_PM_CAPS))
1251 {
1252 /* Query if this device supports power management */
1254 PdoExtension->CapabilitiesPtr,
1256 &PowerCapabilities.Header,
1257 sizeof(PCI_PM_CAPABILITY)))
1258 {
1259 /* No power management, so act as if it had the hackflag set */
1260 DPRINT1("No PM caps, disabling PM\n");
1261 PdoExtension->HackFlags |= PCI_HACK_NO_PM_CAPS;
1262 }
1263 else
1264 {
1265 /* Otherwise, pick the highest wake level that is supported */
1266 WakeLevel = PowerDeviceUnspecified;
1267 if (PowerCapabilities.PMC.Capabilities.Support.PMED0)
1268 WakeLevel = PowerDeviceD0;
1269 if (PowerCapabilities.PMC.Capabilities.Support.PMED1)
1270 WakeLevel = PowerDeviceD1;
1271 if (PowerCapabilities.PMC.Capabilities.Support.PMED2)
1272 WakeLevel = PowerDeviceD2;
1273 if (PowerCapabilities.PMC.Capabilities.Support.PMED3Hot)
1274 WakeLevel = PowerDeviceD3;
1275 if (PowerCapabilities.PMC.Capabilities.Support.PMED3Cold)
1276 WakeLevel = PowerDeviceD3;
1277 PdoExtension->PowerState.DeviceWakeLevel = WakeLevel;
1278
1279 /* Convert the PCI power state to the NT power state */
1280 PdoExtension->PowerState.CurrentDeviceState =
1281 PowerCapabilities.PMCSR.ControlStatus.PowerState + 1;
1282
1283 /* Save all the power capabilities */
1284 PdoExtension->PowerCapabilities = PowerCapabilities.PMC.Capabilities;
1285 DPRINT1("PM Caps Found! Wake Level: %d Power State: %d\n",
1286 WakeLevel, PdoExtension->PowerState.CurrentDeviceState);
1287 }
1288 }
1289 }
1290 }
1291
1292 /* At the very end of all this, does this device not have power management? */
1293 if (PdoExtension->HackFlags & PCI_HACK_NO_PM_CAPS)
1294 {
1295 /* Then guess the current state based on whether the decodes are on */
1296 PdoExtension->PowerState.CurrentDeviceState =
1297 PciData->Command & (PCI_ENABLE_IO_SPACE |
1301 DPRINT1("PM is off, so assumed device is: %d based on enables\n",
1302 PdoExtension->PowerState.CurrentDeviceState);
1303 }
1304}
1305
1306VOID
1307NTAPI
1310{
1312 PPCI_COMMON_HEADER PciData, Current;
1314
1316
1317 /* Grab all parameters from the context */
1318 PdoExtension = Context->PdoExtension;
1319 Current = Context->Current;
1320 PciData = Context->PciData;
1321
1322 /* Write the limit discovery header */
1324
1325 /* Now read what the device indicated the limits are */
1327
1328 /* Then write back the original configuration header */
1330
1331 /* Copy back the original command that was saved in the context */
1332 Current->Command = Context->Command;
1333 if (Context->Command)
1334 {
1335 /* Program it back into the device */
1337 &Context->Command,
1339 sizeof(USHORT));
1340 }
1341
1342 /* Copy back the original status that was saved as well */
1343 Current->Status = Context->Status;
1344
1345 /* Call the configurator to restore any other data that might've changed */
1346 Context->Configurator->RestoreCurrent(Context);
1347}
1348
1350NTAPI
1352{
1353 PPCI_CONFIGURATOR Configurator;
1354 PPCI_COMMON_HEADER PciData, Current;
1356 PCI_IPI_CONTEXT IpiContext;
1357 PIO_RESOURCE_DESCRIPTOR IoDescriptor;
1358 ULONG Offset;
1359 PAGED_CODE();
1360
1361 /* Grab all parameters from the context */
1362 PdoExtension = Context->PdoExtension;
1363 Current = Context->Current;
1364 PciData = Context->PciData;
1365
1366 /* Save the current PCI Command and Status word */
1367 Context->Status = Current->Status;
1368 Context->Command = Current->Command;
1369
1370 /* Now that they're saved, clear the status, and disable all decodes */
1371 Current->Status = 0;
1372 Current->Command &= ~(PCI_ENABLE_IO_SPACE |
1375
1376 /* Make a copy of the current PCI configuration header (with decodes off) */
1377 RtlCopyMemory(PciData, Current, PCI_COMMON_HDR_LENGTH);
1378
1379 /* Locate the correct resource configurator for this type of device */
1380 Configurator = &PciConfigurators[PdoExtension->HeaderType];
1381 Context->Configurator = Configurator;
1382
1383 /* Initialize it, which will typically setup the BARs for limit discovery */
1384 Configurator->Initialize(Context);
1385
1386 /* Check for critical devices and PCI Debugging devices */
1387 if ((PdoExtension->HackFlags & PCI_HACK_CRITICAL_DEVICE) ||
1388 (PdoExtension->OnDebugPath))
1389 {
1390 /* Specifically check for a PCI Debugging device */
1391 if (PdoExtension->OnDebugPath)
1392 {
1393 /* Was it enabled for bus mastering? */
1394 if (Context->Command & PCI_ENABLE_BUS_MASTER)
1395 {
1396 /* This decode needs to be re-enabled so debugging can work */
1397 PciData->Command |= PCI_ENABLE_BUS_MASTER;
1398 Current->Command |= PCI_ENABLE_BUS_MASTER;
1399 }
1400
1401 /* Disable the debugger while the discovery is happening */
1403 }
1404
1405 /* For these devices, an IPI must be sent to force high-IRQL discovery */
1406 IpiContext.Barrier = 1;
1407 IpiContext.RunCount = 1;
1408 IpiContext.DeviceExtension = PdoExtension;
1410 IpiContext.Context = Context;
1412
1413 /* Re-enable the debugger if this was a PCI Debugging Device */
1414 if (PdoExtension->OnDebugPath) KdEnableDebugger();
1415 }
1416 else
1417 {
1418 /* Otherwise, it's safe to do this in-line at low IRQL */
1420 }
1421
1422 /*
1423 * Check if it's valid to compare the headers to see if limit discovery mode
1424 * has properly exited (the expected case is that the PCI header would now
1425 * be equal to what it was before). In some cases, it is known that this will
1426 * fail, because during PciApplyHacks (among other places), software hacks
1427 * had to be applied to the header, which the hardware-side will not see, and
1428 * thus the headers would appear "different".
1429 */
1430 if (!PdoExtension->ExpectedWritebackFailure)
1431 {
1432 /* Read the current PCI header now, after discovery has completed */
1434
1435 /* Check if the current header at entry, is equal to the header now */
1436 Offset = RtlCompareMemory(PciData + 1, Current, PCI_COMMON_HDR_LENGTH);
1438 {
1439 /* It's not, which means configuration somehow changed, dump this */
1440 DPRINT1("PCI - CFG space write verify failed at offset 0x%x\n", Offset);
1441 PciDebugDumpCommonConfig(PciData + 1);
1442 DPRINT1("----------\n");
1443 PciDebugDumpCommonConfig(Current);
1444 }
1445 }
1446
1447 /* This PDO should not already have resources, since this is only done once */
1448 ASSERT(PdoExtension->Resources == NULL);
1449
1450 /* Allocate the structure that will hold the discovered resources and limits */
1452 sizeof(PCI_FUNCTION_RESOURCES),
1453 'BicP');
1454 if (!PdoExtension->Resources) return STATUS_INSUFFICIENT_RESOURCES;
1455
1456 /* Clear it out for now */
1458
1459 /* Now call the configurator, which will first store the limits... */
1460 Configurator->SaveLimits(Context);
1461
1462 /* ...and then store the current resources being used */
1463 Configurator->SaveCurrentSettings(Context);
1464
1465 /* Loop all the limit descriptors backwards */
1466 IoDescriptor = &PdoExtension->Resources->Limit[PCI_TYPE0_ADDRESSES + 1];
1467 while (TRUE)
1468 {
1469 /* Keep going until a non-null descriptor is found */
1470 IoDescriptor--;
1471 if (IoDescriptor->Type != CmResourceTypeNull) break;
1472
1473 /* This is a null descriptor, is it the last one? */
1474 if (IoDescriptor == &PdoExtension->Resources->Limit[PCI_TYPE0_ADDRESSES + 1])
1475 {
1476 /* This means the descriptor is NULL, which means discovery failed */
1477 DPRINT1("PCI Resources fail!\n");
1478
1479 /* No resources will be assigned for the device */
1480 ExFreePoolWithTag(PdoExtension->Resources, 0);
1481 PdoExtension->Resources = NULL;
1482 break;
1483 }
1484 }
1485
1486 /* Return success here, even if the device has no assigned resources */
1487 return STATUS_SUCCESS;
1488}
1489
1491NTAPI
1493 IN PPCI_COMMON_HEADER Current,
1495{
1497 PPCI_COMMON_HEADER PciData;
1499 PAGED_CODE();
1500
1501 /* Do the hackflags indicate this device should be skipped? */
1502 if (PciSkipThisFunction(Current,
1503 PdoExtension->Slot,
1505 HackFlags))
1506 {
1507 /* Do not process its resources */
1508 return STATUS_SUCCESS;
1509 }
1510
1511 /* Allocate a buffer to hold two PCI configuration headers */
1512 PciData = ExAllocatePoolWithTag(0, 2 * PCI_COMMON_HDR_LENGTH, 'BicP');
1513 if (!PciData) return STATUS_INSUFFICIENT_RESOURCES;
1514
1515 /* Set up the context for the resource enumeration, and do it */
1516 Context.Current = Current;
1517 Context.PciData = PciData;
1518 Context.PdoExtension = PdoExtension;
1520
1521 /* Enumeration is completed, free the PCI headers and return the status */
1522 ExFreePoolWithTag(PciData, 0);
1523 return Status;
1524}
1525
1526VOID
1527NTAPI
1529{
1532 PAGED_CODE();
1533
1534 /* Get the PDO Extension */
1535 PhysicalDeviceObject = DeviceExtension->PhysicalDeviceObject;
1537
1538 /* Cheeck if this is the root bus */
1539 if (!PCI_IS_ROOT_FDO(DeviceExtension))
1540 {
1541 /* Not really handling this year */
1543
1544 /* Check for PCI bridges with the ISA bit set, or required */
1545 if ((PdoExtension) &&
1547 ((PdoExtension->Dependent.type1.IsaBitRequired) ||
1548 (PdoExtension->Dependent.type1.IsaBitSet)))
1549 {
1550 /* We'll need to do some legacy support */
1552 }
1553 }
1554 else
1555 {
1556 /* Scan all of the root bus' children bridges */
1557 for (PdoExtension = DeviceExtension->ChildBridgePdoList;
1559 PdoExtension = PdoExtension->NextBridge)
1560 {
1561 /* Find any that have the VGA decode bit on */
1562 if (PdoExtension->Dependent.type1.VgaBitSet)
1563 {
1564 /* Again, some more legacy support we'll have to do */
1566 }
1567 }
1568 }
1569
1570 /* Check for ACPI systems where the OS assigns bus numbers */
1572 {
1573 /* Not yet supported */
1575 }
1576}
1577
1579NTAPI
1581{
1582 ULONG MaxDevice = PCI_MAX_DEVICES;
1583 BOOLEAN ProcessFlag = FALSE;
1584 ULONG i, j, k, Size;
1585 USHORT CapOffset, TempOffset;
1589 UCHAR BiosBuffer[PCI_COMMON_HDR_LENGTH];
1590 PPCI_COMMON_HEADER PciData = (PVOID)Buffer;
1591 PPCI_COMMON_HEADER BiosData = (PVOID)BiosBuffer;
1592 PCI_SLOT_NUMBER PciSlot;
1593 PCHAR Name;
1595 PPCI_PDO_EXTENSION PdoExtension, NewExtension;
1596 PPCI_PDO_EXTENSION* BridgeExtension;
1597 PWCHAR DescriptionText;
1598 USHORT SubVendorId, SubSystemId;
1599 PCI_CAPABILITIES_HEADER CapHeader, PcixCapHeader;
1600 UCHAR SecondaryBus;
1601 DPRINT1("PCI Scan Bus: FDO Extension @ 0x%p, Base Bus = 0x%x\n",
1602 DeviceExtension, DeviceExtension->BaseBus);
1603
1604 /* Is this the root FDO? */
1605 if (!PCI_IS_ROOT_FDO(DeviceExtension))
1606 {
1607 /* Get the PDO for the child bus */
1608 PdoExtension = DeviceExtension->PhysicalDeviceObject->DeviceExtension;
1610
1611 /* Check for hack which only allows bus to have one child device */
1612 if (PdoExtension->HackFlags & PCI_HACK_ONE_CHILD) MaxDevice = 1;
1613
1614 /* Check if the secondary bus number has changed */
1616 &SecondaryBus,
1617 FIELD_OFFSET(PCI_COMMON_HEADER, u.type1.SecondaryBus),
1618 sizeof(UCHAR));
1619 if (SecondaryBus != PdoExtension->Dependent.type1.SecondaryBus)
1620 {
1621 UNIMPLEMENTED_DBGBREAK("PCI: Bus numbers have been changed! Restoring originals.\n");
1622 }
1623 }
1624
1625 /* Loop every device on the bus */
1626 PciSlot.u.bits.Reserved = 0;
1627 i = DeviceExtension->BaseBus;
1628 for (j = 0; j < MaxDevice; j++)
1629 {
1630 /* Loop every function of each device */
1631 PciSlot.u.bits.DeviceNumber = j;
1632 for (k = 0; k < PCI_MAX_FUNCTION; k++)
1633 {
1634 /* Build the final slot structure */
1635 PciSlot.u.bits.FunctionNumber = k;
1636
1637 /* Read the vendor for this slot */
1638 PciReadSlotConfig(DeviceExtension,
1639 PciSlot,
1640 PciData,
1641 0,
1642 sizeof(USHORT));
1643
1644 /* Skip invalid device */
1645 if (PciData->VendorID == PCI_INVALID_VENDORID) continue;
1646
1647 /* Now read the whole header */
1648 PciReadSlotConfig(DeviceExtension,
1649 PciSlot,
1650 &PciData->DeviceID,
1651 sizeof(USHORT),
1652 PCI_COMMON_HDR_LENGTH - sizeof(USHORT));
1653
1654 /* Apply any hacks before even analyzing the configuration header */
1655 PciApplyHacks(DeviceExtension,
1656 PciData,
1657 PciSlot,
1659 NULL);
1660
1661 /* Dump device that was found */
1662 DPRINT1("Scan Found Device 0x%x (b=0x%x, d=0x%x, f=0x%x)\n",
1663 PciSlot.u.AsULONG,
1664 i,
1665 j,
1666 k);
1667
1668 /* Dump the device's header */
1669 PciDebugDumpCommonConfig(PciData);
1670
1671 /* Find description for this device for the debugger's sake */
1672 DescriptionText = PciGetDeviceDescriptionMessage(PciData->BaseClass,
1673 PciData->SubClass);
1674 DPRINT1("Device Description \"%S\".\n",
1675 DescriptionText ? DescriptionText : L"(NULL)");
1676 if (DescriptionText) ExFreePoolWithTag(DescriptionText, 0);
1677
1678 /* Check if there is an ACPI Watchdog Table */
1679 if (WdTable)
1680 {
1681 /* Check if this PCI device is the ACPI Watchdog Device... */
1683 }
1684
1685 /* Check for non-simple devices */
1686 if ((PCI_MULTIFUNCTION_DEVICE(PciData)) ||
1687 (PciData->BaseClass == PCI_CLASS_BRIDGE_DEV))
1688 {
1689 /* No subsystem data defined for these kinds of bridges */
1690 SubVendorId = 0;
1691 SubSystemId = 0;
1692 }
1693 else
1694 {
1695 /* Read the subsystem information from the PCI header */
1696 SubVendorId = PciData->u.type0.SubVendorID;
1697 SubSystemId = PciData->u.type0.SubSystemID;
1698 }
1699
1700 /* Get any hack flags for this device */
1701 HackFlags = PciGetHackFlags(PciData->VendorID,
1702 PciData->DeviceID,
1703 SubVendorId,
1704 SubSystemId,
1705 PciData->RevisionID);
1706
1707 /* Check if this device is considered critical by the OS */
1708 if (PciIsCriticalDeviceClass(PciData->BaseClass, PciData->SubClass))
1709 {
1710 /* Check if normally the decodes would be disabled */
1712 {
1713 /* Because this device is critical, don't disable them */
1714 DPRINT1("Not allowing PM Because device is critical\n");
1716 }
1717 }
1718
1719 /* PCI bridges with a VGA card are also considered critical */
1720 if ((PciData->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
1721 (PciData->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI) &&
1722 (PciData->u.type1.BridgeControl & PCI_ENABLE_BRIDGE_VGA) &&
1724 {
1725 /* Do not disable their decodes either */
1726 DPRINT1("Not allowing PM because device is VGA\n");
1728 }
1729
1730 /* Check if the device should be skipped for whatever reason */
1731 if (PciSkipThisFunction(PciData,
1732 PciSlot,
1734 HackFlags))
1735 {
1736 /* Skip this device */
1737 continue;
1738 }
1739
1740 /* Check if a PDO has already been created for this device */
1741 PdoExtension = PciFindPdoByFunction(DeviceExtension,
1742 PciSlot.u.AsULONG,
1743 PciData);
1744 if (PdoExtension)
1745 {
1746 /* Rescan scenarios are not yet implemented */
1748 }
1749
1750 /* Bus processing will need to happen */
1751 ProcessFlag = TRUE;
1752
1753 /* Create the PDO for this device */
1754 Status = PciPdoCreate(DeviceExtension, PciSlot, &DeviceObject);
1756 NewExtension = (PPCI_PDO_EXTENSION)DeviceObject->DeviceExtension;
1757
1758 /* Check for broken devices with wrong/no class codes */
1760 {
1761 /* Setup a default one */
1762 PciData->BaseClass = PCI_CLASS_BASE_SYSTEM_DEV;
1763 PciData->SubClass = PCI_SUBCLASS_SYS_OTHER;
1764
1765 /* Device will behave erratically when reading back data */
1766 NewExtension->ExpectedWritebackFailure = TRUE;
1767 }
1768
1769 /* Clone all the information from the header */
1770 NewExtension->VendorId = PciData->VendorID;
1771 NewExtension->DeviceId = PciData->DeviceID;
1772 NewExtension->RevisionId = PciData->RevisionID;
1773 NewExtension->ProgIf = PciData->ProgIf;
1774 NewExtension->SubClass = PciData->SubClass;
1775 NewExtension->BaseClass = PciData->BaseClass;
1776 NewExtension->HeaderType = PCI_CONFIGURATION_TYPE(PciData);
1777
1778 /* Check for modern bridge types, which are managed by the driver */
1779 if ((NewExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
1780 ((NewExtension->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI) ||
1781 (NewExtension->SubClass == PCI_SUBCLASS_BR_CARDBUS)))
1782 {
1783 /* Acquire this device's lock */
1785 KeWaitForSingleObject(&DeviceExtension->ChildListLock,
1786 Executive,
1787 KernelMode,
1788 FALSE,
1789 NULL);
1790
1791 /* Scan the bridge list until the first free entry */
1792 for (BridgeExtension = &DeviceExtension->ChildBridgePdoList;
1793 *BridgeExtension;
1794 BridgeExtension = &(*BridgeExtension)->NextBridge);
1795
1796 /* Add this PDO as a bridge */
1797 *BridgeExtension = NewExtension;
1798 ASSERT(NewExtension->NextBridge == NULL);
1799
1800 /* Release this device's lock */
1801 KeSetEvent(&DeviceExtension->ChildListLock,
1803 FALSE);
1805 }
1806
1807 /* Get the PCI BIOS configuration saved in the registry */
1808 Status = PciGetBiosConfig(NewExtension, BiosData);
1809 if (NT_SUCCESS(Status))
1810 {
1811 /* This path has not yet been fully tested by eVb */
1812 DPRINT1("Have BIOS configuration!\n");
1814
1815 /* Check if the PCI BIOS configuration has changed */
1816 if (!PcipIsSameDevice(NewExtension, BiosData))
1817 {
1818 /* This is considered failure, and new data will be saved */
1820 }
1821 else
1822 {
1823 /* Data is still correct, check for interrupt line change */
1824 if (BiosData->u.type0.InterruptLine !=
1825 PciData->u.type0.InterruptLine)
1826 {
1827 /* Update the current BIOS with the saved interrupt line */
1828 PciWriteDeviceConfig(NewExtension,
1829 &BiosData->u.type0.InterruptLine,
1831 u.type0.InterruptLine),
1832 sizeof(UCHAR));
1833 }
1834
1835 /* Save the BIOS interrupt line and the initial command */
1836 NewExtension->RawInterruptLine = BiosData->u.type0.InterruptLine;
1837 NewExtension->InitialCommand = BiosData->Command;
1838 }
1839 }
1840
1841 /* Check if no saved data was present or if it was a mismatch */
1842 if (!NT_SUCCESS(Status))
1843 {
1844 /* Save the new data */
1845 Status = PciSaveBiosConfig(NewExtension, PciData);
1847
1848 /* Save the interrupt line and command from the device */
1849 NewExtension->RawInterruptLine = PciData->u.type0.InterruptLine;
1850 NewExtension->InitialCommand = PciData->Command;
1851 }
1852
1853 /* Save original command from the device and hack flags */
1854 NewExtension->CommandEnables = PciData->Command;
1855 NewExtension->HackFlags = HackFlags;
1856
1857 /* Get power, AGP, and other capability data */
1858 PciGetEnhancedCapabilities(NewExtension, PciData);
1859
1860 /* Now configure the BARs */
1861 Status = PciGetFunctionLimits(NewExtension, PciData, HackFlags);
1862
1863 /* Power up the device */
1865
1866 /* Apply any device hacks required for enumeration */
1867 PciApplyHacks(DeviceExtension,
1868 PciData,
1869 PciSlot,
1871 NewExtension);
1872
1873 /* Save interrupt pin */
1874 NewExtension->InterruptPin = PciData->u.type0.InterruptPin;
1875
1876 /*
1877 * Use either this device's actual IRQ line or, if it's connected on
1878 * a master bus whose IRQ line is actually connected to the host, use
1879 * the HAL to query the bus' IRQ line and store that as the adjusted
1880 * interrupt line instead
1881 */
1882 NewExtension->AdjustedInterruptLine = PciGetAdjustedInterruptLine(NewExtension);
1883
1884 /* Check if this device is used for PCI debugger cards */
1885 NewExtension->OnDebugPath = PciIsDeviceOnDebugPath(NewExtension);
1886
1887 /* Check for devices with invalid/bogus subsystem data */
1889 {
1890 /* Set the subsystem information to zero instead */
1891 NewExtension->SubsystemVendorId = 0;
1892 NewExtension->SubsystemId = 0;
1893 }
1894
1895 /* Scan all capabilities */
1896 CapOffset = NewExtension->CapabilitiesPtr;
1897 while (CapOffset)
1898 {
1899 /* Read this header */
1900 TempOffset = PciReadDeviceCapability(NewExtension,
1901 CapOffset,
1902 0,
1903 &CapHeader,
1904 sizeof(PCI_CAPABILITIES_HEADER));
1905 if (TempOffset != CapOffset)
1906 {
1907 /* This is a strange issue that shouldn't happen normally */
1908 DPRINT1("PCI - Failed to read PCI capability at offset 0x%02x\n",
1909 CapOffset);
1910 ASSERT(TempOffset == CapOffset);
1911 }
1912
1913 /* Check for capabilities that this driver cares about */
1914 switch (CapHeader.CapabilityID)
1915 {
1916 /* Power management capability is heavily used by the bus */
1918
1919 /* Dump the capability */
1920 Name = "POWER";
1921 Size = sizeof(PCI_PM_CAPABILITY);
1922 break;
1923
1924 /* AGP capability is required for AGP bus functionality */
1926
1927 /* Dump the capability */
1928 Name = "AGP";
1929 Size = sizeof(PCI_AGP_CAPABILITY);
1930 break;
1931
1932 /* This driver doesn't really use anything other than that */
1933 default:
1934
1935 /* Windows prints this, we could do a translation later */
1936 Name = "UNKNOWN CAPABILITY";
1937 Size = 0;
1938 break;
1939 }
1940
1941 /* Check if this is a capability that should be dumped */
1942 if (Size)
1943 {
1944 /* Read the whole capability data */
1945 TempOffset = PciReadDeviceCapability(NewExtension,
1946 CapOffset,
1947 CapHeader.CapabilityID,
1948 &CapHeader,
1949 Size);
1950
1951 if (TempOffset != CapOffset)
1952 {
1953 /* Again, a strange issue that shouldn't be seen */
1954 DPRINT1("- Failed to read capability data. ***\n");
1955 ASSERT(TempOffset == CapOffset);
1956 }
1957 }
1958
1959 /* Dump this capability */
1960 DPRINT1("CAP @%02x ID %02x (%s)\n",
1961 CapOffset, CapHeader.CapabilityID, Name);
1962 for (i = 0; i < Size; i += 2)
1963 DPRINT1(" %04x\n", *(PUSHORT)((ULONG_PTR)&CapHeader + i));
1964 DPRINT1("\n");
1965
1966 /* Check the next capability */
1967 CapOffset = CapHeader.Next;
1968 }
1969
1970 /* Check for IDE controllers */
1971 if ((NewExtension->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
1972 (NewExtension->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR))
1973 {
1974 /* Do not allow them to power down completely */
1975 NewExtension->DisablePowerDown = TRUE;
1976 }
1977
1978 /*
1979 * Check if this is a legacy bridge. Note that the i82375 PCI/EISA
1980 * bridge that is present on certain NT Alpha machines appears as
1981 * non-classified so detect it manually by scanning for its VID/PID.
1982 */
1983 if (((NewExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
1984 ((NewExtension->SubClass == PCI_SUBCLASS_BR_ISA) ||
1985 (NewExtension->SubClass == PCI_SUBCLASS_BR_EISA) ||
1986 (NewExtension->SubClass == PCI_SUBCLASS_BR_MCA))) ||
1987 ((NewExtension->VendorId == 0x8086) &&
1988 (NewExtension->DeviceId == 0x482)))
1989 {
1990 /* Do not allow these legacy bridges to be powered down */
1991 NewExtension->DisablePowerDown = TRUE;
1992 }
1993
1994 /* Check if the BIOS did not configure a cache line size */
1995 if (!PciData->CacheLineSize)
1996 {
1997 /* Check if the device is disabled */
1998 if (!(NewExtension->CommandEnables & (PCI_ENABLE_IO_SPACE |
2001 {
2002 /* Check if this is a PCI-X device*/
2003 TempOffset = PciReadDeviceCapability(NewExtension,
2004 NewExtension->CapabilitiesPtr,
2006 &PcixCapHeader,
2007 sizeof(PCI_CAPABILITIES_HEADER));
2008
2009 /*
2010 * A device with default cache line size and latency timer
2011 * settings is considered to be unconfigured. Note that on
2012 * PCI-X, the reset value of the latency timer field in the
2013 * header is 64, not 0, hence why the check for PCI-X caps
2014 * was required, and the value used here below.
2015 */
2016 if (!(PciData->LatencyTimer) ||
2017 ((TempOffset) && (PciData->LatencyTimer == 64)))
2018 {
2019 /* Keep track of the fact that it needs configuration */
2020 DPRINT1("PCI - ScanBus, PDOx %p found unconfigured\n",
2021 NewExtension);
2022 NewExtension->NeedsHotPlugConfiguration = TRUE;
2023 }
2024 }
2025 }
2026
2027 /* Save latency and cache size information */
2028 NewExtension->SavedLatencyTimer = PciData->LatencyTimer;
2029 NewExtension->SavedCacheLineSize = PciData->CacheLineSize;
2030
2031 /* The PDO is now ready to go */
2032 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
2033 }
2034 }
2035
2036 /* Enumeration completed, do a final pass now that all devices are found */
2037 if (ProcessFlag) PciProcessBus(DeviceExtension);
2038 return STATUS_SUCCESS;
2039}
2040
2042NTAPI
2044 IN OUT PDEVICE_RELATIONS *pDeviceRelations)
2045{
2048 ULONG PdoCount = 0;
2049 PDEVICE_RELATIONS DeviceRelations, NewRelations;
2050 SIZE_T Size;
2051 PDEVICE_OBJECT DeviceObject, *ObjectArray;
2052 PAGED_CODE();
2053
2054 /* Make sure the FDO is started */
2055 ASSERT(DeviceExtension->DeviceState == PciStarted);
2056
2057 /* Synchronize while we enumerate the bus */
2059 if (!NT_SUCCESS(Status)) return Status;
2060
2061 /* Scan all children PDO */
2062 for (PdoExtension = DeviceExtension->ChildPdoList;
2064 PdoExtension = PdoExtension->Next)
2065 {
2066 /* Invalidate them */
2067 PdoExtension->NotPresent = TRUE;
2068 }
2069
2070 /* Scan the PCI Bus */
2071 Status = PciScanBus(DeviceExtension);
2073
2074 /* Enumerate all children PDO again */
2075 for (PdoExtension = DeviceExtension->ChildPdoList;
2077 PdoExtension = PdoExtension->Next)
2078 {
2079 /* Check for PDOs that are still invalidated */
2080 if (PdoExtension->NotPresent)
2081 {
2082 /* This means this PDO existed before, but not anymore */
2083 PdoExtension->ReportedMissing = TRUE;
2084 DPRINT1("PCI - Old device (pdox) %p not found on rescan.\n",
2085 PdoExtension);
2086 }
2087 else
2088 {
2089 /* Increase count of detected PDOs */
2090 PdoCount++;
2091 }
2092 }
2093
2094 /* Read the current relations and add the newly discovered relations */
2095 DeviceRelations = *pDeviceRelations;
2096 Size = FIELD_OFFSET(DEVICE_RELATIONS, Objects) +
2097 PdoCount * sizeof(PDEVICE_OBJECT);
2098 if (DeviceRelations) Size += sizeof(PDEVICE_OBJECT) * DeviceRelations->Count;
2099
2100 /* Allocate the device relations */
2101 NewRelations = (PDEVICE_RELATIONS)ExAllocatePoolWithTag(0, Size, 'BicP');
2102 if (!NewRelations)
2103 {
2104 /* Out of space, cancel the operation */
2107 }
2108
2109 /* Check if there were any older relations */
2110 NewRelations->Count = 0;
2111 if (DeviceRelations)
2112 {
2113 /* Copy the old relations into the new buffer, then free the old one */
2114 RtlCopyMemory(NewRelations,
2115 DeviceRelations,
2116 FIELD_OFFSET(DEVICE_RELATIONS, Objects) +
2117 DeviceRelations->Count * sizeof(PDEVICE_OBJECT));
2118 ExFreePoolWithTag(DeviceRelations, 0);
2119 }
2120
2121 /* Print out that we're ready to dump relations */
2122 DPRINT1("PCI QueryDeviceRelations/BusRelations FDOx %p (bus 0x%02x)\n",
2123 DeviceExtension,
2124 DeviceExtension->BaseBus);
2125
2126 /* Loop the current PDO children and the device relation object array */
2127 PdoExtension = DeviceExtension->ChildPdoList;
2128 ObjectArray = &NewRelations->Objects[NewRelations->Count];
2129 while (PdoExtension)
2130 {
2131 /* Dump this relation */
2132 DPRINT1(" QDR PDO %p (x %p)%s\n",
2133 PdoExtension->PhysicalDeviceObject,
2135 PdoExtension->NotPresent ?
2136 "<Omitted, device flaged not present>" : "");
2137
2138 /* Is this PDO present? */
2139 if (!PdoExtension->NotPresent)
2140 {
2141 /* Reference it and add it to the array */
2142 DeviceObject = PdoExtension->PhysicalDeviceObject;
2144 *ObjectArray++ = DeviceObject;
2145 }
2146
2147 /* Go to the next PDO */
2148 PdoExtension = PdoExtension->Next;
2149 }
2150
2151 /* Terminate dumping the relations */
2152 DPRINT1(" QDR Total PDO count = %u (%u already in list)\n",
2153 NewRelations->Count + PdoCount,
2154 NewRelations->Count);
2155
2156 /* Return the final count and the new buffer */
2157 NewRelations->Count += PdoCount;
2158 *pDeviceRelations = NewRelations;
2159 return STATUS_SUCCESS;
2160}
2161
2163NTAPI
2165 IN BOOLEAN DoReset,
2166 IN BOOLEAN SomethingSomethingDarkSide)
2167{
2169 UCHAR NewCacheLineSize, NewLatencyTimer;
2170 PCI_COMMON_HEADER PciData;
2172 PPCI_CONFIGURATOR Configurator;
2173
2174 UNREFERENCED_PARAMETER(SomethingSomethingDarkSide);
2175
2176 /* Get the FDO and read the configuration data */
2177 FdoExtension = PdoExtension->ParentFdoExtension;
2179
2180 /* Make sure this is still the same device */
2181 if (!PcipIsSameDevice(PdoExtension, &PciData))
2182 {
2183 /* Fail */
2184 ASSERTMSG("PCI Set resources - not same device.\n", FALSE);
2186 }
2187
2188 /* Nothing to set for a host bridge */
2189 if ((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
2190 (PdoExtension->SubClass == PCI_SUBCLASS_BR_HOST))
2191 {
2192 /* Fake success */
2193 return STATUS_SUCCESS;
2194 }
2195
2196 /* Check if an IDE controller is being reset */
2197 if ((DoReset) &&
2198 (PdoExtension->BaseClass == PCI_CLASS_MASS_STORAGE_CTLR) &&
2200 {
2201 /* Turn off native mode */
2203 ASSERT(Native == PdoExtension->IDEInNativeMode);
2204 }
2205
2206 /* Check for update of a hotplug device, or first configuration of one */
2207 if ((PdoExtension->NeedsHotPlugConfiguration) &&
2208 (FdoExtension->HotPlugParameters.Acquired))
2209 {
2210 /* Don't have hotplug devices to test with yet, QEMU 0.14 should */
2212 }
2213
2214 /* Locate the correct resource configurator for this type of device */
2215 Configurator = &PciConfigurators[PdoExtension->HeaderType];
2216
2217 /* Apply the settings change */
2218 Configurator->ChangeResourceSettings(PdoExtension, &PciData);
2219
2220 /* Assume no update needed */
2221 PdoExtension->UpdateHardware = FALSE;
2222
2223 /* Check if a reset is needed */
2224 if (DoReset)
2225 {
2226 /* Reset resources */
2227 Configurator->ResetDevice(PdoExtension, &PciData);
2228 PciData.u.type0.InterruptLine = PdoExtension->RawInterruptLine;
2229 }
2230
2231 /* Check if the latency timer changed */
2232 NewLatencyTimer = PdoExtension->SavedLatencyTimer;
2233 if (PciData.LatencyTimer != NewLatencyTimer)
2234 {
2235 /* Debug notification */
2236 DPRINT1("PCI (pdox %p) changing latency from %02x to %02x.\n",
2238 PciData.LatencyTimer,
2239 NewLatencyTimer);
2240 }
2241
2242 /* Check if the cache line changed */
2243 NewCacheLineSize = PdoExtension->SavedCacheLineSize;
2244 if (PciData.CacheLineSize != NewCacheLineSize)
2245 {
2246 /* Debug notification */
2247 DPRINT1("PCI (pdox %p) changing cache line size from %02x to %02x.\n",
2249 PciData.CacheLineSize,
2250 NewCacheLineSize);
2251 }
2252
2253 /* Inherit data from PDO extension */
2254 PciData.LatencyTimer = PdoExtension->SavedLatencyTimer;
2255 PciData.CacheLineSize = PdoExtension->SavedCacheLineSize;
2256 PciData.u.type0.InterruptLine = PdoExtension->RawInterruptLine;
2257
2258 /* Apply any resource hacks required */
2260 &PciData,
2261 PdoExtension->Slot,
2263 PdoExtension);
2264
2265 /* Check if I/O space was disabled by administrator or driver */
2266 if (PdoExtension->IoSpaceNotRequired)
2267 {
2268 /* Don't turn on the decode */
2269 PdoExtension->CommandEnables &= ~PCI_ENABLE_IO_SPACE;
2270 }
2271
2272 /* Update the device with the new settings */
2274
2275 /* Update complete */
2276 PdoExtension->RawInterruptLine = PciData.u.type0.InterruptLine;
2277 PdoExtension->NeedsHotPlugConfiguration = FALSE;
2278 return STATUS_SUCCESS;
2279}
2280
2281/* EOF */
#define PAGED_CODE()
Type
Definition: Type.h:7
unsigned char BOOLEAN
Definition: actypes.h:127
VOID NTAPI ario_ApplyBrokenVideoHack(IN PPCI_FDO_EXTENSION FdoExtension)
Definition: ar_memio.c:104
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
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
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:843
_In_ ULONG_PTR HackFlags
Definition: cdrom.h:983
Definition: bufpool.h:45
FORCEINLINE PCM_PARTIAL_RESOURCE_DESCRIPTOR CmiGetNextPartialDescriptor(_In_ const CM_PARTIAL_RESOURCE_DESCRIPTOR *PartialDescriptor)
Definition: cmreslist.h:31
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define L(x)
Definition: resources.c:13
VOID NTAPI PciDebugPrintPartialResource(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource)
Definition: debug.c:348
VOID NTAPI PciDebugDumpCommonConfig(IN PPCI_COMMON_HEADER PciData)
Definition: debug.c:207
VOID NTAPI PciDebugPrintIoResReqList(IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements)
Definition: debug.c:302
VOID NTAPI PciDebugPrintCmResList(IN PCM_RESOURCE_LIST PartialList)
Definition: debug.c:364
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 PciWriteLimitsAndRestoreCurrent(IN PVOID Reserved, IN PVOID Context2)
Definition: enum.c:1308
VOID NTAPI PciGetEnhancedCapabilities(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: enum.c:1180
NTSTATUS NTAPI PciSetResources(IN PPCI_PDO_EXTENSION PdoExtension, IN BOOLEAN DoReset, IN BOOLEAN SomethingSomethingDarkSide)
Definition: enum.c:2164
BOOLEAN NTAPI PciSkipThisFunction(IN PPCI_COMMON_HEADER PciData, IN PCI_SLOT_NUMBER Slot, IN UCHAR OperationType, IN ULONGLONG HackFlags)
Definition: enum.c:1106
NTSTATUS NTAPI PciBuildRequirementsList(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData, OUT PIO_RESOURCE_REQUIREMENTS_LIST *Buffer)
Definition: enum.c:560
PCM_RESOURCE_LIST NTAPI PciAllocateCmResourceList(IN ULONG Count, IN ULONG BusNumber)
Definition: enum.c:333
VOID NTAPI PciProcessBus(IN PPCI_FDO_EXTENSION DeviceExtension)
Definition: enum.c:1528
BOOLEAN NTAPI PcipIsSameDevice(IN PPCI_PDO_EXTENSION DeviceExtension, IN PPCI_COMMON_HEADER PciData)
Definition: enum.c:1072
NTSTATUS NTAPI PciScanBus(IN PPCI_FDO_EXTENSION DeviceExtension)
Definition: enum.c:1580
NTSTATUS NTAPI PciQueryEjectionRelations(IN PPCI_PDO_EXTENSION PdoExtension, IN OUT PDEVICE_RELATIONS *pDeviceRelations)
Definition: enum.c:547
NTSTATUS NTAPI PciQueryRequirements(IN PPCI_PDO_EXTENSION PdoExtension, IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *RequirementsList)
Definition: enum.c:592
NTSTATUS NTAPI PciQueryTargetDeviceRelations(IN PPCI_PDO_EXTENSION PdoExtension, IN OUT PDEVICE_RELATIONS *pDeviceRelations)
Definition: enum.c:520
BOOLEAN NTAPI PciConfigureIdeController(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData, IN BOOLEAN Initial)
Definition: enum.c:663
NTSTATUS NTAPI PciQueryDeviceRelations(IN PPCI_FDO_EXTENSION DeviceExtension, IN OUT PDEVICE_RELATIONS *pDeviceRelations)
Definition: enum.c:2043
NTSTATUS NTAPI PcipGetFunctionLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: enum.c:1351
VOID NTAPI PcipUpdateHardware(IN PVOID Context, IN PVOID Context2)
Definition: enum.c:247
PIO_RESOURCE_REQUIREMENTS_LIST PciZeroIoResourceRequirements
Definition: enum.c:18
VOID NTAPI PciUpdateHardware(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: enum.c:274
PIO_RESOURCE_REQUIREMENTS_LIST NTAPI PciAllocateIoRequirementsList(IN ULONG Count, IN ULONG BusNumber, IN ULONG SlotNumber)
Definition: enum.c:300
PCI_CONFIGURATOR PciConfigurators[]
Definition: enum.c:20
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:803
BOOLEAN NTAPI PciComputeNewCurrentSettings(IN PPCI_PDO_EXTENSION PdoExtension, IN PCM_RESOURCE_LIST ResourceList)
Definition: enum.c:55
NTSTATUS NTAPI PciGetFunctionLimits(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER Current, IN ULONGLONG HackFlags)
Definition: enum.c:1492
NTSTATUS NTAPI PciQueryResources(IN PPCI_PDO_EXTENSION PdoExtension, OUT PCM_RESOURCE_LIST *Buffer)
Definition: enum.c:363
BOOLEAN PciEnableNativeModeATA
Definition: init.c:24
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
NTSYSAPI BOOLEAN InitSafeBootMode
Definition: init.c:71
VOID NTAPI PPBridge_SaveCurrentSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:225
NTSTATUS NTAPI PciPdoCreate(IN PPCI_FDO_EXTENSION DeviceExtension, IN PCI_SLOT_NUMBER Slot, OUT PDEVICE_OBJECT *PdoDeviceObject)
Definition: pdo.c:530
VOID NTAPI PciWriteDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:91
VOID NTAPI PPBridge_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context, IN PPCI_COMMON_HEADER PciData, IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
Definition: ppbridge.c:628
@ PciStarted
Definition: pci.h:130
@ PciSynchronizedOperation
Definition: pci.h:134
PWCHAR NTAPI PciGetDeviceDescriptionMessage(IN UCHAR BaseClass, IN UCHAR SubClass)
Definition: id.c:88
BOOLEAN NTAPI PciIsSlotPresentInParentMethod(IN PPCI_PDO_EXTENSION PdoExtension, IN ULONG Method)
Definition: utils.c:1094
BOOLEAN PciAssignBusNumbers
Definition: config.c:18
struct _PCI_PDO_EXTENSION * PPCI_PDO_EXTENSION
NTSTATUS NTAPI PciCancelStateTransition(IN PPCI_FDO_EXTENSION DeviceExtension, IN PCI_STATE NewState)
Definition: state.c:145
PCI_DEVICE_TYPES NTAPI PciClassifyDeviceType(IN PPCI_PDO_EXTENSION PdoExtension)
Definition: utils.c:1051
NTSTATUS NTAPI PciBeginStateTransition(IN PPCI_FDO_EXTENSION DeviceExtension, IN PCI_STATE NewState)
Definition: state.c:97
NTSTATUS NTAPI PciGetBiosConfig(IN PPCI_PDO_EXTENSION DeviceExtension, OUT PPCI_COMMON_HEADER PciData)
Definition: utils.c:768
VOID NTAPI PPBridge_RestoreCurrent(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:620
#define PCI_SKIP_RESOURCE_ENUMERATION
Definition: pci.h:65
#define PCI_HACK_FIXUP_BEFORE_UPDATE
Definition: pci.h:72
PPCI_PDO_EXTENSION NTAPI PciFindPdoByFunction(IN PPCI_FDO_EXTENSION DeviceExtension, IN ULONG FunctionNumber, IN PPCI_COMMON_HEADER PciData)
Definition: utils.c:695
VOID NTAPI PPBridge_MassageHeaderForLimitsDetermination(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:582
BOOLEAN NTAPI PciIsDeviceOnDebugPath(IN PPCI_PDO_EXTENSION DeviceExtension)
Definition: utils.c:751
#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
BOOLEAN NTAPI PciIsCriticalDeviceClass(IN UCHAR BaseClass, IN UCHAR SubClass)
Definition: utils.c:672
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
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
VOID NTAPI PPBridge_ChangeResourceSettings(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: ppbridge.c:683
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
VOID NTAPI PPBridge_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:465
#define PCI_HACK_FIXUP_AFTER_CONFIGURATION
Definition: pci.h:71
@ PciTypePciBridge
Definition: pci.h:119
#define PCI_SKIP_DEVICE_ENUMERATION
Definition: pci.h:64
KIPI_BROADCAST_WORKER PciExecuteCriticalSystemRoutine
Definition: pci.h:1132
#define ASSERT_PDO(x)
Definition: pci.h:38
#define PCI_HACK_FIXUP_BEFORE_CONFIGURATION
Definition: pci.h:70
VOID NTAPI PPBridge_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: ppbridge.c:673
VOID NTAPI PciReadDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:107
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
@ PdoExtension
Definition: precomp.h:49
@ FdoExtension
Definition: precomp.h:48
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
struct _DEVICE_OBJECT * PDEVICE_OBJECT
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
unsigned int Native
Definition: fpcontrol.c:84
Status
Definition: gdiplustypes.h:25
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 * u
Definition: glfuncs.h:240
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
NTSTATUS NTAPI KdDisableDebugger(VOID)
Definition: kdapi.c:2169
NTSTATUS NTAPI KdEnableDebugger(VOID)
Definition: kdapi.c:2158
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
int k
Definition: mpi.c:3369
#define CM_RESOURCE_PORT_POSITIVE_DECODE
Definition: cmtypes.h:113
#define CM_RESOURCE_MEMORY_READ_WRITE
Definition: cmtypes.h:121
#define CM_RESOURCE_PORT_10_BIT_DECODE
Definition: cmtypes.h:110
#define KernelMode
Definition: asm.h:38
int Count
Definition: noreturn.cpp:7
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
BOOLEAN NTAPI ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature)
Definition: sysinfo.c:363
ULONG_PTR NTAPI KeIpiGenericCall(_In_ PKIPI_BROADCAST_WORKER Function, _In_ ULONG_PTR Argument)
Definition: ipi.c:44
@ 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 STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:522
unsigned short USHORT
Definition: pedump.c:61
#define CmResourceTypeNull
Definition: restypes.h:103
struct _CM_RESOURCE_LIST CM_RESOURCE_LIST
#define CmResourceTypeMemory
Definition: restypes.h:106
#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
Definition: restypes.h:116
#define CmResourceTypeDevicePrivate
Definition: restypes.h:112
@ PCIBus
Definition: restypes.h:126
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR CM_PARTIAL_RESOURCE_DESCRIPTOR
#define CmResourceTypePort
Definition: restypes.h:104
#define CmResourceTypeInterrupt
Definition: restypes.h:105
struct _IO_RESOURCE_DESCRIPTOR IO_RESOURCE_DESCRIPTOR
#define PCI_HACK_PRESERVE_COMMAND
Definition: pci.h:24
#define PCI_HACK_CRITICAL_DEVICE
Definition: pci.h:47
#define PCI_ENABLE_BRIDGE_VGA
Definition: pci.h:62
#define PCI_HACK_ENUM_NO_RESOURCE
Definition: pci.h:14
#define PCI_HACK_NO_REVISION_AFTER_D3
Definition: pci.h:50
#define PCI_HACK_ONE_CHILD
Definition: pci.h:23
#define PCI_HACK_DONT_DISABLE_DECODES
Definition: pci.h:40
#define PCI_HACK_NO_SUBSYSTEM_AFTER_D3
Definition: pci.h:41
#define PCI_HACK_NO_SUBSYSTEM
Definition: pci.h:32
#define PCI_HACK_FAKE_CLASS_CODE
Definition: pci.h:43
#define PCI_HACK_VIDEO_LEGACY_DECODE
Definition: pci.h:42
#define PCI_HACK_NO_ENUM_AT_ALL
Definition: pci.h:13
#define PCI_HACK_DISABLE_IDE_NATIVE_MODE
Definition: pci.h:45
#define PCI_HACK_DOUBLE_DECKER
Definition: pci.h:22
#define PCI_HACK_BROKEN_SUBTRACTIVE_DECODE
Definition: pci.h:49
#define PCI_HACK_NO_PM_CAPS
Definition: pci.h:39
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ PVOID Context
Definition: storport.h:2269
Definition: shell.h:41
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: restypes.h:144
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384::@387 Interrupt
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384::@391 DevicePrivate
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@384::@385 Generic
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: restypes.h:100
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2165
PCI_CONFIGURATOR_CHANGE_RESOURCE_SETTINGS ChangeResourceSettings
Definition: pci.h:480
PCI_CONFIGURATOR_SAVE_LIMITS SaveLimits
Definition: pci.h:478
PCI_CONFIGURATOR_RESET_DEVICE ResetDevice
Definition: pci.h:482
PCI_CONFIGURATOR_INITIALIZE Initialize
Definition: pci.h:476
PCI_CONFIGURATOR_SAVE_CURRENT_SETTINGS SaveCurrentSettings
Definition: pci.h:479
CM_PARTIAL_RESOURCE_DESCRIPTOR Current[7]
Definition: pci.h:237
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
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
union _PCI_SLOT_NUMBER::@4359 u
struct _PCI_SLOT_NUMBER::@4359::@4360 bits
PBIOS_DATA BiosData
Definition: bios.c:42
_In_ PNET_PNP_EVENT _In_ PTDI_PNP_CONTEXT _In_ PTDI_PNP_CONTEXT Context2
Definition: tdikrnl.h:1096
unsigned char UCHAR
Definition: typedefs.h:53
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_In_ WDFDEVICE _In_ PWDF_DEVICE_POWER_CAPABILITIES PowerCapabilities
Definition: wdfdevice.h:3892
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
Definition: wdfresource.h:309
_In_ WDFIORESREQLIST RequirementsList
Definition: wdfresource.h:65
_In_ WDFIORESREQLIST _In_ ULONG SlotNumber
Definition: wdfresource.h:68
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
@ CmResourceShareDeviceExclusive
Definition: cmtypes.h:241
@ CmResourceShareShared
Definition: cmtypes.h:243
@ CmResourceShareDriverExclusive
Definition: cmtypes.h:242
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:160
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3603
#define PCI_CAPABILITY_ID_AGP
Definition: iotypes.h:3650
#define PCI_CAPABILITY_ID_PCIX
Definition: iotypes.h:3655
#define PCI_ENABLE_BUS_MASTER
Definition: iotypes.h:3620
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define PCI_ENABLE_WRITE_AND_INVALIDATE
Definition: iotypes.h:3622
#define PCI_SUBCLASS_BR_EISA
Definition: iotypes.h:4166
#define PCI_SUBCLASS_BR_HOST
Definition: iotypes.h:4164
#define PCI_TYPE0_ADDRESSES
Definition: iotypes.h:3502
#define PCI_ENABLE_IO_SPACE
Definition: iotypes.h:3618
#define PCI_SUBCLASS_BR_PCI_TO_PCI
Definition: iotypes.h:4168
#define PCI_CLASS_MASS_STORAGE_CTLR
Definition: iotypes.h:4106
struct _PCI_AGP_CAPABILITY PCI_AGP_CAPABILITY
#define PCI_SUBCLASS_SYS_OTHER
Definition: iotypes.h:4187
#define PCI_CONFIGURATION_TYPE(PciData)
Definition: iotypes.h:3611
#define PCI_SUBCLASS_MSC_IDE_CTLR
Definition: iotypes.h:4131
#define PCI_ENABLE_MEMORY_SPACE
Definition: iotypes.h:3619
#define PCI_SUBCLASS_BR_MCA
Definition: iotypes.h:4167
#define PCI_MAX_FUNCTION
Definition: iotypes.h:3601
struct _PCI_PM_CAPABILITY PCI_PM_CAPABILITY
#define PCI_BRIDGE_TYPE
Definition: iotypes.h:3608
#define PCI_COMMON_HDR_LENGTH
Definition: iotypes.h:3596
#define PCI_SUBCLASS_BR_ISA
Definition: iotypes.h:4165
#define PCI_CLASS_BRIDGE_DEV
Definition: iotypes.h:4111
#define PCI_SUBCLASS_BR_CARDBUS
Definition: iotypes.h:4171
#define PCI_STATUS_CAPABILITIES_LIST
Definition: iotypes.h:3632
#define PCI_CAPABILITY_ID_POWER_MANAGEMENT
Definition: iotypes.h:3649
#define PCI_CLASS_NOT_DEFINED
Definition: iotypes.h:4123
#define PCI_CLASS_BASE_SYSTEM_DEV
Definition: iotypes.h:4113
#define PCI_CAPABILITY_ID_AGP_TARGET
Definition: iotypes.h:3662
#define PCI_MAX_DEVICES
Definition: iotypes.h:3600
#define PCI_MULTIFUNCTION_DEVICE(PciData)
Definition: iotypes.h:3614
#define PCI_CARDBUS_BRIDGE_TYPE
Definition: iotypes.h:3609
struct _IO_RESOURCE_REQUIREMENTS_LIST IO_RESOURCE_REQUIREMENTS_LIST
#define PF_PAE_ENABLED
Definition: ketypes.h:185
@ Executive
Definition: ketypes.h:467
#define ObReferenceObject
Definition: obfuncs.h:204