ReactOS 0.4.15-dev-7958-gcd0bb1a
init.c File Reference
#include <pci.h>
#include <debug.h>
Include dependency graph for init.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NTAPI PciAcpiFindRsdt (OUT PACPI_BIOS_MULTI_NODE *AcpiMultiNode)
 
PVOID NTAPI PciGetAcpiTable (IN ULONG TableCode)
 
NTSTATUS NTAPI PciGetIrqRoutingTableFromRegistry (OUT PPCI_IRQ_ROUTING_TABLE *PciRoutingTable)
 
NTSTATUS NTAPI PciBuildHackTable (IN HANDLE KeyHandle)
 
NTSTATUS NTAPI PciGetDebugPorts (IN HANDLE DebugKey)
 
VOID NTAPI PciDriverUnload (IN PDRIVER_OBJECT DriverObject)
 
NTSTATUS NTAPI DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
 

Variables

BOOLEAN PciRunningDatacenter
 
PDRIVER_OBJECT PciDriverObject
 
KEVENT PciGlobalLock
 
KEVENT PciBusLock
 
KEVENT PciLegacyDescriptionLock
 
BOOLEAN PciLockDeviceResources
 
BOOLEAN PciEnableNativeModeATA
 
ULONG PciSystemWideHackFlags
 
PPCI_IRQ_ROUTING_TABLE PciIrqRoutingTable
 
PWATCHDOG_TABLE WdTable
 
PPCI_HACK_ENTRY PciHackTable
 
DRIVER_UNLOAD PciDriverUnload
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file init.c.

Function Documentation

◆ DriverEntry()

NTSTATUS NTAPI DriverEntry ( IN PDRIVER_OBJECT  DriverObject,
IN PUNICODE_STRING  RegistryPath 
)

Definition at line 700 of file init.c.

702{
703 HANDLE KeyHandle, ParametersKey, DebugKey, ControlSetKey;
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 */
727 DriverObject->MajorFunction[IRP_MJ_PNP] = PciDispatchIrp;
728 DriverObject->DriverUnload = PciDriverUnload;
729
730 /* This is how we'll detect a new PCI bus */
731 DriverObject->DriverExtension->AddDevice = PciAddDevice;
732
733 /* Open the PCI key */
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 */
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 */
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 */
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}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN PciEnableNativeModeATA
Definition: init.c:24
PDRIVER_OBJECT PciDriverObject
Definition: init.c:19
NTSTATUS NTAPI PciBuildHackTable(IN HANDLE KeyHandle)
Definition: init.c:480
NTSTATUS NTAPI PciGetIrqRoutingTableFromRegistry(OUT PPCI_IRQ_ROUTING_TABLE *PciRoutingTable)
Definition: init.c:314
KEVENT PciLegacyDescriptionLock
Definition: init.c:22
ULONG PciSystemWideHackFlags
Definition: init.c:25
KEVENT PciBusLock
Definition: init.c:21
PPCI_IRQ_ROUTING_TABLE PciIrqRoutingTable
Definition: init.c:26
KEVENT PciGlobalLock
Definition: init.c:20
BOOLEAN PciRunningDatacenter
Definition: init.c:18
DRIVER_UNLOAD PciDriverUnload
Definition: init.c:687
BOOLEAN PciLockDeviceResources
Definition: init.c:23
NTSTATUS NTAPI PciGetDebugPorts(IN HANDLE DebugKey)
Definition: init.c:679
VOID NTAPI PciVerifierInit(IN PDRIVER_OBJECT DriverObject)
Definition: pcivrify.c:94
BOOLEAN NTAPI PciOpenKey(IN PWCHAR KeyName, IN HANDLE RootKey, IN ACCESS_MASK DesiredAccess, OUT PHANDLE KeyHandle, OUT PNTSTATUS KeyStatus)
Definition: utils.c:165
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
BOOLEAN NTAPI PciUnicodeStringStrStr(IN PUNICODE_STRING InputString, IN PCUNICODE_STRING EqualString, IN BOOLEAN CaseInSensitive)
Definition: utils.c:27
NTSTATUS NTAPI PciBuildDefaultExclusionLists(VOID)
Definition: utils.c:276
DRIVER_DISPATCH PciDispatchIrp
Definition: pci.h:541
BOOLEAN NTAPI PciIsDatacenter(VOID)
Definition: utils.c:131
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
Status
Definition: gdiplustypes.h:25
VOID NTAPI PciHookHal(VOID)
Definition: hookhal.c:248
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define REG_SZ
Definition: layer.c:22
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
@ SynchronizationEvent
#define L(x)
Definition: ntvdm.h:50
static DRIVER_ADD_DEVICE PciAddDevice
Definition: pci.c:20
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define REG_DWORD
Definition: sdbapi.c:596
#define STATUS_SUCCESS
Definition: shellext.h:65
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2289
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint32_t * PULONG
Definition: typedefs.h:59
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_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:409
#define IRP_MJ_SYSTEM_CONTROL
#define IRP_MJ_POWER

