[CRT] Remove useless #undef abort from process.h
[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 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 */