1 /* 2 * PROJECT: ReactOS PCI Bus Driver 3 * LICENSE: BSD - See COPYING.ARM in the top level directory 4 * FILE: drivers/bus/pci/pdo.c 5 * PURPOSE: PDO Device Management 6 * PROGRAMMERS: ReactOS Portable Systems Group 7 */ 8 9 /* INCLUDES *******************************************************************/ 10 11 #include <pci.h> 12 13 #define NDEBUG 14 #include <debug.h> 15 16 /* GLOBALS ********************************************************************/ 17 18 LONG PciPdoSequenceNumber; 19 20 C_ASSERT(FIELD_OFFSET(PCI_FDO_EXTENSION, DeviceState) == FIELD_OFFSET(PCI_PDO_EXTENSION, DeviceState)); 21 C_ASSERT(FIELD_OFFSET(PCI_FDO_EXTENSION, TentativeNextState) == FIELD_OFFSET(PCI_PDO_EXTENSION, TentativeNextState)); 22 C_ASSERT(FIELD_OFFSET(PCI_FDO_EXTENSION, List) == FIELD_OFFSET(PCI_PDO_EXTENSION, Next)); 23 24 PCI_MN_DISPATCH_TABLE PciPdoDispatchPowerTable[] = 25 { 26 {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciPdoWaitWake}, 27 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, 28 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoSetPowerState}, 29 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryPower}, 30 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported} 31 }; 32 33 PCI_MN_DISPATCH_TABLE PciPdoDispatchPnpTable[] = 34 { 35 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpStartDevice}, 36 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryRemoveDevice}, 37 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpRemoveDevice}, 38 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpCancelRemoveDevice}, 39 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpStopDevice}, 40 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryStopDevice}, 41 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpCancelStopDevice}, 42 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryDeviceRelations}, 43 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryInterface}, 44 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryCapabilities}, 45 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryResources}, 46 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryResourceRequirements}, 47 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryDeviceText}, 48 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, 49 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, 50 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpReadConfig}, 51 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpWriteConfig}, 52 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, 53 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}, 54 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryId}, 55 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryDeviceState}, 56 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryBusInformation}, 57 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpDeviceUsageNotification}, 58 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpSurpriseRemoval}, 59 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryLegacyBusInformation}, 60 {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported} 61 }; 62 63 PCI_MJ_DISPATCH_TABLE PciPdoDispatchTable = 64 { 65 IRP_MN_QUERY_LEGACY_BUS_INFORMATION, 66 PciPdoDispatchPnpTable, 67 IRP_MN_QUERY_POWER, 68 PciPdoDispatchPowerTable, 69 IRP_COMPLETE, 70 (PCI_DISPATCH_FUNCTION)PciIrpNotSupported, 71 IRP_COMPLETE, 72 (PCI_DISPATCH_FUNCTION)PciIrpInvalidDeviceRequest 73 }; 74 75 /* FUNCTIONS ******************************************************************/ 76 77 NTSTATUS 78 NTAPI 79 PciPdoWaitWake(IN PIRP Irp, 80 IN PIO_STACK_LOCATION IoStackLocation, 81 IN PPCI_PDO_EXTENSION DeviceExtension) 82 { 83 UNREFERENCED_PARAMETER(Irp); 84 UNREFERENCED_PARAMETER(IoStackLocation); 85 UNREFERENCED_PARAMETER(DeviceExtension); 86 87 UNIMPLEMENTED_DBGBREAK(); 88 return STATUS_NOT_SUPPORTED; 89 } 90 91 NTSTATUS 92 NTAPI 93 PciPdoSetPowerState(IN PIRP Irp, 94 IN PIO_STACK_LOCATION IoStackLocation, 95 IN PPCI_PDO_EXTENSION DeviceExtension) 96 { 97 UNREFERENCED_PARAMETER(Irp); 98 UNREFERENCED_PARAMETER(IoStackLocation); 99 UNREFERENCED_PARAMETER(DeviceExtension); 100 101 UNIMPLEMENTED; 102 return STATUS_NOT_SUPPORTED; 103 } 104 105 NTSTATUS 106 NTAPI 107 PciPdoIrpQueryPower(IN PIRP Irp, 108 IN PIO_STACK_LOCATION IoStackLocation, 109 IN PPCI_PDO_EXTENSION DeviceExtension) 110 { 111 UNREFERENCED_PARAMETER(Irp); 112 UNREFERENCED_PARAMETER(IoStackLocation); 113 UNREFERENCED_PARAMETER(DeviceExtension); 114 115 UNIMPLEMENTED_DBGBREAK(); 116 return STATUS_NOT_SUPPORTED; 117 } 118 119 NTSTATUS 120 NTAPI 121 PciPdoIrpStartDevice(IN PIRP Irp, 122 IN PIO_STACK_LOCATION IoStackLocation, 123 IN PPCI_PDO_EXTENSION DeviceExtension) 124 { 125 NTSTATUS Status; 126 BOOLEAN Changed, DoReset; 127 POWER_STATE PowerState; 128 PAGED_CODE(); 129 130 UNREFERENCED_PARAMETER(Irp); 131 132 DoReset = FALSE; 133 134 /* Begin entering the start phase */ 135 Status = PciBeginStateTransition((PVOID)DeviceExtension, PciStarted); 136 if (!NT_SUCCESS(Status)) return Status; 137 138 /* Check if this is a VGA device */ 139 if (((DeviceExtension->BaseClass == PCI_CLASS_PRE_20) && 140 (DeviceExtension->SubClass == PCI_SUBCLASS_PRE_20_VGA)) || 141 ((DeviceExtension->BaseClass == PCI_CLASS_DISPLAY_CTLR) && 142 (DeviceExtension->SubClass == PCI_SUBCLASS_VID_VGA_CTLR))) 143 { 144 /* Always force it on */ 145 DeviceExtension->CommandEnables |= (PCI_ENABLE_IO_SPACE | 146 PCI_ENABLE_MEMORY_SPACE); 147 } 148 149 /* Check if native IDE is enabled and it owns the I/O ports */ 150 if (DeviceExtension->IoSpaceUnderNativeIdeControl) 151 { 152 /* Then don't allow I/O access */ 153 DeviceExtension->CommandEnables &= ~PCI_ENABLE_IO_SPACE; 154 } 155 156 /* Always enable bus mastering */ 157 DeviceExtension->CommandEnables |= PCI_ENABLE_BUS_MASTER; 158 159 /* Check if the OS assigned resources differ from the PCI configuration */ 160 Changed = PciComputeNewCurrentSettings(DeviceExtension, 161 IoStackLocation->Parameters. 162 StartDevice.AllocatedResources); 163 if (Changed) 164 { 165 /* Remember this for later */ 166 DeviceExtension->MovedDevice = TRUE; 167 } 168 else 169 { 170 /* All good */ 171 DPRINT1("PCI - START not changing resource settings.\n"); 172 } 173 174 /* Check if the device was sleeping */ 175 if (DeviceExtension->PowerState.CurrentDeviceState != PowerDeviceD0) 176 { 177 /* Power it up */ 178 Status = PciSetPowerManagedDevicePowerState(DeviceExtension, 179 PowerDeviceD0, 180 FALSE); 181 if (!NT_SUCCESS(Status)) 182 { 183 /* Powerup fail, fail the request */ 184 PciCancelStateTransition((PVOID)DeviceExtension, PciStarted); 185 return STATUS_DEVICE_POWER_FAILURE; 186 } 187 188 /* Tell the power manager that the device is powered up */ 189 PowerState.DeviceState = PowerDeviceD0; 190 PoSetPowerState(DeviceExtension->PhysicalDeviceObject, 191 DevicePowerState, 192 PowerState); 193 194 /* Update internal state */ 195 DeviceExtension->PowerState.CurrentDeviceState = PowerDeviceD0; 196 197 /* This device's resources and decodes will need to be reset */ 198 DoReset = TRUE; 199 } 200 201 /* Update resource information now that the device is powered up and active */ 202 Status = PciSetResources(DeviceExtension, DoReset, TRUE); 203 if (!NT_SUCCESS(Status)) 204 { 205 /* That failed, so cancel the transition */ 206 PciCancelStateTransition((PVOID)DeviceExtension, PciStarted); 207 } 208 else 209 { 210 /* Fully commit, as the device is now started up and ready to go */ 211 PciCommitStateTransition((PVOID)DeviceExtension, PciStarted); 212 } 213 214 /* Return the result of the start request */ 215 return Status; 216 } 217 218 NTSTATUS 219 NTAPI 220 PciPdoIrpQueryRemoveDevice(IN PIRP Irp, 221 IN PIO_STACK_LOCATION IoStackLocation, 222 IN PPCI_PDO_EXTENSION DeviceExtension) 223 { 224 UNREFERENCED_PARAMETER(Irp); 225 UNREFERENCED_PARAMETER(IoStackLocation); 226 UNREFERENCED_PARAMETER(DeviceExtension); 227 228 UNIMPLEMENTED; 229 return STATUS_NOT_SUPPORTED; 230 } 231 232 NTSTATUS 233 NTAPI 234 PciPdoIrpRemoveDevice(IN PIRP Irp, 235 IN PIO_STACK_LOCATION IoStackLocation, 236 IN PPCI_PDO_EXTENSION DeviceExtension) 237 { 238 UNREFERENCED_PARAMETER(Irp); 239 UNREFERENCED_PARAMETER(IoStackLocation); 240 UNREFERENCED_PARAMETER(DeviceExtension); 241 242 UNIMPLEMENTED_DBGBREAK(); 243 return STATUS_NOT_SUPPORTED; 244 } 245 246 NTSTATUS 247 NTAPI 248 PciPdoIrpCancelRemoveDevice(IN PIRP Irp, 249 IN PIO_STACK_LOCATION IoStackLocation, 250 IN PPCI_PDO_EXTENSION DeviceExtension) 251 { 252 UNREFERENCED_PARAMETER(Irp); 253 UNREFERENCED_PARAMETER(IoStackLocation); 254 UNREFERENCED_PARAMETER(DeviceExtension); 255 256 UNIMPLEMENTED_DBGBREAK(); 257 return STATUS_NOT_SUPPORTED; 258 } 259 260 NTSTATUS 261 NTAPI 262 PciPdoIrpStopDevice(IN PIRP Irp, 263 IN PIO_STACK_LOCATION IoStackLocation, 264 IN PPCI_PDO_EXTENSION DeviceExtension) 265 { 266 UNREFERENCED_PARAMETER(Irp); 267 UNREFERENCED_PARAMETER(IoStackLocation); 268 UNREFERENCED_PARAMETER(DeviceExtension); 269 270 UNIMPLEMENTED_DBGBREAK(); 271 return STATUS_NOT_SUPPORTED; 272 } 273 274 NTSTATUS 275 NTAPI 276 PciPdoIrpQueryStopDevice(IN PIRP Irp, 277 IN PIO_STACK_LOCATION IoStackLocation, 278 IN PPCI_PDO_EXTENSION DeviceExtension) 279 { 280 UNREFERENCED_PARAMETER(Irp); 281 UNREFERENCED_PARAMETER(IoStackLocation); 282 UNREFERENCED_PARAMETER(DeviceExtension); 283 284 UNIMPLEMENTED_DBGBREAK(); 285 return STATUS_NOT_SUPPORTED; 286 } 287 288 NTSTATUS 289 NTAPI 290 PciPdoIrpCancelStopDevice(IN PIRP Irp, 291 IN PIO_STACK_LOCATION IoStackLocation, 292 IN PPCI_PDO_EXTENSION DeviceExtension) 293 { 294 UNREFERENCED_PARAMETER(Irp); 295 UNREFERENCED_PARAMETER(IoStackLocation); 296 UNREFERENCED_PARAMETER(DeviceExtension); 297 298 UNIMPLEMENTED_DBGBREAK(); 299 return STATUS_NOT_SUPPORTED; 300 } 301 302 NTSTATUS 303 NTAPI 304 PciPdoIrpQueryInterface(IN PIRP Irp, 305 IN PIO_STACK_LOCATION IoStackLocation, 306 IN PPCI_PDO_EXTENSION DeviceExtension) 307 { 308 UNREFERENCED_PARAMETER(Irp); 309 UNREFERENCED_PARAMETER(IoStackLocation); 310 UNREFERENCED_PARAMETER(DeviceExtension); 311 312 UNIMPLEMENTED_DBGBREAK(); 313 return STATUS_NOT_SUPPORTED; 314 } 315 316 NTSTATUS 317 NTAPI 318 PciPdoIrpQueryDeviceRelations(IN PIRP Irp, 319 IN PIO_STACK_LOCATION IoStackLocation, 320 IN PPCI_PDO_EXTENSION DeviceExtension) 321 { 322 NTSTATUS Status; 323 PAGED_CODE(); 324 325 /* Are ejection relations being queried? */ 326 if (IoStackLocation->Parameters.QueryDeviceRelations.Type == EjectionRelations) 327 { 328 /* Call the worker function */ 329 Status = PciQueryEjectionRelations(DeviceExtension, 330 (PDEVICE_RELATIONS*)&Irp-> 331 IoStatus.Information); 332 } 333 else if (IoStackLocation->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation) 334 { 335 /* The only other relation supported is the target device relation */ 336 Status = PciQueryTargetDeviceRelations(DeviceExtension, 337 (PDEVICE_RELATIONS*)&Irp-> 338 IoStatus.Information); 339 } 340 else 341 { 342 /* All other relations are unsupported */ 343 Status = STATUS_NOT_SUPPORTED; 344 } 345 346 /* Return either the result of the worker function, or unsupported status */ 347 return Status; 348 } 349 350 NTSTATUS 351 NTAPI 352 PciPdoIrpQueryCapabilities(IN PIRP Irp, 353 IN PIO_STACK_LOCATION IoStackLocation, 354 IN PPCI_PDO_EXTENSION DeviceExtension) 355 { 356 PAGED_CODE(); 357 358 UNREFERENCED_PARAMETER(Irp); 359 360 /* Call the worker function */ 361 return PciQueryCapabilities(DeviceExtension, 362 IoStackLocation-> 363 Parameters.DeviceCapabilities.Capabilities); 364 } 365 366 NTSTATUS 367 NTAPI 368 PciPdoIrpQueryResources(IN PIRP Irp, 369 IN PIO_STACK_LOCATION IoStackLocation, 370 IN PPCI_PDO_EXTENSION DeviceExtension) 371 { 372 PAGED_CODE(); 373 374 UNREFERENCED_PARAMETER(IoStackLocation); 375 376 /* Call the worker function */ 377 return PciQueryResources(DeviceExtension, 378 (PCM_RESOURCE_LIST*)&Irp->IoStatus.Information); 379 } 380 381 NTSTATUS 382 NTAPI 383 PciPdoIrpQueryResourceRequirements(IN PIRP Irp, 384 IN PIO_STACK_LOCATION IoStackLocation, 385 IN PPCI_PDO_EXTENSION DeviceExtension) 386 { 387 PAGED_CODE(); 388 389 UNREFERENCED_PARAMETER(IoStackLocation); 390 391 /* Call the worker function */ 392 return PciQueryRequirements(DeviceExtension, 393 (PIO_RESOURCE_REQUIREMENTS_LIST*)&Irp-> 394 IoStatus.Information); 395 } 396 397 NTSTATUS 398 NTAPI 399 PciPdoIrpQueryDeviceText(IN PIRP Irp, 400 IN PIO_STACK_LOCATION IoStackLocation, 401 IN PPCI_PDO_EXTENSION DeviceExtension) 402 { 403 PAGED_CODE(); 404 405 /* Call the worker function */ 406 return PciQueryDeviceText(DeviceExtension, 407 IoStackLocation-> 408 Parameters.QueryDeviceText.DeviceTextType, 409 IoStackLocation-> 410 Parameters.QueryDeviceText.LocaleId, 411 (PWCHAR*)&Irp->IoStatus.Information); 412 } 413 414 NTSTATUS 415 NTAPI 416 PciPdoIrpQueryId(IN PIRP Irp, 417 IN PIO_STACK_LOCATION IoStackLocation, 418 IN PPCI_PDO_EXTENSION DeviceExtension) 419 { 420 PAGED_CODE(); 421 422 /* Call the worker function */ 423 return PciQueryId(DeviceExtension, 424 IoStackLocation->Parameters.QueryId.IdType, 425 (PWCHAR*)&Irp->IoStatus.Information); 426 } 427 428 NTSTATUS 429 NTAPI 430 PciPdoIrpQueryBusInformation(IN PIRP Irp, 431 IN PIO_STACK_LOCATION IoStackLocation, 432 IN PPCI_PDO_EXTENSION DeviceExtension) 433 { 434 PAGED_CODE(); 435 436 UNREFERENCED_PARAMETER(IoStackLocation); 437 438 /* Call the worker function */ 439 return PciQueryBusInformation(DeviceExtension, 440 (PPNP_BUS_INFORMATION*)&Irp-> 441 IoStatus.Information); 442 } 443 444 NTSTATUS 445 NTAPI 446 PciPdoIrpReadConfig(IN PIRP Irp, 447 IN PIO_STACK_LOCATION IoStackLocation, 448 IN PPCI_PDO_EXTENSION DeviceExtension) 449 { 450 UNREFERENCED_PARAMETER(Irp); 451 UNREFERENCED_PARAMETER(IoStackLocation); 452 UNREFERENCED_PARAMETER(DeviceExtension); 453 454 UNIMPLEMENTED_DBGBREAK(); 455 return STATUS_NOT_SUPPORTED; 456 } 457 458 NTSTATUS 459 NTAPI 460 PciPdoIrpWriteConfig(IN PIRP Irp, 461 IN PIO_STACK_LOCATION IoStackLocation, 462 IN PPCI_PDO_EXTENSION DeviceExtension) 463 { 464 UNREFERENCED_PARAMETER(Irp); 465 UNREFERENCED_PARAMETER(IoStackLocation); 466 UNREFERENCED_PARAMETER(DeviceExtension); 467 468 UNIMPLEMENTED_DBGBREAK(); 469 return STATUS_NOT_SUPPORTED; 470 } 471 472 NTSTATUS 473 NTAPI 474 PciPdoIrpQueryDeviceState(IN PIRP Irp, 475 IN PIO_STACK_LOCATION IoStackLocation, 476 IN PPCI_PDO_EXTENSION DeviceExtension) 477 { 478 UNREFERENCED_PARAMETER(Irp); 479 UNREFERENCED_PARAMETER(IoStackLocation); 480 UNREFERENCED_PARAMETER(DeviceExtension); 481 482 UNIMPLEMENTED; 483 return STATUS_NOT_SUPPORTED; 484 } 485 486 NTSTATUS 487 NTAPI 488 PciPdoIrpDeviceUsageNotification(IN PIRP Irp, 489 IN PIO_STACK_LOCATION IoStackLocation, 490 IN PPCI_PDO_EXTENSION DeviceExtension) 491 { 492 UNREFERENCED_PARAMETER(Irp); 493 UNREFERENCED_PARAMETER(IoStackLocation); 494 UNREFERENCED_PARAMETER(DeviceExtension); 495 496 UNIMPLEMENTED_DBGBREAK(); 497 return STATUS_NOT_SUPPORTED; 498 } 499 500 NTSTATUS 501 NTAPI 502 PciPdoIrpSurpriseRemoval(IN PIRP Irp, 503 IN PIO_STACK_LOCATION IoStackLocation, 504 IN PPCI_PDO_EXTENSION DeviceExtension) 505 { 506 UNREFERENCED_PARAMETER(Irp); 507 UNREFERENCED_PARAMETER(IoStackLocation); 508 UNREFERENCED_PARAMETER(DeviceExtension); 509 510 UNIMPLEMENTED_DBGBREAK(); 511 return STATUS_NOT_SUPPORTED; 512 } 513 514 NTSTATUS 515 NTAPI 516 PciPdoIrpQueryLegacyBusInformation(IN PIRP Irp, 517 IN PIO_STACK_LOCATION IoStackLocation, 518 IN PPCI_PDO_EXTENSION DeviceExtension) 519 { 520 UNREFERENCED_PARAMETER(Irp); 521 UNREFERENCED_PARAMETER(IoStackLocation); 522 UNREFERENCED_PARAMETER(DeviceExtension); 523 524 UNIMPLEMENTED_DBGBREAK(); 525 return STATUS_NOT_SUPPORTED; 526 } 527 528 NTSTATUS 529 NTAPI 530 PciPdoCreate(IN PPCI_FDO_EXTENSION DeviceExtension, 531 IN PCI_SLOT_NUMBER Slot, 532 OUT PDEVICE_OBJECT *PdoDeviceObject) 533 { 534 WCHAR DeviceName[32]; 535 UNICODE_STRING DeviceString; 536 NTSTATUS Status; 537 PDEVICE_OBJECT DeviceObject; 538 PPCI_PDO_EXTENSION PdoExtension; 539 ULONG SequenceNumber; 540 PAGED_CODE(); 541 542 /* Pick an atomically unique sequence number for this device */ 543 SequenceNumber = InterlockedIncrement(&PciPdoSequenceNumber); 544 545 /* Create the standard PCI device name for a PDO */ 546 swprintf(DeviceName, L"\\Device\\NTPNP_PCI%04d", SequenceNumber); 547 RtlInitUnicodeString(&DeviceString, DeviceName); 548 549 /* Create the actual device now */ 550 Status = IoCreateDevice(DeviceExtension->FunctionalDeviceObject->DriverObject, 551 sizeof(PCI_PDO_EXTENSION), 552 &DeviceString, 553 FILE_DEVICE_BUS_EXTENDER, 554 0, 555 0, 556 &DeviceObject); 557 ASSERT(NT_SUCCESS(Status)); 558 559 /* Get the extension for it */ 560 PdoExtension = (PPCI_PDO_EXTENSION)DeviceObject->DeviceExtension; 561 DPRINT1("PCI: New PDO (b=0x%x, d=0x%x, f=0x%x) @ %p, ext @ %p\n", 562 DeviceExtension->BaseBus, 563 Slot.u.bits.DeviceNumber, 564 Slot.u.bits.FunctionNumber, 565 DeviceObject, 566 DeviceObject->DeviceExtension); 567 568 /* Configure the extension */ 569 PdoExtension->ExtensionType = PciPdoExtensionType; 570 PdoExtension->IrpDispatchTable = &PciPdoDispatchTable; 571 PdoExtension->PhysicalDeviceObject = DeviceObject; 572 PdoExtension->Slot = Slot; 573 PdoExtension->PowerState.CurrentSystemState = PowerDeviceD0; 574 PdoExtension->PowerState.CurrentDeviceState = PowerDeviceD0; 575 PdoExtension->ParentFdoExtension = DeviceExtension; 576 577 /* Initialize the lock for arbiters and other interfaces */ 578 KeInitializeEvent(&PdoExtension->SecondaryExtLock, SynchronizationEvent, TRUE); 579 580 /* Initialize the state machine */ 581 PciInitializeState((PPCI_FDO_EXTENSION)PdoExtension); 582 583 /* Add the PDO to the parent's list */ 584 PdoExtension->Next = NULL; 585 PciInsertEntryAtTail((PSINGLE_LIST_ENTRY)&DeviceExtension->ChildPdoList, 586 (PPCI_FDO_EXTENSION)PdoExtension, 587 &DeviceExtension->ChildListLock); 588 589 /* And finally return it to the caller */ 590 *PdoDeviceObject = DeviceObject; 591 return STATUS_SUCCESS; 592 } 593 594 /* EOF */ 595