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