* Sync to trunk HEAD (r53318).
[reactos.git] / drivers / bus / pcix / fdo.c
1 /*
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
7 */
8
9 /* INCLUDES *******************************************************************/
10
11 #include <pci.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 /* GLOBALS ********************************************************************/
16
17 SINGLE_LIST_ENTRY PciFdoExtensionListHead;
18 BOOLEAN PciBreakOnDefault;
19
20 PCI_MN_DISPATCH_TABLE PciFdoDispatchPowerTable[] =
21 {
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}
27 };
28
29 PCI_MN_DISPATCH_TABLE PciFdoDispatchPnpTable[] =
30 {
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}
57 };
58
59 PCI_MJ_DISPATCH_TABLE PciFdoDispatchTable =
60 {
61 IRP_MN_QUERY_LEGACY_BUS_INFORMATION,
62 PciFdoDispatchPnpTable,
63 IRP_MN_QUERY_POWER,
64 PciFdoDispatchPowerTable,
65 IRP_DOWNWARD,
66 (PCI_DISPATCH_FUNCTION)PciIrpNotSupported,
67 IRP_DOWNWARD,
68 (PCI_DISPATCH_FUNCTION)PciIrpNotSupported
69 };
70
71 /* FUNCTIONS ******************************************************************/
72
73 NTSTATUS
74 NTAPI
75 PciFdoIrpStartDevice(IN PIRP Irp,
76 IN PIO_STACK_LOCATION IoStackLocation,
77 IN PPCI_FDO_EXTENSION DeviceExtension)
78 {
79 NTSTATUS Status;
80 PCM_RESOURCE_LIST Resources;
81 PAGED_CODE();
82
83 /* The device stack must be starting the FDO in a success path */
84 if (!NT_SUCCESS(Irp->IoStatus.Status)) return STATUS_NOT_SUPPORTED;
85
86 /* Attempt to switch the state machine to the started state */
87 Status = PciBeginStateTransition(DeviceExtension, PciStarted);
88 if (!NT_SUCCESS(Status)) return Status;
89
90 /* Check for any boot-provided resources */
91 Resources = IoStackLocation->Parameters.StartDevice.AllocatedResources;
92 if ((Resources) && !(PCI_IS_ROOT_FDO(DeviceExtension)))
93 {
94 /* These resources would only be for non-root FDOs, unhandled for now */
95 ASSERT(Resources->Count == 1);
96 UNIMPLEMENTED;
97 while (TRUE);
98 }
99
100 /* Initialize the arbiter for this FDO */
101 Status = PciInitializeArbiterRanges(DeviceExtension, Resources);
102 if (!NT_SUCCESS(Status))
103 {
104 /* Cancel the transition if this failed */
105 PciCancelStateTransition(DeviceExtension, PciStarted);
106 return Status;
107 }
108
109 /* Again, check for boot-provided resources for non-root FDO */
110 if ((Resources) && !(PCI_IS_ROOT_FDO(DeviceExtension)))
111 {
112 /* Unhandled for now */
113 ASSERT(Resources->Count == 1);
114 UNIMPLEMENTED;
115 while (TRUE);
116 }
117
118 /* Commit the transition to the started state */
119 PciCommitStateTransition(DeviceExtension, PciStarted);
120 return STATUS_SUCCESS;
121 }
122
123 NTSTATUS
124 NTAPI
125 PciFdoIrpQueryRemoveDevice(IN PIRP Irp,
126 IN PIO_STACK_LOCATION IoStackLocation,
127 IN PPCI_FDO_EXTENSION DeviceExtension)
128 {
129 UNIMPLEMENTED;
130 while (TRUE);
131 return STATUS_NOT_SUPPORTED;
132 }
133
134 NTSTATUS
135 NTAPI
136 PciFdoIrpRemoveDevice(IN PIRP Irp,
137 IN PIO_STACK_LOCATION IoStackLocation,
138 IN PPCI_FDO_EXTENSION DeviceExtension)
139 {
140 UNIMPLEMENTED;
141 while (TRUE);
142 return STATUS_NOT_SUPPORTED;
143 }
144
145 NTSTATUS
146 NTAPI
147 PciFdoIrpCancelRemoveDevice(IN PIRP Irp,
148 IN PIO_STACK_LOCATION IoStackLocation,
149 IN PPCI_FDO_EXTENSION DeviceExtension)
150 {
151 UNIMPLEMENTED;
152 while (TRUE);
153 return STATUS_NOT_SUPPORTED;
154 }
155
156 NTSTATUS
157 NTAPI
158 PciFdoIrpStopDevice(IN PIRP Irp,
159 IN PIO_STACK_LOCATION IoStackLocation,
160 IN PPCI_FDO_EXTENSION DeviceExtension)
161 {
162 UNIMPLEMENTED;
163 while (TRUE);
164 return STATUS_NOT_SUPPORTED;
165 }
166
167 NTSTATUS
168 NTAPI
169 PciFdoIrpQueryStopDevice(IN PIRP Irp,
170 IN PIO_STACK_LOCATION IoStackLocation,
171 IN PPCI_FDO_EXTENSION DeviceExtension)
172 {
173 UNIMPLEMENTED;
174 while (TRUE);
175 return STATUS_NOT_SUPPORTED;
176 }
177
178 NTSTATUS
179 NTAPI
180 PciFdoIrpCancelStopDevice(IN PIRP Irp,
181 IN PIO_STACK_LOCATION IoStackLocation,
182 IN PPCI_FDO_EXTENSION DeviceExtension)
183 {
184 UNIMPLEMENTED;
185 while (TRUE);
186 return STATUS_NOT_SUPPORTED;
187 }
188
189 NTSTATUS
190 NTAPI
191 PciFdoIrpQueryDeviceRelations(IN PIRP Irp,
192 IN PIO_STACK_LOCATION IoStackLocation,
193 IN PPCI_FDO_EXTENSION DeviceExtension)
194 {
195 NTSTATUS Status;
196 PAGED_CODE();
197
198 /* Are bus relations being queried? */
199 if (IoStackLocation->Parameters.QueryDeviceRelations.Type != BusRelations)
200 {
201 /* The FDO is a bus, so only bus relations can be obtained */
202 Status = STATUS_NOT_SUPPORTED;
203 }
204 else
205 {
206 /* Scan the PCI bus and build the device relations for the caller */
207 Status = PciQueryDeviceRelations(DeviceExtension,
208 (PDEVICE_RELATIONS*)
209 &Irp->IoStatus.Information);
210 }
211
212 /* Return the enumeration status back */
213 return Status;
214 }
215
216 NTSTATUS
217 NTAPI
218 PciFdoIrpQueryInterface(IN PIRP Irp,
219 IN PIO_STACK_LOCATION IoStackLocation,
220 IN PPCI_FDO_EXTENSION DeviceExtension)
221 {
222 NTSTATUS Status;
223 PAGED_CODE();
224 ASSERT(DeviceExtension->ExtensionType == PciFdoExtensionType);
225
226 /* Deleted extensions don't respond to IRPs */
227 if (DeviceExtension->DeviceState == PciDeleted)
228 {
229 /* Hand it back to try to deal with it */
230 return PciPassIrpFromFdoToPdo(DeviceExtension, Irp);
231 }
232
233 /* Query our driver for this interface */
234 Status = PciQueryInterface(DeviceExtension,
235 IoStackLocation->Parameters.QueryInterface.
236 InterfaceType,
237 IoStackLocation->Parameters.QueryInterface.
238 Size,
239 IoStackLocation->Parameters.QueryInterface.
240 Version,
241 IoStackLocation->Parameters.QueryInterface.
242 InterfaceSpecificData,
243 IoStackLocation->Parameters.QueryInterface.
244 Interface,
245 FALSE);
246 if (NT_SUCCESS(Status))
247 {
248 /* We found it, let the PDO handle it */
249 Irp->IoStatus.Status = Status;
250 return PciPassIrpFromFdoToPdo(DeviceExtension, Irp);
251 }
252 else if (Status == STATUS_NOT_SUPPORTED)
253 {
254 /* Otherwise, we can't handle it, let someone else down the stack try */
255 Status = PciCallDownIrpStack(DeviceExtension, Irp);
256 if (Status == STATUS_NOT_SUPPORTED)
257 {
258 /* They can't either, try a last-resort interface lookup */
259 Status = PciQueryInterface(DeviceExtension,
260 IoStackLocation->Parameters.QueryInterface.
261 InterfaceType,
262 IoStackLocation->Parameters.QueryInterface.
263 Size,
264 IoStackLocation->Parameters.QueryInterface.
265 Version,
266 IoStackLocation->Parameters.QueryInterface.
267 InterfaceSpecificData,
268 IoStackLocation->Parameters.QueryInterface.
269 Interface,
270 TRUE);
271 }
272 }
273
274 /* Has anyone claimed this interface yet? */
275 if (Status == STATUS_NOT_SUPPORTED)
276 {
277 /* No, return the original IRP status */
278 Status = Irp->IoStatus.Status;
279 }
280 else
281 {
282 /* Yes, set the new IRP status */
283 Irp->IoStatus.Status = Status;
284 }
285
286 /* Complete this IRP */
287 IoCompleteRequest(Irp, IO_NO_INCREMENT);
288 return Status;
289 }
290
291 NTSTATUS
292 NTAPI
293 PciFdoIrpQueryCapabilities(IN PIRP Irp,
294 IN PIO_STACK_LOCATION IoStackLocation,
295 IN PPCI_FDO_EXTENSION DeviceExtension)
296 {
297 PDEVICE_CAPABILITIES Capabilities;
298 PAGED_CODE();
299 ASSERT_FDO(DeviceExtension);
300
301 /* Get the capabilities */
302 Capabilities = IoStackLocation->Parameters.DeviceCapabilities.Capabilities;
303
304 /* Inherit wake levels and power mappings from the higher-up capabilities */
305 DeviceExtension->PowerState.SystemWakeLevel = Capabilities->SystemWake;
306 DeviceExtension->PowerState.DeviceWakeLevel = Capabilities->DeviceWake;
307 RtlCopyMemory(DeviceExtension->PowerState.SystemStateMapping,
308 Capabilities->DeviceState,
309 sizeof(DeviceExtension->PowerState.SystemStateMapping));
310
311 /* Dump the capabilities and return success */
312 PciDebugDumpQueryCapabilities(Capabilities);
313 return STATUS_SUCCESS;
314 }
315
316 NTSTATUS
317 NTAPI
318 PciFdoIrpDeviceUsageNotification(IN PIRP Irp,
319 IN PIO_STACK_LOCATION IoStackLocation,
320 IN PPCI_FDO_EXTENSION DeviceExtension)
321 {
322 UNIMPLEMENTED;
323 while (TRUE);
324 return STATUS_NOT_SUPPORTED;
325 }
326
327 NTSTATUS
328 NTAPI
329 PciFdoIrpSurpriseRemoval(IN PIRP Irp,
330 IN PIO_STACK_LOCATION IoStackLocation,
331 IN PPCI_FDO_EXTENSION DeviceExtension)
332 {
333 UNIMPLEMENTED;
334 while (TRUE);
335 return STATUS_NOT_SUPPORTED;
336 }
337
338 NTSTATUS
339 NTAPI
340 PciFdoIrpQueryLegacyBusInformation(IN PIRP Irp,
341 IN PIO_STACK_LOCATION IoStackLocation,
342 IN PPCI_FDO_EXTENSION DeviceExtension)
343 {
344 UNIMPLEMENTED;
345 while (TRUE);
346 return STATUS_NOT_SUPPORTED;
347 }
348
349 VOID
350 NTAPI
351 PciGetHotPlugParameters(IN PPCI_FDO_EXTENSION FdoExtension)
352 {
353 ACPI_EVAL_INPUT_BUFFER InputBuffer;
354 PACPI_EVAL_OUTPUT_BUFFER OutputBuffer;
355 ULONG Length;
356 NTSTATUS Status;
357 PAGED_CODE();
358
359 /* We should receive 4 parameters, per the HPP specification */
360 Length = sizeof(ACPI_EVAL_OUTPUT_BUFFER) + 4 * sizeof(ACPI_METHOD_ARGUMENT);
361
362 /* Allocate the buffer to hold the parameters */
363 OutputBuffer = ExAllocatePoolWithTag(PagedPool, Length, PCI_POOL_TAG);
364 if (!OutputBuffer) return;
365
366 /* Initialize the output and input buffers. The method is _HPP */
367 RtlZeroMemory(OutputBuffer, Length);
368 *(PULONG)InputBuffer.MethodName = 'PPH_';
369 InputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE;
370 do
371 {
372 /* Send the IOCTL to the ACPI driver */
373 Status = PciSendIoctl(FdoExtension->PhysicalDeviceObject,
374 IOCTL_ACPI_EVAL_METHOD,
375 &InputBuffer,
376 sizeof(InputBuffer),
377 OutputBuffer,
378 Length);
379 if (!NT_SUCCESS(Status))
380 {
381 /* The method failed, check if we can salvage data from parent */
382 if (!PCI_IS_ROOT_FDO(FdoExtension))
383 {
384 /* Copy the root bus' hot plug parameters */
385 FdoExtension->HotPlugParameters = FdoExtension->ParentFdoExtension->HotPlugParameters;
386 }
387
388 /* Nothing more to do on this path */
389 break;
390 }
391
392 /* ACPI sent back some data. 4 parameters are expected in the output */
393 if (OutputBuffer->Count != 4) break;
394
395 /* HotPlug PCI Support not yet implemented */
396 UNIMPLEMENTED;
397 while (TRUE);
398 } while (FALSE);
399
400 /* Free the buffer and return */
401 ExFreePoolWithTag(OutputBuffer, 0);
402 }
403
404 VOID
405 NTAPI
406 PciInitializeFdoExtensionCommonFields(PPCI_FDO_EXTENSION FdoExtension,
407 IN PDEVICE_OBJECT DeviceObject,
408 IN PDEVICE_OBJECT PhysicalDeviceObject)
409 {
410 /* Initialize the extension */
411 RtlZeroMemory(FdoExtension, sizeof(PCI_FDO_EXTENSION));
412
413 /* Setup the common fields */
414 FdoExtension->PhysicalDeviceObject = PhysicalDeviceObject;
415 FdoExtension->FunctionalDeviceObject = DeviceObject;
416 FdoExtension->ExtensionType = PciFdoExtensionType;
417 FdoExtension->PowerState.CurrentSystemState = PowerSystemWorking;
418 FdoExtension->PowerState.CurrentDeviceState = PowerDeviceD0;
419 FdoExtension->IrpDispatchTable = &PciFdoDispatchTable;
420
421 /* Initialize the extension locks */
422 KeInitializeEvent(&FdoExtension->SecondaryExtLock, SynchronizationEvent, TRUE);
423 KeInitializeEvent(&FdoExtension->ChildListLock, SynchronizationEvent, TRUE);
424
425 /* Initialize the default state */
426 PciInitializeState(FdoExtension);
427 }
428
429 NTSTATUS
430 NTAPI
431 PciAddDevice(IN PDRIVER_OBJECT DriverObject,
432 IN PDEVICE_OBJECT PhysicalDeviceObject)
433 {
434 PCM_RESOURCE_LIST Descriptor;
435 PDEVICE_OBJECT AttachedTo;
436 PPCI_FDO_EXTENSION FdoExtension;
437 PPCI_FDO_EXTENSION ParentExtension;
438 PPCI_PDO_EXTENSION PdoExtension;
439 PDEVICE_OBJECT DeviceObject;
440 UCHAR Buffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
441 PKEY_VALUE_PARTIAL_INFORMATION ValueInfo = (PKEY_VALUE_PARTIAL_INFORMATION)Buffer;
442 NTSTATUS Status;
443 HANDLE KeyHandle;
444 UNICODE_STRING ValueName;
445 ULONG ResultLength;
446 PAGED_CODE();
447 DPRINT1("PCI - AddDevice (a new bus). PDO: %p (Driver: %wZ)\n",
448 PhysicalDeviceObject, &PhysicalDeviceObject->DriverObject->DriverName);
449
450 /* Zero out variables so failure path knows what to do */
451 AttachedTo = NULL;
452 FdoExtension = NULL;
453 PdoExtension = NULL;
454 do
455 {
456 /* Check if there's already a device extension for this bus */
457 ParentExtension = PciFindParentPciFdoExtension(PhysicalDeviceObject,
458 &PciGlobalLock);
459 if (ParentExtension)
460 {
461 /* Make sure we find a real PDO */
462 PdoExtension = PhysicalDeviceObject->DeviceExtension;
463 ASSERT_PDO(PdoExtension);
464
465 /* Make sure it's a PCI-to-PCI bridge */
466 if ((PdoExtension->BaseClass != PCI_CLASS_BRIDGE_DEV) ||
467 (PdoExtension->SubClass != PCI_SUBCLASS_BR_PCI_TO_PCI))
468 {
469 /* This should never happen */
470 DPRINT1("PCI - PciAddDevice for Non-Root/Non-PCI-PCI bridge,\n"
471 " Class %02x, SubClass %02x, will not add.\n",
472 PdoExtension->BaseClass,
473 PdoExtension->SubClass);
474 ASSERT((PdoExtension->BaseClass == PCI_CLASS_BRIDGE_DEV) &&
475 (PdoExtension->SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI));
476
477 /* Enter the failure path */
478 Status = STATUS_INVALID_DEVICE_REQUEST;
479 break;
480 }
481
482 /* Subordinate bus on the bridge */
483 DPRINT1("PCI - AddDevice (new bus is child of bus 0x%x).\n",
484 ParentExtension->BaseBus);
485
486 /* Make sure PCI bus numbers are configured */
487 if (!PciAreBusNumbersConfigured(PdoExtension))
488 {
489 /* This is a critical failure */
490 DPRINT1("PCI - Bus numbers not configured for bridge (0x%x.0x%x.0x%x)\n",
491 ParentExtension->BaseBus,
492 PdoExtension->Slot.u.bits.DeviceNumber,
493 PdoExtension->Slot.u.bits.FunctionNumber);
494
495 /* Enter the failure path */
496 Status = STATUS_INVALID_DEVICE_REQUEST;
497 break;
498 }
499 }
500
501 /* Create the FDO for the bus */
502 Status = IoCreateDevice(DriverObject,
503 sizeof(PCI_FDO_EXTENSION),
504 NULL,
505 FILE_DEVICE_BUS_EXTENDER,
506 0,
507 0,
508 &DeviceObject);
509 if (!NT_SUCCESS(Status)) break;
510
511 /* Initialize the extension for the FDO */
512 FdoExtension = DeviceObject->DeviceExtension;
513 PciInitializeFdoExtensionCommonFields(DeviceObject->DeviceExtension,
514 DeviceObject,
515 PhysicalDeviceObject);
516
517 /* Attach to the root PDO */
518 Status = STATUS_NO_SUCH_DEVICE;
519 AttachedTo = IoAttachDeviceToDeviceStack(DeviceObject,
520 PhysicalDeviceObject);
521 ASSERT(AttachedTo != NULL);
522 if (!AttachedTo) break;
523 FdoExtension->AttachedDeviceObject = AttachedTo;
524
525 /* Check if this is a child bus, or the root */
526 if (ParentExtension)
527 {
528 /* The child inherits root data */
529 FdoExtension->BaseBus = PdoExtension->Dependent.type1.SecondaryBus;
530 FdoExtension->BusRootFdoExtension = ParentExtension->BusRootFdoExtension;
531 PdoExtension->BridgeFdoExtension = FdoExtension;
532 FdoExtension->ParentFdoExtension = ParentExtension;
533 }
534 else
535 {
536 /* Query the boot configuration */
537 Status = PciGetDeviceProperty(PhysicalDeviceObject,
538 DevicePropertyBootConfiguration,
539 (PVOID*)&Descriptor);
540 if (!NT_SUCCESS(Status))
541 {
542 /* No configuration has been set */
543 Descriptor = NULL;
544 }
545 else
546 {
547 /* Root PDO in ReactOS does not assign boot resources */
548 UNIMPLEMENTED;
549 // while (TRUE);
550 DPRINT1("Encountered during setup\n");
551 Descriptor = NULL;
552 }
553
554 if (Descriptor)
555 {
556 /* Root PDO in ReactOS does not assign boot resources */
557 UNIMPLEMENTED;
558 while (TRUE);
559 }
560 else
561 {
562 /* Default configuration isn't the normal path on Windows */
563 if (PciBreakOnDefault)
564 {
565 /* If a second bus is found and there's still no data, crash */
566 KeBugCheckEx(PCI_BUS_DRIVER_INTERNAL,
567 0xDEAD0010u,
568 (ULONG_PTR)DeviceObject,
569 0,
570 0);
571 }
572
573 /* Warn that a default configuration will be used, and set bus 0 */
574 DPRINT1("PCI Will use default configuration.\n");
575 PciBreakOnDefault = TRUE;
576 FdoExtension->BaseBus = 0;
577 }
578
579 /* This is the root bus */
580 FdoExtension->BusRootFdoExtension = FdoExtension;
581 }
582
583 /* Get the HAL or ACPI Bus Handler Callbacks for Configuration Access */
584 Status = PciGetConfigHandlers(FdoExtension);
585 if (!NT_SUCCESS(Status)) break;
586
587 /* Initialize all the supported PCI arbiters */
588 Status = PciInitializeArbiters(FdoExtension);
589 if (!NT_SUCCESS(Status)) break;
590
591 /* This is a real FDO, insert it into the list */
592 FdoExtension->Fake = FALSE;
593 PciInsertEntryAtTail(&PciFdoExtensionListHead,
594 FdoExtension,
595 &PciGlobalLock);
596
597 /* Open the device registry key so that we can query the errata flags */
598 IoOpenDeviceRegistryKey(DeviceObject,
599 PLUGPLAY_REGKEY_DEVICE,
600 KEY_ALL_ACCESS,
601 &KeyHandle),
602
603 /* Open the value that contains errata flags for this bus instance */
604 RtlInitUnicodeString(&ValueName, L"HackFlags");
605 Status = ZwQueryValueKey(KeyHandle,
606 &ValueName,
607 KeyValuePartialInformation,
608 ValueInfo,
609 sizeof(Buffer),
610 &ResultLength);
611 ZwClose(KeyHandle);
612 if (NT_SUCCESS(Status))
613 {
614 /* Make sure the data is of expected type and size */
615 if ((ValueInfo->Type == REG_DWORD) &&
616 (ValueInfo->DataLength == sizeof(ULONG)))
617 {
618 /* Read the flags for this bus */
619 FdoExtension->BusHackFlags = *(PULONG)&ValueInfo->Data;
620 }
621 }
622
623 /* Query ACPI for PCI HotPlug Support */
624 PciGetHotPlugParameters(FdoExtension);
625
626 /* The Bus FDO is now initialized */
627 DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
628 return STATUS_SUCCESS;
629 } while (FALSE);
630
631 /* This is the failure path */
632 ASSERT(!NT_SUCCESS(Status));
633
634 /* Check if the FDO extension exists */
635 if (FdoExtension) DPRINT1("Should destroy secondaries\n");
636
637 /* Delete device objects */
638 if (AttachedTo) IoDetachDevice(AttachedTo);
639 if (DeviceObject) IoDeleteDevice(DeviceObject);
640 return Status;
641 }
642
643 /* EOF */