◆ PciAcpiFindRsdt()

NTSTATUS NTAPI PciAcpiFindRsdt ( OUT PACPI_BIOS_MULTI_NODE AcpiMultiNode)

Definition at line 34 of file init.c.

35{
38 HANDLE KeyHandle, SubKey;
40 PKEY_FULL_INFORMATION FullInfo;
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;
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),
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,
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 */
98 sizeof(L"ACPI BIOS"),
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,
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"),
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,
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}
union node Node
Definition: types.h:1255
#define PCI_POOL_TAG
Definition: pci.h:27
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
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
#define ASSERT(a)
Definition: mode.c:44
@ KeyBasicInformation
Definition: nt_native.h:1131
@ KeyFullInformation
Definition: nt_native.h:1133
@ KeyValuePartialInformation
Definition: nt_native.h:1182
#define REG_FULL_RESOURCE_DESCRIPTOR
Definition: nt_native.h:1503
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
_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)
struct _ACPI_E820_ENTRY ACPI_E820_ENTRY
struct _ACPI_BIOS_MULTI_NODE ACPI_BIOS_MULTI_NODE
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
ULONGLONG Count
Definition: acpi.h:22
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1036
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by PciGetAcpiTable().

◆ PciBuildHackTable()

NTSTATUS NTAPI PciBuildHackTable ( IN HANDLE  KeyHandle)

Definition at line 480 of file init.c.

481{
482 PKEY_FULL_INFORMATION FullInfo;
483 ULONG i, HackCount;
487 ULONG NameLength, ResultLength;
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,
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;
529 sizeof(PCI_HACK_ENTRY),
531 if (!PciHackTable) break;
532
533 /* Allocate the space needed to hold the full value information */
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 */
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);
649 DbgPrint("SybSys:0x%04x SubVendor:0x%04x ",
650 Entry->SubSystemID, Entry->SubVendorID);
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}
_In_ ULONG_PTR HackFlags
Definition: cdrom.h:983
PPCI_HACK_ENTRY PciHackTable
Definition: init.c:28
#define PCI_HACK_ENTRY_SUBSYS_SIZE
Definition: pci.h:45
#define PCI_HACK_ENTRY_SIZE
Definition: pci.h:43
#define PCI_HACK_ENTRY_REV_SIZE
Definition: pci.h:44
#define PCI_HACK_HAS_REVISION_INFO
Definition: pci.h:51
#define PCI_HACK_ENTRY_FULL_SIZE
Definition: pci.h:46
BOOLEAN NTAPI PciStringToUSHORT(IN PWCHAR String, OUT PUSHORT Value)
Definition: utils.c:61
#define PCI_HACK_HAS_SUBSYSTEM_INFO
Definition: pci.h:52
struct _PCI_HACK_ENTRY PCI_HACK_ENTRY
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define DbgPrint
Definition: hal.h:12
#define REG_BINARY
Definition: nt_native.h:1496
@ KeyValueFullInformation
Definition: nt_native.h:1181
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
base of all file and directory entries
Definition: entries.h:83
Definition: pci.h:153
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint64_t ULONGLONG
Definition: typedefs.h:67
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3601

Referenced by DriverEntry().

◆ PciDriverUnload()

VOID NTAPI PciDriverUnload ( IN PDRIVER_OBJECT  DriverObject)

Definition at line 691 of file init.c.

692{
694 /* This function is not yet implemented */
695 UNIMPLEMENTED_DBGBREAK("PCI: Unload\n");
696}
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317

