1 /* 2 * PROJECT: ReactOS Storport Driver 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Storport FDO code 5 * COPYRIGHT: Copyright 2017 Eric Kohl (eric.kohl@reactos.org) 6 */ 7 8 /* INCLUDES *******************************************************************/ 9 10 #include "precomp.h" 11 12 #define NDEBUG 13 #include <debug.h> 14 15 16 /* FUNCTIONS ******************************************************************/ 17 18 static 19 BOOLEAN 20 NTAPI 21 PortFdoInterruptRoutine( 22 _In_ PKINTERRUPT Interrupt, 23 _In_ PVOID ServiceContext) 24 { 25 PFDO_DEVICE_EXTENSION DeviceExtension; 26 27 DPRINT1("PortFdoInterruptRoutine(%p %p)\n", 28 Interrupt, ServiceContext); 29 30 DeviceExtension = (PFDO_DEVICE_EXTENSION)ServiceContext; 31 32 return MiniportHwInterrupt(&DeviceExtension->Miniport); 33 } 34 35 36 static 37 NTSTATUS 38 PortFdoConnectInterrupt( 39 _In_ PFDO_DEVICE_EXTENSION DeviceExtension) 40 { 41 ULONG Vector; 42 KIRQL Irql; 43 KINTERRUPT_MODE InterruptMode; 44 BOOLEAN ShareVector; 45 KAFFINITY Affinity; 46 NTSTATUS Status; 47 48 DPRINT1("PortFdoConnectInterrupt(%p)\n", 49 DeviceExtension); 50 51 /* No resources, no interrupt. Done! */ 52 if (DeviceExtension->AllocatedResources == NULL || 53 DeviceExtension->TranslatedResources == NULL) 54 { 55 DPRINT1("Checkpoint\n"); 56 return STATUS_SUCCESS; 57 } 58 59 /* Get the interrupt data from the resource list */ 60 Status = GetResourceListInterrupt(DeviceExtension, 61 &Vector, 62 &Irql, 63 &InterruptMode, 64 &ShareVector, 65 &Affinity); 66 if (!NT_SUCCESS(Status)) 67 { 68 DPRINT1("GetResourceListInterrupt() failed (Status 0x%08lx)\n", Status); 69 return Status; 70 } 71 72 DPRINT1("Vector: %lu\n", Vector); 73 DPRINT1("Irql: %lu\n", Irql); 74 75 DPRINT1("Affinity: 0x%08lx\n", Affinity); 76 77 /* Connect the interrupt */ 78 Status = IoConnectInterrupt(&DeviceExtension->Interrupt, 79 PortFdoInterruptRoutine, 80 DeviceExtension, 81 NULL, 82 Vector, 83 Irql, 84 Irql, 85 InterruptMode, 86 ShareVector, 87 Affinity, 88 FALSE); 89 if (NT_SUCCESS(Status)) 90 { 91 DeviceExtension->InterruptIrql = Irql; 92 } 93 else 94 { 95 DPRINT1("IoConnectInterrupt() failed (Status 0x%08lx)\n", Status); 96 } 97 98 return Status; 99 } 100 101 102 static 103 NTSTATUS 104 PortFdoStartMiniport( 105 _In_ PFDO_DEVICE_EXTENSION DeviceExtension) 106 { 107 PHW_INITIALIZATION_DATA InitData; 108 INTERFACE_TYPE InterfaceType; 109 NTSTATUS Status; 110 111 DPRINT1("PortFdoStartDevice(%p)\n", DeviceExtension); 112 113 /* Get the interface type of the lower device */ 114 InterfaceType = GetBusInterface(DeviceExtension->LowerDevice); 115 if (InterfaceType == InterfaceTypeUndefined) 116 return STATUS_NO_SUCH_DEVICE; 117 118 /* Get the driver init data for the given interface type */ 119 InitData = PortGetDriverInitData(DeviceExtension->DriverExtension, 120 InterfaceType); 121 if (InitData == NULL) 122 return STATUS_NO_SUCH_DEVICE; 123 124 /* Initialize the miniport */ 125 Status = MiniportInitialize(&DeviceExtension->Miniport, 126 DeviceExtension, 127 InitData); 128 if (!NT_SUCCESS(Status)) 129 { 130 DPRINT1("MiniportInitialize() failed (Status 0x%08lx)\n", Status); 131 return Status; 132 } 133 134 /* Call the miniports FindAdapter function */ 135 Status = MiniportFindAdapter(&DeviceExtension->Miniport); 136 if (!NT_SUCCESS(Status)) 137 { 138 DPRINT1("MiniportFindAdapter() failed (Status 0x%08lx)\n", Status); 139 return Status; 140 } 141 142 /* Connect the configured interrupt */ 143 Status = PortFdoConnectInterrupt(DeviceExtension); 144 if (!NT_SUCCESS(Status)) 145 { 146 DPRINT1("PortFdoConnectInterrupt() failed (Status 0x%08lx)\n", Status); 147 return Status; 148 } 149 150 /* Call the miniports HwInitialize function */ 151 Status = MiniportHwInitialize(&DeviceExtension->Miniport); 152 if (!NT_SUCCESS(Status)) 153 { 154 DPRINT1("MiniportHwInitialize() failed (Status 0x%08lx)\n", Status); 155 return Status; 156 } 157 158 /* Call the HwPassiveInitRoutine function, if available */ 159 if (DeviceExtension->HwPassiveInitRoutine != NULL) 160 { 161 DPRINT1("Calling HwPassiveInitRoutine()\n"); 162 if (!DeviceExtension->HwPassiveInitRoutine(&DeviceExtension->Miniport.MiniportExtension->HwDeviceExtension)) 163 { 164 DPRINT1("HwPassiveInitRoutine() failed\n"); 165 return STATUS_UNSUCCESSFUL; 166 } 167 } 168 169 return STATUS_SUCCESS; 170 } 171 172 173 static 174 NTSTATUS 175 NTAPI 176 PortFdoStartDevice( 177 _In_ PFDO_DEVICE_EXTENSION DeviceExtension, 178 _In_ PIRP Irp) 179 { 180 PIO_STACK_LOCATION Stack; 181 NTSTATUS Status; 182 183 DPRINT1("PortFdoStartDevice(%p %p)\n", 184 DeviceExtension, Irp); 185 186 ASSERT(DeviceExtension->ExtensionType == FdoExtension); 187 188 /* Get the current stack location */ 189 Stack = IoGetCurrentIrpStackLocation(Irp); 190 191 /* Start the lower device if the FDO is in 'stopped' state */ 192 if (DeviceExtension->PnpState == dsStopped) 193 { 194 Status = ForwardIrpAndWait(DeviceExtension->LowerDevice, Irp); 195 if (!NT_SUCCESS(Status)) 196 { 197 DPRINT1("ForwardIrpAndWait() failed (Status 0x%08lx)\n", Status); 198 return Status; 199 } 200 } 201 202 /* Change to the 'started' state */ 203 DeviceExtension->PnpState = dsStarted; 204 205 /* Copy the raw and translated resource lists into the device extension */ 206 if (Stack->Parameters.StartDevice.AllocatedResources != NULL && 207 Stack->Parameters.StartDevice.AllocatedResourcesTranslated != NULL) 208 { 209 DeviceExtension->AllocatedResources = CopyResourceList(NonPagedPool, 210 Stack->Parameters.StartDevice.AllocatedResources); 211 if (DeviceExtension->AllocatedResources == NULL) 212 return STATUS_NO_MEMORY; 213 214 DeviceExtension->TranslatedResources = CopyResourceList(NonPagedPool, 215 Stack->Parameters.StartDevice.AllocatedResourcesTranslated); 216 if (DeviceExtension->TranslatedResources == NULL) 217 return STATUS_NO_MEMORY; 218 } 219 220 /* Get the bus interface of the lower (bus) device */ 221 Status = QueryBusInterface(DeviceExtension->LowerDevice, 222 (PGUID)&GUID_BUS_INTERFACE_STANDARD, 223 sizeof(BUS_INTERFACE_STANDARD), 224 1, 225 &DeviceExtension->BusInterface, 226 NULL); 227 DPRINT1("Status: 0x%08lx\n", Status); 228 if (NT_SUCCESS(Status)) 229 { 230 DPRINT1("Context: %p\n", DeviceExtension->BusInterface.Context); 231 DeviceExtension->BusInitialized = TRUE; 232 } 233 234 /* Start the miniport (FindAdapter & Initialize) */ 235 Status = PortFdoStartMiniport(DeviceExtension); 236 if (!NT_SUCCESS(Status)) 237 { 238 DPRINT1("FdoStartMiniport() failed (Status 0x%08lx)\n", Status); 239 DeviceExtension->PnpState = dsStopped; 240 } 241 242 return Status; 243 } 244 245 246 static 247 NTSTATUS 248 PortSendInquiry( 249 _In_ PPDO_DEVICE_EXTENSION PdoExtension) 250 { 251 IO_STATUS_BLOCK IoStatusBlock; 252 PIO_STACK_LOCATION IrpStack; 253 KEVENT Event; 254 // KIRQL Irql; 255 PIRP Irp; 256 NTSTATUS Status; 257 PSENSE_DATA SenseBuffer; 258 BOOLEAN KeepTrying = TRUE; 259 ULONG RetryCount = 0; 260 SCSI_REQUEST_BLOCK Srb; 261 PCDB Cdb; 262 // PSCSI_PORT_LUN_EXTENSION LunExtension; 263 // PFDO_DEVICE_EXTENSION DeviceExtension; 264 265 DPRINT("PortSendInquiry(%p)\n", PdoExtension); 266 267 if (PdoExtension->InquiryBuffer == NULL) 268 { 269 PdoExtension->InquiryBuffer = ExAllocatePoolWithTag(NonPagedPool, INQUIRYDATABUFFERSIZE, TAG_INQUIRY_DATA); 270 if (PdoExtension->InquiryBuffer == NULL) 271 return STATUS_INSUFFICIENT_RESOURCES; 272 } 273 274 SenseBuffer = ExAllocatePoolWithTag(NonPagedPool, SENSE_BUFFER_SIZE, TAG_SENSE_DATA); 275 if (SenseBuffer == NULL) 276 { 277 return STATUS_INSUFFICIENT_RESOURCES; 278 } 279 280 while (KeepTrying) 281 { 282 /* Initialize event for waiting */ 283 KeInitializeEvent(&Event, 284 NotificationEvent, 285 FALSE); 286 287 /* Create an IRP */ 288 Irp = IoBuildDeviceIoControlRequest(IOCTL_SCSI_EXECUTE_IN, 289 PdoExtension->Device, 290 NULL, 291 0, 292 PdoExtension->InquiryBuffer, 293 INQUIRYDATABUFFERSIZE, 294 TRUE, 295 &Event, 296 &IoStatusBlock); 297 if (Irp == NULL) 298 { 299 DPRINT("IoBuildDeviceIoControlRequest() failed\n"); 300 301 /* Quit the loop */ 302 Status = STATUS_INSUFFICIENT_RESOURCES; 303 KeepTrying = FALSE; 304 continue; 305 } 306 307 /* Prepare SRB */ 308 RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK)); 309 310 Srb.Length = sizeof(SCSI_REQUEST_BLOCK); 311 Srb.OriginalRequest = Irp; 312 Srb.PathId = PdoExtension->Bus; 313 Srb.TargetId = PdoExtension->Target; 314 Srb.Lun = PdoExtension->Lun; 315 Srb.Function = SRB_FUNCTION_EXECUTE_SCSI; 316 Srb.SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_DISABLE_SYNCH_TRANSFER; 317 Srb.TimeOutValue = 4; 318 Srb.CdbLength = 6; 319 320 Srb.SenseInfoBuffer = SenseBuffer; 321 Srb.SenseInfoBufferLength = SENSE_BUFFER_SIZE; 322 323 Srb.DataBuffer = PdoExtension->InquiryBuffer; 324 Srb.DataTransferLength = INQUIRYDATABUFFERSIZE; 325 326 /* Attach Srb to the Irp */ 327 IrpStack = IoGetNextIrpStackLocation(Irp); 328 IrpStack->Parameters.Scsi.Srb = &Srb; 329 330 /* Fill in CDB */ 331 Cdb = (PCDB)Srb.Cdb; 332 Cdb->CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY; 333 Cdb->CDB6INQUIRY.LogicalUnitNumber = PdoExtension->Lun; 334 Cdb->CDB6INQUIRY.AllocationLength = INQUIRYDATABUFFERSIZE; 335 336 /* Call the driver */ 337 Status = IoCallDriver(PdoExtension->Device, Irp); 338 339 /* Wait for it to complete */ 340 if (Status == STATUS_PENDING) 341 { 342 DPRINT1("PortSendInquiry(): Waiting for the driver to process request...\n"); 343 KeWaitForSingleObject(&Event, 344 Executive, 345 KernelMode, 346 FALSE, 347 NULL); 348 Status = IoStatusBlock.Status; 349 } 350 351 DPRINT("PortSendInquiry(): Request processed by driver, status = 0x%08X\n", Status); 352 353 if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_SUCCESS) 354 { 355 DPRINT("Found a device!\n"); 356 357 /* Quit the loop */ 358 Status = STATUS_SUCCESS; 359 KeepTrying = FALSE; 360 continue; 361 } 362 363 DPRINT("Inquiry SRB failed with SrbStatus 0x%08X\n", Srb.SrbStatus); 364 365 /* Check if the queue is frozen */ 366 if (Srb.SrbStatus & SRB_STATUS_QUEUE_FROZEN) 367 { 368 /* Something weird happened, deal with it (unfreeze the queue) */ 369 KeepTrying = FALSE; 370 371 DPRINT("SpiSendInquiry(): the queue is frozen at TargetId %d\n", Srb.TargetId); 372 373 // LunExtension = SpiGetLunExtension(DeviceExtension, 374 // LunInfo->PathId, 375 // LunInfo->TargetId, 376 // LunInfo->Lun); 377 378 /* Clear frozen flag */ 379 // LunExtension->Flags &= ~LUNEX_FROZEN_QUEUE; 380 381 /* Acquire the spinlock */ 382 // KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql); 383 384 /* Process the request */ 385 // SpiGetNextRequestFromLun(DeviceObject->DeviceExtension, LunExtension); 386 387 /* SpiGetNextRequestFromLun() releases the spinlock, 388 so we just lower irql back to what it was before */ 389 // KeLowerIrql(Irql); 390 } 391 392 /* Check if data overrun happened */ 393 if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_DATA_OVERRUN) 394 { 395 DPRINT("Data overrun at TargetId %d\n", PdoExtension->Target); 396 397 /* Quit the loop */ 398 Status = STATUS_SUCCESS; 399 KeepTrying = FALSE; 400 } 401 else if ((Srb.SrbStatus & SRB_STATUS_AUTOSENSE_VALID) && 402 SenseBuffer->SenseKey == SCSI_SENSE_ILLEGAL_REQUEST) 403 { 404 /* LUN is not valid, but some device responds there. 405 Mark it as invalid anyway */ 406 407 /* Quit the loop */ 408 Status = STATUS_INVALID_DEVICE_REQUEST; 409 KeepTrying = FALSE; 410 } 411 else 412 { 413 /* Retry a couple of times if no timeout happened */ 414 if ((RetryCount < 2) && 415 (SRB_STATUS(Srb.SrbStatus) != SRB_STATUS_NO_DEVICE) && 416 (SRB_STATUS(Srb.SrbStatus) != SRB_STATUS_SELECTION_TIMEOUT)) 417 { 418 RetryCount++; 419 KeepTrying = TRUE; 420 } 421 else 422 { 423 /* That's all, quit the loop */ 424 KeepTrying = FALSE; 425 426 /* Set status according to SRB status */ 427 if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_BAD_FUNCTION || 428 SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_BAD_SRB_BLOCK_LENGTH) 429 { 430 Status = STATUS_INVALID_DEVICE_REQUEST; 431 } 432 else 433 { 434 Status = STATUS_IO_DEVICE_ERROR; 435 } 436 } 437 } 438 } 439 440 /* Free the sense buffer */ 441 ExFreePoolWithTag(SenseBuffer, TAG_SENSE_DATA); 442 443 DPRINT("PortSendInquiry() done with Status 0x%08X\n", Status); 444 445 return Status; 446 } 447 448 449 450 static 451 NTSTATUS 452 PortFdoScanBus( 453 _In_ PFDO_DEVICE_EXTENSION DeviceExtension) 454 { 455 PPDO_DEVICE_EXTENSION PdoExtension; 456 ULONG Bus, Target; //, Lun; 457 NTSTATUS Status; 458 459 DPRINT("PortFdoScanBus(%p)\n", DeviceExtension); 460 461 DPRINT("NumberOfBuses: %lu\n", DeviceExtension->Miniport.PortConfig.NumberOfBuses); 462 DPRINT("MaximumNumberOfTargets: %lu\n", DeviceExtension->Miniport.PortConfig.MaximumNumberOfTargets); 463 DPRINT("MaximumNumberOfLogicalUnits: %lu\n", DeviceExtension->Miniport.PortConfig.MaximumNumberOfLogicalUnits); 464 465 /* Scan all buses */ 466 for (Bus = 0; Bus < DeviceExtension->Miniport.PortConfig.NumberOfBuses; Bus++) 467 { 468 DPRINT("Scanning bus %ld\n", Bus); 469 470 /* Scan all targets */ 471 for (Target = 0; Target < DeviceExtension->Miniport.PortConfig.MaximumNumberOfTargets; Target++) 472 { 473 DPRINT(" Scanning target %ld:%ld\n", Bus, Target); 474 475 DPRINT(" Scanning logical unit %ld:%ld:%ld\n", Bus, Target, 0); 476 Status = PortCreatePdo(DeviceExtension, Bus, Target, 0, &PdoExtension); 477 if (NT_SUCCESS(Status)) 478 { 479 /* Scan LUN 0 */ 480 Status = PortSendInquiry(PdoExtension); 481 DPRINT("PortSendInquiry returned 0x%08lx\n", Status); 482 if (!NT_SUCCESS(Status)) 483 { 484 PortDeletePdo(PdoExtension); 485 } 486 else 487 { 488 DPRINT("VendorId: %.8s\n", PdoExtension->InquiryBuffer->VendorId); 489 DPRINT("ProductId: %.16s\n", PdoExtension->InquiryBuffer->ProductId); 490 DPRINT("ProductRevisionLevel: %.4s\n", PdoExtension->InquiryBuffer->ProductRevisionLevel); 491 DPRINT("VendorSpecific: %.20s\n", PdoExtension->InquiryBuffer->VendorSpecific); 492 } 493 } 494 495 #if 0 496 /* Scan all logical units */ 497 for (Lun = 1; Lun < DeviceExtension->Miniport.PortConfig.MaximumNumberOfLogicalUnits; Lun++) 498 { 499 DPRINT(" Scanning logical unit %ld:%ld:%ld\n", Bus, Target, Lun); 500 Status = PortSendInquiry(DeviceExtension->Device, Bus, Target, Lun); 501 DPRINT("PortSendInquiry returned 0x%08lx\n", Status); 502 if (!NT_SUCCESS(Status)) 503 break; 504 } 505 #endif 506 } 507 } 508 509 DPRINT("PortFdoScanBus() done!\n"); 510 511 return STATUS_SUCCESS; 512 } 513 514 515 static 516 NTSTATUS 517 PortFdoQueryBusRelations( 518 _In_ PFDO_DEVICE_EXTENSION DeviceExtension, 519 _Out_ PULONG_PTR Information) 520 { 521 NTSTATUS Status = STATUS_SUCCESS;; 522 523 DPRINT1("PortFdoQueryBusRelations(%p %p)\n", 524 DeviceExtension, Information); 525 526 Status = PortFdoScanBus(DeviceExtension); 527 528 DPRINT1("Units found: %lu\n", DeviceExtension->PdoCount); 529 530 *Information = 0; 531 532 return Status; 533 } 534 535 536 static 537 NTSTATUS 538 PortFdoFilterRequirements( 539 PFDO_DEVICE_EXTENSION DeviceExtension, 540 PIRP Irp) 541 { 542 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList; 543 544 DPRINT1("PortFdoFilterRequirements(%p %p)\n", DeviceExtension, Irp); 545 546 /* Get the bus number and the slot number */ 547 RequirementsList =(PIO_RESOURCE_REQUIREMENTS_LIST)Irp->IoStatus.Information; 548 if (RequirementsList != NULL) 549 { 550 DeviceExtension->BusNumber = RequirementsList->BusNumber; 551 DeviceExtension->SlotNumber = RequirementsList->SlotNumber; 552 } 553 554 return STATUS_SUCCESS; 555 } 556 557 558 NTSTATUS 559 NTAPI 560 PortFdoScsi( 561 _In_ PDEVICE_OBJECT DeviceObject, 562 _In_ PIRP Irp) 563 { 564 PFDO_DEVICE_EXTENSION DeviceExtension; 565 // PIO_STACK_LOCATION Stack; 566 ULONG_PTR Information = 0; 567 NTSTATUS Status = STATUS_NOT_SUPPORTED; 568 569 DPRINT("PortFdoScsi(%p %p)\n", DeviceObject, Irp); 570 571 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 572 ASSERT(DeviceExtension); 573 ASSERT(DeviceExtension->ExtensionType == FdoExtension); 574 575 // Stack = IoGetCurrentIrpStackLocation(Irp); 576 577 578 Irp->IoStatus.Information = Information; 579 Irp->IoStatus.Status = Status; 580 IoCompleteRequest(Irp, IO_NO_INCREMENT); 581 582 return Status; 583 } 584 585 586 NTSTATUS 587 NTAPI 588 PortFdoPnp( 589 _In_ PDEVICE_OBJECT DeviceObject, 590 _In_ PIRP Irp) 591 { 592 PFDO_DEVICE_EXTENSION DeviceExtension; 593 PIO_STACK_LOCATION Stack; 594 ULONG_PTR Information = 0; 595 NTSTATUS Status = STATUS_NOT_SUPPORTED; 596 597 DPRINT1("PortFdoPnp(%p %p)\n", 598 DeviceObject, Irp); 599 600 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 601 ASSERT(DeviceExtension); 602 ASSERT(DeviceExtension->ExtensionType == FdoExtension); 603 604 Stack = IoGetCurrentIrpStackLocation(Irp); 605 606 switch (Stack->MinorFunction) 607 { 608 case IRP_MN_START_DEVICE: /* 0x00 */ 609 DPRINT1("IRP_MJ_PNP / IRP_MN_START_DEVICE\n"); 610 Status = PortFdoStartDevice(DeviceExtension, Irp); 611 break; 612 613 case IRP_MN_QUERY_REMOVE_DEVICE: /* 0x01 */ 614 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_REMOVE_DEVICE\n"); 615 break; 616 617 case IRP_MN_REMOVE_DEVICE: /* 0x02 */ 618 DPRINT1("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n"); 619 break; 620 621 case IRP_MN_CANCEL_REMOVE_DEVICE: /* 0x03 */ 622 DPRINT1("IRP_MJ_PNP / IRP_MN_CANCEL_REMOVE_DEVICE\n"); 623 break; 624 625 case IRP_MN_STOP_DEVICE: /* 0x04 */ 626 DPRINT1("IRP_MJ_PNP / IRP_MN_STOP_DEVICE\n"); 627 break; 628 629 case IRP_MN_QUERY_STOP_DEVICE: /* 0x05 */ 630 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_STOP_DEVICE\n"); 631 break; 632 633 case IRP_MN_CANCEL_STOP_DEVICE: /* 0x06 */ 634 DPRINT1("IRP_MJ_PNP / IRP_MN_CANCEL_STOP_DEVICE\n"); 635 break; 636 637 case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x07 */ 638 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS\n"); 639 switch (Stack->Parameters.QueryDeviceRelations.Type) 640 { 641 case BusRelations: 642 DPRINT1(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); 643 Status = PortFdoQueryBusRelations(DeviceExtension, &Information); 644 break; 645 646 case RemovalRelations: 647 DPRINT1(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n"); 648 return ForwardIrpAndForget(DeviceExtension->LowerDevice, Irp); 649 650 default: 651 DPRINT1(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", 652 Stack->Parameters.QueryDeviceRelations.Type); 653 return ForwardIrpAndForget(DeviceExtension->LowerDevice, Irp); 654 } 655 break; 656 657 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* 0x0d */ 658 DPRINT1("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"); 659 PortFdoFilterRequirements(DeviceExtension, Irp); 660 return ForwardIrpAndForget(DeviceExtension->LowerDevice, Irp); 661 662 case IRP_MN_QUERY_PNP_DEVICE_STATE: /* 0x14 */ 663 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n"); 664 break; 665 666 case IRP_MN_DEVICE_USAGE_NOTIFICATION: /* 0x16 */ 667 DPRINT1("IRP_MJ_PNP / IRP_MN_DEVICE_USAGE_NOTIFICATION\n"); 668 break; 669 670 case IRP_MN_SURPRISE_REMOVAL: /* 0x17 */ 671 DPRINT1("IRP_MJ_PNP / IRP_MN_SURPRISE_REMOVAL\n"); 672 break; 673 674 default: 675 DPRINT1("IRP_MJ_PNP / Unknown IOCTL 0x%lx\n", Stack->MinorFunction); 676 return ForwardIrpAndForget(DeviceExtension->LowerDevice, Irp); 677 } 678 679 Irp->IoStatus.Information = Information; 680 Irp->IoStatus.Status = Status; 681 IoCompleteRequest(Irp, IO_NO_INCREMENT); 682 683 return Status; 684 } 685 686 /* EOF */ 687