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