◆ PciGetAcpiTable()

PVOID NTAPI PciGetAcpiTable ( IN ULONG  TableCode)

Definition at line 198 of file init.c.

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),
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,
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) &&
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),
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,
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}
Definition: Header.h:9
NTSTATUS NTAPI PciAcpiFindRsdt(OUT PACPI_BIOS_MULTI_NODE *AcpiMultiNode)
Definition: init.c:34
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define RSDT_SIGNATURE
Definition: acpi.h:32
#define XSDT_SIGNATURE
Definition: acpi.h:39
PHYSICAL_ADDRESS RsdtAddress
Definition: acpi.h:21
ULONG Signature
Definition: acpi.h:96
ULONG Length
Definition: acpi.h:97
Definition: acpi.h:187
ULONG Tables[ANYSIZE_ARRAY]
Definition: acpi.h:189
DESCRIPTION_HEADER Header
Definition: acpi.h:188
Definition: acpi.h:194
PHYSICAL_ADDRESS Tables[ANYSIZE_ARRAY]
Definition: acpi.h:196
DESCRIPTION_HEADER Header
Definition: acpi.h:195
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098
@ MmNonCached
Definition: mmtypes.h:129

◆ PciGetDebugPorts()

NTSTATUS NTAPI PciGetDebugPorts ( IN HANDLE  DebugKey)

Definition at line 679 of file init.c.

680{
681 UNREFERENCED_PARAMETER(DebugKey);
682 /* This function is not yet implemented */
684 return STATUS_SUCCESS;
685}

Referenced by DriverEntry().

◆ PciGetIrqRoutingTableFromRegistry()

NTSTATUS NTAPI PciGetIrqRoutingTableFromRegistry ( OUT PPCI_IRQ_ROUTING_TABLE PciRoutingTable)

Definition at line 314 of file init.c.

315{
318 HANDLE KeyHandle, SubKey;
320 PKEY_FULL_INFORMATION FullInfo;
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),
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,
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 */
377 sizeof(L"PCI BIOS"),
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,
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"),
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,
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,
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}
ASMGENDATA Table[]
Definition: genincdata.c:61
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by DriverEntry().

Variable Documentation

◆ PciBusLock

KEVENT PciBusLock

Definition at line 21 of file init.c.

Referenced by DriverEntry().

◆ PciDriverObject

PDRIVER_OBJECT PciDriverObject

Definition at line 19 of file init.c.

Referenced by DriverEntry(), and PciGetDescriptionMessage().

◆ PciDriverUnload

DRIVER_UNLOAD PciDriverUnload

Definition at line 687 of file init.c.

Referenced by DriverEntry().

◆ PciEnableNativeModeATA

BOOLEAN PciEnableNativeModeATA

Definition at line 24 of file init.c.

Referenced by DriverEntry(), and PciApplyHacks().

◆ PciGlobalLock

KEVENT PciGlobalLock

Definition at line 20 of file init.c.

Referenced by DriverEntry(), PciAddDevice(), PciAssignSlotResources(), and PciFindPdoByLocation().

◆ PciHackTable

PPCI_HACK_ENTRY PciHackTable

Definition at line 28 of file init.c.

Referenced by PciBuildHackTable(), and PciGetHackFlags().

◆ PciIrqRoutingTable

PPCI_IRQ_ROUTING_TABLE PciIrqRoutingTable

Definition at line 26 of file init.c.

Referenced by DriverEntry(), and PciDetermineSlotNumber().

◆ PciLegacyDescriptionLock

KEVENT PciLegacyDescriptionLock

Definition at line 22 of file init.c.

Referenced by DriverEntry().

◆ PciLockDeviceResources

BOOLEAN PciLockDeviceResources

Definition at line 23 of file init.c.

Referenced by DriverEntry().

◆ PciRunningDatacenter

BOOLEAN PciRunningDatacenter

Definition at line 18 of file init.c.

Referenced by DriverEntry().

◆ PciSystemWideHackFlags

ULONG PciSystemWideHackFlags

Definition at line 25 of file init.c.

Referenced by DriverEntry().

◆ WdTable

PWATCHDOG_TABLE WdTable

Definition at line 27 of file init.c.

Referenced by PciScanBus().