ReactOS  0.4.14-dev-606-g14ebc0b
utils.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/utils.c
5  * PURPOSE: Utility/Helper Support Code
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 
22 
23 /* FUNCTIONS ******************************************************************/
24 
25 BOOLEAN
26 NTAPI
28  IN PCUNICODE_STRING EqualString,
30 {
31  UNICODE_STRING PartialString;
32  LONG EqualChars, TotalChars;
33 
34  /* Build a partial string with the smaller substring */
35  PartialString.Length = EqualString->Length;
36  PartialString.MaximumLength = InputString->MaximumLength;
37  PartialString.Buffer = InputString->Buffer;
38 
39  /* Check how many characters that need comparing */
40  EqualChars = 0;
41  TotalChars = (InputString->Length - EqualString->Length) / sizeof(WCHAR);
42 
43  /* If the substring is bigger, just fail immediately */
44  if (TotalChars < 0) return FALSE;
45 
46  /* Keep checking each character */
47  while (!RtlEqualUnicodeString(EqualString, &PartialString, CaseInSensitive))
48  {
49  /* Continue checking until all the required characters are equal */
50  PartialString.Buffer++;
51  PartialString.MaximumLength -= sizeof(WCHAR);
52  if (++EqualChars > TotalChars) return FALSE;
53  }
54 
55  /* The string is equal */
56  return TRUE;
57 }
58 
59 BOOLEAN
60 NTAPI
63 {
64  USHORT Short;
65  ULONG Low, High, Length;
66  WCHAR Char;
67 
68  /* Initialize everything to zero */
69  Short = 0;
70  Length = 0;
71  while (TRUE)
72  {
73  /* Get the character and set the high byte based on the previous one */
74  Char = *String++;
75  High = 16 * Short;
76 
77  /* Check for numbers */
78  if ( Char >= '0' && Char <= '9' )
79  {
80  /* Convert them to a byte */
81  Low = Char - '0';
82  }
83  else if ( Char >= 'A' && Char <= 'F' )
84  {
85  /* Convert upper-case hex letters into a byte */
86  Low = Char - '7';
87  }
88  else if ( Char >= 'a' && Char <= 'f' )
89  {
90  /* Convert lower-case hex letters into a byte */
91  Low = Char - 'W';
92  }
93  else
94  {
95  /* Invalid string, fail the conversion */
96  return FALSE;
97  }
98 
99  /* Combine the high and low byte */
100  Short = High | Low;
101 
102  /* If 4 letters have been reached, the 16-bit integer should exist */
103  if (++Length >= 4)
104  {
105  /* Return it to the caller */
106  *Value = Short;
107  return TRUE;
108  }
109  }
110 }
111 
112 BOOLEAN
113 NTAPI
115 {
116  ULONGLONG Mask = 0;
117  RTL_OSVERSIONINFOEXW VersionInfo;
118 
119  /* Initialize the version information */
120  RtlZeroMemory(&VersionInfo, sizeof(RTL_OSVERSIONINFOEXW));
121  VersionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
122  VersionInfo.wSuiteMask = SuiteMask;
123 
124  /* Set the comparison mask and return if the passed suite mask matches */
126  return NT_SUCCESS(RtlVerifyVersionInfo(&VersionInfo, VER_SUITENAME, Mask));
127 }
128 
129 BOOLEAN
130 NTAPI
132 {
133  BOOLEAN Result;
134  PVOID Value;
137 
138  /* Assume this isn't Datacenter */
139  Result = FALSE;
140 
141  /* First, try opening the setup key */
143  L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\setupdd",
144  0,
145  REG_BINARY,
146  &Value,
147  &ResultLength);
148  if (!NT_SUCCESS(Status))
149  {
150  /* This is not an in-progress Setup boot, so query the suite version */
152  }
153  else
154  {
155  /* This scenario shouldn't happen yet, since SetupDD isn't used */
156  UNIMPLEMENTED_FATAL("ReactOS doesn't use SetupDD for its installation program. Therefore this scenario must not happen!\n");
157  }
158 
159  /* Return if this is Datacenter or not */
160  return Result;
161 }
162 
163 BOOLEAN
164 NTAPI
166  IN HANDLE RootKey,
169  OUT PNTSTATUS KeyStatus)
170 {
173  UNICODE_STRING KeyString;
174  PAGED_CODE();
175 
176  /* Initialize the object attributes */
177  RtlInitUnicodeString(&KeyString, KeyName);
179  &KeyString,
181  RootKey,
182  NULL);
183 
184  /* Open the key, returning a boolean, and the status, if requested */
186  if (KeyStatus) *KeyStatus = Status;
187  return NT_SUCCESS(Status);
188 }
189 
190 NTSTATUS
191 NTAPI
193  IN PWCHAR KeyName,
194  IN HANDLE RootHandle,
195  IN ULONG Type,
197  OUT PULONG OutputLength)
198 {
200  PKEY_VALUE_PARTIAL_INFORMATION PartialInfo;
201  ULONG NeededLength, ActualLength;
202  UNICODE_STRING ValueString;
204  BOOLEAN Result;
205 
206  /* So we know what to free at the end of the body */
207  PartialInfo = NULL;
208  KeyHandle = NULL;
209  do
210  {
211  /* Open the key by name, rooted off the handle passed */
213  RootHandle,
215  &KeyHandle,
216  &Status);
217  if (!Result) break;
218 
219  /* Query for the size that's needed for the value that was passed in */
220  RtlInitUnicodeString(&ValueString, ValueName);
221  Status = ZwQueryValueKey(KeyHandle,
222  &ValueString,
224  NULL,
225  0,
226  &NeededLength);
228  if (Status != STATUS_BUFFER_TOO_SMALL) break;
229 
230  /* Allocate an appropriate buffer for the size that was returned */
231  ASSERT(NeededLength != 0);
233  PartialInfo = ExAllocatePoolWithTag(PagedPool,
234  NeededLength,
235  PCI_POOL_TAG);
236  if (!PartialInfo) break;
237 
238  /* Query the actual value information now that the size is known */
239  Status = ZwQueryValueKey(KeyHandle,
240  &ValueString,
242  PartialInfo,
243  NeededLength,
244  &ActualLength);
245  if (!NT_SUCCESS(Status)) break;
246 
247  /* Make sure it's of the type that the caller expects */
249  if (PartialInfo->Type != Type) break;
250 
251  /* Subtract the registry-specific header, to get the data size */
252  ASSERT(NeededLength == ActualLength);
253  NeededLength -= sizeof(KEY_VALUE_PARTIAL_INFORMATION);
254 
255  /* Allocate a buffer to hold the data and return it to the caller */
258  NeededLength,
259  PCI_POOL_TAG);
260  if (!*OutputBuffer) break;
261 
262  /* Copy the data into the buffer and return its length to the caller */
263  RtlCopyMemory(*OutputBuffer, PartialInfo->Data, NeededLength);
264  if (OutputLength) *OutputLength = NeededLength;
266  } while (0);
267 
268  /* Close any opened keys and free temporary allocations */
270  if (PartialInfo) ExFreePoolWithTag(PartialInfo, 0);
271  return Status;
272 }
273 
274 NTSTATUS
275 NTAPI
277 {
278  ULONG Start;
282 
283  /* Initialize the range lists */
286 
287  /* Loop x86 I/O ranges */
288  for (Start = 0x100; Start <= 0xFEFF; Start += 0x400)
289  {
290  /* Add the ISA I/O ranges */
292  Start,
293  Start + 0x2FF,
294  0,
296  NULL,
297  NULL);
298  if (!NT_SUCCESS(Status)) break;
299 
300  /* Add the ISA I/O ranges */
302  Start,
303  Start + 0x2AF,
304  0,
306  NULL,
307  NULL);
308  if (!NT_SUCCESS(Status)) break;
309 
310  /* Add the VGA I/O range for Monochrome Video */
312  Start + 0x2BC,
313  Start + 0x2BF,
314  0,
316  NULL,
317  NULL);
318  if (!NT_SUCCESS(Status)) break;
319 
320  /* Add the VGA I/O range for certain CGA adapters */
322  Start + 0x2E0,
323  Start + 0x2FF,
324  0,
326  NULL,
327  NULL);
328  if (!NT_SUCCESS(Status)) break;
329 
330  /* Success, ranges added done */
331  };
332 
335  return Status;
336 }
337 
339 NTAPI
341  IN PKEVENT Lock)
342 {
343  PPCI_FDO_EXTENSION DeviceExtension;
344  PPCI_PDO_EXTENSION SearchExtension, FoundExtension;
345 
346  /* Assume we'll find nothing */
347  SearchExtension = DeviceObject->DeviceExtension;
348  FoundExtension = NULL;
349 
350  /* Check if a lock was specified */
351  if (Lock)
352  {
353  /* Wait for the lock to be released */
356  }
357 
358  /* Now search for the extension */
360  while (DeviceExtension)
361  {
362  /* Acquire this device's lock */
364  KeWaitForSingleObject(&DeviceExtension->ChildListLock,
365  Executive,
366  KernelMode,
367  FALSE,
368  NULL);
369 
370  /* Scan all children PDO, stop when no more PDOs, or found it */
371  for (FoundExtension = DeviceExtension->ChildPdoList;
372  ((FoundExtension) && (FoundExtension != SearchExtension));
373  FoundExtension = FoundExtension->Next);
374 
375  /* Release this device's lock */
376  KeSetEvent(&DeviceExtension->ChildListLock, IO_NO_INCREMENT, FALSE);
378 
379  /* If we found it, break out */
380  if (FoundExtension) break;
381 
382  /* Move to the next device */
383  DeviceExtension = (PPCI_FDO_EXTENSION)DeviceExtension->List.Next;
384  }
385 
386  /* Check if we had acquired a lock previously */
387  if (Lock)
388  {
389  /* Release it */
392  }
393 
394  /* Return which extension was found, if any */
395  return DeviceExtension;
396 }
397 
398 VOID
399 NTAPI
401  IN PPCI_FDO_EXTENSION DeviceExtension,
402  IN PKEVENT Lock)
403 {
404  PSINGLE_LIST_ENTRY NextEntry;
405  PAGED_CODE();
406 
407  /* Check if a lock was specified */
408  if (Lock)
409  {
410  /* Wait for the lock to be released */
413  }
414 
415  /* Loop the list until we get to the end, then insert this entry there */
416  for (NextEntry = ListHead; NextEntry->Next; NextEntry = NextEntry->Next);
417  NextEntry->Next = &DeviceExtension->List;
418 
419  /* Check if we had acquired a lock previously */
420  if (Lock)
421  {
422  /* Release it */
425  }
426 }
427 
428 VOID
429 NTAPI
432  IN PKEVENT Lock)
433 {
434  PAGED_CODE();
435 
436  /* Check if a lock was specified */
437  if (Lock)
438  {
439  /* Wait for the lock to be released */
442  }
443 
444  /* Make the entry point to the current head and make the head point to it */
445  Entry->Next = ListHead->Next;
446  ListHead->Next = Entry;
447 
448  /* Check if we had acquired a lock previously */
449  if (Lock)
450  {
451  /* Release it */
454  }
455 }
456 
457 VOID
458 NTAPI
460  IN PVOID Lock,
461  IN PPCI_SECONDARY_EXTENSION SecondaryExtension,
462  IN PCI_SIGNATURE ExtensionType,
463  IN PVOID Destructor)
464 {
465  PAGED_CODE();
466 
467  /* Setup the extension data, and insert it into the primary's list */
468  SecondaryExtension->ExtensionType = ExtensionType;
469  SecondaryExtension->Destructor = Destructor;
470  PciInsertEntryAtHead(List, &SecondaryExtension->List, Lock);
471 }
472 
473 NTSTATUS
474 NTAPI
478 {
481  PVOID Buffer;
482  do
483  {
484  /* Query the requested property size */
487  0,
488  NULL,
489  &BufferLength);
491  {
492  /* Call should've failed with buffer too small! */
493  DPRINT1("PCI - Unexpected status from GetDeviceProperty, saw %08X, expected %08X.\n",
494  Status,
496  *OutputBuffer = NULL;
497  ASSERTMSG("PCI Successfully did the impossible!\n", FALSE);
498  break;
499  }
500 
501  /* Allocate the required buffer */
503  if (!Buffer)
504  {
505  /* No memory, fail the request */
506  DPRINT1("PCI - Failed to allocate DeviceProperty buffer (%u bytes).\n", BufferLength);
508  break;
509  }
510 
511  /* Do the actual property query call */
514  BufferLength,
515  Buffer,
516  &ResultLength);
517  if (!NT_SUCCESS(Status)) break;
518 
519  /* Return the buffer to the caller */
521  *OutputBuffer = Buffer;
522  return STATUS_SUCCESS;
523  } while (FALSE);
524 
525  /* Failure path */
526  return STATUS_UNSUCCESSFUL;
527 }
528 
529 NTSTATUS
530 NTAPI
537 {
538  PIRP Irp;
540  KEVENT Event;
542  PDEVICE_OBJECT AttachedDevice;
543  PAGED_CODE();
544 
545  /* Initialize the pending IRP event */
547 
548  /* Get a reference to the root PDO (ACPI) */
549  AttachedDevice = IoGetAttachedDeviceReference(DeviceObject);
550  if (!AttachedDevice) return STATUS_INVALID_PARAMETER;
551 
552  /* Build the requested IOCTL IRP */
554  AttachedDevice,
555  InputBuffer,
557  OutputBuffer,
559  0,
560  &Event,
561  &IoStatusBlock);
562  if (!Irp) return STATUS_INSUFFICIENT_RESOURCES;
563 
564  /* Send the IOCTL to the driver */
565  Status = IoCallDriver(AttachedDevice, Irp);
566  if (Status == STATUS_PENDING)
567  {
568  /* Wait for a response */
570  Executive,
571  KernelMode,
572  FALSE,
573  NULL);
574  Status = Irp->IoStatus.Status;
575  }
576 
577  /* Take away the reference we took and return the result to the caller */
578  ObDereferenceObject(AttachedDevice);
579  return Status;
580 }
581 
583 NTAPI
585  IN PCI_SIGNATURE ExtensionType)
586 {
587  PSINGLE_LIST_ENTRY NextEntry;
589 
590  /* Scan the list */
591  for (NextEntry = ListHead; NextEntry; NextEntry = NextEntry->Next)
592  {
593  /* Grab each extension and check if it's the one requested */
595  if (Extension->ExtensionType == ExtensionType) return Extension;
596  }
597 
598  /* Nothing was found */
599  return NULL;
600 }
601 
602 ULONGLONG
603 NTAPI
605  IN USHORT DeviceId,
606  IN USHORT SubVendorId,
607  IN USHORT SubSystemId,
608  IN UCHAR RevisionId)
609 {
610  PPCI_HACK_ENTRY HackEntry;
611  ULONGLONG HackFlags;
612  ULONG LastWeight, MatchWeight;
613  ULONG EntryFlags;
614 
615  /* ReactOS SetupLDR Hack */
616  if (!PciHackTable) return 0;
617 
618  /* Initialize the variables before looping */
619  LastWeight = 0;
620  HackFlags = 0;
622 
623  /* Scan the hack table */
624  for (HackEntry = PciHackTable;
625  HackEntry->VendorID != PCI_INVALID_VENDORID;
626  ++HackEntry)
627  {
628  /* Check if there's an entry for this device */
629  if ((HackEntry->DeviceID == DeviceId) &&
630  (HackEntry->VendorID == VendorId))
631  {
632  /* This is a basic match */
633  EntryFlags = HackEntry->Flags;
634  MatchWeight = 1;
635 
636  /* Does the entry have revision information? */
637  if (EntryFlags & PCI_HACK_HAS_REVISION_INFO)
638  {
639  /* Check if the revision matches, if so, this is a better match */
640  if (HackEntry->RevisionID != RevisionId) continue;
641  MatchWeight = 3;
642  }
643 
644  /* Does the netry have subsystem information? */
645  if (EntryFlags & PCI_HACK_HAS_SUBSYSTEM_INFO)
646  {
647  /* Check if it matches, if so, this is the best possible match */
648  if ((HackEntry->SubVendorID != SubVendorId) ||
649  (HackEntry->SubSystemID != SubSystemId))
650  {
651  continue;
652  }
653  MatchWeight += 4;
654  }
655 
656  /* Is this the best match yet? */
657  if (MatchWeight > LastWeight)
658  {
659  /* This is the best match for now, use this as the hack flags */
660  HackFlags = HackEntry->HackFlags;
661  LastWeight = MatchWeight;
662  }
663  }
664  }
665 
666  /* Return the best match */
667  return HackFlags;
668 }
669 
670 BOOLEAN
671 NTAPI
673  IN UCHAR SubClass)
674 {
675  /* Check for system or bridge devices */
676  if (BaseClass == PCI_CLASS_BASE_SYSTEM_DEV)
677  {
678  /* Interrupt controllers are critical */
679  return SubClass == PCI_SUBCLASS_SYS_INTERRUPT_CTLR;
680  }
681  else if (BaseClass == PCI_CLASS_BRIDGE_DEV)
682  {
683  /* ISA Bridges are critical */
684  return SubClass == PCI_SUBCLASS_BR_ISA;
685  }
686  else
687  {
688  /* All display controllers are critical */
689  return BaseClass == PCI_CLASS_DISPLAY_CTLR;
690  }
691 }
692 
694 NTAPI
696  IN ULONG FunctionNumber,
697  IN PPCI_COMMON_HEADER PciData)
698 {
699  KIRQL Irql;
701 
702  /* Get the current IRQL when this call was made */
704 
705  /* Is this a low-IRQL call? */
706  if (Irql < DISPATCH_LEVEL)
707  {
708  /* Acquire this device's lock */
710  KeWaitForSingleObject(&DeviceExtension->ChildListLock,
711  Executive,
712  KernelMode,
713  FALSE,
714  NULL);
715  }
716 
717  /* Loop every child PDO */
718  for (PdoExtension = DeviceExtension->ChildPdoList;
719  PdoExtension;
720  PdoExtension = PdoExtension->Next)
721  {
722  /* Find only enumerated PDOs */
723  if (!PdoExtension->ReportedMissing)
724  {
725  /* Check if the function number and header data matches */
726  if ((FunctionNumber == PdoExtension->Slot.u.AsULONG) &&
727  (PdoExtension->VendorId == PciData->VendorID) &&
728  (PdoExtension->DeviceId == PciData->DeviceID) &&
729  (PdoExtension->RevisionId == PciData->RevisionID))
730  {
731  /* This is considered to be the same PDO */
732  break;
733  }
734  }
735  }
736 
737  /* Was this a low-IRQL call? */
738  if (Irql < DISPATCH_LEVEL)
739  {
740  /* Release this device's lock */
741  KeSetEvent(&DeviceExtension->ChildListLock, IO_NO_INCREMENT, FALSE);
743  }
744 
745  /* If the search found something, this is non-NULL, otherwise it's NULL */
746  return PdoExtension;
747 }
748 
749 BOOLEAN
750 NTAPI
752 {
753  PAGED_CODE();
754 
755  UNREFERENCED_PARAMETER(DeviceExtension);
756 
757  /* Check for too many, or no, debug ports */
759  if (!PciDebugPortsCount) return FALSE;
760 
761  /* eVb has not been able to test such devices yet */
763  return FALSE;
764 }
765 
766 NTSTATUS
767 NTAPI
769  OUT PPCI_COMMON_HEADER PciData)
770 {
773  UNICODE_STRING KeyName, KeyValue;
774  WCHAR Buffer[32];
776  PKEY_VALUE_PARTIAL_INFORMATION PartialInfo = (PVOID)DataBuffer;
779  PAGED_CODE();
780 
781  /* Open the PCI key */
782  Status = IoOpenDeviceRegistryKey(DeviceExtension->ParentFdoExtension->
784  TRUE,
786  &KeyHandle);
787  if (!NT_SUCCESS(Status)) return Status;
788 
789  /* Create a volatile BIOS configuration key */
790  RtlInitUnicodeString(&KeyName, L"BiosConfig");
792  &KeyName,
794  KeyHandle,
795  NULL);
796  Status = ZwCreateKey(&SubKeyHandle,
797  KEY_READ,
799  0,
800  NULL,
802  NULL);
804  if (!NT_SUCCESS(Status)) return Status;
805 
806  /* Create the key value based on the device and function number */
808  L"DEV_%02x&FUN_%02x",
809  DeviceExtension->Slot.u.bits.DeviceNumber,
810  DeviceExtension->Slot.u.bits.FunctionNumber);
811  RtlInitUnicodeString(&KeyValue, Buffer);
812 
813  /* Query the value information (PCI BIOS configuration header) */
814  Status = ZwQueryValueKey(SubKeyHandle,
815  &KeyValue,
817  PartialInfo,
818  sizeof(DataBuffer),
819  &ResultLength);
821  if (!NT_SUCCESS(Status)) return Status;
822 
823  /* If any information was returned, go ahead and copy its data */
824  ASSERT(PartialInfo->DataLength == PCI_COMMON_HDR_LENGTH);
825  RtlCopyMemory(PciData, PartialInfo->Data, PCI_COMMON_HDR_LENGTH);
826  return Status;
827 }
828 
829 NTSTATUS
830 NTAPI
832  IN PPCI_COMMON_HEADER PciData)
833 {
836  UNICODE_STRING KeyName, KeyValue;
837  WCHAR Buffer[32];
839  PAGED_CODE();
840 
841  /* Open the PCI key */
842  Status = IoOpenDeviceRegistryKey(DeviceExtension->ParentFdoExtension->
844  TRUE,
846  &KeyHandle);
847  if (!NT_SUCCESS(Status)) return Status;
848 
849  /* Create a volatile BIOS configuration key */
850  RtlInitUnicodeString(&KeyName, L"BiosConfig");
852  &KeyName,
854  KeyHandle,
855  NULL);
856  Status = ZwCreateKey(&SubKeyHandle,
859  0,
860  NULL,
862  NULL);
864  if (!NT_SUCCESS(Status)) return Status;
865 
866  /* Create the key value based on the device and function number */
868  L"DEV_%02x&FUN_%02x",
869  DeviceExtension->Slot.u.bits.DeviceNumber,
870  DeviceExtension->Slot.u.bits.FunctionNumber);
871  RtlInitUnicodeString(&KeyValue, Buffer);
872 
873  /* Set the value data (the PCI BIOS configuration header) */
874  Status = ZwSetValueKey(SubKeyHandle,
875  &KeyValue,
876  0,
877  REG_BINARY,
878  PciData,
881  return Status;
882 }
883 
884 UCHAR
885 NTAPI
887  IN UCHAR Offset,
888  IN ULONG CapabilityId,
890  IN ULONG Length)
891 {
892  ULONG CapabilityCount = 0;
893 
894  /* If the device has no capabilility list, fail */
895  if (!Offset) return 0;
896 
897  /* Validate a PDO with capabilities, a valid buffer, and a valid length */
898  ASSERT(DeviceExtension->ExtensionType == PciPdoExtensionType);
899  ASSERT(DeviceExtension->CapabilitiesPtr != 0);
900  ASSERT(Buffer);
902 
903  /* Loop all capabilities */
904  while (Offset)
905  {
906  /* Make sure the pointer is spec-aligned and spec-sized */
907  ASSERT((Offset >= PCI_COMMON_HDR_LENGTH) && ((Offset & 0x3) == 0));
908 
909  /* Read the capability header */
910  PciReadDeviceConfig(DeviceExtension,
911  Buffer,
912  Offset,
913  sizeof(PCI_CAPABILITIES_HEADER));
914 
915  /* Check if this is the capability being looked up */
916  if ((Buffer->CapabilityID == CapabilityId) || !(CapabilityId))
917  {
918  /* Check if was at a valid offset and length */
919  if ((Offset) && (Length > sizeof(PCI_CAPABILITIES_HEADER)))
920  {
921  /* Sanity check */
922  ASSERT(Length <= (sizeof(PCI_COMMON_CONFIG) - Offset));
923 
924  /* Now read the whole capability data into the buffer */
925  PciReadDeviceConfig(DeviceExtension,
926  (PVOID)((ULONG_PTR)Buffer +
927  sizeof(PCI_CAPABILITIES_HEADER)),
929  Length - sizeof(PCI_CAPABILITIES_HEADER));
930  }
931 
932  /* Return the offset where the capability was found */
933  return Offset;
934  }
935 
936  /* Try the next capability instead */
937  CapabilityCount++;
938  Offset = Buffer->Next;
939 
940  /* There can't be more than 48 capabilities (256 bytes max) */
941  if (CapabilityCount > 48)
942  {
943  /* Fail, since this is basically a broken PCI device */
944  DPRINT1("PCI device %p capabilities list is broken.\n", DeviceExtension);
945  return 0;
946  }
947  }
948 
949  /* Capability wasn't found, fail */
950  return 0;
951 }
952 
953 BOOLEAN
954 NTAPI
957  IN ULONGLONG HackFlags,
958  IN BOOLEAN ForPowerDown)
959 {
960  UCHAR BaseClass, SubClass;
961  BOOLEAN IsVga;
962 
963  /* Is there a device extension or should the PCI header be used? */
964  if (DeviceExtension)
965  {
966  /* Never disable decodes for a debug PCI Device */
967  if (DeviceExtension->OnDebugPath) return FALSE;
968 
969  /* Hack flags will be obtained from the extension, not the caller */
970  ASSERT(HackFlags == 0);
971 
972  /* Get hacks and classification from the device extension */
973  HackFlags = DeviceExtension->HackFlags;
974  SubClass = DeviceExtension->SubClass;
975  BaseClass = DeviceExtension->BaseClass;
976  }
977  else
978  {
979  /* There must be a PCI header, go read the classification information */
980  ASSERT(Config != NULL);
981  BaseClass = Config->BaseClass;
982  SubClass = Config->SubClass;
983  }
984 
985  /* Check for hack flags that prevent disabling the decodes */
986  if (HackFlags & (PCI_HACK_PRESERVE_COMMAND |
989  {
990  /* Don't do it */
991  return FALSE;
992  }
993 
994  /* Is this a VGA adapter? */
995  if ((BaseClass == PCI_CLASS_DISPLAY_CTLR) &&
996  (SubClass == PCI_SUBCLASS_VID_VGA_CTLR))
997  {
998  /* Never disable decodes if this is for power down */
999  return ForPowerDown;
1000  }
1001 
1002  /* Check for legacy devices */
1003  if (BaseClass == PCI_CLASS_PRE_20)
1004  {
1005  /* Never disable video adapter cards if this is for power down */
1006  if (SubClass == PCI_SUBCLASS_PRE_20_VGA) return ForPowerDown;
1007  }
1008  else if (BaseClass == PCI_CLASS_DISPLAY_CTLR)
1009  {
1010  /* Never disable VGA adapters if this is for power down */
1011  if (SubClass == PCI_SUBCLASS_VID_VGA_CTLR) return ForPowerDown;
1012  }
1013  else if (BaseClass == PCI_CLASS_BRIDGE_DEV)
1014  {
1015  /* Check for legacy bridges */
1016  if ((SubClass == PCI_SUBCLASS_BR_ISA) ||
1017  (SubClass == PCI_SUBCLASS_BR_EISA) ||
1018  (SubClass == PCI_SUBCLASS_BR_MCA) ||
1019  (SubClass == PCI_SUBCLASS_BR_HOST) ||
1020  (SubClass == PCI_SUBCLASS_BR_OTHER))
1021  {
1022  /* Never disable these */
1023  return FALSE;
1024  }
1025  else if ((SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI) ||
1026  (SubClass == PCI_SUBCLASS_BR_CARDBUS))
1027  {
1028  /* This is a supported bridge, but does it have a VGA card? */
1029  if (!DeviceExtension)
1030  {
1031  /* Read the bridge control flag from the PCI header */
1032  IsVga = Config->u.type1.BridgeControl & PCI_ENABLE_BRIDGE_VGA;
1033  }
1034  else
1035  {
1036  /* Read the cached flag in the device extension */
1037  IsVga = DeviceExtension->Dependent.type1.VgaBitSet;
1038  }
1039 
1040  /* Never disable VGA adapters if this is for power down */
1041  if (IsVga) return ForPowerDown;
1042  }
1043  }
1044 
1045  /* Finally, never disable decodes if there's no power management */
1046  return !(HackFlags & PCI_HACK_NO_PM_CAPS);
1047 }
1048 
1050 NTAPI
1052 {
1053  ASSERT(PdoExtension->ExtensionType == PciPdoExtensionType);
1054 
1055  /* Differentiate between devices and bridges */
1056  if (PdoExtension->BaseClass != PCI_CLASS_BRIDGE_DEV) return PciTypeDevice;
1057 
1058  /* The PCI Bus driver handles only CardBus and PCI bridges (plus host) */
1059  if (PdoExtension->SubClass == PCI_SUBCLASS_BR_HOST) return PciTypeHostBridge;
1060  if (PdoExtension->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI) return PciTypePciBridge;
1062 
1063  /* Any other kind of bridge is treated like a device */
1064  return PciTypeDevice;
1065 }
1066 
1067 ULONG_PTR
1068 NTAPI
1070 {
1072 
1073  /* Check if the IPI is already running */
1074  if (!InterlockedDecrement(&Context->RunCount))
1075  {
1076  /* Nope, this is the first instance, so execute the IPI function */
1077  Context->Function(Context->DeviceExtension, Context->Context);
1078 
1079  /* Notify anyone that was spinning that they can stop now */
1080  Context->Barrier = 0;
1081  }
1082  else
1083  {
1084  /* Spin until it has finished running */
1085  while (Context->Barrier);
1086  }
1087 
1088  /* Done */
1089  return 0;
1090 }
1091 
1092 BOOLEAN
1093 NTAPI
1095  IN ULONG Method)
1096 {
1097  BOOLEAN FoundSlot;
1098  PACPI_METHOD_ARGUMENT Argument;
1101  ULONG i, Length;
1102  NTSTATUS Status;
1103  PAGED_CODE();
1104 
1105  /* Assume slot is not part of the parent method */
1106  FoundSlot = FALSE;
1107 
1108  /* Allocate a 2KB buffer for the method return parameters */
1109  Length = sizeof(ACPI_EVAL_OUTPUT_BUFFER) + 2048;
1111  if (OutputBuffer)
1112  {
1113  /* Clear out the output buffer */
1115 
1116  /* Initialize the input buffer with the method requested */
1117  InputBuffer.Signature = 0;
1118  *(PULONG)InputBuffer.MethodName = Method;
1120 
1121  /* Send it to the ACPI driver */
1122  Status = PciSendIoctl(PdoExtension->ParentFdoExtension->PhysicalDeviceObject,
1124  &InputBuffer,
1125  sizeof(ACPI_EVAL_INPUT_BUFFER),
1126  OutputBuffer,
1127  Length);
1128  if (NT_SUCCESS(Status))
1129  {
1130  /* Scan all output arguments */
1131  for (i = 0; i < OutputBuffer->Count; i++)
1132  {
1133  /* Make sure it's an integer */
1134  Argument = &OutputBuffer->Argument[i];
1135  if (Argument->Type != ACPI_METHOD_ARGUMENT_INTEGER) continue;
1136 
1137  /* Check if the argument matches this PCI slot structure */
1138  if (Argument->Argument == ((PdoExtension->Slot.u.bits.DeviceNumber) |
1139  ((PdoExtension->Slot.u.bits.FunctionNumber) << 16)))
1140  {
1141  /* This slot has been found, return it */
1142  FoundSlot = TRUE;
1143  break;
1144  }
1145  }
1146  }
1147 
1148  /* Finished with the buffer, free it */
1150  }
1151 
1152  /* Return if the slot was found */
1153  return FoundSlot;
1154 }
1155 
1156 ULONG
1157 NTAPI
1159 {
1160  ULONG Length;
1161 
1162  /* I/O addresses vs. memory addresses start differently due to alignment */
1163  Length = 1 << ((Bar & PCI_ADDRESS_IO_SPACE) ? 2 : 4);
1164 
1165  /* Keep going until a set bit */
1166  while (!(Length & Bar) && (Length)) Length <<= 1;
1167 
1168  /* Return the length (might be 0 on 64-bit because it's the low-word) */
1170  return Length;
1171 }
1172 
1173 BOOLEAN
1174 NTAPI
1176  IN PULONG BarArray,
1177  IN BOOLEAN Rom)
1178 {
1179  ULONG CurrentBar, BarLength, BarMask;
1180  BOOLEAN Is64BitBar = FALSE;
1181 
1182  /* Check if the BAR is nor I/O nor memory */
1183  CurrentBar = BarArray[0];
1184  if (!(CurrentBar & ~PCI_ADDRESS_IO_SPACE))
1185  {
1186  /* Fail this descriptor */
1187  ResourceDescriptor->Type = CmResourceTypeNull;
1188  return FALSE;
1189  }
1190 
1191  /* Set default flag and clear high words */
1192  ResourceDescriptor->Flags = 0;
1193  ResourceDescriptor->u.Generic.MaximumAddress.HighPart = 0;
1194  ResourceDescriptor->u.Generic.MinimumAddress.LowPart = 0;
1195  ResourceDescriptor->u.Generic.MinimumAddress.HighPart = 0;
1196 
1197  /* Check for ROM Address */
1198  if (Rom)
1199  {
1200  /* Clean up the BAR to get just the address */
1201  CurrentBar &= PCI_ADDRESS_ROM_ADDRESS_MASK;
1202  if (!CurrentBar)
1203  {
1204  /* Invalid ar, fail this descriptor */
1205  ResourceDescriptor->Type = CmResourceTypeNull;
1206  return FALSE;
1207  }
1208 
1209  /* ROM Addresses are always read only */
1210  ResourceDescriptor->Flags = CM_RESOURCE_MEMORY_READ_ONLY;
1211  }
1212 
1213  /* Compute the length, assume it's the alignment for now */
1214  BarLength = PciGetLengthFromBar(CurrentBar);
1215  ResourceDescriptor->u.Generic.Length = BarLength;
1216  ResourceDescriptor->u.Generic.Alignment = BarLength;
1217 
1218  /* Check what kind of BAR this is */
1219  if (CurrentBar & PCI_ADDRESS_IO_SPACE)
1220  {
1221  /* Use correct mask to decode the address */
1222  BarMask = PCI_ADDRESS_IO_ADDRESS_MASK;
1223 
1224  /* Set this as an I/O Port descriptor */
1225  ResourceDescriptor->Type = CmResourceTypePort;
1226  ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;
1227  }
1228  else
1229  {
1230  /* Use correct mask to decode the address */
1232 
1233  /* Set this as a memory descriptor */
1234  ResourceDescriptor->Type = CmResourceTypeMemory;
1235 
1236  /* Check if it's 64-bit or 20-bit decode */
1237  if ((CurrentBar & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_64BIT)
1238  {
1239  /* The next BAR has the high word, read it */
1240  ResourceDescriptor->u.Port.MaximumAddress.HighPart = BarArray[1];
1241  Is64BitBar = TRUE;
1242  }
1243  else if ((CurrentBar & PCI_ADDRESS_MEMORY_TYPE_MASK) == PCI_TYPE_20BIT)
1244  {
1245  /* Use the correct mask to decode the address */
1246  BarMask = ~0xFFF0000F;
1247  }
1248 
1249  /* Check if the BAR is listed as prefetchable memory */
1250  if (CurrentBar & PCI_ADDRESS_MEMORY_PREFETCHABLE)
1251  {
1252  /* Mark the descriptor in the same way */
1253  ResourceDescriptor->Flags |= CM_RESOURCE_MEMORY_PREFETCHABLE;
1254  }
1255  }
1256 
1257  /* Now write down the maximum address based on the base + length */
1258  ResourceDescriptor->u.Port.MaximumAddress.QuadPart = (CurrentBar & BarMask) +
1259  BarLength - 1;
1260 
1261  /* Return if this is a 64-bit BAR, so the loop code knows to skip the next one */
1262  return Is64BitBar;
1263 }
1264 
1265 VOID
1266 NTAPI
1268  IN BOOLEAN Enable,
1270 {
1271  USHORT CommandValue;
1272 
1273  /*
1274  * If decodes are being disabled, make sure it's allowed, and in both cases,
1275  * make sure that a hackflag isn't preventing touching the decodes at all.
1276  */
1277  if (((Enable) || (PciCanDisableDecodes(PdoExtension, 0, 0, 0))) &&
1278  !(PdoExtension->HackFlags & PCI_HACK_PRESERVE_COMMAND))
1279  {
1280  /* Did the caller already have a command word? */
1281  if (Command)
1282  {
1283  /* Use the caller's */
1284  CommandValue = *Command;
1285  }
1286  else
1287  {
1288  /* Otherwise, read the current command */
1290  &Command,
1292  sizeof(USHORT));
1293  }
1294 
1295  /* Turn off decodes by default */
1296  CommandValue &= ~(PCI_ENABLE_IO_SPACE |
1299 
1300  /* If requested, enable the decodes that were enabled at init time */
1301  if (Enable) CommandValue |= PdoExtension->CommandEnables &
1305 
1306  /* Update the command word */
1308  &CommandValue,
1310  sizeof(USHORT));
1311  }
1312 }
1313 
1314 NTSTATUS
1315 NTAPI
1318 {
1319  PPNP_BUS_INFORMATION BusInfo;
1320 
1322 
1323  /* Allocate a structure for the bus information */
1324  BusInfo = ExAllocatePoolWithTag(PagedPool,
1325  sizeof(PNP_BUS_INFORMATION),
1326  'BicP');
1327  if (!BusInfo) return STATUS_INSUFFICIENT_RESOURCES;
1328 
1329  /* Write the correct GUID and bus type identifier, and fill the bus number */
1330  BusInfo->BusTypeGuid = GUID_BUS_TYPE_PCI;
1331  BusInfo->LegacyBusType = PCIBus;
1332  BusInfo->BusNumber = PdoExtension->ParentFdoExtension->BaseBus;
1333  return STATUS_SUCCESS;
1334 }
1335 
1336 NTSTATUS
1337 NTAPI
1340 {
1341  PPCI_FDO_EXTENSION ParentExtension;
1343  NTSTATUS Status;
1344  PSLOT_INFO SlotInfo;
1345 
1346  /* Check if a $PIR from the BIOS is used (legacy IRQ routing) */
1347  ParentExtension = PdoExtension->ParentFdoExtension;
1348  DPRINT1("Slot lookup for %d.%u.%u\n",
1349  ParentExtension ? ParentExtension->BaseBus : -1,
1350  PdoExtension->Slot.u.bits.DeviceNumber,
1351  PdoExtension->Slot.u.bits.FunctionNumber);
1352  if ((PciIrqRoutingTable) && (ParentExtension))
1353  {
1354  /* Read every slot information entry */
1355  SlotInfo = &PciIrqRoutingTable->Slot[0];
1356  DPRINT1("PIR$ %p is %lx bytes, slot 0 is at: %p\n",
1358  while (SlotInfo < (PSLOT_INFO)((ULONG_PTR)PciIrqRoutingTable +
1360  {
1361  DPRINT1("Slot Info: %u.%u->#%u\n",
1362  SlotInfo->BusNumber,
1363  SlotInfo->DeviceNumber,
1364  SlotInfo->SlotNumber);
1365 
1366  /* Check if this slot information matches the PDO being queried */
1367  if ((ParentExtension->BaseBus == SlotInfo->BusNumber) &&
1368  (PdoExtension->Slot.u.bits.DeviceNumber == SlotInfo->DeviceNumber >> 3) &&
1369  (SlotInfo->SlotNumber))
1370  {
1371  /* We found it, return it and return success */
1372  *SlotNumber = SlotInfo->SlotNumber;
1373  return STATUS_SUCCESS;
1374  }
1375 
1376  /* Try the next slot */
1377  SlotInfo++;
1378  }
1379  }
1380 
1381  /* Otherwise, grab the parent FDO and check if it's the root */
1382  if (PCI_IS_ROOT_FDO(ParentExtension))
1383  {
1384  /* The root FDO doesn't have a slot number */
1386  }
1387  else
1388  {
1389  /* Otherwise, query the slot/UI address/number as a device property */
1390  Status = IoGetDeviceProperty(ParentExtension->PhysicalDeviceObject,
1392  sizeof(ULONG),
1393  SlotNumber,
1394  &ResultLength);
1395  }
1396 
1397  /* Return the status of this endeavour */
1398  return Status;
1399 }
1400 
1401 NTSTATUS
1402 NTAPI
1404  IN OUT PDEVICE_CAPABILITIES DeviceCapability)
1405 {
1406  PIRP Irp;
1407  NTSTATUS Status;
1408  KEVENT Event;
1409  PDEVICE_OBJECT AttachedDevice;
1410  PIO_STACK_LOCATION IoStackLocation;
1412  PAGED_CODE();
1413 
1414  /* Zero out capabilities and set undefined values to start with */
1415  RtlZeroMemory(DeviceCapability, sizeof(DEVICE_CAPABILITIES));
1416  DeviceCapability->Size = sizeof(DEVICE_CAPABILITIES);
1417  DeviceCapability->Version = 1;
1418  DeviceCapability->Address = -1;
1419  DeviceCapability->UINumber = -1;
1420 
1421  /* Build the wait event for the IOCTL */
1423 
1424  /* Find the device the PDO is attached to */
1425  AttachedDevice = IoGetAttachedDeviceReference(DeviceObject);
1426 
1427  /* And build an IRP for it */
1429  AttachedDevice,
1430  NULL,
1431  0,
1432  NULL,
1433  &Event,
1434  &IoStatusBlock);
1435  if (!Irp)
1436  {
1437  /* The IRP failed, fail the request as well */
1438  ObDereferenceObject(AttachedDevice);
1440  }
1441 
1442  /* Set default status */
1443  Irp->IoStatus.Information = 0;
1444  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
1445 
1446  /* Get a stack location in this IRP */
1447  IoStackLocation = IoGetNextIrpStackLocation(Irp);
1448  ASSERT(IoStackLocation);
1449 
1450  /* Initialize it as a query capabilities IRP, with no completion routine */
1451  RtlZeroMemory(IoStackLocation, sizeof(IO_STACK_LOCATION));
1452  IoStackLocation->MajorFunction = IRP_MJ_PNP;
1453  IoStackLocation->MinorFunction = IRP_MN_QUERY_CAPABILITIES;
1454  IoStackLocation->Parameters.DeviceCapabilities.Capabilities = DeviceCapability;
1456 
1457  /* Send the IOCTL to the driver */
1458  Status = IoCallDriver(AttachedDevice, Irp);
1459  if (Status == STATUS_PENDING)
1460  {
1461  /* Wait for a response and update the actual status */
1463  Executive,
1464  KernelMode,
1465  FALSE,
1466  NULL);
1467  Status = Irp->IoStatus.Status;
1468  }
1469 
1470  /* Done, dereference the attached device and return the final result */
1471  ObDereferenceObject(AttachedDevice);
1472  return Status;
1473 }
1474 
1475 NTSTATUS
1476 NTAPI
1478  IN PDEVICE_CAPABILITIES DeviceCapability)
1479 {
1481  NTSTATUS Status;
1482  DEVICE_CAPABILITIES AttachedCaps;
1483  DEVICE_POWER_STATE NewPowerState, DevicePowerState, DeviceWakeLevel, DeviceWakeState;
1484  SYSTEM_POWER_STATE SystemWakeState, DeepestWakeState, CurrentState;
1485 
1486  /* Nothing is known at first */
1487  DeviceWakeState = PowerDeviceUnspecified;
1488  SystemWakeState = DeepestWakeState = PowerSystemUnspecified;
1489 
1490  /* Get the PCI capabilities for the parent PDO */
1491  DeviceObject = PdoExtension->ParentFdoExtension->PhysicalDeviceObject;
1492  Status = PciGetDeviceCapabilities(DeviceObject, &AttachedCaps);
1494  if (!NT_SUCCESS(Status)) return Status;
1495 
1496  /* Check if there's not an existing device state for S0 */
1497  if (!AttachedCaps.DeviceState[PowerSystemWorking])
1498  {
1499  /* Set D0<->S0 mapping */
1500  AttachedCaps.DeviceState[PowerSystemWorking] = PowerDeviceD0;
1501  }
1502 
1503  /* Check if there's not an existing device state for S3 */
1504  if (!AttachedCaps.DeviceState[PowerSystemShutdown])
1505  {
1506  /* Set D3<->S3 mapping */
1507  AttachedCaps.DeviceState[PowerSystemShutdown] = PowerDeviceD3;
1508  }
1509 
1510  /* Check for a PDO with broken, or no, power capabilities */
1511  if (PdoExtension->HackFlags & PCI_HACK_NO_PM_CAPS)
1512  {
1513  /* Unknown wake device states */
1514  DeviceCapability->DeviceWake = PowerDeviceUnspecified;
1515  DeviceCapability->SystemWake = PowerSystemUnspecified;
1516 
1517  /* No device state support */
1518  DeviceCapability->DeviceD1 = FALSE;
1519  DeviceCapability->DeviceD2 = FALSE;
1520 
1521  /* No waking from any low-power device state is supported */
1522  DeviceCapability->WakeFromD0 = FALSE;
1523  DeviceCapability->WakeFromD1 = FALSE;
1524  DeviceCapability->WakeFromD2 = FALSE;
1525  DeviceCapability->WakeFromD3 = FALSE;
1526 
1527  /* For the rest, copy whatever the parent PDO had */
1528  RtlCopyMemory(DeviceCapability->DeviceState,
1529  AttachedCaps.DeviceState,
1530  sizeof(DeviceCapability->DeviceState));
1531  return STATUS_SUCCESS;
1532  }
1533 
1534  /* The PCI Device has power capabilities, so read which ones are supported */
1535  DeviceCapability->DeviceD1 = PdoExtension->PowerCapabilities.Support.D1;
1536  DeviceCapability->DeviceD2 = PdoExtension->PowerCapabilities.Support.D2;
1537  DeviceCapability->WakeFromD0 = PdoExtension->PowerCapabilities.Support.PMED0;
1538  DeviceCapability->WakeFromD1 = PdoExtension->PowerCapabilities.Support.PMED1;
1539  DeviceCapability->WakeFromD2 = PdoExtension->PowerCapabilities.Support.PMED2;
1540 
1541  /* Can the attached device wake from D3? */
1542  if (AttachedCaps.DeviceWake != PowerDeviceD3)
1543  {
1544  /* It can't, so check if this PDO supports hot D3 wake */
1545  DeviceCapability->WakeFromD3 = PdoExtension->PowerCapabilities.Support.PMED3Hot;
1546  }
1547  else
1548  {
1549  /* It can, is this the root bus? */
1550  if (PCI_IS_ROOT_FDO(PdoExtension->ParentFdoExtension))
1551  {
1552  /* This is the root bus, so just check if it supports hot D3 wake */
1553  DeviceCapability->WakeFromD3 = PdoExtension->PowerCapabilities.Support.PMED3Hot;
1554  }
1555  else
1556  {
1557  /* Take the minimums? -- need to check with briang at work */
1558  UNIMPLEMENTED;
1559  }
1560  }
1561 
1562  /* Now loop each system power state to determine its device state mapping */
1565  CurrentState++)
1566  {
1567  /* Read the current mapping from the attached device */
1568  DevicePowerState = AttachedCaps.DeviceState[CurrentState];
1569  NewPowerState = DevicePowerState;
1570 
1571  /* The attachee supports D1, but this PDO does not */
1572  if ((NewPowerState == PowerDeviceD1) &&
1573  !(PdoExtension->PowerCapabilities.Support.D1))
1574  {
1575  /* Fall back to D2 */
1576  NewPowerState = PowerDeviceD2;
1577  }
1578 
1579  /* The attachee supports D2, but this PDO does not */
1580  if ((NewPowerState == PowerDeviceD2) &&
1581  !(PdoExtension->PowerCapabilities.Support.D2))
1582  {
1583  /* Fall back to D3 */
1584  NewPowerState = PowerDeviceD3;
1585  }
1586 
1587  /* Set the mapping based on the best state supported */
1588  DeviceCapability->DeviceState[CurrentState] = NewPowerState;
1589 
1590  /* Check if sleep states are being processed, and a mapping was found */
1592  (NewPowerState != PowerDeviceUnspecified))
1593  {
1594  /* Save this state as being the deepest one found until now */
1595  DeepestWakeState = CurrentState;
1596  }
1597 
1598  /*
1599  * Finally, check if the computed sleep state is within the states that
1600  * this device can wake the system from, and if it's higher or equal to
1601  * the sleep state mapping that came from the attachee, assuming that it
1602  * had a valid mapping to begin with.
1603  *
1604  * It this is the case, then make sure that the computed sleep state is
1605  * matched by the device's ability to actually wake from that state.
1606  *
1607  * For devices that support D3, the PCI device only needs Hot D3 as long
1608  * as the attachee's state is less than D3. Otherwise, if the attachee
1609  * might also be at D3, this would require a Cold D3 wake, so check that
1610  * the device actually support this.
1611  */
1612  if ((CurrentState < AttachedCaps.SystemWake) &&
1613  (NewPowerState >= DevicePowerState) &&
1615  (((NewPowerState == PowerDeviceD0) && (DeviceCapability->WakeFromD0)) ||
1616  ((NewPowerState == PowerDeviceD1) && (DeviceCapability->WakeFromD1)) ||
1617  ((NewPowerState == PowerDeviceD2) && (DeviceCapability->WakeFromD2)) ||
1618  ((NewPowerState == PowerDeviceD3) &&
1619  (PdoExtension->PowerCapabilities.Support.PMED3Hot) &&
1621  (PdoExtension->PowerCapabilities.Support.PMED3Cold)))))
1622  {
1623  /* The mapping is valid, so this will be the lowest wake state */
1624  SystemWakeState = CurrentState;
1625  DeviceWakeState = NewPowerState;
1626  }
1627  }
1628 
1629  /* Read the current wake level */
1630  DeviceWakeLevel = PdoExtension->PowerState.DeviceWakeLevel;
1631 
1632  /* Check if the attachee's wake levels are valid, and the PDO's is higher */
1633  if ((AttachedCaps.SystemWake != PowerSystemUnspecified) &&
1634  (AttachedCaps.DeviceWake != PowerDeviceUnspecified) &&
1635  (DeviceWakeLevel != PowerDeviceUnspecified) &&
1636  (DeviceWakeLevel >= AttachedCaps.DeviceWake))
1637  {
1638  /* Inherit the system wake from the attachee, and this PDO's wake level */
1639  DeviceCapability->SystemWake = AttachedCaps.SystemWake;
1640  DeviceCapability->DeviceWake = DeviceWakeLevel;
1641 
1642  /* Now check if the wake level is D0, but the PDO doesn't support it */
1643  if ((DeviceCapability->DeviceWake == PowerDeviceD0) &&
1644  !(DeviceCapability->WakeFromD0))
1645  {
1646  /* Bump to D1 */
1647  DeviceCapability->DeviceWake = PowerDeviceD1;
1648  }
1649 
1650  /* Now check if the wake level is D1, but the PDO doesn't support it */
1651  if ((DeviceCapability->DeviceWake == PowerDeviceD1) &&
1652  !(DeviceCapability->WakeFromD1))
1653  {
1654  /* Bump to D2 */
1655  DeviceCapability->DeviceWake = PowerDeviceD2;
1656  }
1657 
1658  /* Now check if the wake level is D2, but the PDO doesn't support it */
1659  if ((DeviceCapability->DeviceWake == PowerDeviceD2) &&
1660  !(DeviceCapability->WakeFromD2))
1661  {
1662  /* Bump it to D3 */
1663  DeviceCapability->DeviceWake = PowerDeviceD3;
1664  }
1665 
1666  /* Now check if the wake level is D3, but the PDO doesn't support it */
1667  if ((DeviceCapability->DeviceWake == PowerDeviceD3) &&
1668  !(DeviceCapability->WakeFromD3))
1669  {
1670  /* Then no valid wake state exists */
1671  DeviceCapability->DeviceWake = PowerDeviceUnspecified;
1672  DeviceCapability->SystemWake = PowerSystemUnspecified;
1673  }
1674 
1675  /* Check if no valid wake state was found */
1676  if ((DeviceCapability->DeviceWake == PowerDeviceUnspecified) ||
1677  (DeviceCapability->SystemWake == PowerSystemUnspecified))
1678  {
1679  /* Check if one was computed earlier */
1680  if ((SystemWakeState != PowerSystemUnspecified) &&
1681  (DeviceWakeState != PowerDeviceUnspecified))
1682  {
1683  /* Use the wake state that had been computed earlier */
1684  DeviceCapability->DeviceWake = DeviceWakeState;
1685  DeviceCapability->SystemWake = SystemWakeState;
1686 
1687  /* If that state was D3, then the device supports Hot/Cold D3 */
1688  if (DeviceWakeState == PowerDeviceD3) DeviceCapability->WakeFromD3 = TRUE;
1689  }
1690  }
1691 
1692  /*
1693  * Finally, check for off states (lower than S3, such as hibernate) and
1694  * make sure that the device both supports waking from D3 as well as
1695  * supports a Cold wake
1696  */
1697  if ((DeviceCapability->SystemWake > PowerSystemSleeping3) &&
1698  ((DeviceCapability->DeviceWake != PowerDeviceD3) ||
1699  !(PdoExtension->PowerCapabilities.Support.PMED3Cold)))
1700  {
1701  /* It doesn't, so pick the computed lowest wake state from earlier */
1702  DeviceCapability->SystemWake = DeepestWakeState;
1703  }
1704 
1705  /* Set the PCI Specification mandated maximum latencies for transitions */
1706  DeviceCapability->D1Latency = 0;
1707  DeviceCapability->D2Latency = 2;
1708  DeviceCapability->D3Latency = 100;
1709 
1710  /* Sanity check */
1711  ASSERT(DeviceCapability->DeviceState[PowerSystemWorking] == PowerDeviceD0);
1712  }
1713  else
1714  {
1715  /* No valid sleep states, no latencies to worry about */
1716  DeviceCapability->D1Latency = 0;
1717  DeviceCapability->D2Latency = 0;
1718  DeviceCapability->D3Latency = 0;
1719  }
1720 
1721  /* This function always succeeds, even without power management support */
1722  return STATUS_SUCCESS;
1723 }
1724 
1725 NTSTATUS
1726 NTAPI
1728  IN OUT PDEVICE_CAPABILITIES DeviceCapability)
1729 {
1730  NTSTATUS Status;
1731 
1732  /* A PDO ID is never unique, and its address is its function and device */
1733  DeviceCapability->UniqueID = FALSE;
1734  DeviceCapability->Address = PdoExtension->Slot.u.bits.FunctionNumber |
1735  (PdoExtension->Slot.u.bits.DeviceNumber << 16);
1736 
1737  /* Check for host bridges */
1738  if ((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
1739  (PdoExtension->SubClass == PCI_SUBCLASS_BR_HOST))
1740  {
1741  /* Raw device opens to a host bridge are acceptable */
1742  DeviceCapability->RawDeviceOK = TRUE;
1743  }
1744  else
1745  {
1746  /* Otherwise, other PDOs cannot be directly opened */
1747  DeviceCapability->RawDeviceOK = FALSE;
1748  }
1749 
1750  /* PCI PDOs are pretty fixed things */
1751  DeviceCapability->LockSupported = FALSE;
1752  DeviceCapability->EjectSupported = FALSE;
1753  DeviceCapability->Removable = FALSE;
1754  DeviceCapability->DockDevice = FALSE;
1755 
1756  /* The slot number is stored as a device property, go query it */
1757  PciDetermineSlotNumber(PdoExtension, &DeviceCapability->UINumber);
1758 
1759  /* Finally, query and power capabilities and convert them for PnP usage */
1760  Status = PciQueryPowerCapabilities(PdoExtension, DeviceCapability);
1761 
1762  /* Dump the capabilities if it all worked, and return the status */
1763  if (NT_SUCCESS(Status)) PciDebugDumpQueryCapabilities(DeviceCapability);
1764  return Status;
1765 }
1766 
1768 NTAPI
1770 {
1771  PCM_PARTIAL_RESOURCE_DESCRIPTOR NextDescriptor;
1772 
1773  /* Assume the descriptors are the fixed size ones */
1774  NextDescriptor = CmDescriptor + 1;
1775 
1776  /* But check if this is actually a variable-sized descriptor */
1777  if (CmDescriptor->Type == CmResourceTypeDeviceSpecific)
1778  {
1779  /* Add the size of the variable section as well */
1780  NextDescriptor = (PVOID)((ULONG_PTR)NextDescriptor +
1781  CmDescriptor->u.DeviceSpecificData.DataSize);
1782  }
1783 
1784  /* Now the correct pointer has been computed, return it */
1785  return NextDescriptor;
1786 }
1787 
1788 /* EOF */
VOID NTAPI PcipLinkSecondaryExtension(IN PSINGLE_LIST_ENTRY List, IN PVOID Lock, IN PPCI_SECONDARY_EXTENSION SecondaryExtension, IN PCI_SIGNATURE ExtensionType, IN PVOID Destructor)
Definition: utils.c:459
BOOLEAN NTAPI PciUnicodeStringStrStr(IN PUNICODE_STRING InputString, IN PCUNICODE_STRING EqualString, IN BOOLEAN CaseInSensitive)
Definition: utils.c:27
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
Definition: pci.h:150
DEVICE_REGISTRY_PROPERTY
Definition: iotypes.h:1154
* PNTSTATUS
Definition: strlen.c:14
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:265
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
#define IN
Definition: typedefs.h:38
#define VER_SUITENAME
Definition: rtltypes.h:232
#define VER_AND
Definition: rtltypes.h:242
#define CM_RESOURCE_MEMORY_PREFETCHABLE
Definition: cmtypes.h:123
#define PCI_ADDRESS_IO_ADDRESS_MASK
Definition: iotypes.h:3877
#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
PPCI_SECONDARY_EXTENSION NTAPI PciFindNextSecondaryExtension(IN PSINGLE_LIST_ENTRY ListHead, IN PCI_SIGNATURE ExtensionType)
Definition: utils.c:584
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG IoControlCode
Definition: fltkernel.h:1383
static PMEMKEY RootKey
Definition: registry.c:55
Type
Definition: Type.h:6
#define PCI_TYPE_20BIT
Definition: iotypes.h:3882
BOOLEAN NTAPI PciOpenKey(IN PWCHAR KeyName, IN HANDLE RootKey, IN ACCESS_MASK DesiredAccess, OUT PHANDLE KeyHandle, OUT PNTSTATUS KeyStatus)
Definition: utils.c:165
struct _Entry Entry
Definition: kefuncs.h:640
USHORT VendorID
Definition: pci.h:152
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
Definition: ntbasedef.h:635
USHORT MaximumLength
Definition: env_spec_w32.h:370
PPCI_IRQ_ROUTING_TABLE PciIrqRoutingTable
Definition: init.c:26
#define PCI_ENABLE_IO_SPACE
Definition: iotypes.h:3260
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
PPCI_FDO_EXTENSION NTAPI PciFindParentPciFdoExtension(IN PDEVICE_OBJECT DeviceObject, IN PKEVENT Lock)
Definition: utils.c:340
PPCI_HACK_ENTRY PciHackTable
Definition: init.c:28
#define REG_BINARY
Definition: nt_native.h:1496
_In_ PIRP Irp
Definition: csq.h:116
#define KEY_READ
Definition: nt_native.h:1023
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
ACPI_EVAL_OUTPUT_BUFFER UNALIGNED * PACPI_EVAL_OUTPUT_BUFFER
Definition: acpiioct.h:90
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define PCI_SUBCLASS_BR_OTHER
Definition: iotypes.h:3814
NTSTATUS NTAPI PciQueryPowerCapabilities(IN PPCI_PDO_EXTENSION PdoExtension, IN PDEVICE_CAPABILITIES DeviceCapability)
Definition: utils.c:1477
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
static int Config(const char **args)
Definition: vfdcmd.c:778
LONG NTSTATUS
Definition: precomp.h:26
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:140
NTSTATUS NTAPI PciGetDeviceCapabilities(IN PDEVICE_OBJECT DeviceObject, IN OUT PDEVICE_CAPABILITIES DeviceCapability)
Definition: utils.c:1403
#define PCI_ADDRESS_MEMORY_TYPE_MASK
Definition: iotypes.h:3875
BOOLEAN NTAPI PciIsCriticalDeviceClass(IN UCHAR BaseClass, IN UCHAR SubClass)
Definition: utils.c:672
union _IO_RESOURCE_DESCRIPTOR::@1987 u
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ ULONG _In_ ULONG OutputBufferLength
Definition: fltkernel.h:1374
NTSTATUS NTAPI PciSaveBiosConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PPCI_COMMON_HEADER PciData)
Definition: utils.c:831
#define PCI_HACK_DONT_DISABLE_DECODES
Definition: pci.h:40
Definition: strmini.h:380
enum _PCI_SIGNATURE PCI_SIGNATURE
USHORT DeviceID
Definition: pci.h:153
DEVICE_CAPABILITIES
Definition: iotypes.h:928
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
static WCHAR String[]
Definition: stringtable.c:55
uint16_t * PWCHAR
Definition: typedefs.h:54
Definition: shell.h:41
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1122
VOID NTAPI PciDebugDumpQueryCapabilities(IN PDEVICE_CAPABILITIES DeviceCaps)
Definition: debug.c:221
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
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
#define VER_SUITE_DATACENTER
USHORT wSuiteMask
Definition: rtltypes.h:273
_Out_ PKIRQL Irql
Definition: csq.h:179
VOID NTAPI PciDecodeEnable(IN PPCI_PDO_EXTENSION PdoExtension, IN BOOLEAN Enable, OUT PUSHORT Command)
Definition: utils.c:1267
enum _SYSTEM_POWER_STATE SYSTEM_POWER_STATE
UCHAR Flags
Definition: pci.h:158
#define CmResourceTypePort
Definition: hwresource.cpp:123
#define PAGED_CODE()
Definition: video.h:57
CHAR InputBuffer[80]
Definition: conmgr.c:33
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
ULONG NTAPI PciGetLengthFromBar(IN ULONG Bar)
Definition: utils.c:1158
BOOLEAN NTAPI PciStringToUSHORT(IN PWCHAR String, OUT PUSHORT Value)
Definition: utils.c:61
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
uint32_t ULONG_PTR
Definition: typedefs.h:63
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@376::@385 DeviceSpecificData
NTSTATUS NTAPI PciGetBiosConfig(IN PPCI_PDO_EXTENSION DeviceExtension, OUT PPCI_COMMON_HEADER PciData)
Definition: utils.c:768
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@376 u
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PCI_SUBCLASS_BR_CARDBUS
Definition: iotypes.h:3812
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
Definition: pci.h:77
while(1)
Definition: macro.lex.yy.c:740
UCHAR BusNumber
Definition: pci.h:79
VOID NTAPI PciWriteDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:91
struct _PCI_FDO_EXTENSION * PPCI_FDO_EXTENSION
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
#define PCI_HACK_HAS_REVISION_INFO
Definition: pci.h:49
#define PCI_ADDRESS_MEMORY_ADDRESS_MASK
Definition: iotypes.h:3878
long LONG
Definition: pedump.c:60
_In_ ULONG BufferLength
Definition: usbdlib.h:225
_In_ const STRING _In_ BOOLEAN CaseInSensitive
Definition: rtlfuncs.h:2292
USHORT SubSystemID
Definition: pci.h:155
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
UCHAR DeviceNumber
Definition: pci.h:80
RTL_RANGE_LIST PciIsaBitExclusionList
Definition: utils.c:20
BOOLEAN NTAPI PciCreateIoDescriptorFromBarLimit(PIO_RESOURCE_DESCRIPTOR ResourceDescriptor, IN PULONG BarArray, IN BOOLEAN Rom)
Definition: utils.c:1175
KEVENT ChildListLock
Definition: pci.h:201
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
USHORT SubVendorID
Definition: pci.h:154
#define CM_RESOURCE_MEMORY_READ_ONLY
Definition: cmtypes.h:121
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
struct _OSVERSIONINFOEXW RTL_OSVERSIONINFOEXW
USHORT RevisionID
Definition: pci.h:157
_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
NTSTATUS NTAPI IoGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, IN ULONG BufferLength, OUT PVOID PropertyBuffer, OUT PULONG ResultLength)
Definition: pnpmgr.c:4228
NTSYSAPI VOID NTAPI RtlFreeRangeList(_In_ PRTL_RANGE_LIST RangeList)
BOOLEAN BaseBus
Definition: pci.h:209
struct _IO_RESOURCE_DESCRIPTOR::@1987::@1992 Generic
Definition: bufpool.h:45
NTSTATUS NTAPI PciQueryBusInformation(IN PPCI_PDO_EXTENSION PdoExtension, IN PPNP_BUS_INFORMATION *Buffer)
Definition: utils.c:1316
_Must_inspect_result_ __drv_aliasesMem _In_ PDEVICE_OBJECT _In_opt_ PVOID _In_ ULONG _Out_opt_ PVOID OutputBuffer
Definition: iofuncs.h:713
void * PVOID
Definition: retypes.h:9
NTSYSAPI NTSTATUS NTAPI RtlAddRange(_Inout_ PRTL_RANGE_LIST RangeList, _In_ ULONGLONG Start, _In_ ULONGLONG End, _In_ UCHAR Attributes, _In_ ULONG Flags, _In_opt_ PVOID UserData, _In_opt_ PVOID Owner)
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
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
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
NTSTATUS NTAPI PciQueryCapabilities(IN PPCI_PDO_EXTENSION PdoExtension, IN OUT PDEVICE_CAPABILITIES DeviceCapability)
Definition: utils.c:1727
enum _PCI_DEVICE_TYPES PCI_DEVICE_TYPES
PCI_DEVICE_TYPES NTAPI PciClassifyDeviceType(IN PPCI_PDO_EXTENSION PdoExtension)
Definition: utils.c:1051
PVOID Next
Definition: pci.h:263
USHORT TableSize
Definition: pci.h:90
#define PCI_SUBCLASS_VID_VGA_CTLR
Definition: iotypes.h:3788
struct _PCI_IPI_CONTEXT * PPCI_IPI_CONTEXT
short Short
Definition: ftraster.c:311
enum _DEVICE_POWER_STATE DEVICE_POWER_STATE
#define KEY_WRITE
Definition: nt_native.h:1031
NTSYSAPI NTSTATUS WINAPI RtlVerifyVersionInfo(const RTL_OSVERSIONINFOEXW *, DWORD, DWORDLONG)
ULONGLONG NTAPI PciGetHackFlags(IN USHORT VendorId, IN USHORT DeviceId, IN USHORT SubVendorId, IN USHORT SubSystemId, IN UCHAR RevisionId)
Definition: utils.c:604
NTSTATUS NTAPI PciDetermineSlotNumber(IN PPCI_PDO_EXTENSION PdoExtension, OUT PULONG SlotNumber)
Definition: utils.c:1338
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3245
LIST_ENTRY List
Definition: psmgr.c:57
#define CmResourceTypeNull
Definition: hwresource.cpp:122
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
struct Command Command
uint64_t ULONGLONG
Definition: typedefs.h:65
struct _IO_RESOURCE_DESCRIPTOR::@1987::@1988 Port
#define PCI_ENABLE_BUS_MASTER
Definition: iotypes.h:3262
#define swprintf(buf, format,...)
Definition: sprintf.c:56
ULONGLONG HackFlags
Definition: pci.h:156
NTSYSAPI VOID NTAPI RtlInitializeRangeList(_Inout_ PRTL_RANGE_LIST RangeList)
#define PCI_SUBCLASS_BR_MCA
Definition: iotypes.h:3808
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
UCHAR SlotNumber
Definition: pci.h:82
Definition: partlist.h:33
Definition: strmini.h:378
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ PNDIS_STRING _Out_ PNDIS_HANDLE SubKeyHandle
Definition: ndis.h:4723
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
#define PCI_CLASS_DISPLAY_CTLR
Definition: iotypes.h:3750
_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
struct _SINGLE_LIST_ENTRY * Next
Definition: ntbasedef.h:636
SINGLE_LIST_ENTRY PciFdoExtensionListHead
Definition: fdo.c:18
static const WCHAR L[]
Definition: oid.c:1250
#define InterlockedDecrement
Definition: armddk.h:52
#define PCI_ADDRESS_ROM_ADDRESS_MASK
Definition: iotypes.h:3879
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define PCI_SUBCLASS_BR_PCI_TO_PCI
Definition: iotypes.h:3809
IN OUT PLONG IN OUT PLONG Addend IN OUT PLONG IN LONG IN OUT PLONG IN LONG Increment IN PNDIS_RW_LOCK Lock
Definition: CrNtStubs.h:75
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
PCM_PARTIAL_RESOURCE_DESCRIPTOR NTAPI PciNextPartialDescriptor(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDescriptor)
Definition: utils.c:1769
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ ULONG InputBufferLength
Definition: fltkernel.h:1372
#define IOCTL_ACPI_EVAL_METHOD
Definition: acpiioct.h:178
* PDEVICE_CAPABILITIES
Definition: iotypes.h:928
Status
Definition: gdiplustypes.h:24
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define PCI_IS_ROOT_FDO(x)
Definition: pci.h:30
BOOLEAN NTAPI PciCanDisableDecodes(IN PPCI_PDO_EXTENSION DeviceExtension, IN PPCI_COMMON_HEADER Config, IN ULONGLONG HackFlags, IN BOOLEAN ForPowerDown)
Definition: utils.c:955
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define ACPI_METHOD_ARGUMENT_INTEGER
Definition: acpiioct.h:21
SINGLE_LIST_ENTRY List
Definition: pci.h:192
#define PCI_HACK_HAS_SUBSYSTEM_INFO
Definition: pci.h:50
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define ACPI_EVAL_INPUT_BUFFER_SIGNATURE
Definition: acpiioct.h:7
#define PCI_TYPE_64BIT
Definition: iotypes.h:3883
_In_ DEVICE_REGISTRY_PROPERTY DeviceProperty
Definition: iofuncs.h:1003
#define CM_RESOURCE_PORT_IO
Definition: cmtypes.h:109
unsigned short USHORT
Definition: pedump.c:61
NTSTATUS NTAPI PciGetDeviceProperty(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_REGISTRY_PROPERTY DeviceProperty, OUT PVOID *OutputBuffer)
Definition: utils.c:475
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK DesiredAccess
Definition: create.c:4157
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
ACPI_METHOD_ARGUMENT UNALIGNED * PACPI_METHOD_ARGUMENT
Definition: acpiioct.h:71
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
VOID NTAPI PciInsertEntryAtHead(IN PSINGLE_LIST_ENTRY ListHead, IN PSINGLE_LIST_ENTRY Entry, IN PKEVENT Lock)
Definition: utils.c:430
#define PCI_ENABLE_BRIDGE_VGA
Definition: pci.h:62
ULONG_PTR NTAPI PciExecuteCriticalSystemRoutine(IN ULONG_PTR IpiContext)
Definition: utils.c:1069
#define PCI_HACK_NO_PM_CAPS
Definition: pci.h:39
struct _PCI_PDO_EXTENSION * ChildPdoList
Definition: pci.h:202
NTSTATUS NTAPI IoOpenDeviceRegistryKey(IN PDEVICE_OBJECT DeviceObject, IN ULONG DevInstKeyType, IN ACCESS_MASK DesiredAccess, OUT PHANDLE DevInstRegKey)
Definition: pnpmgr.c:4586
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define DPRINT1
Definition: precomp.h:8
#define PCI_ENABLE_MEMORY_SPACE
Definition: iotypes.h:3261
VOID NTAPI PciReadDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:107
ULONG PciDebugPortsCount
Definition: utils.c:18
#define PCI_SUBCLASS_PRE_20_VGA
Definition: iotypes.h:3769
PDEVICE_OBJECT PhysicalDeviceObject
Definition: pci.h:198
BOOLEAN NTAPI PciIsDeviceOnDebugPath(IN PPCI_PDO_EXTENSION DeviceExtension)
Definition: utils.c:751
PPCI_PDO_EXTENSION NTAPI PciFindPdoByFunction(IN PPCI_FDO_EXTENSION DeviceExtension, IN ULONG FunctionNumber, IN PPCI_COMMON_HEADER PciData)
Definition: utils.c:695
#define UNIMPLEMENTED_FATAL(...)
Definition: debug.h:244
#define OUT
Definition: typedefs.h:39
SLOT_INFO Slot[ANYSIZE_ARRAY]
Definition: pci.h:98
#define PCI_ADDRESS_MEMORY_PREFETCHABLE
Definition: iotypes.h:3876
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
NTSTATUS NTAPI PciBuildDefaultExclusionLists(VOID)
Definition: utils.c:276
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define PCI_SUBCLASS_BR_HOST
Definition: iotypes.h:3805
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
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
NTSTATUS NTAPI PciSendIoctl(IN PDEVICE_OBJECT DeviceObject, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength)
Definition: utils.c:531
struct _ACPI_EVAL_OUTPUT_BUFFER ACPI_EVAL_OUTPUT_BUFFER
RTL_RANGE_LIST PciVgaAndIsaBitExclusionList
Definition: utils.c:21
#define PCI_CLASS_BRIDGE_DEV
Definition: iotypes.h:3753
#define RTL_RANGE_LIST_ADD_IF_CONFLICT
Definition: rtltypes.h:81
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define PCI_SUBCLASS_BR_ISA
Definition: iotypes.h:3806
#define PCI_HACK_CB_SHARE_CMD_BITS
Definition: pci.h:26
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
#define CmResourceTypeMemory
Definition: hwresource.cpp:125
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define PCI_CLASS_BASE_SYSTEM_DEV
Definition: iotypes.h:3755
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define PCI_ADDRESS_IO_SPACE
Definition: iotypes.h:3874
#define PCI_SUBCLASS_BR_EISA
Definition: iotypes.h:3807
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define PCI_SUBCLASS_SYS_INTERRUPT_CTLR
Definition: iotypes.h:3822
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define PCI_HACK_PRESERVE_COMMAND
Definition: pci.h:24
VOID NTAPI PciInsertEntryAtTail(IN PSINGLE_LIST_ENTRY ListHead, IN PPCI_FDO_EXTENSION DeviceExtension, IN PKEVENT Lock)
Definition: utils.c:400
BOOLEAN NTAPI PciIsSuiteVersion(IN USHORT SuiteMask)
Definition: utils.c:114
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
#define VER_SET_CONDITION(ConditionMask, TypeBitMask, ComparisonType)
unsigned short * PUSHORT
Definition: retypes.h:2
ULONG ACCESS_MASK
Definition: nt_native.h:40
INTERFACE_TYPE LegacyBusType
Definition: cmtypes.h:363
base of all file and directory entries
Definition: entries.h:82
_Out_opt_ PBOOLEAN CurrentState
Definition: zwfuncs.h:393
BOOLEAN NTAPI PciIsSlotPresentInParentMethod(IN PPCI_PDO_EXTENSION PdoExtension, IN ULONG Method)
Definition: utils.c:1094
#define MAX_DEBUGGING_DEVICES_SUPPORTED
Definition: pci.h:75
BOOLEAN NTAPI PciIsDatacenter(VOID)
Definition: utils.c:131
#define IRP_MN_QUERY_CAPABILITIES
#define PCI_COMMON_HDR_LENGTH
Definition: iotypes.h:3238
#define PCI_CLASS_PRE_20
Definition: iotypes.h:3747