ReactOS  0.4.14-dev-98-gb0d4763
init.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/init.c
5  * PURPOSE: Driver Initialization
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 
29 
30 /* FUNCTIONS ******************************************************************/
31 
33 NTAPI
35 {
38  HANDLE KeyHandle, SubKey;
40  PKEY_FULL_INFORMATION FullInfo;
41  PKEY_BASIC_INFORMATION KeyInfo;
43  PACPI_BIOS_MULTI_NODE NodeData;
45  struct
46  {
49  } *Package;
50 
51  /* So we know what to free at the end of the body */
52  ValueInfo = NULL;
53  KeyInfo = NULL;
54  KeyHandle = NULL;
55  FullInfo = NULL;
56  Package = NULL;
57  do
58  {
59  /* Open the ACPI BIOS key */
60  Result = PciOpenKey(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\"
61  L"System\\MultiFunctionAdapter",
62  NULL,
64  &KeyHandle,
65  &Status);
66  if (!Result) break;
67 
68  /* Query how much space should be allocated for the key information */
69  Status = ZwQueryKey(KeyHandle,
71  NULL,
72  sizeof(ULONG),
73  &NumberOfBytes);
74  if (Status != STATUS_BUFFER_TOO_SMALL) break;
75 
76  /* Allocate the space required */
79  if ( !FullInfo ) break;
80 
81  /* Now query the key information that's needed */
82  Status = ZwQueryKey(KeyHandle,
84  FullInfo,
86  &NumberOfBytes);
87  if (!NT_SUCCESS(Status)) break;
88 
89  /* Allocate enough space to hold the value information plus the name */
91  Length = FullInfo->MaxNameLen + 26;
93  if ( !KeyInfo ) break;
94 
95  /* Allocate the value information and name we expect to find */
96  ValueInfo = ExAllocatePoolWithTag(PagedPool,
98  sizeof(L"ACPI BIOS"),
99  PCI_POOL_TAG);
100  if (!ValueInfo) break;
101 
102  /* Loop each sub-key */
103  i = 0;
104  while (TRUE)
105  {
106  /* Query each sub-key */
107  Status = ZwEnumerateKey(KeyHandle,
108  i++,
110  KeyInfo,
111  Length,
112  &NumberOfBytes);
113  if (Status == STATUS_NO_MORE_ENTRIES) break;
114 
115  /* Null-terminate the keyname, because the kernel does not */
116  KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
117 
118  /* Open this subkey */
119  Result = PciOpenKey(KeyInfo->Name,
120  KeyHandle,
122  &SubKey,
123  &Status);
124  if (Result)
125  {
126  /* Query the identifier value for this subkey */
127  RtlInitUnicodeString(&ValueName, L"Identifier");
128  Status = ZwQueryValueKey(SubKey,
129  &ValueName,
131  ValueInfo,
133  sizeof(L"ACPI BIOS"),
134  &NumberOfBytes);
135  if (NT_SUCCESS(Status))
136  {
137  /* Check if this is the PCI BIOS subkey */
138  if (!wcsncmp((PWCHAR)ValueInfo->Data,
139  L"ACPI BIOS",
140  ValueInfo->DataLength))
141  {
142  /* It is, proceed to query the PCI IRQ routing table */
143  Status = PciGetRegistryValue(L"Configuration Data",
144  KeyInfo->Name,
145  KeyHandle,
147  (PVOID*)&Package,
148  &NumberOfBytes);
149  ZwClose(SubKey);
150  break;
151  }
152  }
153 
154  /* Close the subkey and try the next one */
155  ZwClose(SubKey);
156  }
157  }
158 
159  /* Check if we got here because the routing table was found */
160  if (!NT_SUCCESS(Status))
161  {
162  /* This should only fail if we're out of entries */
164  break;
165  }
166 
167  /* Check if a descriptor was found */
168  if (!Package) break;
169 
170  /* The configuration data is a resource list, and the BIOS node follows */
171  NodeData = &Package->Node;
172 
173  /* How many E820 memory entries are there? */
174  Length = sizeof(ACPI_BIOS_MULTI_NODE) +
175  (NodeData->Count - 1) * sizeof(ACPI_E820_ENTRY);
176 
177  /* Allocate the buffer needed to copy the information */
180  if (!*AcpiMultiNode) break;
181 
182  /* Copy the data */
183  RtlCopyMemory(*AcpiMultiNode, NodeData, Length);
185  } while (FALSE);
186 
187  /* Close any opened keys, free temporary allocations, and return status */
188  if (Package) ExFreePoolWithTag(Package, 0);
189  if (ValueInfo) ExFreePoolWithTag(ValueInfo, 0);
190  if (KeyInfo) ExFreePoolWithTag(KeyInfo, 0);
191  if (FullInfo) ExFreePoolWithTag(FullInfo, 0);
193  return Status;
194 }
195 
196 PVOID
197 NTAPI
199 {
201  PACPI_BIOS_MULTI_NODE AcpiMultiNode;
202  PRSDT Rsdt;
203  PXSDT Xsdt;
204  ULONG EntryCount, TableLength, Offset, CurrentEntry;
205  PVOID TableBuffer, MappedAddress;
208 
209  /* Try to find the RSDT or XSDT */
210  Status = PciAcpiFindRsdt(&AcpiMultiNode);
211  if (!NT_SUCCESS(Status))
212  {
213  /* No ACPI on the machine */
214  DPRINT1("AcpiFindRsdt() Failed!\n");
215  return NULL;
216  }
217 
218  /* Map the RSDT with the minimum size allowed */
219  MappedAddress = MmMapIoSpace(AcpiMultiNode->RsdtAddress,
220  sizeof(DESCRIPTION_HEADER),
221  MmNonCached);
222  Header = MappedAddress;
223  if (!Header) return NULL;
224 
225  /* Check how big the table really is and get rid of the temporary header */
226  TableLength = Header->Length;
228  Header = NULL;
229 
230  /* Map its true size */
231  MappedAddress = MmMapIoSpace(AcpiMultiNode->RsdtAddress,
232  TableLength,
233  MmNonCached);
234  Rsdt = MappedAddress;
235  Xsdt = MappedAddress;
236  ExFreePoolWithTag(AcpiMultiNode, 0);
237  if (!Rsdt) return NULL;
238 
239  /* Validate the table's signature */
240  if ((Rsdt->Header.Signature != RSDT_SIGNATURE) &&
241  (Rsdt->Header.Signature != XSDT_SIGNATURE))
242  {
243  /* Very bad: crash */
244  HalDisplayString("RSDT table contains invalid signature\r\n");
245  MmUnmapIoSpace(Rsdt, TableLength);
246  return NULL;
247  }
248 
249  /* Smallest RSDT/XSDT is one without table entries */
250  Offset = FIELD_OFFSET(RSDT, Tables);
251  if (Rsdt->Header.Signature == XSDT_SIGNATURE)
252  {
253  /* Figure out total size of table and the offset */
254  TableLength = Xsdt->Header.Length;
255  if (TableLength < Offset) Offset = Xsdt->Header.Length;
256 
257  /* The entries are each 64-bits, so count them */
258  EntryCount = (TableLength - Offset) / sizeof(PHYSICAL_ADDRESS);
259  }
260  else
261  {
262  /* Figure out total size of table and the offset */
263  TableLength = Rsdt->Header.Length;
264  if (TableLength < Offset) Offset = Rsdt->Header.Length;
265 
266  /* The entries are each 32-bits, so count them */
267  EntryCount = (TableLength - Offset) / sizeof(ULONG);
268  }
269 
270  /* Start at the beginning of the array and loop it */
271  for (CurrentEntry = 0; CurrentEntry < EntryCount; CurrentEntry++)
272  {
273  /* Are we using the XSDT? */
274  if (Rsdt->Header.Signature != XSDT_SIGNATURE)
275  {
276  /* Read the 32-bit physical address */
277  PhysicalAddress.QuadPart = Rsdt->Tables[CurrentEntry];
278  }
279  else
280  {
281  /* Read the 64-bit physical address */
282  PhysicalAddress = Xsdt->Tables[CurrentEntry];
283  }
284 
285  /* Map this table */
287  sizeof(DESCRIPTION_HEADER),
288  MmNonCached);
289  if (!Header) break;
290 
291  /* Check if this is the table that's being asked for */
292  if (Header->Signature == TableCode)
293  {
294  /* Allocate a buffer for it */
295  TableBuffer = ExAllocatePoolWithTag(PagedPool,
296  Header->Length,
297  PCI_POOL_TAG);
298  if (!TableBuffer) break;
299 
300  /* Copy the table into the buffer */
301  RtlCopyMemory(TableBuffer, Header, Header->Length);
302  }
303 
304  /* Done with this table, keep going */
306  }
307 
309  return NULL;
310 }
311 
312 NTSTATUS
313 NTAPI
315 {
316  BOOLEAN Result;
318  HANDLE KeyHandle, SubKey;
320  PKEY_FULL_INFORMATION FullInfo;
321  PKEY_BASIC_INFORMATION KeyInfo;
324  struct
325  {
328  } *Package;
329 
330  /* So we know what to free at the end of the body */
331  Package = NULL;
332  ValueInfo = NULL;
333  KeyInfo = NULL;
334  KeyHandle = NULL;
335  FullInfo = NULL;
336  do
337  {
338  /* Open the BIOS key */
339  Result = PciOpenKey(L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\"
340  L"System\\MultiFunctionAdapter",
341  NULL,
343  &KeyHandle,
344  &Status);
345  if (!Result) break;
346 
347  /* Query how much space should be allocated for the key information */
348  Status = ZwQueryKey(KeyHandle,
350  NULL,
351  sizeof(ULONG),
352  &NumberOfBytes);
353  if (Status != STATUS_BUFFER_TOO_SMALL) break;
354 
355  /* Allocate the space required */
358  if ( !FullInfo ) break;
359 
360  /* Now query the key information that's needed */
361  Status = ZwQueryKey(KeyHandle,
363  FullInfo,
365  &NumberOfBytes);
366  if (!NT_SUCCESS(Status)) break;
367 
368  /* Allocate enough space to hold the value information plus the name */
370  Length = FullInfo->MaxNameLen + 26;
372  if (!KeyInfo) break;
373 
374  /* Allocate the value information and name we expect to find */
375  ValueInfo = ExAllocatePoolWithTag(PagedPool,
377  sizeof(L"PCI BIOS"),
378  PCI_POOL_TAG);
379  if (!ValueInfo) break;
380 
381  /* Loop each sub-key */
382  i = 0;
383  while (TRUE)
384  {
385  /* Query each sub-key */
386  Status = ZwEnumerateKey(KeyHandle,
387  i++,
389  KeyInfo,
390  Length,
391  &NumberOfBytes);
392  if (Status == STATUS_NO_MORE_ENTRIES) break;
393 
394  /* Null-terminate the keyname, because the kernel does not */
395  KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
396 
397  /* Open this subkey */
398  Result = PciOpenKey(KeyInfo->Name,
399  KeyHandle,
401  &SubKey,
402  &Status);
403  if (Result)
404  {
405  /* Query the identifier value for this subkey */
406  RtlInitUnicodeString(&ValueName, L"Identifier");
407  Status = ZwQueryValueKey(SubKey,
408  &ValueName,
410  ValueInfo,
412  sizeof(L"PCI BIOS"),
413  &NumberOfBytes);
414  if (NT_SUCCESS(Status))
415  {
416  /* Check if this is the PCI BIOS subkey */
417  if (!wcsncmp((PWCHAR)ValueInfo->Data,
418  L"PCI BIOS",
419  ValueInfo->DataLength))
420  {
421  /* It is, proceed to query the PCI IRQ routing table */
422  Status = PciGetRegistryValue(L"Configuration Data",
423  L"RealModeIrqRoutingTable"
424  L"\\0",
425  SubKey,
427  (PVOID*)&Package,
428  &NumberOfBytes);
429  ZwClose(SubKey);
430  break;
431  }
432  }
433 
434  /* Close the subkey and try the next one */
435  ZwClose(SubKey);
436  }
437  }
438 
439  /* Check if we got here because the routing table was found */
440  if (!NT_SUCCESS(Status)) break;
441 
442  /* Check if a descriptor was found */
443  if (!Package) break;
444 
445  /* Make sure the buffer is large enough to hold the table */
446  if ((NumberOfBytes < sizeof(*Package)) ||
447  (Package->Table.TableSize >
449  {
450  /* Invalid package size */
452  break;
453  }
454 
455  /* Allocate space for the table */
457  *PciRoutingTable = ExAllocatePoolWithTag(PagedPool,
459  PCI_POOL_TAG);
460  if (!*PciRoutingTable) break;
461 
462  /* Copy the registry data */
463  RtlCopyMemory(*PciRoutingTable,
464  &Package->Table,
467  } while (FALSE);
468 
469  /* Close any opened keys, free temporary allocations, and return status */
470  if (Package) ExFreePoolWithTag(Package, 0);
471  if (ValueInfo) ExFreePoolWithTag(ValueInfo, 0);
472  if (KeyInfo) ExFreePoolWithTag(KeyInfo, 0);
473  if (FullInfo) ExFreePoolWithTag(FullInfo, 0);
475  return Status;
476 }
477 
478 NTSTATUS
479 NTAPI
481 {
482  PKEY_FULL_INFORMATION FullInfo;
483  ULONG i, HackCount;
484  PKEY_VALUE_FULL_INFORMATION ValueInfo;
487  ULONG NameLength, ResultLength;
488  ULONGLONG HackFlags;
489 
490  /* So we know what to free at the end of the body */
491  FullInfo = NULL;
492  ValueInfo = NULL;
493  do
494  {
495  /* Query the size required for full key information */
496  Status = ZwQueryKey(KeyHandle,
498  NULL,
499  0,
500  &ResultLength);
501  if (Status != STATUS_BUFFER_TOO_SMALL) break;
502 
503  /* Allocate the space required to hold the full key information */
505  ASSERT(ResultLength > 0);
507  if (!FullInfo) break;
508 
509  /* Go ahead and query the key information */
510  Status = ZwQueryKey(KeyHandle,
512  FullInfo,
513  ResultLength,
514  &ResultLength);
515  if (!NT_SUCCESS(Status)) break;
516 
517  /* The only piece of information that's needed is the count of values */
518  HackCount = FullInfo->Values;
519 
520  /* Free the structure now */
521  ExFreePoolWithTag(FullInfo, 0);
522  FullInfo = NULL;
523 
524  /* Allocate the hack table, now that the number of entries is known */
526  ResultLength = sizeof(PCI_HACK_ENTRY) * HackCount;
528  ResultLength +
529  sizeof(PCI_HACK_ENTRY),
530  PCI_POOL_TAG);
531  if (!PciHackTable) break;
532 
533  /* Allocate the space needed to hold the full value information */
537  PCI_POOL_TAG);
538  if (!PciHackTable) break;
539 
540  /* Loop each value in the registry */
541  Entry = &PciHackTable[0];
542  for (i = 0; i < HackCount; i++)
543  {
544  /* Get the entry for this value */
545  Entry = &PciHackTable[i];
546 
547  /* Query the value in the key */
548  Status = ZwEnumerateValueKey(KeyHandle,
549  i,
551  ValueInfo,
554  &ResultLength);
555  if (!NT_SUCCESS(Status))
556  {
557  /* Check why the call failed */
558  if ((Status != STATUS_BUFFER_OVERFLOW) &&
560  {
561  /* The call failed due to an unknown error, bail out */
562  break;
563  }
564 
565  /* The data seems to mismatch, try the next key in the list */
566  continue;
567  }
568 
569  /* Check if the value data matches what's expected */
570  if ((ValueInfo->Type != REG_BINARY) ||
571  (ValueInfo->DataLength != sizeof(ULONGLONG)))
572  {
573  /* It doesn't, try the next key in the list */
574  continue;
575  }
576 
577  /* Read the actual hack flags */
578  HackFlags = *(PULONGLONG)((ULONG_PTR)ValueInfo +
579  ValueInfo->DataOffset);
580 
581  /* Check what kind of errata entry this is, based on the name */
582  NameLength = ValueInfo->NameLength;
583  if ((NameLength != PCI_HACK_ENTRY_SIZE) &&
584  (NameLength != PCI_HACK_ENTRY_REV_SIZE) &&
585  (NameLength != PCI_HACK_ENTRY_SUBSYS_SIZE) &&
586  (NameLength != PCI_HACK_ENTRY_FULL_SIZE))
587  {
588  /* It's an invalid entry, skip it */
589  DPRINT1("Skipping hack entry with invalid length name\n");
590  continue;
591  }
592 
593  /* Initialize the entry */
595 
596  /* Get the vendor and device data */
597  if (!(PciStringToUSHORT(ValueInfo->Name, &Entry->VendorID)) ||
598  !(PciStringToUSHORT(&ValueInfo->Name[4], &Entry->DeviceID)))
599  {
600  /* This failed, try the next entry */
601  continue;
602  }
603 
604  /* Check if the entry contains subsystem information */
605  if ((NameLength == PCI_HACK_ENTRY_SUBSYS_SIZE) ||
606  (NameLength == PCI_HACK_ENTRY_FULL_SIZE))
607  {
608  /* Get the data */
609  if (!(PciStringToUSHORT(&ValueInfo->Name[8],
610  &Entry->SubVendorID)) ||
611  !(PciStringToUSHORT(&ValueInfo->Name[12],
612  &Entry->SubSystemID)))
613  {
614  /* This failed, try the next entry */
615  continue;
616  }
617 
618  /* Save the fact this entry has finer controls */
620  }
621 
622  /* Check if the entry contains revision information */
623  if ((NameLength == PCI_HACK_ENTRY_REV_SIZE) ||
624  (NameLength == PCI_HACK_ENTRY_FULL_SIZE))
625  {
626  /* Get the data */
627  if (!PciStringToUSHORT(&ValueInfo->Name[16],
628  &Entry->RevisionID))
629  {
630  /* This failed, try the next entry */
631  continue;
632  }
633 
634  /* Save the fact this entry has finer controls */
636  }
637 
638  /* Only the last entry should have this set */
639  ASSERT(Entry->VendorID != PCI_INVALID_VENDORID);
640 
641  /* Save the actual hack flags */
642  Entry->HackFlags = HackFlags;
643 
644  /* Print out for the debugger's sake */
645 #ifdef HACK_DEBUG
646  DPRINT1("Adding Hack entry for Vendor:0x%04x Device:0x%04x ",
647  Entry->VendorID, Entry->DeviceID);
648  if (Entry->Flags & PCI_HACK_HAS_SUBSYSTEM_INFO)
649  DbgPrint("SybSys:0x%04x SubVendor:0x%04x ",
650  Entry->SubSystemID, Entry->SubVendorID);
651  if (Entry->Flags & PCI_HACK_HAS_REVISION_INFO)
652  DbgPrint("Revision:0x%02x", Entry->RevisionID);
653  DbgPrint(" = 0x%I64x\n", Entry->HackFlags);
654 #endif
655  }
656 
657  /* Bail out in case of failure */
658  if (!NT_SUCCESS(Status)) break;
659 
660  /* Terminate the table with an invalid entry */
661  ASSERT(Entry < (PciHackTable + HackCount + 1));
662  Entry->VendorID = PCI_INVALID_VENDORID;
663 
664  /* Success path, free the temporary registry data */
665  ExFreePoolWithTag(ValueInfo, 0);
666  return STATUS_SUCCESS;
667  } while (TRUE);
668 
669  /* Failure path, free temporary allocations and return failure code */
671  if (FullInfo) ExFreePool(FullInfo);
672  if (ValueInfo) ExFreePool(ValueInfo);
674  return Status;
675 }
676 
677 NTSTATUS
678 NTAPI
680 {
681  UNREFERENCED_PARAMETER(DebugKey);
682  /* This function is not yet implemented */
684  return STATUS_SUCCESS;
685 }
686 
687 DRIVER_UNLOAD PciDriverUnload;
688 
689 VOID
690 NTAPI
692 {
694  /* This function is not yet implemented */
695  UNIMPLEMENTED_DBGBREAK("PCI: Unload\n");
696 }
697 
698 NTSTATUS
699 NTAPI
702 {
703  HANDLE KeyHandle, ParametersKey, DebugKey, ControlSetKey;
704  BOOLEAN Result;
707  PULONG Value;
708  PWCHAR StartOptions;
709  UNICODE_STRING OptionString, PciLockString;
711  DPRINT1("PCI: DriverEntry!\n");
712 
713  /* Setup initial loop variables */
714  KeyHandle = NULL;
715  ParametersKey = NULL;
716  DebugKey = NULL;
717  ControlSetKey = NULL;
718  do
719  {
720  /* Remember our object so we can get it to it later */
722 
723  /* Setup the IRP dispatcher */
729 
730  /* This is how we'll detect a new PCI bus */
732 
733  /* Open the PCI key */
735  RegistryPath,
737  NULL,
738  NULL);
740  if (!NT_SUCCESS(Status)) break;
741 
742  /* Open the Parameters subkey */
743  Result = PciOpenKey(L"Parameters",
744  KeyHandle,
746  &ParametersKey,
747  &Status);
748  //if (!Result) break;
749 
750  /* Build the list of all known PCI erratas */
751  Status = PciBuildHackTable(ParametersKey);
752  //if (!NT_SUCCESS(Status)) break;
753 
754  /* Open the debug key, if it exists */
755  Result = PciOpenKey(L"Debug",
756  KeyHandle,
758  &DebugKey,
759  &Status);
760  if (Result)
761  {
762  /* There are PCI debug devices, go discover them */
763  Status = PciGetDebugPorts(DebugKey);
764  if (!NT_SUCCESS(Status)) break;
765  }
766 
767  /* Initialize the synchronization locks */
771 
772  /* Open the control set key */
773  Result = PciOpenKey(L"\\Registry\\Machine\\System\\CurrentControlSet",
774  NULL,
776  &ControlSetKey,
777  &Status);
778  if (!Result) break;
779 
780  /* Read the command line */
781  Status = PciGetRegistryValue(L"SystemStartOptions",
782  L"Control",
783  ControlSetKey,
784  REG_SZ,
785  (PVOID*)&StartOptions,
786  &ResultLength);
787  if (NT_SUCCESS(Status))
788  {
789  /* Initialize the command-line as a string */
790  OptionString.Buffer = StartOptions;
791  OptionString.MaximumLength = OptionString.Length = ResultLength;
792 
793  /* Check if the command-line has the PCILOCK argument */
794  RtlInitUnicodeString(&PciLockString, L"PCILOCK");
795  if (PciUnicodeStringStrStr(&OptionString, &PciLockString, TRUE))
796  {
797  /* The PCI Bus driver will keep the BIOS-assigned resources */
799  }
800 
801  /* This data isn't needed anymore */
802  ExFreePoolWithTag(StartOptions, 0);
803  }
804 
805  /* The PCILOCK feature can also be enabled per-system in the registry */
806  Status = PciGetRegistryValue(L"PCILock",
807  L"Control\\BiosInfo\\PCI",
808  ControlSetKey,
809  REG_DWORD,
810  (PVOID*)&Value,
811  &ResultLength);
812  if (NT_SUCCESS(Status))
813  {
814  /* Read the value it's been set to. This overrides /PCILOCK */
815  if (ResultLength == sizeof(ULONG)) PciLockDeviceResources = *Value;
817  }
818 
819  /* The system can have global PCI erratas in the registry */
820  Status = PciGetRegistryValue(L"HackFlags",
821  L"Control\\PnP\\PCI",
822  ControlSetKey,
823  REG_DWORD,
824  (PVOID*)&Value,
825  &ResultLength);
826  if (NT_SUCCESS(Status))
827  {
828  /* Read them in */
829  if (ResultLength == sizeof(ULONG)) PciSystemWideHackFlags = *Value;
831  }
832 
833  /* Check if the system should allow native ATA support */
834  Status = PciGetRegistryValue(L"EnableNativeModeATA",
835  L"Control\\PnP\\PCI",
836  ControlSetKey,
837  REG_DWORD,
838  (PVOID*)&Value,
839  &ResultLength);
840  if (NT_SUCCESS(Status))
841  {
842  /* This key is typically set by drivers, but users can force it */
843  if (ResultLength == sizeof(ULONG)) PciEnableNativeModeATA = *Value;
845  }
846 
847  /* Build the range lists for all the excluded resource areas */
849  if (!NT_SUCCESS(Status)) break;
850 
851  /* Read the PCI IRQ Routing Table that the loader put in the registry */
853 
854  /* Take over the HAL's default PCI Bus Handler routines */
855  PciHookHal();
856 
857  /* Initialize verification of PCI BIOS and devices, if requested */
859 
860  /* Check if this is a Datacenter SKU, which impacts IRQ alignment */
862  if (PciRunningDatacenter) DPRINT1("PCI running on datacenter build\n");
863 
864  /* Check if the system has an ACPI Hardware Watchdog Timer */
865  //WdTable = PciGetAcpiTable(WDRT_SIGNATURE);
867  } while (FALSE);
868 
869  /* Close all opened keys, return driver status to PnP Manager */
871  if (ControlSetKey) ZwClose(ControlSetKey);
872  if (ParametersKey) ZwClose(ParametersKey);
873  if (DebugKey) ZwClose(DebugKey);
874  return Status;
875 }
876 
877 /* EOF */
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
Definition: pci.h:150
KEVENT PciBusLock
Definition: init.c:21
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define XSDT_SIGNATURE
Definition: acpi.h:39
Definition: acpi.h:193
#define IN
Definition: typedefs.h:38
ASMGENDATA Table[]
Definition: genincdata.c:61
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define PCI_POOL_TAG
Definition: pci.h:25
KEVENT PciGlobalLock
Definition: init.c:20
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
struct _Entry Entry
Definition: kefuncs.h:640
DRIVER_UNLOAD PciDriverUnload
Definition: init.c:687
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define RSDT_SIGNATURE
Definition: acpi.h:32
#define DbgPrint
Definition: loader.c:25
USHORT MaximumLength
Definition: env_spec_w32.h:370
PPCI_IRQ_ROUTING_TABLE PciIrqRoutingTable
Definition: init.c:26
#define PCI_HACK_ENTRY_REV_SIZE
Definition: pci.h:42
PPCI_HACK_ENTRY PciHackTable
Definition: init.c:28
#define REG_BINARY
Definition: nt_native.h:1496
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
NTSTATUS NTAPI PciGetDebugPorts(IN HANDLE DebugKey)
Definition: init.c:679
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define PCI_HACK_ENTRY_SUBSYS_SIZE
Definition: pci.h:43
ULONG Tables[ANYSIZE_ARRAY]
Definition: acpi.h:189
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
BOOLEAN NTAPI PciIsDatacenter(VOID)
Definition: utils.c:131
struct _ACPI_BIOS_MULTI_NODE ACPI_BIOS_MULTI_NODE
LONG NTSTATUS
Definition: precomp.h:26
#define PCI_HACK_ENTRY_SIZE
Definition: pci.h:41
NTSTATUS NTAPI PciAcpiFindRsdt(OUT PACPI_BIOS_MULTI_NODE *AcpiMultiNode)
Definition: init.c:34
uint16_t * PWCHAR
Definition: typedefs.h:54
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
uint32_t ULONG_PTR
Definition: typedefs.h:63
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
BOOLEAN PciEnableNativeModeATA
Definition: init.c:24
struct _ACPI_E820_ENTRY ACPI_E820_ENTRY
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
VOID NTAPI PciVerifierInit(IN PDRIVER_OBJECT DriverObject)
Definition: pcivrify.c:94
PHYSICAL_ADDRESS Tables[ANYSIZE_ARRAY]
Definition: acpi.h:196
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
#define UNICODE_NULL
#define PCI_HACK_HAS_REVISION_INFO
Definition: pci.h:49
Definition: Header.h:8
PHYSICAL_ADDRESS RsdtAddress
Definition: acpi.h:21
NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: init.c:700
ULONG Signature
Definition: acpi.h:96
union node Node
Definition: types.h:1255
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2174
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PWATCHDOG_TABLE WdTable
Definition: init.c:27
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
DESCRIPTION_HEADER Header
Definition: acpi.h:195
BOOLEAN NTAPI PciOpenKey(IN PWCHAR KeyName, IN HANDLE RootKey, IN ACCESS_MASK DesiredAccess, OUT PHANDLE KeyHandle, OUT PNTSTATUS KeyStatus)
Definition: utils.c:165
#define REG_FULL_RESOURCE_DESCRIPTOR
Definition: nt_native.h:1503
VOID NTAPI PciHookHal(VOID)
Definition: hookhal.c:248
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3245
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:65
DRIVER_DISPATCH PciDispatchIrp
Definition: pci.h:539
KEVENT PciLegacyDescriptionLock
Definition: init.c:22
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1061
#define IRP_MJ_POWER
static const WCHAR L[]
Definition: oid.c:1250
#define PCI_HACK_ENTRY_FULL_SIZE
Definition: pci.h:44
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2180
NTSTATUS NTAPI PciGetRegistryValue(IN PWCHAR ValueName, IN PWCHAR KeyName, IN HANDLE RootHandle, IN ULONG Type, OUT PVOID *OutputBuffer, OUT PULONG OutputLength)
Definition: utils.c:192
ULONGLONG Count
Definition: acpi.h:22
struct _PCI_HACK_ENTRY PCI_HACK_ENTRY
#define IRP_MJ_SYSTEM_CONTROL
NTSTATUS NTAPI PciBuildHackTable(IN HANDLE KeyHandle)
Definition: init.c:480
PVOID NTAPI PciGetAcpiTable(IN ULONG TableCode)
Definition: init.c:198
Status
Definition: gdiplustypes.h:24
ULONG Length
Definition: acpi.h:97
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2112
#define PCI_HACK_HAS_SUBSYSTEM_INFO
Definition: pci.h:50
PDRIVER_OBJECT PciDriverObject
Definition: init.c:19
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
NTSTATUS NTAPI PciBuildDefaultExclusionLists(VOID)
Definition: utils.c:276
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
NTSTATUS NTAPI PciGetIrqRoutingTableFromRegistry(OUT PPCI_IRQ_ROUTING_TABLE *PciRoutingTable)
Definition: init.c:314
Definition: acpi.h:186
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int * PULONG
Definition: retypes.h:1
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
#define DPRINT1
Definition: precomp.h:8
#define OUT
Definition: typedefs.h:39
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:390
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
BOOLEAN NTAPI PciUnicodeStringStrStr(IN PUNICODE_STRING InputString, IN PCUNICODE_STRING EqualString, IN BOOLEAN CaseInSensitive)
Definition: utils.c:27
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:998
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
BOOLEAN NTAPI PciStringToUSHORT(IN PWCHAR String, OUT PUSHORT Value)
Definition: utils.c:61
static DRIVER_ADD_DEVICE PciAddDevice
Definition: pci.c:20
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define REG_DWORD
Definition: sdbapi.c:596
ULONG PciSystemWideHackFlags
Definition: init.c:25
BOOLEAN PciLockDeviceResources
Definition: init.c:23
BOOLEAN PciRunningDatacenter
Definition: init.c:18
base of all file and directory entries
Definition: entries.h:82
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
DESCRIPTION_HEADER Header
Definition: acpi.h:188
LONGLONG QuadPart
Definition: typedefs.h:112
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define REG_SZ
Definition: layer.c:22
_In_ PSTORAGE_PROPERTY_ID _Outptr_ PSTORAGE_DESCRIPTOR_HEADER * Descriptor
Definition: classpnp.h:966