ReactOS  0.4.15-dev-2095-g7caf9e9
fdo.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Storage Stack / SCSIPORT storage port library
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Adapter device object (FDO) support routines
5  * COPYRIGHT: Eric Kohl (eric.kohl@reactos.org)
6  * Aleksey Bragin (aleksey@reactos.org)
7  * 2020 Victor Perevertkin (victor.perevertkin@reactos.org)
8  */
9 
10 #include "scsiport.h"
11 
12 #define NDEBUG
13 #include <debug.h>
14 
15 
16 static
20 {
22  PIO_STACK_LOCATION IrpStack;
23  KEVENT Event;
24  KIRQL Irql;
25  PIRP Irp;
27  PINQUIRYDATA InquiryBuffer;
28  PSENSE_DATA SenseBuffer;
29  BOOLEAN KeepTrying = TRUE;
30  ULONG RetryCount = 0;
32  PCDB Cdb;
33 
34  DPRINT("FdoSendInquiry() called\n");
35 
36  PSCSI_PORT_LUN_EXTENSION LunExtension = DeviceObject->DeviceExtension;
37  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension =
38  LunExtension->Common.LowerDevice->DeviceExtension;
39 
41  if (InquiryBuffer == NULL)
43 
45  if (SenseBuffer == NULL)
46  {
47  ExFreePoolWithTag(InquiryBuffer, TAG_SCSIPORT);
49  }
50 
51  while (KeepTrying)
52  {
53  /* Initialize event for waiting */
56  FALSE);
57 
58  /* Create an IRP */
61  NULL,
62  0,
63  InquiryBuffer,
65  TRUE,
66  &Event,
67  &IoStatusBlock);
68  if (Irp == NULL)
69  {
70  DPRINT("IoBuildDeviceIoControlRequest() failed\n");
71 
72  /* Quit the loop */
74  KeepTrying = FALSE;
75  continue;
76  }
77 
78  /* Prepare SRB */
80 
81  Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
82  Srb.OriginalRequest = Irp;
83  Srb.PathId = LunExtension->PathId;
84  Srb.TargetId = LunExtension->TargetId;
85  Srb.Lun = LunExtension->Lun;
86  Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
88  Srb.TimeOutValue = 4;
89  Srb.CdbLength = 6;
90 
91  Srb.SenseInfoBuffer = SenseBuffer;
92  Srb.SenseInfoBufferLength = SENSE_BUFFER_SIZE;
93 
94  Srb.DataBuffer = InquiryBuffer;
95  Srb.DataTransferLength = INQUIRYDATABUFFERSIZE;
96 
97  /* Attach Srb to the Irp */
98  IrpStack = IoGetNextIrpStackLocation (Irp);
99  IrpStack->Parameters.Scsi.Srb = &Srb;
100 
101  /* Fill in CDB */
102  Cdb = (PCDB)Srb.Cdb;
103  Cdb->CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY;
104  Cdb->CDB6INQUIRY.LogicalUnitNumber = LunExtension->Lun;
105  Cdb->CDB6INQUIRY.AllocationLength = INQUIRYDATABUFFERSIZE;
106 
107  /* Call the driver */
109 
110  /* Wait for it to complete */
111  if (Status == STATUS_PENDING)
112  {
113  DPRINT("FdoSendInquiry(): Waiting for the driver to process request...\n");
115  Executive,
116  KernelMode,
117  FALSE,
118  NULL);
120  }
121 
122  DPRINT("FdoSendInquiry(): Request processed by driver, status = 0x%08X\n", Status);
123 
124  if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_SUCCESS)
125  {
126  /* All fine, copy data over */
127  RtlCopyMemory(&LunExtension->InquiryData,
128  InquiryBuffer,
130 
131  /* Quit the loop */
133  KeepTrying = FALSE;
134  continue;
135  }
136 
137  DPRINT("Inquiry SRB failed with SrbStatus 0x%08X\n", Srb.SrbStatus);
138 
139  /* Check if the queue is frozen */
140  if (Srb.SrbStatus & SRB_STATUS_QUEUE_FROZEN)
141  {
142  /* Something weird happened, deal with it (unfreeze the queue) */
143  KeepTrying = FALSE;
144 
145  DPRINT("FdoSendInquiry(): the queue is frozen at TargetId %d\n", Srb.TargetId);
146 
147  /* Clear frozen flag */
148  LunExtension->Flags &= ~LUNEX_FROZEN_QUEUE;
149 
150  /* Acquire the spinlock */
151  KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql);
152 
153  /* Process the request. SpiGetNextRequestFromLun will unlock for us */
154  SpiGetNextRequestFromLun(DeviceExtension, LunExtension, &Irql);
155  }
156 
157  /* Check if data overrun happened */
158  if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_DATA_OVERRUN)
159  {
160  DPRINT("Data overrun at TargetId %d\n", LunExtension->TargetId);
161 
162  /* Nothing dramatic, just copy data, but limiting the size */
163  RtlCopyMemory(&LunExtension->InquiryData,
164  InquiryBuffer,
165  (Srb.DataTransferLength > INQUIRYDATABUFFERSIZE) ?
166  INQUIRYDATABUFFERSIZE : Srb.DataTransferLength);
167 
168  /* Quit the loop */
170  KeepTrying = FALSE;
171  }
172  else if ((Srb.SrbStatus & SRB_STATUS_AUTOSENSE_VALID) &&
173  SenseBuffer->SenseKey == SCSI_SENSE_ILLEGAL_REQUEST)
174  {
175  /* LUN is not valid, but some device responds there.
176  Mark it as invalid anyway */
177 
178  /* Quit the loop */
180  KeepTrying = FALSE;
181  }
182  else
183  {
184  /* Retry a couple of times if no timeout happened */
185  if ((RetryCount < 2) &&
186  (SRB_STATUS(Srb.SrbStatus) != SRB_STATUS_NO_DEVICE) &&
188  {
189  RetryCount++;
190  KeepTrying = TRUE;
191  }
192  else
193  {
194  /* That's all, quit the loop */
195  KeepTrying = FALSE;
196 
197  /* Set status according to SRB status */
198  if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_BAD_FUNCTION ||
200  {
202  }
203  else
204  {
206  }
207  }
208  }
209  }
210 
211  /* Free buffers */
212  ExFreePoolWithTag(InquiryBuffer, TAG_SCSIPORT);
213  ExFreePoolWithTag(SenseBuffer, TAG_SCSIPORT);
214 
215  DPRINT("FdoSendInquiry() done with Status 0x%08X\n", Status);
216 
217  return Status;
218 }
219 
220 /* Scans all SCSI buses */
221 VOID
223  _In_ PSCSI_PORT_DEVICE_EXTENSION PortExtension)
224 {
226  UINT32 totalLUNs = PortExtension->TotalLUCount;
227 
228  DPRINT("FdoScanAdapter() called\n");
229 
230  /* Scan all buses */
231  for (UINT8 pathId = 0; pathId < PortExtension->NumberOfBuses; pathId++)
232  {
233  DPRINT(" Scanning bus/pathID %u\n", pathId);
234 
235  /* Get pointer to the scan information */
236  PSCSI_BUS_INFO currentBus = &PortExtension->Buses[pathId];
237 
238  /* And send INQUIRY to every target */
239  for (UINT8 targetId = 0;
240  targetId < PortExtension->PortConfig->MaximumNumberOfTargets;
241  targetId++)
242  {
243  BOOLEAN targetFound = FALSE;
244 
245  /* TODO: Support scan bottom-up */
246 
247  /* Skip if it's the same address */
248  if (targetId == currentBus->BusIdentifier)
249  continue;
250 
251  /* Scan all logical units */
252  for (UINT8 lun = 0; lun < PortExtension->MaxLunCount; lun++)
253  {
254  // try to find an existing device
255  PSCSI_PORT_LUN_EXTENSION lunExt = GetLunByPath(PortExtension,
256  pathId,
257  targetId,
258  lun);
259 
260  if (lunExt)
261  {
262  // check if the device still exists
264  if (!NT_SUCCESS(status))
265  {
266  // remove the device
268  __debugbreak();
269  }
270 
272  {
273  // remove the device
275  __debugbreak();
276  }
277 
278  /* Decide whether we are continuing or not */
280  continue;
281  else
282  break;
283  }
284 
285  // create a new LUN device
286  PDEVICE_OBJECT lunPDO = PdoCreateLunDevice(PortExtension);
287  if (!lunPDO)
288  {
289  continue;
290  }
291 
292  lunExt = lunPDO->DeviceExtension;
293 
294  lunExt->PathId = pathId;
295  lunExt->TargetId = targetId;
296  lunExt->Lun = lun;
297 
298  DPRINT("Add PDO to list: PDO: %p, FDOExt: %p, PDOExt: %p\n", lunPDO, PortExtension, lunExt);
299 
300  /* Set flag to prevent race conditions */
302 
303  /* Finally send the inquiry command */
304  status = FdoSendInquiry(lunPDO);
305 
306  if (NT_SUCCESS(status))
307  {
308  /* Let's see if we really found a device */
309  PINQUIRYDATA InquiryData = &lunExt->InquiryData;
310 
311  /* Check if this device is unsupported */
313  {
314  IoDeleteDevice(lunPDO);
315  continue;
316  }
317 
318  /* Clear the "in scan" flag */
319  lunExt->Flags &= ~SCSI_PORT_SCAN_IN_PROGRESS;
320 
321  DPRINT("FdoScanAdapter(): Found device of type %d at bus %d tid %d lun %d\n",
322  InquiryData->DeviceType, pathId, targetId, lun);
323 
324  InsertTailList(&currentBus->LunsListHead, &lunExt->LunEntry);
325 
326  DPRINT1("SCSIPORT: created lun device: %p Status: %x\n", lunPDO, status);
327 
328  totalLUNs++;
329  currentBus->LogicalUnitsCount++;
330  targetFound = TRUE;
331  }
332  else
333  {
334  /* Decide whether we are continuing or not */
336  continue;
337  else
338  break;
339  }
340  }
341 
342  if (targetFound)
343  {
344  currentBus->TargetsCount++;
345  }
346  }
347  }
348 
349  PortExtension->TotalLUCount = totalLUNs;
350 }
351 
361 NTSTATUS
363  _In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
364 {
365  PPORT_CONFIGURATION_INFORMATION PortConfig = DeviceExtension->PortConfig;
367  KIRQL OldIrql;
368 
369  /* Deal with interrupts */
370  if (DeviceExtension->HwInterrupt == NULL ||
371  (PortConfig->BusInterruptLevel == 0 && PortConfig->BusInterruptVector == 0))
372  {
373  /* No interrupts */
374  DeviceExtension->InterruptCount = 0;
375 
376  DPRINT1("Interrupt Count: 0\n");
377 
379 
380  /* This code path will ALWAYS crash so stop it now */
381  __debugbreak();
382  }
383  else
384  {
385  BOOLEAN InterruptShareable;
387  ULONG InterruptVector[2], i, MappedIrq[2];
388  KIRQL Dirql[2], MaxDirql;
389  KAFFINITY Affinity[2];
390 
391  DeviceExtension->InterruptLevel[0] = PortConfig->BusInterruptLevel;
392  DeviceExtension->InterruptLevel[1] = PortConfig->BusInterruptLevel2;
393 
394  InterruptVector[0] = PortConfig->BusInterruptVector;
395  InterruptVector[1] = PortConfig->BusInterruptVector2;
396 
397  InterruptMode[0] = PortConfig->InterruptMode;
398  InterruptMode[1] = PortConfig->InterruptMode2;
399 
400  DeviceExtension->InterruptCount =
401  (PortConfig->BusInterruptLevel2 != 0 ||
402  PortConfig->BusInterruptVector2 != 0) ? 2 : 1;
403 
404  for (i = 0; i < DeviceExtension->InterruptCount; i++)
405  {
406  /* Register an interrupt handler for this device */
407  MappedIrq[i] = HalGetInterruptVector(
408  PortConfig->AdapterInterfaceType, PortConfig->SystemIoBusNumber,
409  DeviceExtension->InterruptLevel[i], InterruptVector[i], &Dirql[i],
410  &Affinity[i]);
411  }
412 
413  if (DeviceExtension->InterruptCount == 1 || Dirql[0] > Dirql[1])
414  {
415  MaxDirql = Dirql[0];
416  }
417  else
418  {
419  MaxDirql = Dirql[1];
420  }
421 
422  for (i = 0; i < DeviceExtension->InterruptCount; i++)
423  {
424  /* Determine IRQ sharability as usual */
425  if (PortConfig->AdapterInterfaceType == MicroChannel ||
427  {
428  InterruptShareable = TRUE;
429  }
430  else
431  {
432  InterruptShareable = FALSE;
433  }
434 
435  Status = IoConnectInterrupt(&DeviceExtension->Interrupt[i],
436  ScsiPortIsr,
437  DeviceExtension,
438  &DeviceExtension->IrqLock,
439  MappedIrq[i], Dirql[i],
440  MaxDirql,
441  InterruptMode[i],
442  InterruptShareable,
443  Affinity[i],
444  FALSE);
445 
446  if (!(NT_SUCCESS(Status)))
447  {
448  DPRINT1("Could not connect interrupt %d\n", InterruptVector[i]);
449  DeviceExtension->Interrupt[i] = NULL;
450  return Status;
451  }
452  }
453  }
454 
455  /* Save IoAddress (from access ranges) */
456  if (PortConfig->NumberOfAccessRanges != 0)
457  {
458  DeviceExtension->IoAddress = ((*(PortConfig->AccessRanges))[0]).RangeStart.LowPart;
459 
460  DPRINT("Io Address %x\n", DeviceExtension->IoAddress);
461  }
462 
463  /* Set flag that it's allowed to disconnect during this command */
464  DeviceExtension->Flags |= SCSI_PORT_DISCONNECT_ALLOWED;
465 
466  /* Initialize counter of active requests (-1 means there are none) */
467  DeviceExtension->ActiveRequestCounter = -1;
468 
469  /* Analyze what we have about DMA */
470  if (DeviceExtension->AdapterObject != NULL && PortConfig->Master &&
471  PortConfig->NeedPhysicalAddresses)
472  {
473  DeviceExtension->MapRegisters = TRUE;
474  }
475  else
476  {
477  DeviceExtension->MapRegisters = FALSE;
478  }
479 
480  /* Call HwInitialize at DISPATCH_LEVEL */
482 
484  DeviceExtension->Interrupt[0], DeviceExtension->HwInitialize,
485  DeviceExtension->MiniPortDeviceExtension))
486  {
487  DPRINT1("HwInitialize() failed!\n");
490  }
491 
492  /* Check if a notification is needed */
493  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
494  {
495  /* Call DPC right away, because we're already at DISPATCH_LEVEL */
496  ScsiPortDpcForIsr(NULL, DeviceExtension->Common.DeviceObject, NULL, NULL);
497  }
498 
499  /* Lower irql back to what it was */
501 
502  return STATUS_SUCCESS;
503 }
504 
505 NTSTATUS
507  _In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
508 {
509  IoStopTimer(DeviceExtension->Common.DeviceObject);
510 
511  // release device interface
512  if (DeviceExtension->InterfaceName.Buffer)
513  {
514  IoSetDeviceInterfaceState(&DeviceExtension->InterfaceName, FALSE);
515 
516  RtlFreeUnicodeString(&DeviceExtension->InterfaceName);
517  RtlInitUnicodeString(&DeviceExtension->InterfaceName, NULL);
518  }
519 
520  // remove the dos device link
521  WCHAR dosNameBuffer[12];
522  UNICODE_STRING dosDeviceName;
523 
524  swprintf(dosNameBuffer, L"\\??\\Scsi%lu:", DeviceExtension->PortNumber);
525  RtlInitUnicodeString(&dosDeviceName, dosNameBuffer);
526 
527  IoDeleteSymbolicLink(&dosDeviceName); // don't check the result
528 
529  // decrease the port count
530  if (DeviceExtension->DeviceStarted)
531  {
533  sysConfig->ScsiPortCount--;
534  }
535 
536  // disconnect the interrupts
537  while (DeviceExtension->InterruptCount)
538  {
539  if (DeviceExtension->Interrupt[--DeviceExtension->InterruptCount])
540  IoDisconnectInterrupt(DeviceExtension->Interrupt[DeviceExtension->InterruptCount]);
541  }
542 
543  // FIXME: delete LUNs
544  if (DeviceExtension->Buses)
545  {
546  for (UINT8 pathId = 0; pathId < DeviceExtension->NumberOfBuses; pathId++)
547  {
548  PSCSI_BUS_INFO bus = &DeviceExtension->Buses[pathId];
549  if (bus->RegistryMapKey)
550  {
551  ZwDeleteKey(bus->RegistryMapKey);
552  ZwClose(bus->RegistryMapKey);
553  bus->RegistryMapKey = NULL;
554  }
555  }
556 
557  ExFreePoolWithTag(DeviceExtension->Buses, TAG_SCSIPORT);
558  }
559 
560  /* Free PortConfig */
561  if (DeviceExtension->PortConfig)
562  {
563  ExFreePoolWithTag(DeviceExtension->PortConfig, TAG_SCSIPORT);
564  }
565 
566  /* Free common buffer (if it exists) */
567  if (DeviceExtension->SrbExtensionBuffer != NULL && DeviceExtension->CommonBufferLength != 0)
568  {
569  if (!DeviceExtension->AdapterObject)
570  {
571  ExFreePoolWithTag(DeviceExtension->SrbExtensionBuffer, TAG_SCSIPORT);
572  }
573  else
574  {
575  HalFreeCommonBuffer(DeviceExtension->AdapterObject,
576  DeviceExtension->CommonBufferLength,
577  DeviceExtension->PhysicalAddress,
578  DeviceExtension->SrbExtensionBuffer,
579  FALSE);
580  }
581  }
582 
583  /* Free SRB info */
584  if (DeviceExtension->SrbInfo != NULL)
585  ExFreePoolWithTag(DeviceExtension->SrbInfo, TAG_SCSIPORT);
586 
587  /* Unmap mapped addresses */
588  while (DeviceExtension->MappedAddressList != NULL)
589  {
590  MmUnmapIoSpace(DeviceExtension->MappedAddressList->MappedAddress,
591  DeviceExtension->MappedAddressList->NumberOfBytes);
592 
593  PVOID ptr = DeviceExtension->MappedAddressList;
594  DeviceExtension->MappedAddressList = DeviceExtension->MappedAddressList->NextMappedAddress;
595 
597  }
598 
599  IoDeleteDevice(DeviceExtension->Common.DeviceObject);
600 
601  return STATUS_SUCCESS;
602 }
603 
604 NTSTATUS
606  _In_ PSCSI_PORT_DEVICE_EXTENSION PortExtension)
607 {
608  WCHAR dosNameBuffer[12];
609  UNICODE_STRING dosDeviceName;
611 
612  // Start our timer
613  IoStartTimer(PortExtension->Common.DeviceObject);
614 
615  // Create the dos device link
616  swprintf(dosNameBuffer, L"\\??\\Scsi%u:", PortExtension->PortNumber);
617  RtlInitUnicodeString(&dosDeviceName, dosNameBuffer);
618  status = IoCreateSymbolicLink(&dosDeviceName, &PortExtension->DeviceName);
619  if (!NT_SUCCESS(status))
620  {
621  return status;
622  }
623 
624  // start building a device map
625  RegistryInitAdapterKey(PortExtension);
626 
627  // increase the port count
629  sysConfig->ScsiPortCount++;
630 
631  // Register and enable the device interface
632  status = IoRegisterDeviceInterface(PortExtension->Common.DeviceObject,
633  &StoragePortClassGuid,
634  NULL,
635  &PortExtension->InterfaceName);
636  DPRINT("IoRegisterDeviceInterface status: %x, InterfaceName: %wZ\n",
637  status, &PortExtension->InterfaceName);
638 
639  if (NT_SUCCESS(status))
640  {
641  IoSetDeviceInterfaceState(&PortExtension->InterfaceName, TRUE);
642  }
643 
644  PortExtension->DeviceStarted = TRUE;
645 
646  return STATUS_SUCCESS;
647 }
648 
649 static
650 NTSTATUS
652  _In_ PSCSI_PORT_DEVICE_EXTENSION PortExtension,
653  _Inout_ PIRP Irp)
654 {
656 
657  // FDO always only handles bus relations
658  if (ioStack->Parameters.QueryDeviceRelations.Type == BusRelations)
659  {
660  FdoScanAdapter(PortExtension);
661  DPRINT("Found %u PD objects, FDOExt: %p\n", PortExtension->TotalLUCount, PortExtension);
662 
663  // check that no filter driver has messed up this
664  ASSERT(Irp->IoStatus.Information == 0);
665 
666  PDEVICE_RELATIONS deviceRelations =
668  (sizeof(DEVICE_RELATIONS) +
669  sizeof(PDEVICE_OBJECT) * (PortExtension->TotalLUCount - 1)),
670  TAG_SCSIPORT);
671 
672  if (!deviceRelations)
673  {
674  Irp->IoStatus.Information = 0;
675  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
678  }
679 
680  deviceRelations->Count = 0;
681 
682  for (UINT8 pathId = 0; pathId < PortExtension->NumberOfBuses; pathId++)
683  {
684  PSCSI_BUS_INFO bus = &PortExtension->Buses[pathId];
685 
686  for (PLIST_ENTRY lunEntry = bus->LunsListHead.Flink;
687  lunEntry != &bus->LunsListHead;
688  lunEntry = lunEntry->Flink)
689  {
690  PSCSI_PORT_LUN_EXTENSION lunExt =
691  CONTAINING_RECORD(lunEntry, SCSI_PORT_LUN_EXTENSION, LunEntry);
692 
693  deviceRelations->Objects[deviceRelations->Count++] = lunExt->Common.DeviceObject;
695  }
696  }
697 
698  ASSERT(deviceRelations->Count == PortExtension->TotalLUCount);
699 
700  Irp->IoStatus.Information = (ULONG_PTR)deviceRelations;
701  Irp->IoStatus.Status = STATUS_SUCCESS;
702  }
703 
705  return IoCallDriver(PortExtension->Common.LowerDevice, Irp);
706 }
707 
708 static
709 NTSTATUS
711  _Inout_ PZZWSTR* PwIds)
712 {
713  static WCHAR GenScsiAdapterId[] = L"GEN_SCSIADAPTER";
714  PWCHAR Ids = *PwIds, NewIds;
715  ULONG Length = 0;
716 
717  if (Ids)
718  {
719  /* Calculate the length of existing MULTI_SZ value line by line */
720  while (*Ids)
721  {
722  Ids += wcslen(Ids) + 1;
723  }
724  Length = Ids - *PwIds;
725  Ids = *PwIds;
726  }
727 
728  /* New MULTI_SZ with added identifier and finalizing zeros */
729  NewIds = ExAllocatePoolZero(PagedPool,
730  Length * sizeof(WCHAR) + sizeof(GenScsiAdapterId) + sizeof(UNICODE_NULL),
731  TAG_SCSIPORT);
732  if (!NewIds)
733  {
735  }
736 
737  if (Length)
738  {
739  RtlCopyMemory(NewIds, Ids, Length * sizeof(WCHAR));
740  }
741  RtlCopyMemory(&NewIds[Length], GenScsiAdapterId, sizeof(GenScsiAdapterId));
742 
743  /* Finally replace identifiers */
744  if (Ids)
745  {
746  ExFreePool(Ids);
747  }
748  *PwIds = NewIds;
749 
750  return STATUS_SUCCESS;
751 }
752 
753 NTSTATUS
756  _Inout_ PIRP Irp)
757 {
759  PSCSI_PORT_DEVICE_EXTENSION portExt = DeviceObject->DeviceExtension;
761 
762  ASSERT(portExt->Common.IsFDO);
763 
764  DPRINT("FDO PnP request %s\n", GetIRPMinorFunctionString(ioStack->MinorFunction));
765 
766  switch (ioStack->MinorFunction)
767  {
768  case IRP_MN_START_DEVICE:
769  {
770  // as we don't support PnP yet, this is a no-op for us
771  // (FdoStartAdapter is being called during initialization for legacy miniports)
773  // status = FdoStartAdapter(DeviceExtension);
774  break;
775  }
777  {
778  return FdoHandleDeviceRelations(portExt, Irp);
779  }
780  case IRP_MN_QUERY_ID:
781  {
782  if (ioStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
783  {
784  Irp->IoStatus.Information = 0;
785  IoForwardIrpSynchronously(portExt->Common.LowerDevice, Irp);
786  status = FdoHandleQueryCompatibleId((PZZWSTR*)&Irp->IoStatus.Information);
787  break;
788  }
789  // otherwise fall through the default case
790  }
791  default:
792  {
793  // forward irp to next device object
795  return IoCallDriver(portExt->Common.LowerDevice, Irp);
796  }
797  }
798 
799  if (status != STATUS_PENDING)
800  {
801  Irp->IoStatus.Status = status;
803  }
804 
805  return status;
806 }
UCHAR SenseKey
Definition: cdrw_hw.h:1167
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
INTERFACE_TYPE AdapterInterfaceType
Definition: srb.h:55
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:798
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IRP_MN_QUERY_ID
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
PDEVICE_OBJECT DeviceObject
Definition: scsiport.h:138
KSERVICE_ROUTINE ScsiPortIsr
Definition: scsiport.h:459
VOID NTAPI IoStartTimer(IN PDEVICE_OBJECT DeviceObject)
Definition: iotimer.c:133
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Definition: iorsrce.c:830
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:379
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2160
PDEVICE_OBJECT LowerDevice
Definition: scsiport.h:139
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
#define TAG_SCSIPORT
Definition: scsiport.h:21
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define SRB_STATUS_NO_DEVICE
Definition: srb.h:340
#define SCSI_PORT_SCAN_IN_PROGRESS
Definition: scsiport.h:51
ACCESS_RANGE(* AccessRanges)[]
Definition: srb.h:70
uint16_t * PWCHAR
Definition: typedefs.h:56
IO_DPC_ROUTINE ScsiPortDpcForIsr
Definition: scsiport.h:451
#define swprintf
Definition: precomp.h:40
#define SRB_STATUS_BAD_SRB_BLOCK_LENGTH
Definition: srb.h:352
#define InsertTailList(ListHead, Entry)
_NullNull_terminated_ WCHAR * PZZWSTR
Definition: ntbasedef.h:420
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define SCSI_PORT_NOTIFICATION_NEEDED
Definition: scsiport.h:31
_Out_ PKIRQL Irql
Definition: csq.h:179
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
#define SRB_STATUS(Status)
Definition: srb.h:381
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
FORCEINLINE VOID IoCopyCurrentIrpStackLocationToNext(_Inout_ PIRP Irp)
Definition: iofuncs.h:2864
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
static NTSTATUS FdoHandleQueryCompatibleId(_Inout_ PZZWSTR *PwIds)
Definition: fdo.c:710
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
_In_ PIRP Irp
Definition: csq.h:116
unsigned int UINT32
NTSTATUS NTAPI IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN KAFFINITY ProcessorEnableMask, IN BOOLEAN FloatingSave)
Definition: irq.c:22
VOID NTAPI IoStopTimer(PDEVICE_OBJECT DeviceObject)
Definition: iotimer.c:166
static PVOID ptr
Definition: dispmode.c:27
VOID SpiGetNextRequestFromLun(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _Inout_ PSCSI_PORT_LUN_EXTENSION LunExtension, _Inout_opt_ PKIRQL OldIrql)
Definition: scsi.c:342
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:467
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define INQUIRYDATABUFFERSIZE
Definition: cdrw_hw.h:1113
enum _KINTERRUPT_MODE KINTERRUPT_MODE
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:140
union _CDB * PCDB
#define IoCompleteRequest
Definition: irp.c:1240
KINTERRUPT_MODE InterruptMode2
Definition: srb.h:97
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
UCHAR DeviceTypeQualifier
Definition: cdrw_hw.h:1117
NTHALAPI ULONG NTAPI HalGetInterruptVector(INTERFACE_TYPE, ULONG, ULONG, ULONG, PKIRQL, PKAFFINITY)
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
KINTERRUPT_MODE InterruptMode
Definition: srb.h:60
#define SCSIOP_INQUIRY
Definition: cdrw_hw.h:888
Status
Definition: gdiplustypes.h:24
UCHAR LogicalUnitsCount
Definition: scsiport.h:188
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define SRB_STATUS_BAD_FUNCTION
Definition: srb.h:356
#define ASSERT(a)
Definition: mode.c:45
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
NTSTATUS FdoStartAdapter(_In_ PSCSI_PORT_DEVICE_EXTENSION PortExtension)
Definition: fdo.c:605
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define IRP_MN_START_DEVICE
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:170
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB Cdb
Definition: scratch.h:156
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define _Inout_
Definition: no_sal2.h:162
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
static const WCHAR L[]
Definition: oid.c:1250
#define DEVICE_QUALIFIER_NOT_SUPPORTED
Definition: cdrw_hw.h:1155
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define SRB_STATUS_SELECTION_TIMEOUT
Definition: srb.h:342
Definition: typedefs.h:119
VOID FdoScanAdapter(_In_ PSCSI_PORT_DEVICE_EXTENSION PortExtension)
Definition: fdo.c:222
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
HANDLE RegistryMapKey
Definition: scsiport.h:191
#define IOCTL_SCSI_EXECUTE_IN
Definition: cdrw_hw.h:1451
static NTSTATUS FdoSendInquiry(_In_ PDEVICE_OBJECT DeviceObject)
Definition: fdo.c:18
static NTSTATUS FdoHandleDeviceRelations(_In_ PSCSI_PORT_DEVICE_EXTENSION PortExtension, _Inout_ PIRP Irp)
Definition: fdo.c:651
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define _In_
Definition: no_sal2.h:158
FORCEINLINE PCHAR GetIRPMinorFunctionString(UCHAR MinorFunction)
Definition: driverdbg.h:13
UCHAR DeviceType
Definition: cdrw_hw.h:1116
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
INQUIRYDATA InquiryData
Definition: scsiport.h:158
NTSTATUS FdoRemoveAdapter(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
Definition: fdo.c:506
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONG_PTR KAFFINITY
Definition: compat.h:85
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
NTSTATUS RegistryInitAdapterKey(_Inout_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
Definition: registry.c:127
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
UCHAR TargetsCount
Definition: scsiport.h:189
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define DPRINT1
Definition: precomp.h:8
SCSI_PORT_COMMON_EXTENSION Common
Definition: scsiport.h:146
LIST_ENTRY LunsListHead
Definition: scsiport.h:187
#define ObReferenceObject
Definition: obfuncs.h:204
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:115
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:142
NTSTATUS FdoDispatchPnp(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: fdo.c:754
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
PSCSI_PORT_LUN_EXTENSION GetLunByPath(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _In_ UCHAR PathId, _In_ UCHAR TargetId, _In_ UCHAR Lun)
Definition: pdo.c:68
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _CDB::_CDB6INQUIRY CDB6INQUIRY
PDEVICE_OBJECT PdoCreateLunDevice(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
Definition: pdo.c:18
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
#define STATUS_ADAPTER_HARDWARE_ERROR
Definition: ntstatus.h:430
#define DPRINT
Definition: sndvol32.h:71
#define SCSI_SENSE_ILLEGAL_REQUEST
Definition: cdrw_hw.h:1192
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3124
#define SCSI_PORT_DISCONNECT_ALLOWED
Definition: scsiport.h:39
unsigned char UINT8
static SERVICE_STATUS status
Definition: service.c:31
UCHAR BusIdentifier
Definition: scsiport.h:190
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define LUNEX_FROZEN_QUEUE
Definition: scsiport.h:46
VOID NTAPI HalFreeCommonBuffer(IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PHYSICAL_ADDRESS LogicalAddress, IN PVOID VirtualAddress, IN BOOLEAN CacheEnabled)
Definition: dma.c:61
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSTATUS FdoCallHWInitialize(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
Calls HwInitialize routine of the miniport and sets up interrupts Should be called inside ScsiPortIni...
Definition: fdo.c:362
Definition: ps.c:97