[STORPORT] Enumerate attached devices
[reactos.git] / drivers / storage / port / storport / fdo.c
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 */