ReactOS  0.4.13-dev-92-gf251225
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 
53 BOOLEAN
54 NTAPI
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 */
113  case CmResourceTypePort:
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 = PciNextPartialDescriptor(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 }
235 
236 VOID
237 NTAPI
239  IN PVOID Context2)
240 {
242  PPCI_COMMON_HEADER PciData = Context2;
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 }
262 
263 VOID
264 NTAPI
266  IN PPCI_COMMON_HEADER PciData)
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 }
288 
290 NTAPI
294 {
295  SIZE_T Size;
296  PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
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 */
304  RequirementsList = ExAllocatePoolWithTag(PagedPool, Size, 'BicP');
305  if (!RequirementsList) return NULL;
306 
307  /* Initialize it */
308  RtlZeroMemory(RequirementsList, Size);
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 }
321 
323 NTAPI
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 }
351 
352 NTSTATUS
353 NTAPI
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 */
505  *Buffer = ResourceList;
506  return STATUS_SUCCESS;
507 }
508 
509 NTSTATUS
510 NTAPI
512  IN OUT PDEVICE_RELATIONS *pDeviceRelations)
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 }
535 
536 NTSTATUS
537 NTAPI
539  IN OUT PDEVICE_RELATIONS *pDeviceRelations)
540 {
542  UNREFERENCED_PARAMETER(pDeviceRelations);
543 
544  /* Not yet implemented */
546  return STATUS_NOT_IMPLEMENTED;
547 }
548 
549 NTSTATUS
550 NTAPI
552  IN PPCI_COMMON_HEADER PciData,
554 {
555  PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList;
556 
558  UNREFERENCED_PARAMETER(PciData);
559 
560  {
561  /* There aren't, so use the zero descriptor */
562  RequirementsList = PciZeroIoResourceRequirements;
563 
564  /* Does it actually exist yet? */
566  {
567  /* Allocate it, and use it for future use */
568  RequirementsList = PciAllocateIoRequirementsList(0, 0, 0);
569  PciZeroIoResourceRequirements = RequirementsList;
571  }
572 
573  /* Return the zero requirements list to the caller */
574  *Buffer = RequirementsList;
575  DPRINT1("PCI - build resource reqs - early out, 0 resources\n");
576  return STATUS_SUCCESS;
577  }
578  return STATUS_SUCCESS;
579 }
580 
581 NTSTATUS
582 NTAPI
584  IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *RequirementsList)
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 */
597  Status = PciBuildRequirementsList(PdoExtension, &PciHeader, RequirementsList);
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 */
611  if (*RequirementsList == PciZeroIoResourceRequirements)
612  {
613  /* A simple NULL will suffice for the PnP Manager */
614  *RequirementsList = NULL;
615  DPRINT1("Returning NULL requirements list\n");
616  }
617  else
618  {
619  /* Otherwise, print out the requirements list */
620  PciDebugPrintIoResReqList(*RequirementsList);
621  }
622  }
623  else
624  {
625  /* There aren't any resources, so simply return NULL */
626  DPRINT1("PciQueryRequirements returning NULL requirements list\n");
627  *RequirementsList = NULL;
628  }
629 
630  /* This call always succeeds (but maybe with no requirements) */
631  return STATUS_SUCCESS;
632 }
633 
634 /*
635  * 7. The IO/MEM/Busmaster decodes are disabled for the device.
636  * 8. The PCI bus driver sets the operating mode bits of the Programming
637  * Interface byte to switch the controller to native mode.
638  *
639  * Important: When the controller is set to native mode, it must quiet itself
640  * and must not decode I/O resources or generate interrupts until the operating
641  * system has enabled the ports in the PCI configuration header.
642  * The IO/MEM/BusMaster bits will be disabled before the mode change, but it
643  * is not possible to disable interrupts on the device. The device must not
644  * generate interrupts (either legacy or native mode) while the decodes are
645  * disabled in the command register.
646  *
647  * This operation is expected to be instantaneous and the operating system does
648  * not stall afterward. It is also expected that the interrupt pin register in
649  * the PCI Configuration space for this device is accurate. The operating system
650  * re-reads this data after previously ignoring it.
651  */
652 BOOLEAN
653 NTAPI
655  IN PPCI_COMMON_HEADER PciData,
656  IN BOOLEAN Initial)
657 {
658  UCHAR MasterMode, SlaveMode, MasterFixed, SlaveFixed, ProgIf, NewProgIf;
659  BOOLEAN Switched;
660  USHORT Command;
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 */
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 }
791 
792 VOID
793 NTAPI
795  IN PPCI_COMMON_HEADER PciData,
797  IN ULONG OperationType,
799 {
800  ULONG LegacyBaseAddress;
801  USHORT Command;
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  */
901  if ((PciEnableNativeModeATA) &&
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 }
1060 
1061 BOOLEAN
1062 NTAPI
1064  IN PPCI_COMMON_HEADER PciData)
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 */
1075  RevMatch = (HackFlags & PCI_HACK_NO_REVISION_AFTER_D3) ||
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 }
1094 
1095 BOOLEAN
1096 NTAPI
1098  IN PCI_SLOT_NUMBER Slot,
1099  IN UCHAR OperationType,
1100  IN ULONGLONG HackFlags)
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 */
1108  if (HackFlags & PCI_HACK_NO_ENUM_AT_ALL) break;
1109 
1110  /* Check if this is the high end of a double decker device */
1111  if ((HackFlags & PCI_HACK_DOUBLE_DECKER) &&
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 */
1126  if (HackFlags & PCI_HACK_ENUM_NO_RESOURCE) break;
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 */
1161  if (PCI_CONFIGURATION_TYPE(PciData) <= PCI_CARDBUS_BRIDGE_TYPE) return FALSE;
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 }
1168 
1169 VOID
1170 NTAPI
1172  IN PPCI_COMMON_HEADER PciData)
1173 {
1174  ULONG HeaderType, CapPtr, TargetAgpCapabilityId;
1175  DEVICE_POWER_STATE WakeLevel;
1176  PCI_CAPABILITIES_HEADER AgpCapability;
1177  PCI_PM_CAPABILITY PowerCapabilities;
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) ||
1221  (PdoExtension->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI)))
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 }
1296 
1297 VOID
1298 NTAPI
1300  IN PVOID Context2)
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 }
1339 
1340 NTSTATUS
1341 NTAPI
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 */
1448  RtlZeroMemory(PdoExtension->Resources, sizeof(PCI_FUNCTION_RESOURCES));
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 }
1480 
1481 NTSTATUS
1482 NTAPI
1484  IN PPCI_COMMON_HEADER Current,
1485  IN ULONGLONG HackFlags)
1486 {
1487  NTSTATUS Status;
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 }
1516 
1517 VOID
1518 NTAPI
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;
1549  PdoExtension;
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 */
1562  if (PciAssignBusNumbers)
1563  {
1564  /* Not yet supported */
1566  }
1567 }
1568 
1569 NTSTATUS
1570 NTAPI
1572 {
1573  ULONG MaxDevice = PCI_MAX_DEVICES;
1574  BOOLEAN ProcessFlag = FALSE;
1575  ULONG i, j, k, Size;
1576  USHORT CapOffset, TempOffset;
1577  LONGLONG HackFlags;
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;
1585  NTSTATUS Status;
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 */
1702  if (!(HackFlags & PCI_HACK_DONT_DISABLE_DECODES))
1703  {
1704  /* Because this device is critical, don't disable them */
1705  DPRINT1("Not allowing PM Because device is critical\n");
1706  HackFlags |= PCI_HACK_CRITICAL_DEVICE;
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) &&
1714  !(HackFlags & PCI_HACK_DONT_DISABLE_DECODES))
1715  {
1716  /* Do not disable their decodes either */
1717  DPRINT1("Not allowing PM because device is VGA\n");
1718  HackFlags |= PCI_HACK_CRITICAL_DEVICE;
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);
1748 
1749  /* Check for broken devices with wrong/no class codes */
1750  if (HackFlags & PCI_HACK_FAKE_CLASS_CODE)
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");
1804  UNIMPLEMENTED;
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 */
1879  if (HackFlags & PCI_HACK_NO_SUBSYSTEM)
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 */
1916  case PCI_CAPABILITY_ID_AGP:
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 */
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 }
2031 
2032 NTSTATUS
2033 NTAPI
2035  IN OUT PDEVICE_RELATIONS *pDeviceRelations)
2036 {
2037  NTSTATUS Status;
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;
2054  PdoExtension;
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;
2067  PdoExtension;
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,
2125  PdoExtension,
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 }
2152 
2153 NTSTATUS
2154 NTAPI
2156  IN BOOLEAN DoReset,
2157  IN BOOLEAN SomethingSomethingDarkSide)
2158 {
2160  UCHAR NewCacheLineSize, NewLatencyTimer;
2161  PCI_COMMON_HEADER PciData;
2162  BOOLEAN Native;
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) &&
2190  (PdoExtension->SubClass == PCI_SUBCLASS_MSC_IDE_CTLR))
2191  {
2192  /* Turn off native mode */
2193  Native = PciConfigureIdeController(PdoExtension, &PciData, FALSE);
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",
2228  PdoExtension,
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",
2239  PdoExtension,
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 */
2264  PciUpdateHardware(PdoExtension, &PciData);
2265 
2266  /* Update complete */
2267  PdoExtension->RawInterruptLine = PciData.u.type0.InterruptLine;
2268  PdoExtension->NeedsHotPlugConfiguration = FALSE;
2269  return STATUS_SUCCESS;
2270 }
2271 
2272 /* EOF */
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 DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
PVOID Context
Definition: pci.h:514
signed char * PCHAR
Definition: retypes.h:7
NTSTATUS NTAPI PciBuildRequirementsList(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData, OUT PIO_RESOURCE_REQUIREMENTS_LIST *Buffer)
Definition: enum.c:551
VOID NTAPI Device_SaveCurrentSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: device.c:20
ULONG Barrier
Definition: pci.h:511
VOID NTAPI PPBridge_SaveCurrentSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:225
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:414
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
#define PCI_TYPE0_ADDRESSES
Definition: iotypes.h:3143
#define PCI_STATUS_CAPABILITIES_LIST
Definition: iotypes.h:3273
VOID NTAPI PciUpdateHardware(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: enum.c:265
#define IN
Definition: typedefs.h:38
BOOLEAN NTAPI PciComputeNewCurrentSettings(IN PPCI_PDO_EXTENSION PdoExtension, IN PCM_RESOURCE_LIST ResourceList)
Definition: enum.c:55
PCI_CONFIGURATOR PciConfigurators[]
Definition: enum.c:20
PCI_CONFIGURATOR_SAVE_CURRENT_SETTINGS SaveCurrentSettings
Definition: pci.h:477
VOID NTAPI Device_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context, IN PPCI_COMMON_HEADER PciData, IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
Definition: device.c:259
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define CmResourceTypeDevicePrivate
Definition: hwresource.cpp:131
BOOLEAN NTAPI PciIsSlotPresentInParentMethod(IN PPCI_PDO_EXTENSION PdoExtension, IN ULONG Method)
Definition: utils.c:1094
BOOLEAN DisablePowerDown
Definition: pci.h:299
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
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
#define PCI_SKIP_RESOURCE_ENUMERATION
Definition: pci.h:63
Type
Definition: Type.h:6
#define PCI_CAPABILITY_ID_PCIX
Definition: iotypes.h:3296
USHORT VendorId
Definition: pci.h:276
BOOLEAN NTAPI ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature)
Definition: sysinfo.c:363
struct _PCI_PDO_EXTENSION * NextBridge
Definition: pci.h:311
union _PCI_PM_CAPABILITY::@3630 PMCSR
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define DbgPrint
Definition: loader.c:25
#define PCI_ENABLE_IO_SPACE
Definition: iotypes.h:3259
NTSTATUS NTAPI KdDisableDebugger(VOID)
Definition: kdmain.c:317
BOOLEAN RawInterruptLine
Definition: pci.h:287
#define PCI_CAPABILITY_ID_AGP_TARGET
Definition: iotypes.h:3303
BOOLEAN RevisionId
Definition: pci.h:280
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
struct _PCI_PMC::_PM_SUPPORT Support
struct _DEVICE_OBJECT * PDEVICE_OBJECT
VOID NTAPI Cardbus_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: cardbus.c:79
NTSTATUS NTAPI PciScanBus(IN PPCI_FDO_EXTENSION DeviceExtension)
Definition: enum.c:1571
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2054
PCI_PMC Capabilities
Definition: iotypes.h:3349
VOID NTAPI PPBridge_RestoreCurrent(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:620
NTSTATUS NTAPI PciPdoCreate(IN PPCI_FDO_EXTENSION DeviceExtension, IN PCI_SLOT_NUMBER Slot, OUT PDEVICE_OBJECT *PdoDeviceObject)
Definition: pdo.c:530
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@369::@376 DevicePrivate
BOOLEAN NTAPI PciIsDeviceOnDebugPath(IN PPCI_PDO_EXTENSION DeviceExtension)
Definition: utils.c:751
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI Cardbus_MassageHeaderForLimitsDetermination(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: cardbus.c:51
#define PCI_HACK_VIDEO_LEGACY_DECODE
Definition: pci.h:42
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@369 u
NTSTATUS NTAPI PciQueryResources(IN PPCI_PDO_EXTENSION PdoExtension, OUT PCM_RESOURCE_LIST *Buffer)
Definition: enum.c:354
VOID NTAPI PciProcessBus(IN PPCI_FDO_EXTENSION DeviceExtension)
Definition: enum.c:1519
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
#define PCI_HACK_DONT_DISABLE_DECODES
Definition: pci.h:40
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@369::@372 Interrupt
BOOLEAN ExpectedWritebackFailure
Definition: pci.h:294
USHORT CommandEnables
Definition: pci.h:316
BOOLEAN NTAPI PciIsCriticalDeviceClass(IN UCHAR BaseClass, IN UCHAR SubClass)
Definition: utils.c:672
NTSTATUS NTAPI PciQueryRequirements(IN PPCI_PDO_EXTENSION PdoExtension, IN OUT PIO_RESOURCE_REQUIREMENTS_LIST *RequirementsList)
Definition: enum.c:583
struct _IO_RESOURCE_REQUIREMENTS_LIST IO_RESOURCE_REQUIREMENTS_LIST
uint16_t * PWCHAR
Definition: typedefs.h:54
Definition: shell.h:41
VOID NTAPI ario_ApplyBrokenVideoHack(IN PPCI_FDO_EXTENSION FdoExtension)
Definition: ar_memio.c:104
VOID NTAPI Device_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: device.c:118
VOID NTAPI Device_RestoreCurrent(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: device.c:250
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
BOOLEAN InterruptPin
Definition: pci.h:286
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
const MUI_LANGUAGE_RESOURCE ResourceList[]
Definition: muilanguages.h:414
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR CM_PARTIAL_RESOURCE_DESCRIPTOR
#define CM_RESOURCE_MEMORY_READ_WRITE
Definition: cmtypes.h:120
#define CmResourceTypePort
Definition: hwresource.cpp:123
struct _PCI_PDO_EXTENSION * PPCI_PDO_EXTENSION
#define PAGED_CODE()
Definition: video.h:57
USHORT SubsystemId
Definition: pci.h:279
NTSTATUS NTAPI PciSetPowerManagedDevicePowerState(IN PPCI_PDO_EXTENSION DeviceExtension, IN DEVICE_POWER_STATE DeviceState, IN BOOLEAN IrpSet)
Definition: power.c:121
BOOLEAN NTAPI PciSkipThisFunction(IN PPCI_COMMON_HEADER PciData, IN PCI_SLOT_NUMBER Slot, IN UCHAR OperationType, IN ULONGLONG HackFlags)
Definition: enum.c:1097
#define PCI_CLASS_NOT_DEFINED
Definition: iotypes.h:3764
uint32_t ULONG_PTR
Definition: typedefs.h:63
NTSTATUS NTAPI PciQueryEjectionRelations(IN PPCI_PDO_EXTENSION PdoExtension, IN OUT PDEVICE_RELATIONS *pDeviceRelations)
Definition: enum.c:538
#define PCI_SUBCLASS_BR_CARDBUS
Definition: iotypes.h:3811
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
VOID NTAPI Device_MassageHeaderForLimitsDetermination(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: device.c:218
#define ASSERT_PDO(x)
Definition: pci.h:36
BOOLEAN PciEnableNativeModeATA
Definition: init.c:24
VOID NTAPI PciWriteDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:91
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
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:848
USHORT InitialCommand
Definition: pci.h:317
BOOLEAN SubClass
Definition: pci.h:282
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
VOID NTAPI PcipUpdateHardware(IN PVOID Context, IN PVOID Context2)
Definition: enum.c:238
PIO_RESOURCE_REQUIREMENTS_LIST NTAPI PciAllocateIoRequirementsList(IN ULONG Count, IN ULONG BusNumber, IN ULONG SlotNumber)
Definition: enum.c:291
#define PCI_HACK_FAKE_CLASS_CODE
Definition: pci.h:43
#define PCI_ENABLE_WRITE_AND_INVALIDATE
Definition: iotypes.h:3263
VOID NTAPI Cardbus_RestoreCurrent(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: cardbus.c:59
#define PCI_HACK_DISABLE_IDE_NATIVE_MODE
Definition: pci.h:45
struct NameRec_ * Name
Definition: cdprocs.h:464
NTSTATUS NTAPI PciSetResources(IN PPCI_PDO_EXTENSION PdoExtension, IN BOOLEAN DoReset, IN BOOLEAN SomethingSomethingDarkSide)
Definition: enum.c:2155
#define PCI_HACK_FIXUP_AFTER_CONFIGURATION
Definition: pci.h:69
PCI_DEVICE_TYPES NTAPI PciClassifyDeviceType(IN PPCI_PDO_EXTENSION PdoExtension)
Definition: utils.c:1051
PCI_CONFIGURATOR_INITIALIZE Initialize
Definition: pci.h:474
#define PCI_HACK_CRITICAL_DEVICE
Definition: pci.h:47
NTSTATUS NTAPI PciCancelStateTransition(IN PPCI_FDO_EXTENSION DeviceExtension, IN PCI_STATE StateNotEntered)
Definition: state.c:145
INTERFACE_TYPE InterfaceType
Definition: iotypes.h:2387
VOID NTAPI PciDebugPrintPartialResource(IN PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResource)
Definition: debug.c:348
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define PCI_CAPABILITY_ID_POWER_MANAGEMENT
Definition: iotypes.h:3290
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
unsigned char BOOLEAN
PCM_RESOURCE_LIST NTAPI PciAllocateCmResourceList(IN ULONG Count, IN ULONG BusNumber)
Definition: enum.c:324
NTSTATUS NTAPI PciGetBiosConfig(IN PPCI_PDO_EXTENSION DeviceExtension, OUT PPCI_COMMON_HEADER PciData)
Definition: utils.c:768
smooth NULL
Definition: ftsmooth.c:416
KIPI_BROADCAST_WORKER PciExecuteCriticalSystemRoutine
Definition: pci.h:1130
PWATCHDOG_TABLE WdTable
Definition: init.c:27
NTSTATUS NTAPI PciSaveBiosConfig(IN PPCI_PDO_EXTENSION DeviceExtension, OUT PPCI_COMMON_HEADER PciData)
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
Definition: bufpool.h:45
#define PCI_HACK_ENUM_NO_RESOURCE
Definition: pci.h:14
void * PVOID
Definition: retypes.h:9
ULONGLONG NTAPI PciGetHackFlags(IN USHORT VendorId, IN USHORT DeviceId, IN USHORT SubVendorId, IN USHORT SubSystemId, IN UCHAR RevisionId)
Definition: utils.c:604
struct _PCI_PM_CAPABILITY PCI_PM_CAPABILITY
#define CM_RESOURCE_PORT_10_BIT_DECODE
Definition: cmtypes.h:110
VOID NTAPI PPBridge_MassageHeaderForLimitsDetermination(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:582
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:156
BOOLEAN PciAssignBusNumbers
Definition: config.c:18
union _PCI_SLOT_NUMBER::@3627 u
PCI_CONFIGURATOR_SAVE_LIMITS SaveLimits
Definition: pci.h:476
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
BOOLEAN SavedLatencyTimer
Definition: pci.h:289
VOID NTAPI Cardbus_SaveCurrentSettings(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: cardbus.c:35
enum _DEVICE_POWER_STATE DEVICE_POWER_STATE
int64_t LONGLONG
Definition: typedefs.h:66
VOID NTAPI PPBridge_ChangeResourceSettings(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: ppbridge.c:683
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3244
VOID NTAPI PPBridge_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: ppbridge.c:673
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define CmResourceTypeNull
Definition: hwresource.cpp:122
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct Command Command
#define CM_RESOURCE_PORT_POSITIVE_DECODE
Definition: cmtypes.h:113
uint64_t ULONGLONG
Definition: typedefs.h:65
struct _PCI_SLOT_NUMBER::@3627::@3628 bits
#define PCI_ENABLE_BUS_MASTER
Definition: iotypes.h:3261
VOID NTAPI PciGetEnhancedCapabilities(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: enum.c:1171
#define PCI_MAX_DEVICES
Definition: iotypes.h:3241
VOID NTAPI Device_ChangeResourceSettings(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: device.c:283
#define PCI_SUBCLASS_BR_MCA
Definition: iotypes.h:3807
NTSTATUS NTAPI PciGetFunctionLimits(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER Current, IN ULONGLONG HackFlags)
Definition: enum.c:1483
#define PCI_HACK_NO_ENUM_AT_ALL
Definition: pci.h:13
NTSTATUS NTAPI KdEnableDebugger(VOID)
Definition: kdmain.c:342
#define PCI_HACK_NO_SUBSYSTEM_AFTER_D3
Definition: pci.h:41
NTSTATUS NTAPI PciQueryTargetDeviceRelations(IN PPCI_PDO_EXTENSION PdoExtension, IN OUT PDEVICE_RELATIONS *pDeviceRelations)
Definition: enum.c:511
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PCI_CONFIGURATOR_RESET_DEVICE ResetDevice
Definition: pci.h:480
VOID NTAPI PPBridge_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: ppbridge.c:465
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PCI_HACK_NO_REVISION_AFTER_D3
Definition: pci.h:50
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG _In_ ULONG SlotNumber
Definition: halfuncs.h:156
unsigned char UCHAR
Definition: xmlstorage.h:181
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
NTSTATUS NTAPI PciBeginStateTransition(IN PPCI_FDO_EXTENSION DeviceExtension, IN PCI_STATE NewState)
Definition: state.c:97
IO_RESOURCE_LIST List[1]
Definition: iotypes.h:2392
static const WCHAR L[]
Definition: oid.c:1250
LONG RunCount
Definition: pci.h:510
BOOLEAN NTAPI PcipIsSameDevice(IN PPCI_PDO_EXTENSION DeviceExtension, IN PPCI_COMMON_HEADER PciData)
Definition: enum.c:1063
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define PCI_HACK_FIXUP_BEFORE_CONFIGURATION
Definition: pci.h:68
#define PCI_SUBCLASS_BR_PCI_TO_PCI
Definition: iotypes.h:3808
BOOLEAN NTAPI PciConfigureIdeController(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData, IN BOOLEAN Initial)
Definition: enum.c:654
#define PCI_MULTIFUNCTION_DEVICE(PciData)
Definition: iotypes.h:3255
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define PCI_SUBCLASS_MSC_IDE_CTLR
Definition: iotypes.h:3772
PPCI_PDO_EXTENSION NTAPI PciFindPdoByFunction(IN PPCI_FDO_EXTENSION DeviceExtension, IN ULONG FunctionNumber, IN PPCI_COMMON_HEADER PciData)
Definition: utils.c:695
ULONGLONG HackFlags
Definition: pci.h:308
struct _CM_RESOURCE_LIST CM_RESOURCE_LIST
_In_ PNET_PNP_EVENT _In_ PTDI_PNP_CONTEXT _In_ PTDI_PNP_CONTEXT Context2
Definition: tdikrnl.h:1094
PCM_PARTIAL_RESOURCE_DESCRIPTOR NTAPI PciNextPartialDescriptor(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor)
Definition: utils.c:1769
Status
Definition: gdiplustypes.h:24
struct _IO_RESOURCE_DESCRIPTOR IO_RESOURCE_DESCRIPTOR
#define PCI_MAX_FUNCTION
Definition: iotypes.h:3242
VOID NTAPI PciDebugPrintCmResList(IN PCM_RESOURCE_LIST PartialList)
Definition: debug.c:364
union _PCI_PM_CAPABILITY::@3629 PMC
#define PCI_IS_ROOT_FDO(x)
Definition: pci.h:30
PVOID DeviceExtension
Definition: pci.h:512
PCI_PMCSR ControlStatus
Definition: iotypes.h:3353
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
ULONG_PTR SIZE_T
Definition: typedefs.h:78
VOID NTAPI PciDebugDumpCommonConfig(IN PPCI_COMMON_HEADER PciData)
Definition: debug.c:207
BOOLEAN SavedCacheLineSize
Definition: pci.h:290
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
struct _PCI_AGP_CAPABILITY PCI_AGP_CAPABILITY
unsigned short USHORT
Definition: pedump.c:61
#define PF_PAE_ENABLED
BOOLEAN CapabilitiesPtr
Definition: pci.h:288
#define PCI_SKIP_DEVICE_ENUMERATION
Definition: pci.h:62
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@369::@370 Generic
BOOLEAN HeaderType
Definition: pci.h:291
VOID NTAPI Cardbus_ChangeResourceSettings(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: cardbus.c:89
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
#define PCI_HACK_ONE_CHILD
Definition: pci.h:23
NTSTATUS NTAPI PcipGetFunctionLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: enum.c:1342
#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
Definition: cmtypes.h:143
#define PCI_ENABLE_BRIDGE_VGA
Definition: pci.h:62
VOID NTAPI PciDebugPrintIoResReqList(IN PIO_RESOURCE_REQUIREMENTS_LIST Requirements)
Definition: debug.c:302
USHORT PowerState
Definition: iotypes.h:3332
#define PCI_HACK_NO_PM_CAPS
Definition: pci.h:39
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
VOID NTAPI PciWriteLimitsAndRestoreCurrent(IN PVOID Reserved, IN PVOID Context2)
Definition: enum.c:1299
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
#define DPRINT1
Definition: precomp.h:8
VOID NTAPI PciDecodeEnable(IN PPCI_PDO_EXTENSION PdoExtension, IN BOOLEAN Enable, OUT PUSHORT Command)
Definition: utils.c:1267
#define PCI_ENABLE_MEMORY_SPACE
Definition: iotypes.h:3260
VOID NTAPI PciReadDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:107
#define PCI_SUBCLASS_SYS_OTHER
Definition: iotypes.h:3827
BOOLEAN OnDebugPath
Definition: pci.h:304
#define PCI_HACK_DOUBLE_DECKER
Definition: pci.h:22
#define OUT
Definition: typedefs.h:39
#define ObReferenceObject
Definition: obfuncs.h:204
USHORT SubsystemVendorId
Definition: pci.h:278
NTSYSAPI BOOLEAN InitSafeBootMode
Definition: init.c:68
VOID NTAPI Device_ResetDevice(IN PPCI_PDO_EXTENSION PdoExtension, IN PPCI_COMMON_HEADER PciData)
Definition: device.c:272
BOOLEAN AdjustedInterruptLine
Definition: pci.h:285
struct tagContext Context
Definition: acpixf.h:1012
#define PCI_CONFIGURATION_TYPE(PciData)
Definition: iotypes.h:3252
NTSTATUS NTAPI PciQueryDeviceRelations(IN PPCI_FDO_EXTENSION DeviceExtension, IN OUT PDEVICE_RELATIONS *pDeviceRelations)
Definition: enum.c:2034
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define PCI_SUBCLASS_BR_HOST
Definition: iotypes.h:3804
PWCHAR NTAPI PciGetDeviceDescriptionMessage(IN UCHAR BaseClass, IN UCHAR SubClass)
Definition: id.c:88
VOID NTAPI Cardbus_SaveLimits(IN PPCI_CONFIGURATOR_CONTEXT Context)
Definition: cardbus.c:43
#define PCI_CLASS_BRIDGE_DEV
Definition: iotypes.h:3752
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define PCI_SUBCLASS_BR_ISA
Definition: iotypes.h:3805
UCHAR NTAPI PciGetAdjustedInterruptLine(IN PPCI_PDO_EXTENSION PdoExtension)
Definition: config.c:24
#define CmResourceTypeMemory
Definition: hwresource.cpp:125
BOOLEAN NeedsHotPlugConfiguration
Definition: pci.h:300
#define PCI_CLASS_BASE_SYSTEM_DEV
Definition: iotypes.h:3754
return STATUS_SUCCESS
Definition: btrfs.c:2725
PIO_RESOURCE_REQUIREMENTS_LIST PciZeroIoResourceRequirements
Definition: enum.c:18
#define PCI_SUBCLASS_BR_EISA
Definition: iotypes.h:3806
BOOLEAN ProgIf
Definition: pci.h:281
USHORT DeviceId
Definition: pci.h:277
#define PCI_HACK_FIXUP_BEFORE_UPDATE
Definition: pci.h:70
#define PCI_HACK_PRESERVE_COMMAND
Definition: pci.h:24
int k
Definition: mpi.c:3369
BOOLEAN BaseClass
Definition: pci.h:283
unsigned short * PUSHORT
Definition: retypes.h:2
VOID NTAPI PPBridge_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context, IN PPCI_COMMON_HEADER PciData, IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
Definition: ppbridge.c:628
PCI_IPI_FUNCTION Function
Definition: pci.h:513
PBIOS_DATA BiosData
Definition: bios.c:42
PCI_CONFIGURATOR_CHANGE_RESOURCE_SETTINGS ChangeResourceSettings
Definition: pci.h:478
CM_PARTIAL_RESOURCE_DESCRIPTOR Current[7]
Definition: pci.h:235
ULONG_PTR NTAPI KeIpiGenericCall(IN PKIPI_BROADCAST_WORKER Function, IN ULONG_PTR Argument)
Definition: ipi.c:196
#define PCI_HACK_NO_SUBSYSTEM
Definition: pci.h:32
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define PCI_CARDBUS_BRIDGE_TYPE
Definition: iotypes.h:3250
#define PCI_HACK_BROKEN_SUBTRACTIVE_DECODE
Definition: pci.h:49
#define PCI_CAPABILITY_ID_AGP
Definition: iotypes.h:3291
#define PCI_CLASS_MASS_STORAGE_CTLR
Definition: iotypes.h:3747
VOID NTAPI Cardbus_GetAdditionalResourceDescriptors(IN PPCI_CONFIGURATOR_CONTEXT Context, IN PPCI_COMMON_HEADER PciData, IN PIO_RESOURCE_DESCRIPTOR IoDescriptor)
Definition: cardbus.c:67
#define PCI_COMMON_HDR_LENGTH
Definition: iotypes.h:3237
PCI_CAPABILITIES_HEADER Header
Definition: iotypes.h:3347
#define PCI_BRIDGE_TYPE
Definition: iotypes.h:3249