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 */ 644