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 if (IoForwardIrpSynchronously(DeviceExtension->LowerDevice, Irp)) 195 { 196 Status = Irp->IoStatus.Status; 197 } 198 else 199 { 200 Status = STATUS_UNSUCCESSFUL; 201 } 202 203 if (!NT_SUCCESS(Status)) 204 { 205 DPRINT1("Lower device failed the IRP (Status 0x%08lx)\n", Status); 206 return Status; 207 } 208 } 209 210 /* Change to the 'started' state */ 211 DeviceExtension->PnpState = dsStarted; 212 213 /* Copy the raw and translated resource lists into the device extension */ 214 if (Stack->Parameters.StartDevice.AllocatedResources != NULL && 215 Stack->Parameters.StartDevice.AllocatedResourcesTranslated != NULL) 216 { 217 DeviceExtension->AllocatedResources = CopyResourceList(NonPagedPool, 218 Stack->Parameters.StartDevice.AllocatedResources); 219 if (DeviceExtension->AllocatedResources == NULL) 220 return STATUS_NO_MEMORY; 221 222 DeviceExtension->TranslatedResources = CopyResourceList(NonPagedPool, 223 Stack->Parameters.StartDevice.AllocatedResourcesTranslated); 224 if (DeviceExtension->TranslatedResources == NULL) 225 return STATUS_NO_MEMORY; 226 } 227 228 /* Get the bus interface of the lower (bus) device */ 229 Status = QueryBusInterface(DeviceExtension->LowerDevice, 230 (PGUID)&GUID_BUS_INTERFACE_STANDARD, 231 sizeof(BUS_INTERFACE_STANDARD), 232 1, 233 &DeviceExtension->BusInterface, 234 NULL); 235 DPRINT1("Status: 0x%08lx\n", Status); 236 if (NT_SUCCESS(Status)) 237 { 238 DPRINT1("Context: %p\n", DeviceExtension->BusInterface.Context); 239 DeviceExtension->BusInitialized = TRUE; 240 } 241 242 /* Start the miniport (FindAdapter & Initialize) */ 243 Status = PortFdoStartMiniport(DeviceExtension); 244 if (!NT_SUCCESS(Status)) 245 { 246 DPRINT1("FdoStartMiniport() failed (Status 0x%08lx)\n", Status); 247 DeviceExtension->PnpState = dsStopped; 248 } 249 250 return Status; 251 } 252 253 254 static 255 NTSTATUS 256 PortSendInquiry( 257 _In_ PPDO_DEVICE_EXTENSION PdoExtension) 258 { 259 IO_STATUS_BLOCK IoStatusBlock; 260 PIO_STACK_LOCATION IrpStack; 261 KEVENT Event; 262 // KIRQL Irql; 263 PIRP Irp; 264 NTSTATUS Status; 265 PSENSE_DATA SenseBuffer; 266 BOOLEAN KeepTrying = TRUE; 267 ULONG RetryCount = 0; 268 SCSI_REQUEST_BLOCK Srb; 269 PCDB Cdb; 270 // PSCSI_PORT_LUN_EXTENSION LunExtension; 271 // PFDO_DEVICE_EXTENSION DeviceExtension; 272 273 DPRINT("PortSendInquiry(%p)\n", PdoExtension); 274 275 if (PdoExtension->InquiryBuffer == NULL) 276 { 277 PdoExtension->InquiryBuffer = ExAllocatePoolWithTag(NonPagedPool, INQUIRYDATABUFFERSIZE, TAG_INQUIRY_DATA); 278 if (PdoExtension->InquiryBuffer == NULL) 279 return STATUS_INSUFFICIENT_RESOURCES; 280 } 281 282 SenseBuffer = ExAllocatePoolWithTag(NonPagedPool, SENSE_BUFFER_SIZE, TAG_SENSE_DATA); 283 if (SenseBuffer == NULL) 284 { 285 return STATUS_INSUFFICIENT_RESOURCES; 286 } 287 288 while (KeepTrying) 289 { 290 /* Initialize event for waiting */ 291 KeInitializeEvent(&Event, 292 NotificationEvent, 293 FALSE); 294 295 /* Create an IRP */ 296 Irp = IoBuildDeviceIoControlRequest(IOCTL_SCSI_EXECUTE_IN, 297 PdoExtension->Device, 298 NULL, 299 0, 300 PdoExtension->InquiryBuffer, 301 INQUIRYDATABUFFERSIZE, 302 TRUE, 303 &Event, 304 &IoStatusBlock); 305 if (Irp == NULL) 306 { 307 DPRINT("IoBuildDeviceIoControlRequest() failed\n"); 308 309 /* Quit the loop */ 310 Status = STATUS_INSUFFICIENT_RESOURCES; 311 KeepTrying = FALSE; 312 continue; 313 } 314 315 /* Prepare SRB */ 316 RtlZeroMemory(&Srb, sizeof(SCSI_REQUEST_BLOCK)); 317 318 Srb.Length = sizeof(SCSI_REQUEST_BLOCK); 319 Srb.OriginalRequest = Irp; 320 Srb.PathId = PdoExtension->Bus; 321 Srb.TargetId = PdoExtension->Target; 322 Srb.Lun = PdoExtension->Lun; 323 Srb.Function = SRB_FUNCTION_EXECUTE_SCSI; 324 Srb.SrbFlags = SRB_FLAGS_DATA_IN | SRB_FLAGS_DISABLE_SYNCH_TRANSFER; 325 Srb.TimeOutValue = 4; 326 Srb.CdbLength = 6; 327 328 Srb.SenseInfoBuffer = SenseBuffer; 329 Srb.SenseInfoBufferLength = SENSE_BUFFER_SIZE; 330 331 Srb.DataBuffer = PdoExtension->InquiryBuffer; 332 Srb.DataTransferLength = INQUIRYDATABUFFERSIZE; 333 334 /* Attach Srb to the Irp */ 335 IrpStack = IoGetNextIrpStackLocation(Irp); 336 IrpStack->Parameters.Scsi.Srb = &Srb; 337 338 /* Fill in CDB */ 339 Cdb = (PCDB)Srb.Cdb; 340 Cdb->CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY; 341 Cdb->CDB6INQUIRY.LogicalUnitNumber = PdoExtension->Lun; 342 Cdb->CDB6INQUIRY.AllocationLength = INQUIRYDATABUFFERSIZE; 343 344 /* Call the driver */ 345 Status = IoCallDriver(PdoExtension->Device, Irp); 346 347 /* Wait for it to complete */ 348 if (Status == STATUS_PENDING) 349 { 350 DPRINT1("PortSendInquiry(): Waiting for the driver to process request...\n"); 351 KeWaitForSingleObject(&Event, 352 Executive, 353 KernelMode, 354 FALSE, 355 NULL); 356 Status = IoStatusBlock.Status; 357 } 358 359 DPRINT("PortSendInquiry(): Request processed by driver, status = 0x%08X\n", Status); 360 361 if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_SUCCESS) 362 { 363 DPRINT("Found a device!\n"); 364 365 /* Quit the loop */ 366 Status = STATUS_SUCCESS; 367 KeepTrying = FALSE; 368 continue; 369 } 370 371 DPRINT("Inquiry SRB failed with SrbStatus 0x%08X\n", Srb.SrbStatus); 372 373 /* Check if the queue is frozen */ 374 if (Srb.SrbStatus & SRB_STATUS_QUEUE_FROZEN) 375 { 376 /* Something weird happened, deal with it (unfreeze the queue) */ 377 KeepTrying = FALSE; 378 379 DPRINT("SpiSendInquiry(): the queue is frozen at TargetId %d\n", Srb.TargetId); 380 381 // LunExtension = SpiGetLunExtension(DeviceExtension, 382 // LunInfo->PathId, 383 // LunInfo->TargetId, 384 // LunInfo->Lun); 385 386 /* Clear frozen flag */ 387 // LunExtension->Flags &= ~LUNEX_FROZEN_QUEUE; 388 389 /* Acquire the spinlock */ 390 // KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql); 391 392 /* Process the request */ 393 // SpiGetNextRequestFromLun(DeviceObject->DeviceExtension, LunExtension); 394 395 /* SpiGetNextRequestFromLun() releases the spinlock, 396 so we just lower irql back to what it was before */ 397 // KeLowerIrql(Irql); 398 } 399 400 /* Check if data overrun happened */ 401 if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_DATA_OVERRUN) 402 { 403 DPRINT("Data overrun at TargetId %d\n", PdoExtension->Target); 404 405 /* Quit the loop */ 406 Status = STATUS_SUCCESS; 407 KeepTrying = FALSE; 408 } 409 else if ((Srb.SrbStatus & SRB_STATUS_AUTOSENSE_VALID) && 410 SenseBuffer->SenseKey == SCSI_SENSE_ILLEGAL_REQUEST) 411 { 412 /* LUN is not valid, but some device responds there. 413 Mark it as invalid anyway */ 414 415 /* Quit the loop */ 416 Status = STATUS_INVALID_DEVICE_REQUEST; 417 KeepTrying = FALSE; 418 } 419 else 420 { 421 /* Retry a couple of times if no timeout happened */ 422 if ((RetryCount < 2) && 423 (SRB_STATUS(Srb.SrbStatus) != SRB_STATUS_NO_DEVICE) && 424 (SRB_STATUS(Srb.SrbStatus) != SRB_STATUS_SELECTION_TIMEOUT)) 425 { 426 RetryCount++; 427 KeepTrying = TRUE; 428 } 429 else 430 { 431 /* That's all, quit the loop */ 432 KeepTrying = FALSE; 433 434 /* Set status according to SRB status */ 435 if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_BAD_FUNCTION || 436 SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_BAD_SRB_BLOCK_LENGTH) 437 { 438 Status = STATUS_INVALID_DEVICE_REQUEST; 439 } 440 else 441 { 442 Status = STATUS_IO_DEVICE_ERROR; 443 } 444 } 445 } 446 } 447 448 /* Free the sense buffer */ 449 ExFreePoolWithTag(SenseBuffer, TAG_SENSE_DATA); 450 451 DPRINT("PortSendInquiry() done with Status 0x%08X\n", Status); 452 453 return Status; 454 } 455 456 457 458 static 459 NTSTATUS 460 PortFdoScanBus( 461 _In_ PFDO_DEVICE_EXTENSION DeviceExtension) 462 { 463 PPDO_DEVICE_EXTENSION PdoExtension; 464 ULONG Bus, Target; //, Lun; 465 NTSTATUS Status; 466 467 DPRINT("PortFdoScanBus(%p)\n", DeviceExtension); 468 469 DPRINT("NumberOfBuses: %lu\n", DeviceExtension->Miniport.PortConfig.NumberOfBuses); 470 DPRINT("MaximumNumberOfTargets: %lu\n", DeviceExtension->Miniport.PortConfig.MaximumNumberOfTargets); 471 DPRINT("MaximumNumberOfLogicalUnits: %lu\n", DeviceExtension->Miniport.PortConfig.MaximumNumberOfLogicalUnits); 472 473 /* Scan all buses */ 474 for (Bus = 0; Bus < DeviceExtension->Miniport.PortConfig.NumberOfBuses; Bus++) 475 { 476 DPRINT("Scanning bus %ld\n", Bus); 477 478 /* Scan all targets */ 479 for (Target = 0; Target < DeviceExtension->Miniport.PortConfig.MaximumNumberOfTargets; Target++) 480 { 481 DPRINT(" Scanning target %ld:%ld\n", Bus, Target); 482 483 DPRINT(" Scanning logical unit %ld:%ld:%ld\n", Bus, Target, 0); 484 Status = PortCreatePdo(DeviceExtension, Bus, Target, 0, &PdoExtension); 485 if (NT_SUCCESS(Status)) 486 { 487 /* Scan LUN 0 */ 488 Status = PortSendInquiry(PdoExtension); 489 DPRINT("PortSendInquiry returned 0x%08lx\n", Status); 490 if (!NT_SUCCESS(Status)) 491 { 492 PortDeletePdo(PdoExtension); 493 } 494 else 495 { 496 DPRINT("VendorId: %.8s\n", PdoExtension->InquiryBuffer->VendorId); 497 DPRINT("ProductId: %.16s\n", PdoExtension->InquiryBuffer->ProductId); 498 DPRINT("ProductRevisionLevel: %.4s\n", PdoExtension->InquiryBuffer->ProductRevisionLevel); 499 DPRINT("VendorSpecific: %.20s\n", PdoExtension->InquiryBuffer->VendorSpecific); 500 } 501 } 502 503 #if 0 504 /* Scan all logical units */ 505 for (Lun = 1; Lun < DeviceExtension->Miniport.PortConfig.MaximumNumberOfLogicalUnits; Lun++) 506 { 507 DPRINT(" Scanning logical unit %ld:%ld:%ld\n", Bus, Target, Lun); 508 Status = PortSendInquiry(DeviceExtension->Device, Bus, Target, Lun); 509 DPRINT("PortSendInquiry returned 0x%08lx\n", Status); 510 if (!NT_SUCCESS(Status)) 511 break; 512 } 513 #endif 514 } 515 } 516 517 DPRINT("PortFdoScanBus() done!\n"); 518 519 return STATUS_SUCCESS; 520 } 521 522 523 static 524 NTSTATUS 525 PortFdoQueryBusRelations( 526 _In_ PFDO_DEVICE_EXTENSION DeviceExtension, 527 _Out_ PULONG_PTR Information) 528 { 529 NTSTATUS Status = STATUS_SUCCESS;; 530 531 DPRINT1("PortFdoQueryBusRelations(%p %p)\n", 532 DeviceExtension, Information); 533 534 Status = PortFdoScanBus(DeviceExtension); 535 536 DPRINT1("Units found: %lu\n", DeviceExtension->PdoCount); 537 538 *Information = 0; 539 540 return Status; 541 } 542 543 544 static 545 NTSTATUS 546 PortFdoFilterRequirements( 547 PFDO_DEVICE_EXTENSION DeviceExtension, 548 PIRP Irp) 549 { 550 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList; 551 552 DPRINT1("PortFdoFilterRequirements(%p %p)\n", DeviceExtension, Irp); 553 554 /* Get the bus number and the slot number */ 555 RequirementsList =(PIO_RESOURCE_REQUIREMENTS_LIST)Irp->IoStatus.Information; 556 if (RequirementsList != NULL) 557 { 558 DeviceExtension->BusNumber = RequirementsList->BusNumber; 559 DeviceExtension->SlotNumber = RequirementsList->SlotNumber; 560 } 561 562 return STATUS_SUCCESS; 563 } 564 565 566 NTSTATUS 567 NTAPI 568 PortFdoScsi( 569 _In_ PDEVICE_OBJECT DeviceObject, 570 _In_ PIRP Irp) 571 { 572 PFDO_DEVICE_EXTENSION DeviceExtension; 573 // PIO_STACK_LOCATION Stack; 574 ULONG_PTR Information = 0; 575 NTSTATUS Status = STATUS_NOT_SUPPORTED; 576 577 DPRINT("PortFdoScsi(%p %p)\n", DeviceObject, Irp); 578 579 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 580 ASSERT(DeviceExtension); 581 ASSERT(DeviceExtension->ExtensionType == FdoExtension); 582 583 // Stack = IoGetCurrentIrpStackLocation(Irp); 584 585 586 Irp->IoStatus.Information = Information; 587 Irp->IoStatus.Status = Status; 588 IoCompleteRequest(Irp, IO_NO_INCREMENT); 589 590 return Status; 591 } 592 593 594 NTSTATUS 595 NTAPI 596 PortFdoPnp( 597 _In_ PDEVICE_OBJECT DeviceObject, 598 _In_ PIRP Irp) 599 { 600 PFDO_DEVICE_EXTENSION DeviceExtension; 601 PIO_STACK_LOCATION Stack; 602 ULONG_PTR Information = 0; 603 NTSTATUS Status = STATUS_NOT_SUPPORTED; 604 605 DPRINT1("PortFdoPnp(%p %p)\n", 606 DeviceObject, Irp); 607 608 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 609 ASSERT(DeviceExtension); 610 ASSERT(DeviceExtension->ExtensionType == FdoExtension); 611 612 Stack = IoGetCurrentIrpStackLocation(Irp); 613 614 switch (Stack->MinorFunction) 615 { 616 case IRP_MN_START_DEVICE: /* 0x00 */ 617 DPRINT1("IRP_MJ_PNP / IRP_MN_START_DEVICE\n"); 618 Status = PortFdoStartDevice(DeviceExtension, Irp); 619 break; 620 621 case IRP_MN_QUERY_REMOVE_DEVICE: /* 0x01 */ 622 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_REMOVE_DEVICE\n"); 623 break; 624 625 case IRP_MN_REMOVE_DEVICE: /* 0x02 */ 626 DPRINT1("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n"); 627 break; 628 629 case IRP_MN_CANCEL_REMOVE_DEVICE: /* 0x03 */ 630 DPRINT1("IRP_MJ_PNP / IRP_MN_CANCEL_REMOVE_DEVICE\n"); 631 break; 632 633 case IRP_MN_STOP_DEVICE: /* 0x04 */ 634 DPRINT1("IRP_MJ_PNP / IRP_MN_STOP_DEVICE\n"); 635 break; 636 637 case IRP_MN_QUERY_STOP_DEVICE: /* 0x05 */ 638 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_STOP_DEVICE\n"); 639 break; 640 641 case IRP_MN_CANCEL_STOP_DEVICE: /* 0x06 */ 642 DPRINT1("IRP_MJ_PNP / IRP_MN_CANCEL_STOP_DEVICE\n"); 643 break; 644 645 case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x07 */ 646 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS\n"); 647 switch (Stack->Parameters.QueryDeviceRelations.Type) 648 { 649 case BusRelations: 650 DPRINT1(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); 651 Status = PortFdoQueryBusRelations(DeviceExtension, &Information); 652 break; 653 654 case RemovalRelations: 655 DPRINT1(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n"); 656 return ForwardIrpAndForget(DeviceExtension->LowerDevice, Irp); 657 658 default: 659 DPRINT1(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", 660 Stack->Parameters.QueryDeviceRelations.Type); 661 return ForwardIrpAndForget(DeviceExtension->LowerDevice, Irp); 662 } 663 break; 664 665 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* 0x0d */ 666 DPRINT1("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"); 667 PortFdoFilterRequirements(DeviceExtension, Irp); 668 return ForwardIrpAndForget(DeviceExtension->LowerDevice, Irp); 669 670 case IRP_MN_QUERY_PNP_DEVICE_STATE: /* 0x14 */ 671 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n"); 672 break; 673 674 case IRP_MN_DEVICE_USAGE_NOTIFICATION: /* 0x16 */ 675 DPRINT1("IRP_MJ_PNP / IRP_MN_DEVICE_USAGE_NOTIFICATION\n"); 676 break; 677 678 case IRP_MN_SURPRISE_REMOVAL: /* 0x17 */ 679 DPRINT1("IRP_MJ_PNP / IRP_MN_SURPRISE_REMOVAL\n"); 680 break; 681 682 default: 683 DPRINT1("IRP_MJ_PNP / Unknown IOCTL 0x%lx\n", Stack->MinorFunction); 684 return ForwardIrpAndForget(DeviceExtension->LowerDevice, Irp); 685 } 686 687 Irp->IoStatus.Information = Information; 688 Irp->IoStatus.Status = Status; 689 IoCompleteRequest(Irp, IO_NO_INCREMENT); 690 691 return Status; 692 } 693 694 /* EOF */ 695