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