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 *******************************************************************/
15 /* GLOBALS ********************************************************************/
17 SINGLE_LIST_ENTRY PciFdoExtensionListHead
;
18 BOOLEAN PciBreakOnDefault
;
20 PCI_MN_DISPATCH_TABLE PciFdoDispatchPowerTable
[] =
22 {IRP_DISPATCH
, (PCI_DISPATCH_FUNCTION
)PciFdoWaitWake
},
23 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
},
24 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoSetPowerState
},
25 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpQueryPower
},
26 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
}
29 PCI_MN_DISPATCH_TABLE PciFdoDispatchPnpTable
[] =
31 {IRP_UPWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpStartDevice
},
32 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpQueryRemoveDevice
},
33 {IRP_DISPATCH
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpRemoveDevice
},
34 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpCancelRemoveDevice
},
35 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpStopDevice
},
36 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpQueryStopDevice
},
37 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpCancelStopDevice
},
38 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpQueryDeviceRelations
},
39 {IRP_DISPATCH
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpQueryInterface
},
40 {IRP_UPWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpQueryCapabilities
},
41 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
},
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_UPWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpDeviceUsageNotification
},
54 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpSurpriseRemoval
},
55 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciFdoIrpQueryLegacyBusInformation
},
56 {IRP_DOWNWARD
, (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
}
59 PCI_MJ_DISPATCH_TABLE PciFdoDispatchTable
=
61 IRP_MN_QUERY_LEGACY_BUS_INFORMATION
,
62 PciFdoDispatchPnpTable
,
64 PciFdoDispatchPowerTable
,
66 (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
,
68 (PCI_DISPATCH_FUNCTION
)PciIrpNotSupported
71 /* FUNCTIONS ******************************************************************/
75 PciFdoIrpStartDevice(IN PIRP Irp
,
76 IN PIO_STACK_LOCATION IoStackLocation
,
77 IN PPCI_FDO_EXTENSION DeviceExtension
)
80 PCM_RESOURCE_LIST Resources
;
83 /* The device stack must be starting the FDO in a success path */
84 if (!NT_SUCCESS(Irp
->IoStatus
.Status
)) return STATUS_NOT_SUPPORTED
;
86 /* Attempt to switch the state machine to the started state */
87 Status
= PciBeginStateTransition(DeviceExtension
, PciStarted
);
88 if (!NT_SUCCESS(Status
)) return Status
;
90 /* Check for any boot-provided resources */
91 Resources
= IoStackLocation
->Parameters
.StartDevice
.AllocatedResources
;
92 if ((Resources
) && !(PCI_IS_ROOT_FDO(DeviceExtension
)))
94 /* These resources would only be for non-root FDOs, unhandled for now */
95 ASSERT(Resources
->Count
== 1);
96 UNIMPLEMENTED_DBGBREAK();
99 /* Initialize the arbiter for this FDO */
100 Status
= PciInitializeArbiterRanges(DeviceExtension
, Resources
);
101 if (!NT_SUCCESS(Status
))
103 /* Cancel the transition if this failed */
104 PciCancelStateTransition(DeviceExtension
, PciStarted
);
108 /* Again, check for boot-provided resources for non-root FDO */
109 if ((Resources
) && !(PCI_IS_ROOT_FDO(DeviceExtension
)))
111 /* Unhandled for now */
112 ASSERT(Resources
->Count
== 1);
113 UNIMPLEMENTED_DBGBREAK();
116 /* Commit the transition to the started state */
117 PciCommitStateTransition(DeviceExtension
, PciStarted
);
118 return STATUS_SUCCESS
;
123 PciFdoIrpQueryRemoveDevice(IN PIRP Irp
,
124 IN PIO_STACK_LOCATION IoStackLocation
,
125 IN PPCI_FDO_EXTENSION DeviceExtension
)
127 UNREFERENCED_PARAMETER(Irp
);
128 UNREFERENCED_PARAMETER(IoStackLocation
);
129 UNREFERENCED_PARAMETER(DeviceExtension
);
132 return STATUS_NOT_SUPPORTED
;
137 PciFdoIrpRemoveDevice(IN PIRP Irp
,
138 IN PIO_STACK_LOCATION IoStackLocation
,
139 IN PPCI_FDO_EXTENSION DeviceExtension
)
141 UNREFERENCED_PARAMETER(Irp
);
142 UNREFERENCED_PARAMETER(IoStackLocation
);
143 UNREFERENCED_PARAMETER(DeviceExtension
);
145 UNIMPLEMENTED_DBGBREAK();
146 return STATUS_NOT_SUPPORTED
;
151 PciFdoIrpCancelRemoveDevice(IN PIRP Irp
,
152 IN PIO_STACK_LOCATION IoStackLocation
,
153 IN PPCI_FDO_EXTENSION DeviceExtension
)
155 UNREFERENCED_PARAMETER(Irp
);
156 UNREFERENCED_PARAMETER(IoStackLocation
);
157 UNREFERENCED_PARAMETER(DeviceExtension
);
159 UNIMPLEMENTED_DBGBREAK();
160 return STATUS_NOT_SUPPORTED
;
165 PciFdoIrpStopDevice(IN PIRP Irp
,
166 IN PIO_STACK_LOCATION IoStackLocation
,
167 IN PPCI_FDO_EXTENSION DeviceExtension
)
169 UNREFERENCED_PARAMETER(Irp
);
170 UNREFERENCED_PARAMETER(IoStackLocation
);
171 UNREFERENCED_PARAMETER(DeviceExtension
);
173 UNIMPLEMENTED_DBGBREAK();
174 return STATUS_NOT_SUPPORTED
;
179 PciFdoIrpQueryStopDevice(IN PIRP Irp
,
180 IN PIO_STACK_LOCATION IoStackLocation
,
181 IN PPCI_FDO_EXTENSION DeviceExtension
)
183 UNREFERENCED_PARAMETER(Irp
);
184 UNREFERENCED_PARAMETER(IoStackLocation
);
185 UNREFERENCED_PARAMETER(DeviceExtension
);
187 UNIMPLEMENTED_DBGBREAK();
188 return STATUS_NOT_SUPPORTED
;
193 PciFdoIrpCancelStopDevice(IN PIRP Irp
,
194 IN PIO_STACK_LOCATION IoStackLocation
,
195 IN PPCI_FDO_EXTENSION DeviceExtension
)
197 UNREFERENCED_PARAMETER(Irp
);
198 UNREFERENCED_PARAMETER(IoStackLocation
);
199 UNREFERENCED_PARAMETER(DeviceExtension
);
201 UNIMPLEMENTED_DBGBREAK();
202 return STATUS_NOT_SUPPORTED
;
207 PciFdoIrpQueryDeviceRelations(IN PIRP Irp
,
208 IN PIO_STACK_LOCATION IoStackLocation
,
209 IN PPCI_FDO_EXTENSION DeviceExtension
)
214 /* Are bus relations being queried? */
215 if (IoStackLocation
->Parameters
.QueryDeviceRelations
.Type
!= BusRelations
)
217 /* The FDO is a bus, so only bus relations can be obtained */
218 Status
= STATUS_NOT_SUPPORTED
;
222 /* Scan the PCI bus and build the device relations for the caller */
223 Status
= PciQueryDeviceRelations(DeviceExtension
,
225 &Irp
->IoStatus
.Information
);
228 /* Return the enumeration status back */
234 PciFdoIrpQueryInterface(IN PIRP Irp
,
235 IN PIO_STACK_LOCATION IoStackLocation
,
236 IN PPCI_FDO_EXTENSION DeviceExtension
)
240 ASSERT(DeviceExtension
->ExtensionType
== PciFdoExtensionType
);
242 /* Deleted extensions don't respond to IRPs */
243 if (DeviceExtension
->DeviceState
== PciDeleted
)
245 /* Hand it back to try to deal with it */
246 return PciPassIrpFromFdoToPdo(DeviceExtension
, Irp
);
249 /* Query our driver for this interface */
250 Status
= PciQueryInterface(DeviceExtension
,
251 IoStackLocation
->Parameters
.QueryInterface
.
253 IoStackLocation
->Parameters
.QueryInterface
.
255 IoStackLocation
->Parameters
.QueryInterface
.
257 IoStackLocation
->Parameters
.QueryInterface
.
258 InterfaceSpecificData
,
259 IoStackLocation
->Parameters
.QueryInterface
.
262 if (NT_SUCCESS(Status
))
264 /* We found it, let the PDO handle it */
265 Irp
->IoStatus
.Status
= Status
;
266 return PciPassIrpFromFdoToPdo(DeviceExtension
, Irp
);
268 else if (Status
== STATUS_NOT_SUPPORTED
)
270 /* Otherwise, we can't handle it, let someone else down the stack try */
271 Status
= PciCallDownIrpStack(DeviceExtension
, Irp
);
272 if (Status
== STATUS_NOT_SUPPORTED
)
274 /* They can't either, try a last-resort interface lookup */
275 Status
= PciQueryInterface(DeviceExtension
,
276 IoStackLocation
->Parameters
.QueryInterface
.
278 IoStackLocation
->Parameters
.QueryInterface
.
280 IoStackLocation
->Parameters
.QueryInterface
.
282 IoStackLocation
->Parameters
.QueryInterface
.
283 InterfaceSpecificData
,
284 IoStackLocation
->Parameters
.QueryInterface
.
290 /* Has anyone claimed this interface yet? */
291 if (Status
== STATUS_NOT_SUPPORTED
)
293 /* No, return the original IRP status */
294 Status
= Irp
->IoStatus
.Status
;
298 /* Yes, set the new IRP status */
299 Irp
->IoStatus
.Status
= Status
;
302 /* Complete this IRP */
303 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
309 PciFdoIrpQueryCapabilities(IN PIRP Irp
,
310 IN PIO_STACK_LOCATION IoStackLocation
,
311 IN PPCI_FDO_EXTENSION DeviceExtension
)
313 PDEVICE_CAPABILITIES Capabilities
;
315 ASSERT_FDO(DeviceExtension
);
317 UNREFERENCED_PARAMETER(Irp
);
319 /* Get the capabilities */
320 Capabilities
= IoStackLocation
->Parameters
.DeviceCapabilities
.Capabilities
;
322 /* Inherit wake levels and power mappings from the higher-up capabilities */
323 DeviceExtension
->PowerState
.SystemWakeLevel
= Capabilities
->SystemWake
;
324 DeviceExtension
->PowerState
.DeviceWakeLevel
= Capabilities
->DeviceWake
;
325 RtlCopyMemory(DeviceExtension
->PowerState
.SystemStateMapping
,
326 Capabilities
->DeviceState
,
327 sizeof(DeviceExtension
->PowerState
.SystemStateMapping
));
329 /* Dump the capabilities and return success */
330 PciDebugDumpQueryCapabilities(Capabilities
);
331 return STATUS_SUCCESS
;
336 PciFdoIrpDeviceUsageNotification(IN PIRP Irp
,
337 IN PIO_STACK_LOCATION IoStackLocation
,
338 IN PPCI_FDO_EXTENSION DeviceExtension
)
340 UNREFERENCED_PARAMETER(Irp
);
341 UNREFERENCED_PARAMETER(IoStackLocation
);
342 UNREFERENCED_PARAMETER(DeviceExtension
);
344 UNIMPLEMENTED_DBGBREAK();
345 return STATUS_NOT_SUPPORTED
;
350 PciFdoIrpSurpriseRemoval(IN PIRP Irp
,
351 IN PIO_STACK_LOCATION IoStackLocation
,
352 IN PPCI_FDO_EXTENSION DeviceExtension
)
354 UNREFERENCED_PARAMETER(Irp
);
355 UNREFERENCED_PARAMETER(IoStackLocation
);
356 UNREFERENCED_PARAMETER(DeviceExtension
);
358 UNIMPLEMENTED_DBGBREAK();
359 return STATUS_NOT_SUPPORTED
;
364 PciFdoIrpQueryLegacyBusInformation(IN PIRP Irp
,
365 IN PIO_STACK_LOCATION IoStackLocation
,
366 IN PPCI_FDO_EXTENSION DeviceExtension
)
368 UNREFERENCED_PARAMETER(Irp
);
369 UNREFERENCED_PARAMETER(IoStackLocation
);
370 UNREFERENCED_PARAMETER(DeviceExtension
);
372 UNIMPLEMENTED_DBGBREAK();
373 return STATUS_NOT_SUPPORTED
;
378 PciGetHotPlugParameters(IN PPCI_FDO_EXTENSION FdoExtension
)
380 ACPI_EVAL_INPUT_BUFFER InputBuffer
;
381 PACPI_EVAL_OUTPUT_BUFFER OutputBuffer
;
386 /* We should receive 4 parameters, per the HPP specification */
387 Length
= sizeof(ACPI_EVAL_OUTPUT_BUFFER
) + 4 * sizeof(ACPI_METHOD_ARGUMENT
);
389 /* Allocate the buffer to hold the parameters */
390 OutputBuffer
= ExAllocatePoolWithTag(PagedPool
, Length
, PCI_POOL_TAG
);
391 if (!OutputBuffer
) return;
393 /* Initialize the output and input buffers. The method is _HPP */
394 RtlZeroMemory(OutputBuffer
, Length
);
395 *(PULONG
)InputBuffer
.MethodName
= 'PPH_';
396 InputBuffer
.Signature
= ACPI_EVAL_INPUT_BUFFER_SIGNATURE
;
399 /* Send the IOCTL to the ACPI driver */
400 Status
= PciSendIoctl(FdoExtension
->PhysicalDeviceObject
,
401 IOCTL_ACPI_EVAL_METHOD
,
406 if (!NT_SUCCESS(Status
))
408 /* The method failed, check if we can salvage data from parent */
409 if (!PCI_IS_ROOT_FDO(FdoExtension
))
411 /* Copy the root bus' hot plug parameters */
412 FdoExtension
->HotPlugParameters
= FdoExtension
->ParentFdoExtension
->HotPlugParameters
;
415 /* Nothing more to do on this path */
419 /* ACPI sent back some data. 4 parameters are expected in the output */
420 if (OutputBuffer
->Count
!= 4) break;
422 /* HotPlug PCI Support not yet implemented */
423 UNIMPLEMENTED_DBGBREAK();
426 /* Free the buffer and return */
427 ExFreePoolWithTag(OutputBuffer
, 0);
432 PciInitializeFdoExtensionCommonFields(PPCI_FDO_EXTENSION FdoExtension
,
433 IN PDEVICE_OBJECT DeviceObject
,
434 IN PDEVICE_OBJECT PhysicalDeviceObject
)
436 /* Initialize the extension */
437 RtlZeroMemory(FdoExtension
, sizeof(PCI_FDO_EXTENSION
));
439 /* Setup the common fields */
440 FdoExtension
->PhysicalDeviceObject
= PhysicalDeviceObject
;
441 FdoExtension
->FunctionalDeviceObject
= DeviceObject
;
442 FdoExtension
->ExtensionType
= PciFdoExtensionType
;
443 FdoExtension
->PowerState
.CurrentSystemState
= PowerSystemWorking
;
444 FdoExtension
->PowerState
.CurrentDeviceState
= PowerDeviceD0
;
445 FdoExtension
->IrpDispatchTable
= &PciFdoDispatchTable
;
447 /* Initialize the extension locks */
448 KeInitializeEvent(&FdoExtension
->SecondaryExtLock
, SynchronizationEvent
, TRUE
);
449 KeInitializeEvent(&FdoExtension
->ChildListLock
, SynchronizationEvent
, TRUE
);
451 /* Initialize the default state */
452 PciInitializeState(FdoExtension
);
457 PciAddDevice(IN PDRIVER_OBJECT DriverObject
,
458 IN PDEVICE_OBJECT PhysicalDeviceObject
)
460 PCM_RESOURCE_LIST Descriptor
;
461 PDEVICE_OBJECT AttachedTo
;
462 PPCI_FDO_EXTENSION FdoExtension
;
463 PPCI_FDO_EXTENSION ParentExtension
;
464 PPCI_PDO_EXTENSION PdoExtension
;
465 PDEVICE_OBJECT DeviceObject
;
466 UCHAR Buffer
[sizeof(KEY_VALUE_PARTIAL_INFORMATION
) + sizeof(ULONG
)];
467 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo
= (PKEY_VALUE_PARTIAL_INFORMATION
)Buffer
;
470 UNICODE_STRING ValueName
;
473 DPRINT1("PCI - AddDevice (a new bus). PDO: %p (Driver: %wZ)\n",
474 PhysicalDeviceObject
, &PhysicalDeviceObject
->DriverObject
->DriverName
);
476 /* Zero out variables so failure path knows what to do */
482 /* Check if there's already a device extension for this bus */
483 ParentExtension
= PciFindParentPciFdoExtension(PhysicalDeviceObject
,
487 /* Make sure we find a real PDO */
488 PdoExtension
= PhysicalDeviceObject
->DeviceExtension
;
489 ASSERT_PDO(PdoExtension
);
491 /* Make sure it's a PCI-to-PCI bridge */
492 if ((PdoExtension
->BaseClass
!= PCI_CLASS_BRIDGE_DEV
) ||
493 (PdoExtension
->SubClass
!= PCI_SUBCLASS_BR_PCI_TO_PCI
))
495 /* This should never happen */
496 DPRINT1("PCI - PciAddDevice for Non-Root/Non-PCI-PCI bridge,\n"
497 " Class %02x, SubClass %02x, will not add.\n",
498 PdoExtension
->BaseClass
,
499 PdoExtension
->SubClass
);
500 ASSERT((PdoExtension
->BaseClass
== PCI_CLASS_BRIDGE_DEV
) &&
501 (PdoExtension
->SubClass
== PCI_SUBCLASS_BR_PCI_TO_PCI
));
503 /* Enter the failure path */
504 Status
= STATUS_INVALID_DEVICE_REQUEST
;
508 /* Subordinate bus on the bridge */
509 DPRINT1("PCI - AddDevice (new bus is child of bus 0x%x).\n",
510 ParentExtension
->BaseBus
);
512 /* Make sure PCI bus numbers are configured */
513 if (!PciAreBusNumbersConfigured(PdoExtension
))
515 /* This is a critical failure */
516 DPRINT1("PCI - Bus numbers not configured for bridge (0x%x.0x%x.0x%x)\n",
517 ParentExtension
->BaseBus
,
518 PdoExtension
->Slot
.u
.bits
.DeviceNumber
,
519 PdoExtension
->Slot
.u
.bits
.FunctionNumber
);
521 /* Enter the failure path */
522 Status
= STATUS_INVALID_DEVICE_REQUEST
;
527 /* Create the FDO for the bus */
528 Status
= IoCreateDevice(DriverObject
,
529 sizeof(PCI_FDO_EXTENSION
),
531 FILE_DEVICE_BUS_EXTENDER
,
535 if (!NT_SUCCESS(Status
)) break;
537 /* Initialize the extension for the FDO */
538 FdoExtension
= DeviceObject
->DeviceExtension
;
539 PciInitializeFdoExtensionCommonFields(DeviceObject
->DeviceExtension
,
541 PhysicalDeviceObject
);
543 /* Attach to the root PDO */
544 Status
= STATUS_NO_SUCH_DEVICE
;
545 AttachedTo
= IoAttachDeviceToDeviceStack(DeviceObject
,
546 PhysicalDeviceObject
);
547 ASSERT(AttachedTo
!= NULL
);
548 if (!AttachedTo
) break;
549 FdoExtension
->AttachedDeviceObject
= AttachedTo
;
551 /* Check if this is a child bus, or the root */
554 /* The child inherits root data */
555 FdoExtension
->BaseBus
= PdoExtension
->Dependent
.type1
.SecondaryBus
;
556 FdoExtension
->BusRootFdoExtension
= ParentExtension
->BusRootFdoExtension
;
557 PdoExtension
->BridgeFdoExtension
= FdoExtension
;
558 FdoExtension
->ParentFdoExtension
= ParentExtension
;
562 /* Query the boot configuration */
563 Status
= PciGetDeviceProperty(PhysicalDeviceObject
,
564 DevicePropertyBootConfiguration
,
565 (PVOID
*)&Descriptor
);
566 if (!NT_SUCCESS(Status
))
568 /* No configuration has been set */
573 /* Root PDO in ReactOS does not assign boot resources */
574 UNIMPLEMENTED_DBGBREAK("Encountered during setup\n");
580 /* Root PDO in ReactOS does not assign boot resources */
581 UNIMPLEMENTED_DBGBREAK();
585 /* Default configuration isn't the normal path on Windows */
586 if (PciBreakOnDefault
)
588 /* If a second bus is found and there's still no data, crash */
589 KeBugCheckEx(PCI_BUS_DRIVER_INTERNAL
,
591 (ULONG_PTR
)DeviceObject
,
596 /* Warn that a default configuration will be used, and set bus 0 */
597 DPRINT1("PCI Will use default configuration.\n");
598 PciBreakOnDefault
= TRUE
;
599 FdoExtension
->BaseBus
= 0;
602 /* This is the root bus */
603 FdoExtension
->BusRootFdoExtension
= FdoExtension
;
606 /* Get the HAL or ACPI Bus Handler Callbacks for Configuration Access */
607 Status
= PciGetConfigHandlers(FdoExtension
);
608 if (!NT_SUCCESS(Status
)) break;
610 /* Initialize all the supported PCI arbiters */
611 Status
= PciInitializeArbiters(FdoExtension
);
612 if (!NT_SUCCESS(Status
)) break;
614 /* This is a real FDO, insert it into the list */
615 FdoExtension
->Fake
= FALSE
;
616 PciInsertEntryAtTail(&PciFdoExtensionListHead
,
620 /* Open the device registry key so that we can query the errata flags */
621 IoOpenDeviceRegistryKey(DeviceObject
,
622 PLUGPLAY_REGKEY_DEVICE
,
626 /* Open the value that contains errata flags for this bus instance */
627 RtlInitUnicodeString(&ValueName
, L
"HackFlags");
628 Status
= ZwQueryValueKey(KeyHandle
,
630 KeyValuePartialInformation
,
635 if (NT_SUCCESS(Status
))
637 /* Make sure the data is of expected type and size */
638 if ((ValueInfo
->Type
== REG_DWORD
) &&
639 (ValueInfo
->DataLength
== sizeof(ULONG
)))
641 /* Read the flags for this bus */
642 FdoExtension
->BusHackFlags
= *(PULONG
)&ValueInfo
->Data
;
646 /* Query ACPI for PCI HotPlug Support */
647 PciGetHotPlugParameters(FdoExtension
);
649 /* The Bus FDO is now initialized */
650 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
651 return STATUS_SUCCESS
;
654 /* This is the failure path */
655 ASSERT(!NT_SUCCESS(Status
));
657 /* Check if the FDO extension exists */
658 if (FdoExtension
) DPRINT1("Should destroy secondaries\n");
660 /* Delete device objects */
661 if (AttachedTo
) IoDetachDevice(AttachedTo
);
662 if (DeviceObject
) IoDeleteDevice(DeviceObject
);