2 * PROJECT: ReactOS PCI Bus Driver
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/bus/pci/fdo.c
5 * PURPOSE: FDO Device Management
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
16 /* GLOBALS ********************************************************************/
18 SINGLE_LIST_ENTRY PciFdoExtensionListHead
;
19 BOOLEAN PciBreakOnDefault
;
21 PCI_MN_DISPATCH_TABLE PciFdoDispatchPowerTable
[] =
23 {IRP_DISPATCH
, (PCI_DISPATCH_FUNCTION
)PciFdoWaitWake
},
24 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
},
25 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoSetPowerState
},
26 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpQueryPower
},
27 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
}
30 PCI_MN_DISPATCH_TABLE PciFdoDispatchPnpTable
[] =
32 {IRP_UPWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpStartDevice
},
33 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpQueryRemoveDevice
},
34 {IRP_DISPATCH
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpRemoveDevice
},
35 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpCancelRemoveDevice
},
36 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpStopDevice
},
37 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpQueryStopDevice
},
38 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpCancelStopDevice
},
39 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpQueryDeviceRelations
},
40 {IRP_DISPATCH
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpQueryInterface
},
41 {IRP_UPWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpQueryCapabilities
},
42 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
},
43 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
},
44 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
},
45 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
},
46 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
},
47 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
},
48 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
},
49 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
},
50 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
},
51 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
},
52 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
},
53 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
},
54 {IRP_UPWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpDeviceUsageNotification
},
55 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpSurpriseRemoval
},
56 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpQueryLegacyBusInformation
},
57 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
}
60 PCI_MJ_DISPATCH_TABLE PciFdoDispatchTable
=
62 IRP_MN_QUERY_LEGACY_BUS_INFORMATION
,
63 PciFdoDispatchPnpTable
,
65 PciFdoDispatchPowerTable
,
67 (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
,
69 (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
72 /* FUNCTIONS ******************************************************************/
76 PciFdoIrpStartDevice(IN PIRP Irp
,
77 IN PIO_STACK_LOCATION IoStackLocation
,
78 IN PPCI_FDO_EXTENSION DeviceExtension
)
81 PCM_RESOURCE_LIST Resources
;
84 /* The device stack must be starting the FDO in a success path */
85 if (!NT_SUCCESS(Irp
->IoStatus
.Status
)) return STATUS_NOT_SUPPORTED
;
87 /* Attempt to switch the state machine to the started state */
88 Status
= PciBeginStateTransition(DeviceExtension
, PciStarted
);
89 if (!NT_SUCCESS(Status
)) return Status
;
91 /* Check for any boot-provided resources */
92 Resources
= IoStackLocation
->Parameters
.StartDevice
.AllocatedResources
;
93 if ((Resources
) && !(PCI_IS_ROOT_FDO(DeviceExtension
)))
95 /* These resources would only be for non-root FDOs, unhandled for now */
96 ASSERT(Resources
->Count
== 1);
97 UNIMPLEMENTED_DBGBREAK();
100 /* Initialize the arbiter for this FDO */
101 Status
= PciInitializeArbiterRanges(DeviceExtension
, Resources
);
102 if (!NT_SUCCESS(Status
))
104 /* Cancel the transition if this failed */
105 PciCancelStateTransition(DeviceExtension
, PciStarted
);
109 /* Again, check for boot-provided resources for non-root FDO */
110 if ((Resources
) && !(PCI_IS_ROOT_FDO(DeviceExtension
)))
112 /* Unhandled for now */
113 ASSERT(Resources
->Count
== 1);
114 UNIMPLEMENTED_DBGBREAK();
117 /* Commit the transition to the started state */
118 PciCommitStateTransition(DeviceExtension
, PciStarted
);
119 return STATUS_SUCCESS
;
124 PciFdoIrpQueryRemoveDevice(IN PIRP Irp
,
125 IN PIO_STACK_LOCATION IoStackLocation
,
126 IN PPCI_FDO_EXTENSION DeviceExtension
)
128 UNREFERENCED_PARAMETER(Irp
);
129 UNREFERENCED_PARAMETER(IoStackLocation
);
130 UNREFERENCED_PARAMETER(DeviceExtension
);
133 return STATUS_NOT_SUPPORTED
;
138 PciFdoIrpRemoveDevice(IN PIRP Irp
,
139 IN PIO_STACK_LOCATION IoStackLocation
,
140 IN PPCI_FDO_EXTENSION DeviceExtension
)
142 UNREFERENCED_PARAMETER(Irp
);
143 UNREFERENCED_PARAMETER(IoStackLocation
);
144 UNREFERENCED_PARAMETER(DeviceExtension
);
146 UNIMPLEMENTED_DBGBREAK();
147 return STATUS_NOT_SUPPORTED
;
152 PciFdoIrpCancelRemoveDevice(IN PIRP Irp
,
153 IN PIO_STACK_LOCATION IoStackLocation
,
154 IN PPCI_FDO_EXTENSION DeviceExtension
)
156 UNREFERENCED_PARAMETER(Irp
);
157 UNREFERENCED_PARAMETER(IoStackLocation
);
158 UNREFERENCED_PARAMETER(DeviceExtension
);
160 UNIMPLEMENTED_DBGBREAK();
161 return STATUS_NOT_SUPPORTED
;
166 PciFdoIrpStopDevice(IN PIRP Irp
,
167 IN PIO_STACK_LOCATION IoStackLocation
,
168 IN PPCI_FDO_EXTENSION DeviceExtension
)
170 UNREFERENCED_PARAMETER(Irp
);
171 UNREFERENCED_PARAMETER(IoStackLocation
);
172 UNREFERENCED_PARAMETER(DeviceExtension
);
174 UNIMPLEMENTED_DBGBREAK();
175 return STATUS_NOT_SUPPORTED
;
180 PciFdoIrpQueryStopDevice(IN PIRP Irp
,
181 IN PIO_STACK_LOCATION IoStackLocation
,
182 IN PPCI_FDO_EXTENSION DeviceExtension
)
184 UNREFERENCED_PARAMETER(Irp
);
185 UNREFERENCED_PARAMETER(IoStackLocation
);
186 UNREFERENCED_PARAMETER(DeviceExtension
);
188 UNIMPLEMENTED_DBGBREAK();
189 return STATUS_NOT_SUPPORTED
;
194 PciFdoIrpCancelStopDevice(IN PIRP Irp
,
195 IN PIO_STACK_LOCATION IoStackLocation
,
196 IN PPCI_FDO_EXTENSION DeviceExtension
)
198 UNREFERENCED_PARAMETER(Irp
);
199 UNREFERENCED_PARAMETER(IoStackLocation
);
200 UNREFERENCED_PARAMETER(DeviceExtension
);
202 UNIMPLEMENTED_DBGBREAK();
203 return STATUS_NOT_SUPPORTED
;
208 PciFdoIrpQueryDeviceRelations(IN PIRP Irp
,
209 IN PIO_STACK_LOCATION IoStackLocation
,
210 IN PPCI_FDO_EXTENSION DeviceExtension
)
215 /* Are bus relations being queried? */
216 if (IoStackLocation
->Parameters
.QueryDeviceRelations
.Type
!= BusRelations
)
218 /* The FDO is a bus, so only bus relations can be obtained */
219 Status
= STATUS_NOT_SUPPORTED
;
223 /* Scan the PCI bus and build the device relations for the caller */
224 Status
= PciQueryDeviceRelations(DeviceExtension
,
226 &Irp
->IoStatus
.Information
);
229 /* Return the enumeration status back */
235 PciFdoIrpQueryInterface(IN PIRP Irp
,
236 IN PIO_STACK_LOCATION IoStackLocation
,
237 IN PPCI_FDO_EXTENSION DeviceExtension
)
241 ASSERT(DeviceExtension
->ExtensionType
== PciFdoExtensionType
);
243 /* Deleted extensions don't respond to IRPs */
244 if (DeviceExtension
->DeviceState
== PciDeleted
)
246 /* Hand it back to try to deal with it */
247 return PciPassIrpFromFdoToPdo(DeviceExtension
, Irp
);
250 /* Query our driver for this interface */
251 Status
= PciQueryInterface(DeviceExtension
,
252 IoStackLocation
->Parameters
.QueryInterface
.
254 IoStackLocation
->Parameters
.QueryInterface
.
256 IoStackLocation
->Parameters
.QueryInterface
.
258 IoStackLocation
->Parameters
.QueryInterface
.
259 InterfaceSpecificData
,
260 IoStackLocation
->Parameters
.QueryInterface
.
263 if (NT_SUCCESS(Status
))
265 /* We found it, let the PDO handle it */
266 Irp
->IoStatus
.Status
= Status
;
267 return PciPassIrpFromFdoToPdo(DeviceExtension
, Irp
);
269 else if (Status
== STATUS_NOT_SUPPORTED
)
271 /* Otherwise, we can't handle it, let someone else down the stack try */
272 Status
= PciCallDownIrpStack(DeviceExtension
, Irp
);
273 if (Status
== STATUS_NOT_SUPPORTED
)
275 /* They can't either, try a last-resort interface lookup */
276 Status
= PciQueryInterface(DeviceExtension
,
277 IoStackLocation
->Parameters
.QueryInterface
.
279 IoStackLocation
->Parameters
.QueryInterface
.
281 IoStackLocation
->Parameters
.QueryInterface
.
283 IoStackLocation
->Parameters
.QueryInterface
.
284 InterfaceSpecificData
,
285 IoStackLocation
->Parameters
.QueryInterface
.
291 /* Has anyone claimed this interface yet? */
292 if (Status
== STATUS_NOT_SUPPORTED
)
294 /* No, return the original IRP status */
295 Status
= Irp
->IoStatus
.Status
;
299 /* Yes, set the new IRP status */
300 Irp
->IoStatus
.Status
= Status
;
303 /* Complete this IRP */
304 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
310 PciFdoIrpQueryCapabilities(IN PIRP Irp
,
311 IN PIO_STACK_LOCATION IoStackLocation
,
312 IN PPCI_FDO_EXTENSION DeviceExtension
)
314 PDEVICE_CAPABILITIES Capabilities
;
316 ASSERT_FDO(DeviceExtension
);
318 UNREFERENCED_PARAMETER(Irp
);
320 /* Get the capabilities */
321 Capabilities
= IoStackLocation
->Parameters
.DeviceCapabilities
.Capabilities
;
323 /* Inherit wake levels and power mappings from the higher-up capabilities */
324 DeviceExtension
->PowerState
.SystemWakeLevel
= Capabilities
->SystemWake
;
325 DeviceExtension
->PowerState
.DeviceWakeLevel
= Capabilities
->DeviceWake
;
326 RtlCopyMemory(DeviceExtension
->PowerState
.SystemStateMapping
,
327 Capabilities
->DeviceState
,
328 sizeof(DeviceExtension
->PowerState
.SystemStateMapping
));
330 /* Dump the capabilities and return success */
331 PciDebugDumpQueryCapabilities(Capabilities
);
332 return STATUS_SUCCESS
;
337 PciFdoIrpDeviceUsageNotification(IN PIRP Irp
,
338 IN PIO_STACK_LOCATION IoStackLocation
,
339 IN PPCI_FDO_EXTENSION DeviceExtension
)
341 UNREFERENCED_PARAMETER(Irp
);
342 UNREFERENCED_PARAMETER(IoStackLocation
);
343 UNREFERENCED_PARAMETER(DeviceExtension
);
345 UNIMPLEMENTED_DBGBREAK();
346 return STATUS_NOT_SUPPORTED
;
351 PciFdoIrpSurpriseRemoval(IN PIRP Irp
,
352 IN PIO_STACK_LOCATION IoStackLocation
,
353 IN PPCI_FDO_EXTENSION DeviceExtension
)
355 UNREFERENCED_PARAMETER(Irp
);
356 UNREFERENCED_PARAMETER(IoStackLocation
);
357 UNREFERENCED_PARAMETER(DeviceExtension
);
359 UNIMPLEMENTED_DBGBREAK();
360 return STATUS_NOT_SUPPORTED
;
365 PciFdoIrpQueryLegacyBusInformation(IN PIRP Irp
,
366 IN PIO_STACK_LOCATION IoStackLocation
,
367 IN PPCI_FDO_EXTENSION DeviceExtension
)
369 UNREFERENCED_PARAMETER(Irp
);
370 UNREFERENCED_PARAMETER(IoStackLocation
);
371 UNREFERENCED_PARAMETER(DeviceExtension
);
373 UNIMPLEMENTED_DBGBREAK();
374 return STATUS_NOT_SUPPORTED
;
379 PciGetHotPlugParameters(IN PPCI_FDO_EXTENSION FdoExtension
)
381 ACPI_EVAL_INPUT_BUFFER InputBuffer
;
382 PACPI_EVAL_OUTPUT_BUFFER OutputBuffer
;
387 /* We should receive 4 parameters, per the HPP specification */
388 Length
= sizeof(ACPI_EVAL_OUTPUT_BUFFER
) + 4 * sizeof(ACPI_METHOD_ARGUMENT
);
390 /* Allocate the buffer to hold the parameters */
391 OutputBuffer
= ExAllocatePoolWithTag(PagedPool
, Length
, PCI_POOL_TAG
);
392 if (!OutputBuffer
) return;
394 /* Initialize the output and input buffers. The method is _HPP */
395 RtlZeroMemory(OutputBuffer
, Length
);
396 *(PULONG
)InputBuffer
.MethodName
= 'PPH_';
397 InputBuffer
.Signature
= ACPI_EVAL_INPUT_BUFFER_SIGNATURE
;
400 /* Send the IOCTL to the ACPI driver */
401 Status
= PciSendIoctl(FdoExtension
->PhysicalDeviceObject
,
402 IOCTL_ACPI_EVAL_METHOD
,
407 if (!NT_SUCCESS(Status
))
409 /* The method failed, check if we can salvage data from parent */
410 if (!PCI_IS_ROOT_FDO(FdoExtension
))
412 /* Copy the root bus' hot plug parameters */
413 FdoExtension
->HotPlugParameters
= FdoExtension
->ParentFdoExtension
->HotPlugParameters
;
416 /* Nothing more to do on this path */
420 /* ACPI sent back some data. 4 parameters are expected in the output */
421 if (OutputBuffer
->Count
!= 4) break;
423 /* HotPlug PCI Support not yet implemented */
424 UNIMPLEMENTED_DBGBREAK();
427 /* Free the buffer and return */
428 ExFreePoolWithTag(OutputBuffer
, 0);
433 PciInitializeFdoExtensionCommonFields(PPCI_FDO_EXTENSION FdoExtension
,
434 IN PDEVICE_OBJECT DeviceObject
,
435 IN PDEVICE_OBJECT PhysicalDeviceObject
)
437 /* Initialize the extension */
438 RtlZeroMemory(FdoExtension
, sizeof(PCI_FDO_EXTENSION
));
440 /* Setup the common fields */
441 FdoExtension
->PhysicalDeviceObject
= PhysicalDeviceObject
;
442 FdoExtension
->FunctionalDeviceObject
= DeviceObject
;
443 FdoExtension
->ExtensionType
= PciFdoExtensionType
;
444 FdoExtension
->PowerState
.CurrentSystemState
= PowerSystemWorking
;
445 FdoExtension
->PowerState
.CurrentDeviceState
= PowerDeviceD0
;
446 FdoExtension
->IrpDispatchTable
= &PciFdoDispatchTable
;
448 /* Initialize the extension locks */
449 KeInitializeEvent(&FdoExtension
->SecondaryExtLock
, SynchronizationEvent
, TRUE
);
450 KeInitializeEvent(&FdoExtension
->ChildListLock
, SynchronizationEvent
, TRUE
);
452 /* Initialize the default state */
453 PciInitializeState(FdoExtension
);
458 PciAddDevice(IN PDRIVER_OBJECT DriverObject
,
459 IN PDEVICE_OBJECT PhysicalDeviceObject
)
461 PCM_RESOURCE_LIST Descriptor
;
462 PDEVICE_OBJECT AttachedTo
;
463 PPCI_FDO_EXTENSION FdoExtension
;
464 PPCI_FDO_EXTENSION ParentExtension
;
465 PPCI_PDO_EXTENSION PdoExtension
;
466 PDEVICE_OBJECT DeviceObject
;
467 UCHAR Buffer
[sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + sizeof(ULONG
)];
468 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
)Buffer
;
471 UNICODE_STRING ValueName
;
474 DPRINT1("PCI - AddDevice (a new bus). PDO: %p (Driver: %wZ)\n",
475 PhysicalDeviceObject
, &PhysicalDeviceObject
->DriverObject
->DriverName
);
477 /* Zero out variables so failure path knows what to do */
485 /* Check if there's already a device extension for this bus */
486 ParentExtension
= PciFindParentPciFdoExtension(PhysicalDeviceObject
,
490 /* Make sure we find a real PDO */
491 PdoExtension
= PhysicalDeviceObject
->DeviceExtension
;
492 ASSERT_PDO(PdoExtension
);
494 /* Make sure it's a PCI-to-PCI bridge */
495 if ((PdoExtension
->BaseClass
!= PCI_CLASS_BRIDGE_DEV
) ||
496 (PdoExtension
->SubClass
!= PCI_SUBCLASS_BR_PCI_TO_PCI
))
498 /* This should never happen */
499 DPRINT1("PCI - PciAddDevice for Non-Root/Non-PCI-PCI bridge,\n"
500 " Class %02x, SubClass %02x, will not add.\n",
501 PdoExtension
->BaseClass
,
502 PdoExtension
->SubClass
);
503 ASSERT((PdoExtension
->BaseClass
== PCI_CLASS_BRIDGE_DEV
) &&
504 (PdoExtension
->SubClass
== PCI_SUBCLASS_BR_PCI_TO_PCI
));
506 /* Enter the failure path */
507 Status
= STATUS_INVALID_DEVICE_REQUEST
;
511 /* Subordinate bus on the bridge */
512 DPRINT1("PCI - AddDevice (new bus is child of bus 0x%x).\n",
513 ParentExtension
->BaseBus
);
515 /* Make sure PCI bus numbers are configured */
516 if (!PciAreBusNumbersConfigured(PdoExtension
))
518 /* This is a critical failure */
519 DPRINT1("PCI - Bus numbers not configured for bridge (0x%x.0x%x.0x%x)\n",
520 ParentExtension
->BaseBus
,
521 PdoExtension
->Slot
.u
.bits
.DeviceNumber
,
522 PdoExtension
->Slot
.u
.bits
.FunctionNumber
);
524 /* Enter the failure path */
525 Status
= STATUS_INVALID_DEVICE_REQUEST
;
530 /* Create the FDO for the bus */
531 Status
= IoCreateDevice(DriverObject
,
532 sizeof(PCI_FDO_EXTENSION
),
534 FILE_DEVICE_BUS_EXTENDER
,
538 if (!NT_SUCCESS(Status
)) break;
540 /* Initialize the extension for the FDO */
541 FdoExtension
= DeviceObject
->DeviceExtension
;
542 PciInitializeFdoExtensionCommonFields(DeviceObject
->DeviceExtension
,
544 PhysicalDeviceObject
);
546 /* Attach to the root PDO */
547 Status
= STATUS_NO_SUCH_DEVICE
;
548 AttachedTo
= IoAttachDeviceToDeviceStack(DeviceObject
,
549 PhysicalDeviceObject
);
550 ASSERT(AttachedTo
!= NULL
);
551 if (!AttachedTo
) break;
552 FdoExtension
->AttachedDeviceObject
= AttachedTo
;
554 /* Check if this is a child bus, or the root */
557 /* The child inherits root data */
558 FdoExtension
->BaseBus
= PdoExtension
->Dependent
.type1
.SecondaryBus
;
559 FdoExtension
->BusRootFdoExtension
= ParentExtension
->BusRootFdoExtension
;
560 PdoExtension
->BridgeFdoExtension
= FdoExtension
;
561 FdoExtension
->ParentFdoExtension
= ParentExtension
;
565 /* Query the boot configuration */
566 Status
= PciGetDeviceProperty(PhysicalDeviceObject
,
567 DevicePropertyBootConfiguration
,
568 (PVOID
*)&Descriptor
);
569 if (!NT_SUCCESS(Status
))
571 /* No configuration has been set */
576 /* Root PDO in ReactOS does not assign boot resources */
577 UNIMPLEMENTED_DBGBREAK("Encountered during setup\n");
583 /* Root PDO in ReactOS does not assign boot resources */
584 UNIMPLEMENTED_DBGBREAK();
588 /* Default configuration isn't the normal path on Windows */
589 if (PciBreakOnDefault
)
591 /* If a second bus is found and there's still no data, crash */
592 KeBugCheckEx(PCI_BUS_DRIVER_INTERNAL
,
594 (ULONG_PTR
)DeviceObject
,
599 /* Warn that a default configuration will be used, and set bus 0 */
600 DPRINT1("PCI Will use default configuration.\n");
601 PciBreakOnDefault
= TRUE
;
602 FdoExtension
->BaseBus
= 0;
605 /* This is the root bus */
606 FdoExtension
->BusRootFdoExtension
= FdoExtension
;
609 /* Get the HAL or ACPI Bus Handler Callbacks for Configuration Access */
610 Status
= PciGetConfigHandlers(FdoExtension
);
611 if (!NT_SUCCESS(Status
)) break;
613 /* Initialize all the supported PCI arbiters */
614 Status
= PciInitializeArbiters(FdoExtension
);
615 if (!NT_SUCCESS(Status
)) break;
617 /* This is a real FDO, insert it into the list */
618 FdoExtension
->Fake
= FALSE
;
619 PciInsertEntryAtTail(&PciFdoExtensionListHead
,
623 /* Open the device registry key so that we can query the errata flags */
624 IoOpenDeviceRegistryKey(DeviceObject
,
625 PLUGPLAY_REGKEY_DEVICE
,
629 /* Open the value that contains errata flags for this bus instance */
630 RtlInitUnicodeString(&ValueName
, L
"HackFlags");
631 Status
= ZwQueryValueKey(KeyHandle
,
633 KeyValuePartialInformation
,
638 if (NT_SUCCESS(Status
))
640 /* Make sure the data is of expected type and size */
641 if ((ValueInfo
->Type
== REG_DWORD
) &&
642 (ValueInfo
->DataLength
== sizeof(ULONG
)))
644 /* Read the flags for this bus */
645 FdoExtension
->BusHackFlags
= *(PULONG
)&ValueInfo
->Data
;
649 /* Query ACPI for PCI HotPlug Support */
650 PciGetHotPlugParameters(FdoExtension
);
652 /* The Bus FDO is now initialized */
653 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
654 return STATUS_SUCCESS
;
657 /* This is the failure path */
658 ASSERT(!NT_SUCCESS(Status
));
660 /* Check if the FDO extension exists */
661 if (FdoExtension
) DPRINT1("Should destroy secondaries\n");
663 /* Delete device objects */
664 if (AttachedTo
) IoDetachDevice(AttachedTo
);
665 if (DeviceObject
) IoDeleteDevice(DeviceObject
);