ReactOS  0.4.15-dev-5142-g967f5b9
scsiport.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: Main and exported functions
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 /* INCLUDES *****************************************************************/
11 
12 #include "scsiport.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
18 
19 #undef ScsiPortMoveMemory
20 
21 /* GLOBALS *******************************************************************/
22 
23 static BOOLEAN
30  IN OUT PPCI_SLOT_NUMBER NextSlotNumber);
31 
32 static NTSTATUS NTAPI
34  IN PIRP Irp);
35 
36 static VOID NTAPI
38  PVOID Context);
39 
40 VOID NTAPI
45 
46 static NTSTATUS
48  PHW_INITIALIZATION_DATA HwInitData,
49  PCONFIGURATION_INFO InternalConfigInfo,
51  BOOLEAN FirstCall);
52 
55  IN PUNICODE_STRING PathName,
59  IN CONFIGURATION_TYPE ControllerType,
60  IN ULONG ControllerNumber,
61  IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
62  IN CONFIGURATION_TYPE PeripheralType,
63  IN ULONG PeripheralNumber,
64  IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation);
65 
66 static VOID
68  IN HANDLE Key,
70  IN PCONFIGURATION_INFO InternalConfigInfo,
71  IN PUCHAR Buffer);
72 
73 static VOID
75  IN PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor,
77 
78 static PCM_RESOURCE_LIST
81 
82 static NTSTATUS
83 SpiAllocateCommonBuffer(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, ULONG NonCachedSize);
84 
88 
89 /* FUNCTIONS *****************************************************************/
90 
91 /**********************************************************************
92  * NAME EXPORTED
93  * DriverEntry
94  *
95  * DESCRIPTION
96  * This function initializes the driver.
97  *
98  * RUN LEVEL
99  * PASSIVE_LEVEL
100  *
101  * ARGUMENTS
102  * DriverObject
103  * System allocated Driver Object for this driver.
104  *
105  * RegistryPath
106  * Name of registry driver service key.
107  *
108  * RETURN VALUE
109  * Status.
110  */
111 
115 {
116  return STATUS_SUCCESS;
117 }
118 
119 VOID
120 NTAPI
123 {
124  // no-op
125 }
126 
127 NTSTATUS
128 NTAPI
131  PIRP Irp)
132 {
133  if (((PSCSI_PORT_COMMON_EXTENSION)DeviceObject->DeviceExtension)->IsFDO)
134  {
136  }
137  else
138  {
140  }
141 }
142 
143 NTSTATUS
144 NTAPI
148 {
149 
150  DPRINT("AddDevice no-op DriverObj: %p, PDO: %p\n", DriverObject, PhysicalDeviceObject);
151 
152  return STATUS_SUCCESS;
153 }
154 
155 
156 /**********************************************************************
157  * NAME EXPORTED
158  * ScsiDebugPrint
159  *
160  * DESCRIPTION
161  * Prints debugging messages.
162  *
163  * RUN LEVEL
164  * PASSIVE_LEVEL
165  *
166  * ARGUMENTS
167  * DebugPrintLevel
168  * Debug level of the given message.
169  *
170  * DebugMessage
171  * Pointer to printf()-compatible format string.
172  *
173  * ...
174  Additional output data (see printf()).
175  *
176  * RETURN VALUE
177  * None.
178  *
179  * @implemented
180  */
181 
182 VOID
183 ScsiDebugPrint(IN ULONG DebugPrintLevel,
184  IN PCHAR DebugMessage,
185  ...)
186 {
187  char Buffer[256];
188  va_list ap;
189 
190  if (DebugPrintLevel > InternalDebugLevel)
191  return;
192 
193  va_start(ap, DebugMessage);
194  vsprintf(Buffer, DebugMessage, ap);
195  va_end(ap);
196 
197  DbgPrint(Buffer);
198 }
199 
200 /* An internal helper function for ScsiPortCompleteRequest */
201 VOID
202 NTAPI
203 SpiCompleteRequest(IN PVOID HwDeviceExtension,
205  IN UCHAR SrbStatus)
206 {
208 
209  /* Get current SRB */
210  Srb = SrbInfo->Srb;
211 
212  /* Return if there is no SRB or it is not active */
213  if (!Srb || !(Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE)) return;
214 
215  /* Set status */
216  Srb->SrbStatus = SrbStatus;
217 
218  /* Set data transfered to 0 */
219  Srb->DataTransferLength = 0;
220 
221  /* Notify */
223  HwDeviceExtension,
224  Srb);
225 }
226 
227 /*
228  * @unimplemented
229  */
230 VOID NTAPI
231 ScsiPortCompleteRequest(IN PVOID HwDeviceExtension,
232  IN UCHAR PathId,
233  IN UCHAR TargetId,
234  IN UCHAR Lun,
235  IN UCHAR SrbStatus)
236 {
237  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
238  PSCSI_PORT_LUN_EXTENSION LunExtension;
239  PSCSI_REQUEST_BLOCK_INFO SrbInfo;
240  PLIST_ENTRY ListEntry;
241 
242  DPRINT("ScsiPortCompleteRequest() called\n");
243 
244  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
246  MiniPortDeviceExtension);
247 
248  /* Go through all buses */
249  for (UINT8 pathId = 0; pathId < DeviceExtension->NumberOfBuses; pathId++)
250  {
251  PSCSI_BUS_INFO bus = &DeviceExtension->Buses[pathId];
252 
253  /* Go through all logical units */
254  for (PLIST_ENTRY lunEntry = bus->LunsListHead.Flink;
255  lunEntry != &bus->LunsListHead;
256  lunEntry = lunEntry->Flink)
257  {
258  LunExtension = CONTAINING_RECORD(lunEntry, SCSI_PORT_LUN_EXTENSION, LunEntry);
259 
260  /* Now match what caller asked with what we are at now */
261  if ((PathId == SP_UNTAGGED || PathId == LunExtension->PathId) &&
262  (TargetId == SP_UNTAGGED || TargetId == LunExtension->TargetId) &&
263  (Lun == SP_UNTAGGED || Lun == LunExtension->Lun))
264  {
265  /* Yes, that's what caller asked for. Complete abort requests */
266  if (LunExtension->CompletedAbortRequests)
267  {
268  /* TODO: Save SrbStatus in this request */
269  DPRINT1("Completing abort request without setting SrbStatus!\n");
270 
271  /* Issue a notification request */
273  HwDeviceExtension,
274  LunExtension->CompletedAbortRequests);
275  }
276 
277  /* Complete the request using our helper */
278  SpiCompleteRequest(HwDeviceExtension,
279  &LunExtension->SrbInfo,
280  SrbStatus);
281 
282  /* Go through the queue and complete everything there too */
283  ListEntry = LunExtension->SrbInfo.Requests.Flink;
284  while (ListEntry != &LunExtension->SrbInfo.Requests)
285  {
286  /* Get the actual SRB info entry */
287  SrbInfo = CONTAINING_RECORD(ListEntry,
289  Requests);
290 
291  /* Complete it */
292  SpiCompleteRequest(HwDeviceExtension,
293  SrbInfo,
294  SrbStatus);
295 
296  /* Advance to the next request in queue */
297  ListEntry = SrbInfo->Requests.Flink;
298  }
299  }
300  }
301  }
302 }
303 
304 /*
305  * @unimplemented
306  */
307 VOID NTAPI
308 ScsiPortFlushDma(IN PVOID HwDeviceExtension)
309 {
310  DPRINT("ScsiPortFlushDma()\n");
312 }
313 
314 
315 /*
316  * @implemented
317  */
318 VOID NTAPI
319 ScsiPortFreeDeviceBase(IN PVOID HwDeviceExtension,
320  IN PVOID MappedAddress)
321 {
322  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
323  PMAPPED_ADDRESS NextMa, LastMa;
324 
325  //DPRINT("ScsiPortFreeDeviceBase() called\n");
326 
327  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
329  MiniPortDeviceExtension);
330 
331  /* Initialize our pointers */
332  NextMa = DeviceExtension->MappedAddressList;
333  LastMa = NextMa;
334 
335  while (NextMa)
336  {
337  if (NextMa->MappedAddress == MappedAddress)
338  {
339  /* Unmap it first */
340  MmUnmapIoSpace(MappedAddress, NextMa->NumberOfBytes);
341 
342  /* Remove it from the list */
343  if (NextMa == DeviceExtension->MappedAddressList)
344  {
345  /* Remove the first entry */
346  DeviceExtension->MappedAddressList = NextMa->NextMappedAddress;
347  }
348  else
349  {
350  LastMa->NextMappedAddress = NextMa->NextMappedAddress;
351  }
352 
353  /* Free the resources and quit */
354  ExFreePool(NextMa);
355 
356  return;
357  }
358  else
359  {
360  LastMa = NextMa;
361  NextMa = NextMa->NextMappedAddress;
362  }
363  }
364 }
365 
366 
367 /*
368  * @implemented
369  */
370 ULONG NTAPI
371 ScsiPortGetBusData(IN PVOID DeviceExtension,
372  IN ULONG BusDataType,
373  IN ULONG SystemIoBusNumber,
375  IN PVOID Buffer,
376  IN ULONG Length)
377 {
378  DPRINT("ScsiPortGetBusData()\n");
379 
380  if (Length)
381  {
382  /* If Length is non-zero, just forward the call to
383  HalGetBusData() function */
384  return HalGetBusData(BusDataType,
385  SystemIoBusNumber,
386  SlotNumber,
387  Buffer,
388  Length);
389  }
390 
391  /* We have a more complex case here */
393  return 0;
394 }
395 
396 /*
397  * @implemented
398  */
399 ULONG NTAPI
401  IN ULONG BusDataType,
402  IN ULONG SystemIoBusNumber,
404  IN PVOID Buffer,
405  IN ULONG Offset,
406  IN ULONG Length)
407 {
408  DPRINT("ScsiPortSetBusDataByOffset()\n");
409  return HalSetBusDataByOffset(BusDataType,
410  SystemIoBusNumber,
411  SlotNumber,
412  Buffer,
413  Offset,
414  Length);
415 }
416 
417 /*
418  * @implemented
419  */
420 PVOID NTAPI
421 ScsiPortGetDeviceBase(IN PVOID HwDeviceExtension,
423  IN ULONG SystemIoBusNumber,
424  IN SCSI_PHYSICAL_ADDRESS IoAddress,
426  IN BOOLEAN InIoSpace)
427 {
428  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
430  PMAPPED_ADDRESS DeviceBase;
432  PVOID MappedAddress;
433 
434  //DPRINT ("ScsiPortGetDeviceBase() called\n");
435 
436  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
438  MiniPortDeviceExtension);
439 
440  AddressSpace = (ULONG)InIoSpace;
442  SystemIoBusNumber,
443  IoAddress,
444  &AddressSpace,
446  {
447  return NULL;
448  }
449 
450  /* i/o space */
451  if (AddressSpace != 0)
453 
454  MappedAddress = MmMapIoSpace(TranslatedAddress,
456  FALSE);
457 
458  DeviceBase = ExAllocatePoolWithTag(NonPagedPool,
459  sizeof(MAPPED_ADDRESS), TAG_SCSIPORT);
460 
461  if (DeviceBase == NULL)
462  return MappedAddress;
463 
464  DeviceBase->MappedAddress = MappedAddress;
465  DeviceBase->NumberOfBytes = NumberOfBytes;
466  DeviceBase->IoAddress = IoAddress;
467  DeviceBase->BusNumber = SystemIoBusNumber;
468 
469  /* Link it to the Device Extension list */
470  DeviceBase->NextMappedAddress = DeviceExtension->MappedAddressList;
471  DeviceExtension->MappedAddressList = DeviceBase;
472 
473  return MappedAddress;
474 }
475 
476 /*
477  * @unimplemented
478  */
479 PVOID NTAPI
480 ScsiPortGetLogicalUnit(IN PVOID HwDeviceExtension,
481  IN UCHAR PathId,
482  IN UCHAR TargetId,
483  IN UCHAR Lun)
484 {
485  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
486  PSCSI_PORT_LUN_EXTENSION LunExtension;
487 
488  DPRINT("ScsiPortGetLogicalUnit() called\n");
489 
490  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
492  MiniPortDeviceExtension);
493 
494  /* Check the extension size */
495  if (!DeviceExtension->LunExtensionSize)
496  {
497  /* They didn't want one */
498  return NULL;
499  }
500 
501  LunExtension = GetLunByPath(DeviceExtension, PathId, TargetId, Lun);
502 
503  /* Check that the logical unit exists */
504  if (!LunExtension)
505  {
506  /* Nope, return NULL */
507  return NULL;
508  }
509 
510  /* Return the logical unit miniport extension */
511  return (LunExtension + 1);
512 }
513 
514 
515 /*
516  * @implemented
517  */
522  OUT ULONG *Length)
523 {
524  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
526  SIZE_T BufferLength = 0;
528  PSCSI_SG_ADDRESS SGList;
529  PSCSI_REQUEST_BLOCK_INFO SrbInfo;
530 
531  DPRINT("ScsiPortGetPhysicalAddress(%p %p %p %p)\n",
532  HwDeviceExtension, Srb, VirtualAddress, Length);
533 
534  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
536  MiniPortDeviceExtension);
537 
538  if (Srb == NULL || Srb->SenseInfoBuffer == VirtualAddress)
539  {
540  /* Simply look it up in the allocated common buffer */
541  Offset = (PUCHAR)VirtualAddress - (PUCHAR)DeviceExtension->SrbExtensionBuffer;
542 
543  BufferLength = DeviceExtension->CommonBufferLength - Offset;
544  PhysicalAddress.QuadPart = DeviceExtension->PhysicalAddress.QuadPart + Offset;
545  }
546  else if (DeviceExtension->MapRegisters)
547  {
549  PSCSI_PORT_LUN_EXTENSION LunExtension = IoStack->DeviceObject->DeviceExtension;
550  ASSERT(LunExtension && !LunExtension->Common.IsFDO);
551 
552  /* Scatter-gather list must be used */
553  SrbInfo = SpiGetSrbData(DeviceExtension, LunExtension, Srb->QueueTag);
554 
555  SGList = SrbInfo->ScatterGather;
556 
557  /* Find needed item in the SG list */
559  while (Offset >= SGList->Length)
560  {
561  Offset -= SGList->Length;
562  SGList++;
563  }
564 
565  /* We're done, store length and physical address */
566  BufferLength = SGList->Length - Offset;
568  }
569  else
570  {
571  /* Nothing */
573  }
574 
576  return PhysicalAddress;
577 }
578 
579 
580 /*
581  * @unimplemented
582  */
584 ScsiPortGetSrb(IN PVOID DeviceExtension,
585  IN UCHAR PathId,
586  IN UCHAR TargetId,
587  IN UCHAR Lun,
588  IN LONG QueueTag)
589 {
590  DPRINT1("ScsiPortGetSrb() unimplemented\n");
592  return NULL;
593 }
594 
595 
596 /*
597  * @implemented
598  */
599 PVOID NTAPI
603 {
604  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
606  ULONG MapRegistersCount;
608 
609  DPRINT("ScsiPortGetUncachedExtension(%p %p %lu)\n",
610  HwDeviceExtension, ConfigInfo, NumberOfBytes);
611 
612  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
614  MiniPortDeviceExtension);
615 
616  /* Check for allocated common DMA buffer */
617  if (DeviceExtension->SrbExtensionBuffer != NULL)
618  {
619  DPRINT1("The HBA has already got a common DMA buffer!\n");
620  return NULL;
621  }
622 
623  /* Check for DMA adapter object */
624  if (DeviceExtension->AdapterObject == NULL)
625  {
626  /* Initialize DMA adapter description */
628 
630  DeviceDescription.Master = ConfigInfo->Master;
631  DeviceDescription.ScatterGather = ConfigInfo->ScatterGather;
632  DeviceDescription.DemandMode = ConfigInfo->DemandMode;
633  DeviceDescription.Dma32BitAddresses = ConfigInfo->Dma32BitAddresses;
634  DeviceDescription.BusNumber = ConfigInfo->SystemIoBusNumber;
635  DeviceDescription.DmaChannel = ConfigInfo->DmaChannel;
636  DeviceDescription.InterfaceType = ConfigInfo->AdapterInterfaceType;
637  DeviceDescription.DmaWidth = ConfigInfo->DmaWidth;
638  DeviceDescription.DmaSpeed = ConfigInfo->DmaSpeed;
639  DeviceDescription.MaximumLength = ConfigInfo->MaximumTransferLength;
640  DeviceDescription.DmaPort = ConfigInfo->DmaPort;
641 
642  /* Get a DMA adapter object */
643  DeviceExtension->AdapterObject =
644  HalGetAdapter(&DeviceDescription, &MapRegistersCount);
645 
646  /* Fail in case of error */
647  if (DeviceExtension->AdapterObject == NULL)
648  {
649  DPRINT1("HalGetAdapter() failed\n");
650  return NULL;
651  }
652 
653  /* Set number of physical breaks */
654  if (ConfigInfo->NumberOfPhysicalBreaks != 0 &&
655  MapRegistersCount > ConfigInfo->NumberOfPhysicalBreaks)
656  {
657  DeviceExtension->PortCapabilities.MaximumPhysicalPages =
658  ConfigInfo->NumberOfPhysicalBreaks;
659  }
660  else
661  {
662  DeviceExtension->PortCapabilities.MaximumPhysicalPages = MapRegistersCount;
663  }
664  }
665 
666  /* Update auto request sense feature */
667  DeviceExtension->SupportsAutoSense = ConfigInfo->AutoRequestSense;
668 
669  /* Update Srb extension size */
670  if (DeviceExtension->SrbExtensionSize != ConfigInfo->SrbExtensionSize)
671  DeviceExtension->SrbExtensionSize = ConfigInfo->SrbExtensionSize;
672 
673  /* Update Srb extension alloc flag */
674  if (ConfigInfo->AutoRequestSense || DeviceExtension->SrbExtensionSize)
675  DeviceExtension->NeedSrbExtensionAlloc = TRUE;
676 
677  /* Allocate a common DMA buffer */
678  Status = SpiAllocateCommonBuffer(DeviceExtension, NumberOfBytes);
679 
680  if (!NT_SUCCESS(Status))
681  {
682  DPRINT1("SpiAllocateCommonBuffer() failed with Status = 0x%08X!\n", Status);
683  return NULL;
684  }
685 
686  return DeviceExtension->NonCachedExtension;
687 }
688 
689 static NTSTATUS
691 {
692  PVOID *SrbExtension, CommonBuffer;
693  ULONG CommonBufferLength, BufSize;
694 
695  /* If size is 0, set it to 16 */
696  if (!DeviceExtension->SrbExtensionSize)
697  DeviceExtension->SrbExtensionSize = 16;
698 
699  /* Calculate size */
700  BufSize = DeviceExtension->SrbExtensionSize;
701 
702  /* Add autosense data size if needed */
703  if (DeviceExtension->SupportsAutoSense)
704  BufSize += sizeof(SENSE_DATA);
705 
706 
707  /* Round it */
708  BufSize = (BufSize + sizeof(LONGLONG) - 1) & ~(sizeof(LONGLONG) - 1);
709 
710  /* Sum up into the total common buffer length, and round it to page size */
711  CommonBufferLength =
712  ROUND_TO_PAGES(NonCachedSize + BufSize * DeviceExtension->RequestsNumber);
713 
714  /* Allocate it */
715  if (!DeviceExtension->AdapterObject)
716  {
717  /* From nonpaged pool if there is no DMA */
719  }
720  else
721  {
722  /* Perform a full request since we have a DMA adapter*/
724  CommonBufferLength,
725  &DeviceExtension->PhysicalAddress,
726  FALSE );
727  }
728 
729  /* Fail in case of error */
730  if (!CommonBuffer)
732 
733  /* Zero it */
734  RtlZeroMemory(CommonBuffer, CommonBufferLength);
735 
736  /* Store its size in Device Extension */
737  DeviceExtension->CommonBufferLength = CommonBufferLength;
738 
739  /* SrbExtension buffer is located at the beginning of the buffer */
740  DeviceExtension->SrbExtensionBuffer = CommonBuffer;
741 
742  /* Non-cached extension buffer is located at the end of
743  the common buffer */
744  if (NonCachedSize)
745  {
746  CommonBufferLength -= NonCachedSize;
747  DeviceExtension->NonCachedExtension = (PUCHAR)CommonBuffer + CommonBufferLength;
748  }
749  else
750  {
751  DeviceExtension->NonCachedExtension = NULL;
752  }
753 
754  if (DeviceExtension->NeedSrbExtensionAlloc)
755  {
756  /* Look up how many SRB data structures we need */
757  DeviceExtension->SrbDataCount = CommonBufferLength / BufSize;
758 
759  /* Initialize the free SRB extensions list */
760  SrbExtension = (PVOID *)CommonBuffer;
761  DeviceExtension->FreeSrbExtensions = SrbExtension;
762 
763  /* Fill the remaining pointers (if we have more than 1 SRB) */
764  while (CommonBufferLength >= 2 * BufSize)
765  {
766  *SrbExtension = (PVOID*)((PCHAR)SrbExtension + BufSize);
767  SrbExtension = *SrbExtension;
768 
769  CommonBufferLength -= BufSize;
770  }
771  }
772 
773  return STATUS_SUCCESS;
774 }
775 
776 
777 
778 /*
779  * @implemented
780  */
781 PVOID NTAPI
784 {
785  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
786  ULONG Offset;
787 
788  DPRINT("ScsiPortGetVirtualAddress(%p %I64x)\n",
789  HwDeviceExtension, PhysicalAddress.QuadPart);
790 
791  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
793  MiniPortDeviceExtension);
794 
795  if (DeviceExtension->PhysicalAddress.QuadPart > PhysicalAddress.QuadPart)
796  return NULL;
797 
798  Offset = (ULONG)(PhysicalAddress.QuadPart - DeviceExtension->PhysicalAddress.QuadPart);
799 
800  if (Offset >= DeviceExtension->CommonBufferLength)
801  return NULL;
802 
803  return (PVOID)((ULONG_PTR)DeviceExtension->SrbExtensionBuffer + Offset);
804 }
805 
806 /**********************************************************************
807  * NAME EXPORTED
808  * ScsiPortInitialize
809  *
810  * DESCRIPTION
811  * Initializes SCSI port driver specific data.
812  *
813  * RUN LEVEL
814  * PASSIVE_LEVEL
815  *
816  * ARGUMENTS
817  * Argument1
818  * Pointer to the miniport driver's driver object.
819  *
820  * Argument2
821  * Pointer to the miniport driver's registry path.
822  *
823  * HwInitializationData
824  * Pointer to port driver specific configuration data.
825  *
826  * HwContext
827  Miniport driver specific context.
828  *
829  * RETURN VALUE
830  * Status.
831  *
832  * @implemented
833  */
834 
835 ULONG NTAPI
841 {
844  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension = NULL;
845  PCONFIGURATION_INFORMATION SystemConfig;
847  CONFIGURATION_INFO ConfigInfo;
848  ULONG DeviceExtensionSize;
849  ULONG PortConfigSize;
850  BOOLEAN Again;
851  BOOLEAN DeviceFound = FALSE;
852  BOOLEAN FirstConfigCall = TRUE;
853  ULONG Result;
855  ULONG MaxBus;
857 
858  PDEVICE_OBJECT PortDeviceObject;
860  PIO_SCSI_CAPABILITIES PortCapabilities;
861 
863 
864  DPRINT ("ScsiPortInitialize() called!\n");
865 
866  /* Check params for validity */
867  if ((HwInitializationData->HwInitialize == NULL) ||
868  (HwInitializationData->HwStartIo == NULL) ||
869  (HwInitializationData->HwInterrupt == NULL) ||
870  (HwInitializationData->HwFindAdapter == NULL) ||
871  (HwInitializationData->HwResetBus == NULL))
872  {
874  }
875 
876  PSCSI_PORT_DRIVER_EXTENSION driverExtension;
877 
878  // ScsiPortInitialize may be called multiple times by the same driver
879  driverExtension = IoGetDriverObjectExtension(DriverObject, HwInitializationData->HwInitialize);
880 
881  if (!driverExtension)
882  {
884  HwInitializationData->HwInitialize,
886  (PVOID *)&driverExtension);
887 
888  if (!NT_SUCCESS(Status))
889  {
890  DPRINT1("Failed to allocate the driver extension! Status 0x%x\n", Status);
891  return Status;
892  }
893  }
894 
895  // set up the driver extension
896  driverExtension->RegistryPath.Buffer =
898  driverExtension->RegistryPath.MaximumLength = RegistryPath->MaximumLength;
899  RtlCopyUnicodeString(&driverExtension->RegistryPath, RegistryPath);
900 
901  driverExtension->DriverObject = DriverObject;
902 
903  /* Set handlers */
905  DriverObject->DriverStartIo = ScsiPortStartIo;
906  DriverObject->DriverExtension->AddDevice = ScsiPortAddDevice;
911  DriverObject->MajorFunction[IRP_MJ_PNP] = ScsiPortDispatchPnp;
913 
914  /* Obtain configuration information */
915  SystemConfig = IoGetConfigurationInformation();
916 
917  /* Zero the internal configuration info structure */
918  RtlZeroMemory(&ConfigInfo, sizeof(CONFIGURATION_INFO));
919 
920  /* Zero starting slot number */
921  SlotNumber.u.AsULONG = 0;
922 
923  /* Allocate space for access ranges */
924  if (HwInitializationData->NumberOfAccessRanges)
925  {
926  ConfigInfo.AccessRanges =
928  HwInitializationData->NumberOfAccessRanges * sizeof(ACCESS_RANGE), TAG_SCSIPORT);
929 
930  /* Fail if failed */
931  if (ConfigInfo.AccessRanges == NULL)
933  }
934 
935  /* Open registry keys and fill the driverExtension */
936  SpiInitOpenKeys(&ConfigInfo, driverExtension);
937 
938  // FIXME: PnP miniports are not supported
939  ASSERT(driverExtension->IsLegacyDriver);
940 
941  /* Last adapter number = not known */
943 
944  /* Calculate sizes of DeviceExtension and PortConfig */
945  DeviceExtensionSize = sizeof(SCSI_PORT_DEVICE_EXTENSION) +
946  HwInitializationData->DeviceExtensionSize;
947 
948  MaxBus = (HwInitializationData->AdapterInterfaceType == PCIBus) ? 8 : 1;
949  DPRINT("MaxBus: %lu\n", MaxBus);
950 
951  while (TRUE)
952  {
953  WCHAR NameBuffer[27];
954  /* Create a unicode device name */
955  swprintf(NameBuffer,
956  L"\\Device\\ScsiPort%lu",
957  SystemConfig->ScsiPortCount);
958  if (!RtlCreateUnicodeString(&DeviceName, NameBuffer))
959  {
960  DPRINT1("Failed to allocate memory for device name!\n");
962  PortDeviceObject = NULL;
963  break;
964  }
965 
966  DPRINT("Creating device: %wZ\n", &DeviceName);
967 
968  /* Create the port device */
970  DeviceExtensionSize,
971  &DeviceName,
974  FALSE,
975  &PortDeviceObject);
976 
977  if (!NT_SUCCESS(Status))
978  {
979  DPRINT1("IoCreateDevice call failed! (Status 0x%lX)\n", Status);
980  PortDeviceObject = NULL;
981  break;
982  }
983 
984  /* Set the buffering strategy here... */
985  PortDeviceObject->Flags |= DO_DIRECT_IO;
986  PortDeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT; /* FIXME: Is this really needed? */
987 
988  /* Fill Device Extension */
989  DeviceExtension = PortDeviceObject->DeviceExtension;
990  RtlZeroMemory(DeviceExtension, DeviceExtensionSize);
991  DeviceExtension->Common.DeviceObject = PortDeviceObject;
992  DeviceExtension->Common.IsFDO = TRUE;
993  DeviceExtension->Length = DeviceExtensionSize;
994  DeviceExtension->PortNumber = SystemConfig->ScsiPortCount;
995  DeviceExtension->DeviceName = DeviceName;
996 
997  /* Driver's routines... */
998  DeviceExtension->HwInitialize = HwInitializationData->HwInitialize;
999  DeviceExtension->HwStartIo = HwInitializationData->HwStartIo;
1000  DeviceExtension->HwInterrupt = HwInitializationData->HwInterrupt;
1001  DeviceExtension->HwResetBus = HwInitializationData->HwResetBus;
1002  DeviceExtension->HwDmaStarted = HwInitializationData->HwDmaStarted;
1003 
1004  /* Extensions sizes */
1005  DeviceExtension->MiniPortExtensionSize = HwInitializationData->DeviceExtensionSize;
1006  DeviceExtension->LunExtensionSize =
1007  ALIGN_UP(HwInitializationData->SpecificLuExtensionSize, INT64);
1008  DeviceExtension->SrbExtensionSize =
1009  ALIGN_UP(HwInitializationData->SrbExtensionSize, INT64);
1010 
1011  /* Fill some numbers (bus count, lun count, etc) */
1012  DeviceExtension->MaxLunCount = SCSI_MAXIMUM_LOGICAL_UNITS;
1013  DeviceExtension->RequestsNumber = 16;
1014 
1015  /* Initialize the spin lock in the controller extension */
1016  KeInitializeSpinLock(&DeviceExtension->IrqLock);
1017  KeInitializeSpinLock(&DeviceExtension->SpinLock);
1018 
1019  /* Initialize the DPC object */
1020  IoInitializeDpcRequest(PortDeviceObject,
1022 
1023  /* Initialize the device timer */
1024  DeviceExtension->TimerCount = -1;
1025  IoInitializeTimer(PortDeviceObject,
1027  DeviceExtension);
1028 
1029  /* Initialize miniport timer */
1030  KeInitializeTimer(&DeviceExtension->MiniportTimer);
1031  KeInitializeDpc(&DeviceExtension->MiniportTimerDpc,
1033  PortDeviceObject);
1034 
1035 CreatePortConfig:
1036 
1037  /* Allocate and initialize port configuration info */
1038  PortConfigSize = sizeof(PORT_CONFIGURATION_INFORMATION) +
1039  HwInitializationData->NumberOfAccessRanges * sizeof(ACCESS_RANGE);
1040  PortConfigSize = ALIGN_UP(PortConfigSize, INT64);
1041  DeviceExtension->PortConfig = ExAllocatePoolWithTag(NonPagedPool, PortConfigSize, TAG_SCSIPORT);
1042 
1043  /* Fail if failed */
1044  if (DeviceExtension->PortConfig == NULL)
1045  {
1047  break;
1048  }
1049 
1050  Status = SpiCreatePortConfig(DeviceExtension,
1052  &ConfigInfo,
1053  DeviceExtension->PortConfig,
1054  FirstConfigCall);
1055 
1056  if (!NT_SUCCESS(Status))
1057  {
1058  DPRINT("SpiCreatePortConfig() failed with Status 0x%08X\n", Status);
1059  break;
1060  }
1061 
1062  PortConfig = DeviceExtension->PortConfig;
1063 
1064  /* Copy extension sizes into the PortConfig */
1065  PortConfig->SpecificLuExtensionSize = DeviceExtension->LunExtensionSize;
1066  PortConfig->SrbExtensionSize = DeviceExtension->SrbExtensionSize;
1067 
1068  /* Initialize Access ranges */
1069  if (HwInitializationData->NumberOfAccessRanges != 0)
1070  {
1071  PortConfig->AccessRanges = ALIGN_UP_POINTER(PortConfig + 1, INT64);
1072 
1073  /* Copy the data */
1074  RtlCopyMemory(PortConfig->AccessRanges,
1075  ConfigInfo.AccessRanges,
1076  HwInitializationData->NumberOfAccessRanges * sizeof(ACCESS_RANGE));
1077  }
1078 
1079  /* Search for matching PCI device */
1080  if ((HwInitializationData->AdapterInterfaceType == PCIBus) &&
1081  (HwInitializationData->VendorIdLength > 0) &&
1082  (HwInitializationData->VendorId != NULL) &&
1083  (HwInitializationData->DeviceIdLength > 0) && (HwInitializationData->DeviceId != NULL))
1084  {
1085  PortConfig->BusInterruptLevel = 0;
1086 
1087  /* Get PCI device data */
1088  DPRINT(
1089  "VendorId '%.*s' DeviceId '%.*s'\n", HwInitializationData->VendorIdLength,
1090  HwInitializationData->VendorId, HwInitializationData->DeviceIdLength,
1091  HwInitializationData->DeviceId);
1092 
1093  if (!SpiGetPciConfigData(
1094  DriverObject, PortDeviceObject, HwInitializationData, PortConfig, RegistryPath,
1095  ConfigInfo.BusNumber, &SlotNumber))
1096  {
1097  /* Continue to the next bus, nothing here */
1098  ConfigInfo.BusNumber++;
1099  DeviceExtension->PortConfig = NULL;
1100  ExFreePool(PortConfig);
1101  Again = FALSE;
1102  goto CreatePortConfig;
1103  }
1104 
1105  if (!PortConfig->BusInterruptLevel)
1106  {
1107  /* Bypass this slot, because no interrupt was assigned */
1108  DeviceExtension->PortConfig = NULL;
1109  ExFreePool(PortConfig);
1110  goto CreatePortConfig;
1111  }
1112  }
1113  else
1114  {
1115  DPRINT("Non-pci bus\n");
1116  }
1117 
1118  /* Note: HwFindAdapter is called once for each bus */
1119  Again = FALSE;
1120  DPRINT("Calling HwFindAdapter() for Bus %lu\n", PortConfig->SystemIoBusNumber);
1121  Result = (HwInitializationData->HwFindAdapter)(
1122  &DeviceExtension->MiniPortDeviceExtension, HwContext, 0, /* BusInformation */
1123  ConfigInfo.Parameter, /* ArgumentString */
1124  PortConfig, &Again);
1125 
1126  DPRINT("HwFindAdapter() Result: %lu Again: %s\n", Result, (Again) ? "True" : "False");
1127 
1128  /* Free MapRegisterBase, it's not needed anymore */
1129  if (DeviceExtension->MapRegisterBase != NULL)
1130  {
1131  ExFreePool(DeviceExtension->MapRegisterBase);
1132  DeviceExtension->MapRegisterBase = NULL;
1133  }
1134 
1135  /* If result is nothing good... */
1136  if (Result != SP_RETURN_FOUND)
1137  {
1138  DPRINT("HwFindAdapter() Result: %lu\n", Result);
1139 
1140  if (Result == SP_RETURN_NOT_FOUND)
1141  {
1142  /* We can continue on the next bus */
1143  ConfigInfo.BusNumber++;
1144  Again = FALSE;
1145 
1146  DeviceExtension->PortConfig = NULL;
1147  ExFreePool(PortConfig);
1148  goto CreatePortConfig;
1149  }
1150 
1151  /* Otherwise, break */
1153  break;
1154  }
1155 
1156  DPRINT(
1157  "ScsiPortInitialize(): Found HBA! (%x), adapter Id %d\n",
1158  PortConfig->BusInterruptVector, PortConfig->InitiatorBusId[0]);
1159 
1160  /* If the SRB extension size was updated */
1161  if (!DeviceExtension->NonCachedExtension &&
1162  (PortConfig->SrbExtensionSize != DeviceExtension->SrbExtensionSize))
1163  {
1164  /* Set it (rounding to LONGLONG again) */
1165  DeviceExtension->SrbExtensionSize = ALIGN_UP(PortConfig->SrbExtensionSize, INT64);
1166  }
1167 
1168  /* The same with LUN extension size */
1169  if (PortConfig->SpecificLuExtensionSize != DeviceExtension->LunExtensionSize)
1170  DeviceExtension->LunExtensionSize = PortConfig->SpecificLuExtensionSize;
1171 
1172  /* Construct a resource list */
1173  ResourceList = SpiConfigToResource(DeviceExtension, PortConfig);
1174 
1175  PDEVICE_OBJECT LowerPDO = NULL;
1176 
1178  HwInitializationData->AdapterInterfaceType,
1179  ConfigInfo.BusNumber,
1180  PortConfig->SlotNumber,
1181  ResourceList,
1182  NULL,
1183  TRUE,
1184  &LowerPDO);
1185 
1186  if (!NT_SUCCESS(Status))
1187  {
1188  DPRINT1("IoReportDetectedDevice failed. Status: 0x%x\n", Status);
1189  __debugbreak();
1190  break;
1191  }
1192 
1193  DeviceExtension->Common.LowerDevice = IoAttachDeviceToDeviceStack(PortDeviceObject, LowerPDO);
1194 
1195  ASSERT(DeviceExtension->Common.LowerDevice);
1196 
1197  PortDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1198 
1199  if (ResourceList)
1200  {
1202  }
1203 
1204  /* Copy all stuff which we ever need from PortConfig to the DeviceExtension */
1206  DeviceExtension->MaxTargedIds = SCSI_MAXIMUM_TARGETS_PER_BUS;
1207  else
1208  DeviceExtension->MaxTargedIds = PortConfig->MaximumNumberOfTargets;
1209 
1210  DeviceExtension->NumberOfBuses = PortConfig->NumberOfBuses;
1211  DeviceExtension->CachesData = PortConfig->CachesData;
1212  DeviceExtension->ReceiveEvent = PortConfig->ReceiveEvent;
1213  DeviceExtension->SupportsTaggedQueuing = PortConfig->TaggedQueuing;
1214  DeviceExtension->MultipleReqsPerLun = PortConfig->MultipleRequestPerLu;
1215 
1216  /* Initialize bus scanning information */
1217  size_t BusConfigSize = DeviceExtension->NumberOfBuses * sizeof(*DeviceExtension->Buses);
1218  DeviceExtension->Buses = ExAllocatePoolZero(NonPagedPool, BusConfigSize, TAG_SCSIPORT);
1219  if (!DeviceExtension->Buses)
1220  {
1221  DPRINT1("Out of resources!\n");
1223  break;
1224  }
1225 
1226  // initialize bus data
1227  for (UINT8 pathId = 0; pathId < DeviceExtension->NumberOfBuses; pathId++)
1228  {
1229  DeviceExtension->Buses[pathId].BusIdentifier =
1230  DeviceExtension->PortConfig->InitiatorBusId[pathId];
1231  InitializeListHead(&DeviceExtension->Buses[pathId].LunsListHead);
1232  }
1233 
1234  /* If something was disabled via registry - apply it */
1235  if (ConfigInfo.DisableMultipleLun)
1236  DeviceExtension->MultipleReqsPerLun = PortConfig->MultipleRequestPerLu = FALSE;
1237 
1238  if (ConfigInfo.DisableTaggedQueueing)
1239  DeviceExtension->SupportsTaggedQueuing = PortConfig->MultipleRequestPerLu = FALSE;
1240 
1241  /* Check if we need to alloc SRB data */
1242  if (DeviceExtension->SupportsTaggedQueuing || DeviceExtension->MultipleReqsPerLun)
1243  {
1244  DeviceExtension->NeedSrbDataAlloc = TRUE;
1245  }
1246  else
1247  {
1248  DeviceExtension->NeedSrbDataAlloc = FALSE;
1249  }
1250 
1251  /* Get a pointer to the port capabilities */
1252  PortCapabilities = &DeviceExtension->PortCapabilities;
1253 
1254  /* Copy one field there */
1255  DeviceExtension->MapBuffers = PortConfig->MapBuffers;
1256  PortCapabilities->AdapterUsesPio = PortConfig->MapBuffers;
1257 
1258  if (DeviceExtension->AdapterObject == NULL &&
1259  (PortConfig->DmaChannel != SP_UNINITIALIZED_VALUE || PortConfig->Master))
1260  {
1261  DPRINT1("DMA is not supported yet\n");
1262  ASSERT(FALSE);
1263  }
1264 
1265  if (DeviceExtension->SrbExtensionBuffer == NULL &&
1266  (DeviceExtension->SrbExtensionSize != 0 || PortConfig->AutoRequestSense))
1267  {
1268  DeviceExtension->SupportsAutoSense = PortConfig->AutoRequestSense;
1269  DeviceExtension->NeedSrbExtensionAlloc = TRUE;
1270 
1271  /* Allocate common buffer */
1272  Status = SpiAllocateCommonBuffer(DeviceExtension, 0);
1273 
1274  /* Check for failure */
1275  if (!NT_SUCCESS(Status))
1276  break;
1277  }
1278 
1279  /* Allocate SrbData, if needed */
1280  if (DeviceExtension->NeedSrbDataAlloc)
1281  {
1282  ULONG Count;
1283  PSCSI_REQUEST_BLOCK_INFO SrbData;
1284 
1285  if (DeviceExtension->SrbDataCount != 0)
1286  Count = DeviceExtension->SrbDataCount;
1287  else
1288  Count = DeviceExtension->RequestsNumber * 2;
1289 
1290  /* Allocate the data */
1291  SrbData = ExAllocatePoolWithTag(
1293  if (SrbData == NULL)
1295 
1296  RtlZeroMemory(SrbData, Count * sizeof(SCSI_REQUEST_BLOCK_INFO));
1297 
1298  DeviceExtension->SrbInfo = SrbData;
1299  DeviceExtension->FreeSrbInfo = SrbData;
1300  DeviceExtension->SrbDataCount = Count;
1301 
1302  /* Link it to the list */
1303  while (Count > 0)
1304  {
1305  SrbData->Requests.Flink = (PLIST_ENTRY)(SrbData + 1);
1306  SrbData++;
1307  Count--;
1308  }
1309 
1310  /* Mark the last entry of the list */
1311  SrbData--;
1312  SrbData->Requests.Flink = NULL;
1313  }
1314 
1315  /* Initialize port capabilities */
1316  PortCapabilities = &DeviceExtension->PortCapabilities;
1317  PortCapabilities->Length = sizeof(IO_SCSI_CAPABILITIES);
1318  PortCapabilities->MaximumTransferLength = PortConfig->MaximumTransferLength;
1319 
1320  if (PortConfig->ReceiveEvent)
1322 
1323  PortCapabilities->TaggedQueuing = DeviceExtension->SupportsTaggedQueuing;
1324  PortCapabilities->AdapterScansDown = PortConfig->AdapterScansDown;
1325 
1326  if (PortConfig->AlignmentMask > PortDeviceObject->AlignmentRequirement)
1327  PortDeviceObject->AlignmentRequirement = PortConfig->AlignmentMask;
1328 
1329  PortCapabilities->AlignmentMask = PortDeviceObject->AlignmentRequirement;
1330 
1331  if (PortCapabilities->MaximumPhysicalPages == 0)
1332  {
1333  PortCapabilities->MaximumPhysicalPages =
1334  BYTES_TO_PAGES(PortCapabilities->MaximumTransferLength);
1335 
1336  /* Apply miniport's limits */
1337  if (PortConfig->NumberOfPhysicalBreaks < PortCapabilities->MaximumPhysicalPages)
1338  {
1339  PortCapabilities->MaximumPhysicalPages = PortConfig->NumberOfPhysicalBreaks;
1340  }
1341  }
1342 
1343  FdoCallHWInitialize(DeviceExtension);
1344 
1345  Status = FdoStartAdapter(DeviceExtension);
1346 
1347  if (!NT_SUCCESS(Status))
1348  {
1349  DPRINT1("Failed to start the legacy adapter. Status 0x%x\n", Status);
1350  break;
1351  }
1352 
1353  FdoScanAdapter(DeviceExtension);
1354 
1355  FirstConfigCall = FALSE;
1356 
1357  /* Increase adapter number and bus number respectively */
1358  ConfigInfo.AdapterNumber++;
1359 
1360  if (!Again)
1361  ConfigInfo.BusNumber++;
1362 
1363  DPRINT("Bus: %lu MaxBus: %lu\n", ConfigInfo.BusNumber, MaxBus);
1364 
1365  DeviceFound = TRUE;
1366  }
1367 
1368  /* Clean up the mess */
1369  if (!NT_SUCCESS(Status) && PortDeviceObject)
1370  {
1371  FdoRemoveAdapter(DeviceExtension);
1372  }
1373 
1374  /* Close registry keys */
1375  if (ConfigInfo.ServiceKey != NULL)
1376  ZwClose(ConfigInfo.ServiceKey);
1377 
1378  if (ConfigInfo.DeviceKey != NULL)
1379  ZwClose(ConfigInfo.DeviceKey);
1380 
1381  if (ConfigInfo.BusKey != NULL)
1382  ZwClose(ConfigInfo.BusKey);
1383 
1384  if (ConfigInfo.AccessRanges != NULL)
1385  ExFreePool(ConfigInfo.AccessRanges);
1386 
1387  if (ConfigInfo.Parameter != NULL)
1388  ExFreePool(ConfigInfo.Parameter);
1389 
1390  DPRINT("ScsiPortInitialize() done, Status = 0x%08X, DeviceFound = %d!\n",
1391  Status, DeviceFound);
1392 
1393  return (DeviceFound == FALSE) ? Status : STATUS_SUCCESS;
1394 }
1395 
1396 /*
1397  * @unimplemented
1398  */
1399 VOID NTAPI
1400 ScsiPortIoMapTransfer(IN PVOID HwDeviceExtension,
1402  IN PVOID LogicalAddress,
1403  IN ULONG Length)
1404 {
1405  DPRINT1("ScsiPortIoMapTransfer()\n");
1406  UNIMPLEMENTED;
1407 }
1408 
1409 /*
1410  * @unimplemented
1411  */
1412 VOID NTAPI
1413 ScsiPortLogError(IN PVOID HwDeviceExtension,
1415  IN UCHAR PathId,
1416  IN UCHAR TargetId,
1417  IN UCHAR Lun,
1418  IN ULONG ErrorCode,
1419  IN ULONG UniqueId)
1420 {
1421  //PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
1422 
1423  DPRINT1("ScsiPortLogError() called\n");
1424  DPRINT1("PathId: 0x%02x TargetId: 0x%02x Lun: 0x%02x ErrorCode: 0x%08lx UniqueId: 0x%08lx\n",
1425  PathId, TargetId, Lun, ErrorCode, UniqueId);
1426 
1427  //DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, SCSI_PORT_DEVICE_EXTENSION, MiniPortDeviceExtension);
1428 
1429 
1430  DPRINT("ScsiPortLogError() done\n");
1431 }
1432 
1433 /*
1434  * @implemented
1435  */
1436 VOID NTAPI
1438  IN PVOID Source,
1439  IN ULONG Length)
1440 {
1442  Source,
1443  Length);
1444 }
1445 
1446 
1447 /*
1448  * @implemented
1449  */
1450 VOID
1452 {
1453  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
1454  va_list ap;
1455 
1456  DPRINT("ScsiPortNotification() called\n");
1457 
1458  DeviceExtension =
1459  CONTAINING_RECORD(HwDeviceExtension, SCSI_PORT_DEVICE_EXTENSION, MiniPortDeviceExtension);
1460 
1461  DPRINT("DeviceExtension %p\n", DeviceExtension);
1462 
1463  va_start(ap, HwDeviceExtension);
1464 
1465  switch (NotificationType)
1466  {
1467  case RequestComplete:
1468  {
1470  PSCSI_REQUEST_BLOCK_INFO SrbData;
1471 
1473 
1474  DPRINT("Notify: RequestComplete (Srb %p)\n", Srb);
1475 
1476  /* Make sure Srb is alright */
1478  ASSERT(
1481 
1482  if (!(Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE))
1483  {
1484  /* It's been already completed */
1485  va_end(ap);
1486  return;
1487  }
1488 
1489  /* It's not active anymore */
1491 
1493  {
1494  /* TODO: Treat it specially */
1495  ASSERT(FALSE);
1496  }
1497  else
1498  {
1500  PSCSI_PORT_LUN_EXTENSION LunExtension = IoStack->DeviceObject->DeviceExtension;
1501  ASSERT(LunExtension && !LunExtension->Common.IsFDO);
1502 
1503  /* Get the SRB data */
1504  SrbData = SpiGetSrbData(DeviceExtension, LunExtension, Srb->QueueTag);
1505 
1506  /* Make sure there are no CompletedRequests and there is a Srb */
1507  ASSERT(SrbData->CompletedRequests == NULL && SrbData->Srb != NULL);
1508 
1509  /* If it's a read/write request, make sure it has data inside it */
1510  if ((Srb->SrbStatus == SRB_STATUS_SUCCESS) &&
1511  ((Srb->Cdb[0] == SCSIOP_READ) || (Srb->Cdb[0] == SCSIOP_WRITE)))
1512  {
1514  }
1515 
1516  SrbData->CompletedRequests = DeviceExtension->InterruptData.CompletedRequests;
1517  DeviceExtension->InterruptData.CompletedRequests = SrbData;
1518  }
1519  }
1520  break;
1521 
1522  case NextRequest:
1523  DPRINT("Notify: NextRequest\n");
1524  DeviceExtension->InterruptData.Flags |= SCSI_PORT_NEXT_REQUEST_READY;
1525  break;
1526 
1527  case NextLuRequest:
1528  {
1529  UCHAR PathId;
1530  UCHAR TargetId;
1531  UCHAR Lun;
1532  PSCSI_PORT_LUN_EXTENSION LunExtension;
1533 
1534  PathId = (UCHAR)va_arg(ap, int);
1535  TargetId = (UCHAR)va_arg(ap, int);
1536  Lun = (UCHAR)va_arg(ap, int);
1537 
1538  DPRINT(
1539  "Notify: NextLuRequest(PathId %u TargetId %u Lun %u)\n", PathId, TargetId, Lun);
1540 
1541  /* Mark it in the flags field */
1542  DeviceExtension->InterruptData.Flags |= SCSI_PORT_NEXT_REQUEST_READY;
1543 
1544  /* Get the LUN extension */
1545  LunExtension = GetLunByPath(DeviceExtension, PathId, TargetId, Lun);
1546 
1547  /* If returned LunExtension is NULL, break out */
1548  if (!LunExtension)
1549  break;
1550 
1551  /* This request should not be processed if */
1552  if ((LunExtension->ReadyLun) || (LunExtension->SrbInfo.Srb))
1553  {
1554  /* Nothing to do here */
1555  break;
1556  }
1557 
1558  /* Add this LUN to the list */
1559  LunExtension->ReadyLun = DeviceExtension->InterruptData.ReadyLun;
1560  DeviceExtension->InterruptData.ReadyLun = LunExtension;
1561  }
1562  break;
1563 
1564  case ResetDetected:
1565  DPRINT("Notify: ResetDetected\n");
1566  /* Add RESET flags */
1567  DeviceExtension->InterruptData.Flags |= SCSI_PORT_RESET | SCSI_PORT_RESET_REPORTED;
1568  break;
1569 
1570  case CallDisableInterrupts:
1571  DPRINT1("UNIMPLEMENTED SCSI Notification called: CallDisableInterrupts!\n");
1572  break;
1573 
1574  case CallEnableInterrupts:
1575  DPRINT1("UNIMPLEMENTED SCSI Notification called: CallEnableInterrupts!\n");
1576  break;
1577 
1578  case RequestTimerCall:
1579  DPRINT("Notify: RequestTimerCall\n");
1580  DeviceExtension->InterruptData.Flags |= SCSI_PORT_TIMER_NEEDED;
1581  DeviceExtension->InterruptData.HwScsiTimer = (PHW_TIMER)va_arg(ap, PHW_TIMER);
1582  DeviceExtension->InterruptData.MiniportTimerValue = (ULONG)va_arg(ap, ULONG);
1583  break;
1584 
1585  case BusChangeDetected:
1586  DPRINT1("UNIMPLEMENTED SCSI Notification called: BusChangeDetected!\n");
1587  break;
1588 
1589  default:
1590  DPRINT1("Unsupported notification from WMI: %lu\n", NotificationType);
1591  break;
1592  }
1593 
1594  va_end(ap);
1595 
1596  /* Request a DPC after we're done with the interrupt */
1597  DeviceExtension->InterruptData.Flags |= SCSI_PORT_NOTIFICATION_NEEDED;
1598 }
1599 
1600 /*
1601  * @implemented
1602  */
1603 BOOLEAN NTAPI
1604 ScsiPortValidateRange(IN PVOID HwDeviceExtension,
1606  IN ULONG SystemIoBusNumber,
1607  IN SCSI_PHYSICAL_ADDRESS IoAddress,
1609  IN BOOLEAN InIoSpace)
1610 {
1611  DPRINT("ScsiPortValidateRange()\n");
1612  return(TRUE);
1613 }
1614 
1615 
1616 /* INTERNAL FUNCTIONS ********************************************************/
1617 
1618 static VOID
1620  IN PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor,
1622 {
1623  PACCESS_RANGE AccessRange;
1624  PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialData;
1625  ULONG RangeNumber;
1626  ULONG Index;
1627  ULONG Interrupt = 0;
1628  ULONG Dma = 0;
1629 
1630  RangeNumber = 0;
1631 
1632  /* Loop through all entries */
1633  for (Index = 0; Index < ResourceDescriptor->PartialResourceList.Count; Index++)
1634  {
1635  PartialData = &ResourceDescriptor->PartialResourceList.PartialDescriptors[Index];
1636 
1637  switch (PartialData->Type)
1638  {
1639  case CmResourceTypePort:
1640  /* Copy access ranges */
1641  if (RangeNumber < HwInitializationData->NumberOfAccessRanges)
1642  {
1643  AccessRange = &((*(PortConfig->AccessRanges))[RangeNumber]);
1644 
1645  AccessRange->RangeStart = PartialData->u.Port.Start;
1646  AccessRange->RangeLength = PartialData->u.Port.Length;
1647 
1648  AccessRange->RangeInMemory = FALSE;
1649  RangeNumber++;
1650  }
1651  break;
1652 
1653  case CmResourceTypeMemory:
1654  /* Copy access ranges */
1655  if (RangeNumber < HwInitializationData->NumberOfAccessRanges)
1656  {
1657  AccessRange = &((*(PortConfig->AccessRanges))[RangeNumber]);
1658 
1659  AccessRange->RangeStart = PartialData->u.Memory.Start;
1660  AccessRange->RangeLength = PartialData->u.Memory.Length;
1661 
1662  AccessRange->RangeInMemory = TRUE;
1663  RangeNumber++;
1664  }
1665  break;
1666 
1668 
1669  if (Interrupt == 0)
1670  {
1671  /* Copy interrupt data */
1672  PortConfig->BusInterruptLevel = PartialData->u.Interrupt.Level;
1673  PortConfig->BusInterruptVector = PartialData->u.Interrupt.Vector;
1674 
1675  /* Set interrupt mode accordingly to the resource */
1676  if (PartialData->Flags == CM_RESOURCE_INTERRUPT_LATCHED)
1677  {
1678  PortConfig->InterruptMode = Latched;
1679  }
1680  else if (PartialData->Flags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE)
1681  {
1682  PortConfig->InterruptMode = LevelSensitive;
1683  }
1684  }
1685  else if (Interrupt == 1)
1686  {
1687  /* Copy interrupt data */
1688  PortConfig->BusInterruptLevel2 = PartialData->u.Interrupt.Level;
1689  PortConfig->BusInterruptVector2 = PartialData->u.Interrupt.Vector;
1690 
1691  /* Set interrupt mode accordingly to the resource */
1692  if (PartialData->Flags == CM_RESOURCE_INTERRUPT_LATCHED)
1693  {
1694  PortConfig->InterruptMode2 = Latched;
1695  }
1696  else if (PartialData->Flags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE)
1697  {
1698  PortConfig->InterruptMode2 = LevelSensitive;
1699  }
1700  }
1701 
1702  Interrupt++;
1703  break;
1704 
1705  case CmResourceTypeDma:
1706 
1707  if (Dma == 0)
1708  {
1709  PortConfig->DmaChannel = PartialData->u.Dma.Channel;
1710  PortConfig->DmaPort = PartialData->u.Dma.Port;
1711 
1712  if (PartialData->Flags & CM_RESOURCE_DMA_8)
1713  PortConfig->DmaWidth = Width8Bits;
1714  else if ((PartialData->Flags & CM_RESOURCE_DMA_16) ||
1715  (PartialData->Flags & CM_RESOURCE_DMA_8_AND_16)) //???
1716  PortConfig->DmaWidth = Width16Bits;
1717  else if (PartialData->Flags & CM_RESOURCE_DMA_32)
1718  PortConfig->DmaWidth = Width32Bits;
1719  }
1720  else if (Dma == 1)
1721  {
1722  PortConfig->DmaChannel2 = PartialData->u.Dma.Channel;
1723  PortConfig->DmaPort2 = PartialData->u.Dma.Port;
1724 
1725  if (PartialData->Flags & CM_RESOURCE_DMA_8)
1726  PortConfig->DmaWidth2 = Width8Bits;
1727  else if ((PartialData->Flags & CM_RESOURCE_DMA_16) ||
1728  (PartialData->Flags & CM_RESOURCE_DMA_8_AND_16)) //???
1729  PortConfig->DmaWidth2 = Width16Bits;
1730  else if (PartialData->Flags & CM_RESOURCE_DMA_32)
1731  PortConfig->DmaWidth2 = Width32Bits;
1732  }
1733  break;
1734  }
1735  }
1736 }
1737 
1738 static PCM_RESOURCE_LIST
1741 {
1742  PCONFIGURATION_INFORMATION ConfigInfo;
1744  PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
1745  PACCESS_RANGE AccessRange;
1746  ULONG ListLength = 0, i, FullSize;
1747  ULONG Interrupt, Dma;
1748 
1749  /* Get current Atdisk usage from the system */
1750  ConfigInfo = IoGetConfigurationInformation();
1751 
1752  if (PortConfig->AtdiskPrimaryClaimed)
1753  ConfigInfo->AtDiskPrimaryAddressClaimed = TRUE;
1754 
1755  if (PortConfig->AtdiskSecondaryClaimed)
1756  ConfigInfo->AtDiskSecondaryAddressClaimed = TRUE;
1757 
1758  /* Do we use DMA? */
1759  if (PortConfig->DmaChannel != SP_UNINITIALIZED_VALUE ||
1760  PortConfig->DmaPort != SP_UNINITIALIZED_VALUE)
1761  {
1762  Dma = 1;
1763 
1764  if (PortConfig->DmaChannel2 != SP_UNINITIALIZED_VALUE ||
1765  PortConfig->DmaPort2 != SP_UNINITIALIZED_VALUE)
1766  Dma++;
1767  }
1768  else
1769  {
1770  Dma = 0;
1771  }
1772  ListLength += Dma;
1773 
1774  /* How many interrupts to we have? */
1775  Interrupt = DeviceExtension->InterruptCount;
1776  ListLength += Interrupt;
1777 
1778  /* How many access ranges do we use? */
1779  AccessRange = &((*(PortConfig->AccessRanges))[0]);
1780  for (i = 0; i < PortConfig->NumberOfAccessRanges; i++)
1781  {
1782  if (AccessRange->RangeLength != 0)
1783  ListLength++;
1784 
1785  AccessRange++;
1786  }
1787 
1788  /* Allocate the resource list, since we know its size now */
1789  FullSize = sizeof(CM_RESOURCE_LIST) + (ListLength - 1) *
1791 
1793 
1794  if (!ResourceList)
1795  return NULL;
1796 
1797  /* Zero it */
1798  RtlZeroMemory(ResourceList, FullSize);
1799 
1800  /* Initialize it */
1801  ResourceList->Count = 1;
1802  ResourceList->List[0].InterfaceType = PortConfig->AdapterInterfaceType;
1803  ResourceList->List[0].BusNumber = PortConfig->SystemIoBusNumber;
1804  ResourceList->List[0].PartialResourceList.Count = ListLength;
1805  ResourceDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors;
1806 
1807  /* Copy access ranges array over */
1808  for (i = 0; i < PortConfig->NumberOfAccessRanges; i++)
1809  {
1810  AccessRange = &((*(PortConfig->AccessRanges))[i]);
1811 
1812  /* If the range is empty - skip it */
1813  if (AccessRange->RangeLength == 0)
1814  continue;
1815 
1816  if (AccessRange->RangeInMemory)
1817  {
1818  ResourceDescriptor->Type = CmResourceTypeMemory;
1819  ResourceDescriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
1820  }
1821  else
1822  {
1823  ResourceDescriptor->Type = CmResourceTypePort;
1824  ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;
1825  }
1826 
1827  ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1828 
1829  ResourceDescriptor->u.Memory.Start = AccessRange->RangeStart;
1830  ResourceDescriptor->u.Memory.Length = AccessRange->RangeLength;
1831 
1832  ResourceDescriptor++;
1833  }
1834 
1835  /* If we use interrupt(s), copy them */
1836  while (Interrupt)
1837  {
1838  ResourceDescriptor->Type = CmResourceTypeInterrupt;
1839 
1840  if (PortConfig->AdapterInterfaceType == MicroChannel ||
1841  ((Interrupt == 2) ? PortConfig->InterruptMode2 : PortConfig->InterruptMode) == LevelSensitive)
1842  {
1843  ResourceDescriptor->ShareDisposition = CmResourceShareShared;
1844  ResourceDescriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
1845  }
1846  else
1847  {
1848  ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1849  ResourceDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
1850  }
1851 
1852  ResourceDescriptor->u.Interrupt.Level = (Interrupt == 2) ? PortConfig->BusInterruptLevel2 : PortConfig->BusInterruptLevel;
1853  ResourceDescriptor->u.Interrupt.Vector = (Interrupt == 2) ? PortConfig->BusInterruptVector2 : PortConfig->BusInterruptVector;
1854  ResourceDescriptor->u.Interrupt.Affinity = 0;
1855 
1856  ResourceDescriptor++;
1857  Interrupt--;
1858  }
1859 
1860  /* Copy DMA data */
1861  while (Dma)
1862  {
1863  ResourceDescriptor->Type = CmResourceTypeDma;
1864  ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1865  ResourceDescriptor->u.Dma.Channel = (Dma == 2) ? PortConfig->DmaChannel2 : PortConfig->DmaChannel;
1866  ResourceDescriptor->u.Dma.Port = (Dma == 2) ? PortConfig->DmaPort2 : PortConfig->DmaPort;
1867  ResourceDescriptor->Flags = 0;
1868 
1869  if (((Dma == 2) ? PortConfig->DmaWidth2 : PortConfig->DmaWidth) == Width8Bits)
1870  ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8;
1871  else if (((Dma == 2) ? PortConfig->DmaWidth2 : PortConfig->DmaWidth) == Width16Bits)
1872  ResourceDescriptor->Flags |= CM_RESOURCE_DMA_16;
1873  else
1874  ResourceDescriptor->Flags |= CM_RESOURCE_DMA_32;
1875 
1876  if (((Dma == 2) ? PortConfig->DmaChannel2 : PortConfig->DmaChannel) == SP_UNINITIALIZED_VALUE)
1877  ResourceDescriptor->u.Dma.Channel = 0;
1878 
1879  if (((Dma == 2) ? PortConfig->DmaPort2 : PortConfig->DmaPort) == SP_UNINITIALIZED_VALUE)
1880  ResourceDescriptor->u.Dma.Port = 0;
1881 
1882  ResourceDescriptor++;
1883  Dma--;
1884  }
1885 
1886  return ResourceList;
1887 }
1888 
1889 
1890 static BOOLEAN
1896  IN ULONG BusNumber,
1897  IN OUT PPCI_SLOT_NUMBER NextSlotNumber)
1898 {
1899  PCI_COMMON_CONFIG PciConfig;
1901  ULONG DataSize;
1903  ULONG FunctionNumber;
1904  CHAR VendorIdString[8];
1905  CHAR DeviceIdString[8];
1906  UNICODE_STRING UnicodeStr;
1908  NTSTATUS Status;
1909 
1910  DPRINT ("SpiGetPciConfiguration() called\n");
1911 
1912  SlotNumber.u.AsULONG = 0;
1913 
1914  /* Loop through all devices */
1915  for (DeviceNumber = NextSlotNumber->u.bits.DeviceNumber; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++)
1916  {
1917  SlotNumber.u.bits.DeviceNumber = DeviceNumber;
1918 
1919  /* Loop through all functions */
1920  for (FunctionNumber = NextSlotNumber->u.bits.FunctionNumber; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++)
1921  {
1922  SlotNumber.u.bits.FunctionNumber = FunctionNumber;
1923 
1924  /* Get PCI config bytes */
1926  BusNumber,
1927  SlotNumber.u.AsULONG,
1928  &PciConfig,
1929  sizeof(ULONG));
1930 
1931  /* If result of HalGetBusData is 0, then the bus is wrong */
1932  if (DataSize == 0)
1933  return FALSE;
1934 
1935  /* Check if result is PCI_INVALID_VENDORID or too small */
1936  if ((DataSize < sizeof(ULONG)) ||
1937  (PciConfig.VendorID == PCI_INVALID_VENDORID))
1938  {
1939  /* Continue to try the next function */
1940  continue;
1941  }
1942 
1943  sprintf (VendorIdString, "%04hx", PciConfig.VendorID);
1944  sprintf (DeviceIdString, "%04hx", PciConfig.DeviceID);
1945 
1946  if (_strnicmp(VendorIdString, HwInitializationData->VendorId, HwInitializationData->VendorIdLength) ||
1947  _strnicmp(DeviceIdString, HwInitializationData->DeviceId, HwInitializationData->DeviceIdLength))
1948  {
1949  /* It is not our device */
1950  continue;
1951  }
1952 
1953  DPRINT("Found device 0x%04hx 0x%04hx at %1lu %2lu %1lu\n",
1954  PciConfig.VendorID,
1955  PciConfig.DeviceID,
1956  BusNumber,
1957  SlotNumber.u.bits.DeviceNumber,
1958  SlotNumber.u.bits.FunctionNumber);
1959 
1960 
1961  RtlInitUnicodeString(&UnicodeStr, L"ScsiAdapter");
1963  &UnicodeStr,
1964  DriverObject,
1965  DeviceObject,
1966  PCIBus,
1967  BusNumber,
1968  SlotNumber.u.AsULONG,
1969  &ResourceList);
1970 
1971  if (!NT_SUCCESS(Status))
1972  break;
1973 
1974  /* Create configuration information */
1976  ResourceList->List,
1977  PortConfig);
1978 
1979  /* Free the resource list */
1981 
1982  /* Set dev & fn numbers */
1983  NextSlotNumber->u.bits.DeviceNumber = DeviceNumber;
1984  NextSlotNumber->u.bits.FunctionNumber = FunctionNumber + 1;
1985 
1986  /* Save the slot number */
1987  PortConfig->SlotNumber = SlotNumber.u.AsULONG;
1988 
1989  return TRUE;
1990  }
1991  NextSlotNumber->u.bits.FunctionNumber = 0;
1992  }
1993 
1994  NextSlotNumber->u.bits.DeviceNumber = 0;
1995  DPRINT ("No device found\n");
1996 
1997  return FALSE;
1998 }
1999 
2000 
2001 
2002 /**********************************************************************
2003  * NAME INTERNAL
2004  * ScsiPortCreateClose
2005  *
2006  * DESCRIPTION
2007  * Answer requests for Create/Close calls: a null operation.
2008  *
2009  * RUN LEVEL
2010  * PASSIVE_LEVEL
2011  *
2012  * ARGUMENTS
2013  * DeviceObject
2014  * Pointer to a device object.
2015  *
2016  * Irp
2017  * Pointer to an IRP.
2018  *
2019  * RETURN VALUE
2020  * Status.
2021  */
2022 
2023 static NTSTATUS NTAPI
2025  IN PIRP Irp)
2026 {
2027  DPRINT("ScsiPortCreateClose()\n");
2028 
2029  Irp->IoStatus.Status = STATUS_SUCCESS;
2031 
2032  return STATUS_SUCCESS;
2033 }
2034 
2036 NTAPI
2038  PIRP Irp,
2040  PVOID Context)
2041 {
2043  PSCSI_SG_ADDRESS ScatterGatherList;
2044  KIRQL CurrentIrql;
2045  PIO_STACK_LOCATION IrpStack;
2046  ULONG TotalLength = 0;
2047  PSCSI_REQUEST_BLOCK_INFO SrbInfo;
2048  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
2049  PUCHAR DataVA;
2051 
2052  /* Get pointers to SrbInfo and DeviceExtension */
2053  SrbInfo = (PSCSI_REQUEST_BLOCK_INFO)Context;
2054  DeviceExtension = DeviceObject->DeviceExtension;
2055 
2056  /* Get pointer to SRB */
2057  IrpStack = IoGetCurrentIrpStackLocation(Irp);
2058  Srb = (PSCSI_REQUEST_BLOCK)IrpStack->Parameters.Others.Argument1;
2059 
2060  /* Depending on the map registers number, we allocate
2061  either from NonPagedPool, or from our static list */
2062  if (SrbInfo->NumberOfMapRegisters > MAX_SG_LIST)
2063  {
2066 
2067  if (SrbInfo->ScatterGather == NULL)
2068  ASSERT(FALSE);
2069 
2071  }
2072  else
2073  {
2074  SrbInfo->ScatterGather = SrbInfo->ScatterGatherList;
2075  }
2076 
2077  /* Use chosen SG list source */
2078  ScatterGatherList = SrbInfo->ScatterGather;
2079 
2080  /* Save map registers base */
2082 
2083  /* Determine WriteToDevice flag */
2085 
2086  /* Get virtual address of the data buffer */
2087  DataVA = (PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress) +
2088  ((PCHAR)Srb->DataBuffer - SrbInfo->DataOffset);
2089 
2090  /* Build the actual SG list */
2091  while (TotalLength < Srb->DataTransferLength)
2092  {
2093  if (!ScatterGatherList)
2094  break;
2095 
2096  ScatterGatherList->Length = Srb->DataTransferLength - TotalLength;
2097  ScatterGatherList->PhysicalAddress = IoMapTransfer(DeviceExtension->AdapterObject,
2098  Irp->MdlAddress,
2100  DataVA + TotalLength,
2101  &ScatterGatherList->Length,
2102  WriteToDevice);
2103 
2104  TotalLength += ScatterGatherList->Length;
2105  ScatterGatherList++;
2106  }
2107 
2108  /* Schedule an active request */
2109  InterlockedIncrement(&DeviceExtension->ActiveRequestCounter );
2110  KeAcquireSpinLock(&DeviceExtension->SpinLock, &CurrentIrql);
2111  KeSynchronizeExecution(DeviceExtension->Interrupt[0],
2113  DeviceObject);
2114  KeReleaseSpinLock(&DeviceExtension->SpinLock, CurrentIrql);
2115 
2117 }
2118 
2119 BOOLEAN
2120 NTAPI
2124 {
2125  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
2126 
2127  DPRINT("ScsiPortIsr() called!\n");
2128 
2129  DeviceExtension = (PSCSI_PORT_DEVICE_EXTENSION)ServiceContext;
2130 
2131  /* If interrupts are disabled - we don't expect any */
2132  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_DISABLE_INTERRUPTS)
2133  return FALSE;
2134 
2135  /* Call miniport's HwInterrupt routine */
2136  if (DeviceExtension->HwInterrupt(&DeviceExtension->MiniPortDeviceExtension) == FALSE)
2137  {
2138  /* This interrupt doesn't belong to us */
2139  return FALSE;
2140  }
2141 
2142  /* If flag of notification is set - queue a DPC */
2143  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
2144  {
2145  IoRequestDpc(DeviceExtension->Common.DeviceObject,
2146  DeviceExtension->CurrentIrp,
2147  DeviceExtension);
2148  }
2149 
2150  return TRUE;
2151 }
2152 
2153 BOOLEAN
2154 NTAPI
2156 {
2158  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
2159  ULONG Bus;
2160 
2161  DPRINT("SpiProcessTimeout() entered\n");
2162 
2163  DeviceExtension->TimerCount = -1;
2164 
2165  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_RESET)
2166  {
2167  DeviceExtension->InterruptData.Flags &= ~SCSI_PORT_RESET;
2168 
2169  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_RESET_REQUEST)
2170  {
2171  DeviceExtension->InterruptData.Flags &= ~SCSI_PORT_RESET_REQUEST;
2173  }
2174 
2175  return FALSE;
2176  }
2177  else
2178  {
2179  DPRINT("Resetting the bus\n");
2180 
2181  for (Bus = 0; Bus < DeviceExtension->NumberOfBuses; Bus++)
2182  {
2183  DeviceExtension->HwResetBus(DeviceExtension->MiniPortDeviceExtension, Bus);
2184 
2185  /* Reset flags and set reset timeout to 4 seconds */
2186  DeviceExtension->InterruptData.Flags |= SCSI_PORT_RESET;
2187  DeviceExtension->TimerCount = 4;
2188  }
2189 
2190  /* If miniport requested - request a dpc for it */
2191  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
2192  IoRequestDpc(DeviceExtension->Common.DeviceObject, NULL, NULL);
2193  }
2194 
2195  return TRUE;
2196 }
2197 
2198 
2199 BOOLEAN
2200 NTAPI
2202 {
2204  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
2205 
2206  /* Perform the bus reset */
2207  DeviceExtension = (PSCSI_PORT_DEVICE_EXTENSION)ResetParams->DeviceExtension;
2208  DeviceExtension->HwResetBus(DeviceExtension->MiniPortDeviceExtension,
2209  ResetParams->PathId);
2210 
2211  /* Set flags and start the timer */
2212  DeviceExtension->InterruptData.Flags |= SCSI_PORT_RESET;
2213  DeviceExtension->TimerCount = 4;
2214 
2215  /* If miniport requested - give him a DPC */
2216  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
2217  IoRequestDpc(DeviceExtension->Common.DeviceObject, NULL, NULL);
2218 
2219  return TRUE;
2220 }
2221 
2222 // ScsiPortIoTimer
2223 // DESCRIPTION:
2224 // This function handles timeouts and other time delayed processing
2225 //
2226 // RUN LEVEL:
2227 //
2228 // ARGUMENTS:
2229 // IN PDEVICE_OBJECT DeviceObject Device object registered with timer
2230 // IN PVOID Context the Controller extension for the
2231 // controller the device is on
2232 //
2233 static VOID NTAPI
2235  PVOID Context)
2236 {
2237  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
2238  PSCSI_PORT_LUN_EXTENSION LunExtension;
2239  PIRP Irp;
2240 
2241  DPRINT("ScsiPortIoTimer()\n");
2242 
2243  DeviceExtension = (PSCSI_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
2244 
2245  /* Protect with the spinlock */
2246  KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
2247 
2248  /* Check timeouts */
2249  if (DeviceExtension->TimerCount > 0)
2250  {
2251  /* Decrease the timeout counter */
2252  DeviceExtension->TimerCount--;
2253 
2254  if (DeviceExtension->TimerCount == 0)
2255  {
2256  /* Timeout, process it */
2257  if (KeSynchronizeExecution(DeviceExtension->Interrupt[0],
2259  DeviceExtension->Common.DeviceObject))
2260  {
2261  DPRINT("Error happened during processing timeout, but nothing critical\n");
2262  }
2263  }
2264 
2265  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
2266 
2267  /* We should exit now, since timeout is processed */
2268  return;
2269  }
2270 
2271  /* Per-Lun scanning of timeouts is needed... */
2272  for (UINT8 pathId = 0; pathId < DeviceExtension->NumberOfBuses; pathId++)
2273  {
2274  PSCSI_BUS_INFO bus = &DeviceExtension->Buses[pathId];
2275 
2276  for (PLIST_ENTRY lunEntry = bus->LunsListHead.Flink;
2277  lunEntry != &bus->LunsListHead;
2278  lunEntry = lunEntry->Flink)
2279  {
2280  LunExtension = CONTAINING_RECORD(lunEntry, SCSI_PORT_LUN_EXTENSION, LunEntry);
2281 
2282  if (LunExtension->Flags & LUNEX_BUSY)
2283  {
2284  if (!(LunExtension->Flags &
2286  {
2287  DPRINT("Retrying busy request\n");
2288 
2289  /* Clear flags, and retry busy request */
2290  LunExtension->Flags &= ~(LUNEX_BUSY | LUNEX_FULL_QUEUE);
2291  Irp = LunExtension->BusyRequest;
2292 
2293  /* Clearing busy request */
2294  LunExtension->BusyRequest = NULL;
2295 
2296  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
2297 
2299 
2300  KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
2301  }
2302  }
2303  else if (LunExtension->RequestTimeout == 0)
2304  {
2305  RESETBUS_PARAMS ResetParams;
2306 
2307  LunExtension->RequestTimeout = -1;
2308 
2309  DPRINT("Request timed out, resetting bus\n");
2310 
2311  /* Pass params to the bus reset routine */
2312  ResetParams.PathId = LunExtension->PathId;
2313  ResetParams.DeviceExtension = DeviceExtension;
2314 
2315  if (!KeSynchronizeExecution(DeviceExtension->Interrupt[0],
2316  SpiResetBus,
2317  &ResetParams))
2318  {
2319  DPRINT1("Reset failed\n");
2320  }
2321  }
2322  else if (LunExtension->RequestTimeout > 0)
2323  {
2324  /* Decrement the timeout counter */
2325  LunExtension->RequestTimeout--;
2326  }
2327  }
2328  }
2329 
2330  /* Release the spinlock */
2331  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
2332 }
2333 
2334 VOID
2335 NTAPI
2340 {
2341  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
2342 
2343  DPRINT("Miniport timer DPC\n");
2344 
2345  DeviceExtension = ((PDEVICE_OBJECT)DeviceObject)->DeviceExtension;
2346 
2347  /* Acquire the spinlock */
2348  KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
2349 
2350  /* Call the timer routine */
2351  if (DeviceExtension->HwScsiTimer != NULL)
2352  {
2353  DeviceExtension->HwScsiTimer(&DeviceExtension->MiniPortDeviceExtension);
2354  }
2355 
2356  /* Release the spinlock */
2357  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
2358 
2359  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
2360  {
2362  DeviceExtension->Common.DeviceObject,
2363  NULL,
2364  NULL);
2365  }
2366 }
2367 
2368 static NTSTATUS
2370  PHW_INITIALIZATION_DATA HwInitData,
2371  PCONFIGURATION_INFO InternalConfigInfo,
2373  BOOLEAN ZeroStruct)
2374 {
2377  PCONFIGURATION_INFORMATION DdkConfigInformation;
2378  HANDLE RootKey, Key;
2379  BOOLEAN Found;
2380  WCHAR DeviceBuffer[16];
2381  WCHAR StrBuffer[512];
2382  ULONG Bus;
2383  NTSTATUS Status;
2384 
2385  /* Zero out the struct if told so */
2386  if (ZeroStruct)
2387  {
2388  /* First zero the portconfig */
2389  RtlZeroMemory(ConfigInfo, sizeof(PORT_CONFIGURATION_INFORMATION));
2390 
2391  /* Then access ranges */
2392  RtlZeroMemory(InternalConfigInfo->AccessRanges,
2393  HwInitData->NumberOfAccessRanges * sizeof(ACCESS_RANGE));
2394 
2395  /* Initialize the struct */
2396  ConfigInfo->Length = sizeof(PORT_CONFIGURATION_INFORMATION);
2397  ConfigInfo->AdapterInterfaceType = HwInitData->AdapterInterfaceType;
2398  ConfigInfo->InterruptMode = Latched;
2399  ConfigInfo->DmaChannel = SP_UNINITIALIZED_VALUE;
2400  ConfigInfo->DmaPort = SP_UNINITIALIZED_VALUE;
2401  ConfigInfo->DmaChannel2 = SP_UNINITIALIZED_VALUE;
2402  ConfigInfo->DmaPort2 = SP_UNINITIALIZED_VALUE;
2404  ConfigInfo->NumberOfAccessRanges = HwInitData->NumberOfAccessRanges;
2405  ConfigInfo->MaximumNumberOfTargets = 8;
2406 
2407  /* Store parameters */
2408  ConfigInfo->NeedPhysicalAddresses = HwInitData->NeedPhysicalAddresses;
2409  ConfigInfo->MapBuffers = HwInitData->MapBuffers;
2410  ConfigInfo->AutoRequestSense = HwInitData->AutoRequestSense;
2411  ConfigInfo->ReceiveEvent = HwInitData->ReceiveEvent;
2412  ConfigInfo->TaggedQueuing = HwInitData->TaggedQueuing;
2413  ConfigInfo->MultipleRequestPerLu = HwInitData->MultipleRequestPerLu;
2414 
2415  /* Get the disk usage */
2416  DdkConfigInformation = IoGetConfigurationInformation();
2417  ConfigInfo->AtdiskPrimaryClaimed = DdkConfigInformation->AtDiskPrimaryAddressClaimed;
2418  ConfigInfo->AtdiskSecondaryClaimed = DdkConfigInformation->AtDiskSecondaryAddressClaimed;
2419 
2420  /* Initiator bus id is not set */
2421  for (Bus = 0; Bus < 8; Bus++)
2422  ConfigInfo->InitiatorBusId[Bus] = (CCHAR)SP_UNINITIALIZED_VALUE;
2423  }
2424 
2425  ConfigInfo->NumberOfPhysicalBreaks = 17;
2426 
2427  /* Clear this information */
2428  InternalConfigInfo->DisableTaggedQueueing = FALSE;
2429  InternalConfigInfo->DisableMultipleLun = FALSE;
2430 
2431  /* Store Bus Number */
2432  ConfigInfo->SystemIoBusNumber = InternalConfigInfo->BusNumber;
2433 
2434 TryNextAd:
2435 
2436  if (ConfigInfo->AdapterInterfaceType == Internal)
2437  {
2438  /* Open registry key for HW database */
2440  DeviceExtension->Common.DeviceObject->DriverObject->HardwareDatabase,
2442  NULL,
2443  NULL);
2444 
2445  Status = ZwOpenKey(&RootKey,
2446  KEY_READ,
2447  &ObjectAttributes);
2448 
2449  if (NT_SUCCESS(Status))
2450  {
2451  /* Create name for it */
2452  swprintf(StrBuffer, L"ScsiAdapter\\%lu",
2453  InternalConfigInfo->AdapterNumber);
2454 
2455  RtlInitUnicodeString(&UnicodeString, StrBuffer);
2456 
2457  /* Open device key */
2459  &UnicodeString,
2461  RootKey,
2462  NULL);
2463 
2464  Status = ZwOpenKey(&Key,
2465  KEY_READ,
2466  &ObjectAttributes);
2467 
2468  ZwClose(RootKey);
2469 
2470  if (NT_SUCCESS(Status))
2471  {
2472  if (InternalConfigInfo->LastAdapterNumber != InternalConfigInfo->AdapterNumber)
2473  {
2474  DPRINT("Hardware info found at %S\n", StrBuffer);
2475 
2476  /* Parse it */
2477  SpiParseDeviceInfo(DeviceExtension,
2478  Key,
2479  ConfigInfo,
2480  InternalConfigInfo,
2481  (PUCHAR)StrBuffer);
2482 
2483  InternalConfigInfo->BusNumber = 0;
2484  }
2485  else
2486  {
2487  /* Try the next adapter */
2488  InternalConfigInfo->AdapterNumber++;
2489  goto TryNextAd;
2490  }
2491  }
2492  else
2493  {
2494  /* Info was not found, exit */
2495  DPRINT("ZwOpenKey() failed with Status=0x%08X\n", Status);
2497  }
2498  }
2499  else
2500  {
2501  DPRINT1("ZwOpenKey() failed with Status=0x%08X\n", Status);
2502  }
2503  }
2504 
2505  /* Look at device params */
2506  Key = NULL;
2507  if (InternalConfigInfo->Parameter)
2508  {
2509  ExFreePool(InternalConfigInfo->Parameter);
2510  InternalConfigInfo->Parameter = NULL;
2511  }
2512 
2513  if (InternalConfigInfo->ServiceKey != NULL)
2514  {
2515  swprintf(DeviceBuffer, L"Device%lu", InternalConfigInfo->AdapterNumber);
2516  RtlInitUnicodeString(&UnicodeString, DeviceBuffer);
2517 
2518  /* Open the service key */
2520  &UnicodeString,
2522  InternalConfigInfo->ServiceKey,
2523  NULL);
2524 
2525  Status = ZwOpenKey(&Key,
2526  KEY_READ,
2527  &ObjectAttributes);
2528  }
2529 
2530  /* Parse device key */
2531  if (InternalConfigInfo->DeviceKey != NULL)
2532  {
2533  SpiParseDeviceInfo(DeviceExtension,
2534  InternalConfigInfo->DeviceKey,
2535  ConfigInfo,
2536  InternalConfigInfo,
2537  (PUCHAR)StrBuffer);
2538  }
2539 
2540  /* Then parse hw info */
2541  if (Key != NULL)
2542  {
2543  if (InternalConfigInfo->LastAdapterNumber != InternalConfigInfo->AdapterNumber)
2544  {
2545  SpiParseDeviceInfo(DeviceExtension,
2546  Key,
2547  ConfigInfo,
2548  InternalConfigInfo,
2549  (PUCHAR)StrBuffer);
2550 
2551  /* Close the key */
2552  ZwClose(Key);
2553  }
2554  else
2555  {
2556  /* Adapter not found, go try the next one */
2557  InternalConfigInfo->AdapterNumber++;
2558 
2559  /* Close the key */
2560  ZwClose(Key);
2561 
2562  goto TryNextAd;
2563  }
2564  }
2565 
2566  /* Update the last adapter number */
2567  InternalConfigInfo->LastAdapterNumber = InternalConfigInfo->AdapterNumber;
2568 
2569  /* Do we have this kind of bus at all? */
2570  Found = FALSE;
2572  &InternalConfigInfo->BusNumber,
2573  NULL,
2574  NULL,
2575  NULL,
2576  NULL,
2578  &Found);
2579 
2580  /* This bus was not found */
2581  if (!Found)
2582  {
2584 
2585  /* Check for EISA */
2586  if (HwInitData->AdapterInterfaceType == Isa)
2587  {
2589  &InternalConfigInfo->BusNumber,
2590  NULL,
2591  NULL,
2592  NULL,
2593  NULL,
2595  &Found);
2596 
2597  /* Return respectively */
2598  if (Found)
2599  return STATUS_SUCCESS;
2600  else
2602  }
2603  else
2604  {
2606  }
2607  }
2608  else
2609  {
2610  return STATUS_SUCCESS;
2611  }
2612 }
2613 
2614 static VOID
2616  IN HANDLE Key,
2618  IN PCONFIGURATION_INFO InternalConfigInfo,
2619  IN PUCHAR Buffer)
2620 {
2621  PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
2622  PCM_FULL_RESOURCE_DESCRIPTOR FullResource;
2623  PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
2624  PCM_SCSI_DEVICE_DATA ScsiDeviceData;
2625  ULONG Length, Count, Dma = 0, Interrupt = 0;
2626  ULONG Index = 0, RangeCount = 0;
2630 
2631 
2632  KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION) Buffer;
2633 
2634  /* Loop through all values in the device node */
2635  while(TRUE)
2636  {
2637  Status = ZwEnumerateValueKey(Key,
2638  Index,
2640  Buffer,
2641  512,
2642  &Length);
2643 
2644  if (!NT_SUCCESS(Status))
2645  return;
2646 
2647  Index++;
2648 
2649  /* Length for DWORD is ok? */
2650  if (KeyValueInformation->Type == REG_DWORD &&
2651  KeyValueInformation->DataLength != sizeof(ULONG))
2652  {
2653  continue;
2654  }
2655 
2656  /* Get MaximumLogicalUnit */
2657  if (_wcsnicmp(KeyValueInformation->Name, L"MaximumLogicalUnit",
2658  KeyValueInformation->NameLength/2) == 0)
2659  {
2660 
2661  if (KeyValueInformation->Type != REG_DWORD)
2662  {
2663  DPRINT("Bad data type for MaximumLogicalUnit\n");
2664  continue;
2665  }
2666 
2667  DeviceExtension->MaxLunCount = *((PUCHAR)
2668  (Buffer + KeyValueInformation->DataOffset));
2669 
2670  /* Check / reset if needed */
2671  if (DeviceExtension->MaxLunCount > SCSI_MAXIMUM_LOGICAL_UNITS)
2672  DeviceExtension->MaxLunCount = SCSI_MAXIMUM_LOGICAL_UNITS;
2673 
2674  DPRINT("MaximumLogicalUnit = %d\n", DeviceExtension->MaxLunCount);
2675  }
2676 
2677  /* Get InitiatorTargetId */
2678  if (_wcsnicmp(KeyValueInformation->Name, L"InitiatorTargetId",
2679  KeyValueInformation->NameLength / 2) == 0)
2680  {
2681 
2682  if (KeyValueInformation->Type != REG_DWORD)
2683  {
2684  DPRINT("Bad data type for InitiatorTargetId\n");
2685  continue;
2686  }
2687 
2688  ConfigInfo->InitiatorBusId[0] = *((PUCHAR)
2689  (Buffer + KeyValueInformation->DataOffset));
2690 
2691  /* Check / reset if needed */
2692  if (ConfigInfo->InitiatorBusId[0] > ConfigInfo->MaximumNumberOfTargets - 1)
2693  ConfigInfo->InitiatorBusId[0] = (CCHAR)-1;
2694 
2695  DPRINT("InitiatorTargetId = %d\n", ConfigInfo->InitiatorBusId[0]);
2696  }
2697 
2698  /* Get ScsiDebug */
2699  if (_wcsnicmp(KeyValueInformation->Name, L"ScsiDebug",
2700  KeyValueInformation->NameLength/2) == 0)
2701  {
2702  DPRINT("ScsiDebug key not supported\n");
2703  }
2704 
2705  /* Check for a breakpoint */
2706  if (_wcsnicmp(KeyValueInformation->Name, L"BreakPointOnEntry",
2707  KeyValueInformation->NameLength/2) == 0)
2708  {
2709  DPRINT1("Breakpoint on entry requested!\n");
2710  DbgBreakPoint();
2711  }
2712 
2713  /* Get DisableSynchronousTransfers */
2714  if (_wcsnicmp(KeyValueInformation->Name, L"DisableSynchronousTransfers",
2715  KeyValueInformation->NameLength/2) == 0)
2716  {
2717  DeviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
2718  DPRINT("Synch transfers disabled\n");
2719  }
2720 
2721  /* Get DisableDisconnects */
2722  if (_wcsnicmp(KeyValueInformation->Name, L"DisableDisconnects",
2723  KeyValueInformation->NameLength/2) == 0)
2724  {
2725  DeviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_DISCONNECT;
2726  DPRINT("Disconnects disabled\n");
2727  }
2728 
2729  /* Get DisableTaggedQueuing */
2730  if (_wcsnicmp(KeyValueInformation->Name, L"DisableTaggedQueuing",
2731  KeyValueInformation->NameLength/2) == 0)
2732  {
2733  InternalConfigInfo->DisableTaggedQueueing = TRUE;
2734  DPRINT("Tagged queueing disabled\n");
2735  }
2736 
2737  /* Get DisableMultipleRequests */
2738  if (_wcsnicmp(KeyValueInformation->Name, L"DisableMultipleRequests",
2739  KeyValueInformation->NameLength/2) == 0)
2740  {
2741  InternalConfigInfo->DisableMultipleLun = TRUE;
2742  DPRINT("Multiple requests disabled\n");
2743  }
2744 
2745  /* Get DriverParameters */
2746  if (_wcsnicmp(KeyValueInformation->Name, L"DriverParameters",
2747  KeyValueInformation->NameLength/2) == 0)
2748  {
2749  /* Skip if nothing */
2750  if (KeyValueInformation->DataLength == 0)
2751  continue;
2752 
2753  /* If there was something previously allocated - free it */
2754  if (InternalConfigInfo->Parameter != NULL)
2755  ExFreePool(InternalConfigInfo->Parameter);
2756 
2757  /* Allocate it */
2758  InternalConfigInfo->Parameter = ExAllocatePoolWithTag(NonPagedPool,
2759  KeyValueInformation->DataLength, TAG_SCSIPORT);
2760 
2761  if (InternalConfigInfo->Parameter != NULL)
2762  {
2763  if (KeyValueInformation->Type != REG_SZ)
2764  {
2765  /* Just copy */
2766  RtlCopyMemory(
2767  InternalConfigInfo->Parameter,
2768  (PCCHAR)KeyValueInformation + KeyValueInformation->DataOffset,
2769  KeyValueInformation->DataLength);
2770  }
2771  else
2772  {
2773  /* If it's a unicode string, convert it to ansi */
2774  UnicodeString.Length = (USHORT)KeyValueInformation->DataLength;
2775  UnicodeString.MaximumLength = (USHORT)KeyValueInformation->DataLength;
2776  UnicodeString.Buffer =
2777  (PWSTR)((PCCHAR)KeyValueInformation + KeyValueInformation->DataOffset);
2778 
2779  AnsiString.Length = 0;
2780  AnsiString.MaximumLength = (USHORT)KeyValueInformation->DataLength;
2781  AnsiString.Buffer = (PCHAR)InternalConfigInfo->Parameter;
2782 
2784  &UnicodeString,
2785  FALSE);
2786 
2787  /* In case of error, free the allocated space */
2788  if (!NT_SUCCESS(Status))
2789  {
2790  ExFreePool(InternalConfigInfo->Parameter);
2791  InternalConfigInfo->Parameter = NULL;
2792  }
2793 
2794  }
2795  }
2796 
2797  DPRINT("Found driver parameter\n");
2798  }
2799 
2800  /* Get MaximumSGList */
2801  if (_wcsnicmp(KeyValueInformation->Name, L"MaximumSGList",
2802  KeyValueInformation->NameLength/2) == 0)
2803  {
2804  if (KeyValueInformation->Type != REG_DWORD)
2805  {
2806  DPRINT("Bad data type for MaximumSGList\n");
2807  continue;
2808  }
2809 
2810  ConfigInfo->NumberOfPhysicalBreaks = *((PUCHAR)(Buffer + KeyValueInformation->DataOffset));
2811 
2812  /* Check / fix */
2813  if (ConfigInfo->NumberOfPhysicalBreaks > SCSI_MAXIMUM_PHYSICAL_BREAKS)
2814  {
2815  ConfigInfo->NumberOfPhysicalBreaks = SCSI_MAXIMUM_PHYSICAL_BREAKS;
2816  }
2817  else if (ConfigInfo->NumberOfPhysicalBreaks < SCSI_MINIMUM_PHYSICAL_BREAKS)
2818  {
2819  ConfigInfo->NumberOfPhysicalBreaks = SCSI_MINIMUM_PHYSICAL_BREAKS;
2820  }
2821 
2822  DPRINT("MaximumSGList = %d\n", ConfigInfo->NumberOfPhysicalBreaks);
2823  }
2824 
2825  /* Get NumberOfRequests */
2826  if (_wcsnicmp(KeyValueInformation->Name, L"NumberOfRequests",
2827  KeyValueInformation->NameLength/2) == 0)
2828  {
2829  if (KeyValueInformation->Type != REG_DWORD)
2830  {
2831  DPRINT("NumberOfRequests has wrong data type\n");
2832  continue;
2833  }
2834 
2835  DeviceExtension->RequestsNumber = *((PUCHAR)(Buffer + KeyValueInformation->DataOffset));
2836 
2837  /* Check / fix */
2838  if (DeviceExtension->RequestsNumber < 16)
2839  {
2840  DeviceExtension->RequestsNumber = 16;
2841  }
2842  else if (DeviceExtension->RequestsNumber > 512)
2843  {
2844  DeviceExtension->RequestsNumber = 512;
2845  }
2846 
2847  DPRINT("Number Of Requests = %d\n", DeviceExtension->RequestsNumber);
2848  }
2849 
2850  /* Get resource list */
2851  if (_wcsnicmp(KeyValueInformation->Name, L"ResourceList",
2852  KeyValueInformation->NameLength/2) == 0 ||
2853  _wcsnicmp(KeyValueInformation->Name, L"Configuration Data",
2854  KeyValueInformation->NameLength/2) == 0 )
2855  {
2856  if (KeyValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR ||
2857  KeyValueInformation->DataLength < sizeof(REG_FULL_RESOURCE_DESCRIPTOR))
2858  {
2859  DPRINT("Bad data type for ResourceList\n");
2860  continue;
2861  }
2862  else
2863  {
2864  DPRINT("Found ResourceList\n");
2865  }
2866 
2867  FullResource = (PCM_FULL_RESOURCE_DESCRIPTOR)(Buffer + KeyValueInformation->DataOffset);
2868 
2869  /* Copy some info from it */
2870  InternalConfigInfo->BusNumber = FullResource->BusNumber;
2871  ConfigInfo->SystemIoBusNumber = FullResource->BusNumber;
2872 
2873  /* Loop through it */
2874  for (Count = 0; Count < FullResource->PartialResourceList.Count; Count++)
2875  {
2876  /* Get partial descriptor */
2877  PartialDescriptor =
2879 
2880  /* Check datalength */
2881  if ((ULONG)((PCHAR)(PartialDescriptor + 1) -
2882  (PCHAR)FullResource) > KeyValueInformation->DataLength)
2883  {
2884  DPRINT("Resource data is of incorrect size\n");
2885  break;
2886  }
2887 
2888  switch (PartialDescriptor->Type)
2889  {
2890  case CmResourceTypePort:
2891  if (RangeCount >= ConfigInfo->NumberOfAccessRanges)
2892  {
2893  DPRINT("Too many access ranges\n");
2894  continue;
2895  }
2896 
2897  InternalConfigInfo->AccessRanges[RangeCount].RangeInMemory = FALSE;
2898  InternalConfigInfo->AccessRanges[RangeCount].RangeStart = PartialDescriptor->u.Port.Start;
2899  InternalConfigInfo->AccessRanges[RangeCount].RangeLength = PartialDescriptor->u.Port.Length;
2900  RangeCount++;
2901 
2902  break;
2903 
2904  case CmResourceTypeMemory:
2905  if (RangeCount >= ConfigInfo->NumberOfAccessRanges)
2906  {
2907  DPRINT("Too many access ranges\n");
2908  continue;
2909  }
2910 
2911  InternalConfigInfo->AccessRanges[RangeCount].RangeInMemory = TRUE;
2912  InternalConfigInfo->AccessRanges[RangeCount].RangeStart = PartialDescriptor->u.Memory.Start;
2913  InternalConfigInfo->AccessRanges[RangeCount].RangeLength = PartialDescriptor->u.Memory.Length;
2914  RangeCount++;
2915 
2916  break;
2917 
2919 
2920  if (Interrupt == 0)
2921  {
2922  ConfigInfo->BusInterruptLevel =
2923  PartialDescriptor->u.Interrupt.Level;
2924 
2925  ConfigInfo->BusInterruptVector =
2926  PartialDescriptor->u.Interrupt.Vector;
2927 
2928  ConfigInfo->InterruptMode = (PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED) ? Latched : LevelSensitive;
2929  }
2930  else if (Interrupt == 1)
2931  {
2932  ConfigInfo->BusInterruptLevel2 =
2933  PartialDescriptor->u.Interrupt.Level;
2934 
2935  ConfigInfo->BusInterruptVector2 =
2936  PartialDescriptor->u.Interrupt.Vector;
2937 
2938  ConfigInfo->InterruptMode2 = (PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED) ? Latched : LevelSensitive;
2939  }
2940 
2941  Interrupt++;
2942  break;
2943 
2944  case CmResourceTypeDma:
2945 
2946  if (Dma == 0)
2947  {
2948  ConfigInfo->DmaChannel = PartialDescriptor->u.Dma.Channel;
2949  ConfigInfo->DmaPort = PartialDescriptor->u.Dma.Port;
2950 
2951  if (PartialDescriptor->Flags & CM_RESOURCE_DMA_8)
2952  ConfigInfo->DmaWidth = Width8Bits;
2953  else if ((PartialDescriptor->Flags & CM_RESOURCE_DMA_16) ||
2954  (PartialDescriptor->Flags & CM_RESOURCE_DMA_8_AND_16)) //???
2955  ConfigInfo->DmaWidth = Width16Bits;
2956  else if (PartialDescriptor->Flags & CM_RESOURCE_DMA_32)
2957  ConfigInfo->DmaWidth = Width32Bits;
2958  }
2959  else if (Dma == 1)
2960  {
2961  ConfigInfo->DmaChannel2 = PartialDescriptor->u.Dma.Channel;
2962  ConfigInfo->DmaPort2 = PartialDescriptor->u.Dma.Port;
2963 
2964  if (PartialDescriptor->Flags & CM_RESOURCE_DMA_8)
2965  ConfigInfo->DmaWidth2 = Width8Bits;
2966  else if ((PartialDescriptor->Flags & CM_RESOURCE_DMA_16) ||
2967  (PartialDescriptor->Flags & CM_RESOURCE_DMA_8_AND_16)) //???
2968  ConfigInfo->DmaWidth2 = Width16Bits;
2969  else if (PartialDescriptor->Flags & CM_RESOURCE_DMA_32)
2970  ConfigInfo->DmaWidth2 = Width32Bits;
2971  }
2972 
2973  Dma++;
2974  break;
2975 
2977  if (PartialDescriptor->u.DeviceSpecificData.DataSize <
2978  sizeof(CM_SCSI_DEVICE_DATA) ||
2979  (PCHAR) (PartialDescriptor + 1) - (PCHAR)FullResource +
2980  PartialDescriptor->u.DeviceSpecificData.DataSize >
2981  KeyValueInformation->DataLength)
2982  {
2983  DPRINT("Resource data length is incorrect");
2984  break;
2985  }
2986 
2987  /* Set only one field from it */
2988  ScsiDeviceData = (PCM_SCSI_DEVICE_DATA) (PartialDescriptor+1);
2989  ConfigInfo->InitiatorBusId[0] = ScsiDeviceData->HostIdentifier;
2990  break;
2991  }
2992  }
2993  }
2994  }
2995 }
2996 
2997 NTSTATUS
2998 NTAPI
3000  IN PUNICODE_STRING PathName,
3002  IN ULONG BusNumber,
3004  IN CONFIGURATION_TYPE ControllerType,
3005  IN ULONG ControllerNumber,
3006  IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
3007  IN CONFIGURATION_TYPE PeripheralType,
3008  IN ULONG PeripheralNumber,
3009  IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation)
3010 {
3012  /* We just set our Found variable to TRUE */
3013 
3014  *Found = TRUE;
3015  return STATUS_SUCCESS;
3016 }
3017 
3019 NTAPI
3021  IN PIRP Irp,
3023  IN PVOID Context)
3024 {
3025  KIRQL Irql;
3026  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
3027 
3028  /* Guard access with the spinlock */
3029  KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql);
3030 
3031  /* Save MapRegisterBase we've got here */
3032  DeviceExtension->MapRegisterBase = MapRegisterBase;
3033 
3034  /* Start pending request */
3035  KeSynchronizeExecution(DeviceExtension->Interrupt[0],
3037 
3038  /* Release spinlock we took */
3039  KeReleaseSpinLock(&DeviceExtension->SpinLock, Irql);
3040 
3041  return KeepObject;
3042 }
3043 
3044 #undef ScsiPortConvertPhysicalAddressToUlong
3045 /*
3046  * @implemented
3047  */
3048 ULONG NTAPI
3050 {
3051  DPRINT("ScsiPortConvertPhysicalAddressToUlong()\n");
3052  return(Address.u.LowPart);
3053 }
struct _LIST_ENTRY * PLIST_ENTRY
struct _SCSI_REQUEST_BLOCK_INFO * CompletedRequests
Definition: scsiport.h:129
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
struct _RESETBUS_PARAMS * PRESETBUS_PARAMS
_In_ WDFIORESREQLIST _In_ ULONG SlotNumber
Definition: wdfresource.h:65
#define STATUS_REVISION_MISMATCH
Definition: ntstatus.h:325
#define SRBEV_SCSI_ASYNC_NOTIFICATION
Definition: srb.h:240
FORCEINLINE VOID IoInitializeDpcRequest(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIO_DPC_ROUTINE DpcRoutine)
Definition: iofuncs.h:2840
signed char * PCHAR
Definition: retypes.h:7
#define CM_RESOURCE_DMA_16
Definition: cmtypes.h:132
struct _CM_RESOURCE_LIST * PCM_RESOURCE_LIST
enum _IO_ALLOCATION_ACTION IO_ALLOCATION_ACTION
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
VOID NTAPI SpiCompleteRequest(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK_INFO SrbInfo, IN UCHAR SrbStatus)
Definition: scsiport.c:203
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
PVOID NTAPI ScsiPortGetUncachedExtension(IN PVOID HwDeviceExtension, IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, IN ULONG NumberOfBytes)
Definition: scsiport.c:728
#define CmResourceTypeDeviceSpecific
Definition: hwresource.cpp:127
#define IN
Definition: typedefs.h:39
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3767
#define SP_UNINITIALIZED_VALUE
Definition: srb.h:232
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
INTERFACE_TYPE AdapterInterfaceType
Definition: srb.h:59
ULONG SupportedAsynchronousEvents
Definition: scsi_port.h:139
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
#define LUNEX_FULL_QUEUE
Definition: scsiport.h:49
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ULONG SrbFlags
Definition: srb.h:260
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:107
enum _INTERFACE_TYPE INTERFACE_TYPE
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1310
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
Definition: scsiport.h:329
static PMEMKEY RootKey
Definition: registry.c:55
_IRQL_requires_same_ _In_opt_ PVOID Argument1
Definition: cmtypes.h:696
PVOID OriginalRequest
Definition: srb.h:266
#define DbgPrint
Definition: hal.h:12
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: cdrom.h:989
UCHAR Cdb[16]
Definition: srb.h:279
BOOLEAN DisableMultipleLun
Definition: scsiport.h:93
NTSTATUS NTAPI IoAllocateDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress, IN ULONG DriverObjectExtensionSize, OUT PVOID *DriverObjectExtension)
Definition: driver.c:1797
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
USHORT MaximumLength
Definition: env_spec_w32.h:370
enum _SCSI_NOTIFICATION_TYPE SCSI_NOTIFICATION_TYPE
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
#define MmGetMdlVirtualAddress(_Mdl)
#define NTHALAPI
Definition: ntoskrnl.h:40
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Definition: iorsrce.c:830
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE BusType
Definition: halfuncs.h:156
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1310
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
#define SRB_FLAGS_IS_ACTIVE
Definition: srb.h:407
struct _DEVICE_OBJECT * PDEVICE_OBJECT
PVOID DataBuffer
Definition: srb.h:263
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:56
VOID SpiInitOpenKeys(_Inout_ PCONFIGURATION_INFO ConfigInfo, _In_ PSCSI_PORT_DRIVER_EXTENSION DriverExtension)
Definition: registry.c:18
PHYSICAL_ADDRESS NTAPI IoMapTransfer(IN PADAPTER_OBJECT AdapterObject, IN PMDL Mdl, IN PVOID MapRegisterBase, IN PVOID CurrentVa, IN OUT PULONG Length, IN BOOLEAN WriteToDevice)
Definition: dma.c:144
IO_SCSI_CAPABILITIES PortCapabilities
Definition: scsiport.c:78
enum _BUS_DATA_TYPE BUS_DATA_TYPE
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1310
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2272
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:372
#define SCSI_MAXIMUM_LOGICAL_UNITS
Definition: srb.h:21
KSYNCHRONIZE_ROUTINE ScsiPortStartPacket
Definition: scsiport.h:453
unsigned char * PUCHAR
Definition: retypes.h:3
LARGE_INTEGER IoAddress
Definition: ntdddisk.h:760
char CHAR
Definition: xmlstorage.h:175
ULONG DataTransferLength
Definition: srb.h:261
#define SCSI_PORT_DISABLE_INTERRUPTS
Definition: scsiport.h:41
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
#define MAX_SG_LIST
Definition: scsiport.h:26
struct SCSI_PORT_DEVICE_EXTENSION * PSCSI_PORT_DEVICE_EXTENSION
BOOLEAN AdapterScansDown
Definition: scsi_port.h:142
NTSTATUS NTAPI SpQueryDeviceCallout(IN PVOID Context, IN PUNICODE_STRING PathName, IN INTERFACE_TYPE BusType, IN ULONG BusNumber, IN PKEY_VALUE_FULL_INFORMATION *BusInformation, IN CONFIGURATION_TYPE ControllerType, IN ULONG ControllerNumber, IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation, IN CONFIGURATION_TYPE PeripheralType, IN ULONG PeripheralNumber, IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation)
Definition: scsiport.c:2999
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:198
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
static VOID NTAPI ScsiPortIoTimer(PDEVICE_OBJECT DeviceObject, PVOID Context)
Definition: scsiport.c:2234
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
_Must_inspect_result_ _In_ PVOID _In_ struct _HW_INITIALIZATION_DATA _In_ PVOID HwContext
Definition: srb.h:897
ULONG NTAPI ScsiPortSetBusDataByOffset(IN PVOID DeviceExtension, IN ULONG BusDataType, IN ULONG SystemIoBusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: scsiport.c:1464
#define TAG_SCSIPORT
Definition: scsiport.h:21
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@378::@387 DeviceSpecificData
BOOLEAN MultipleRequestPerLu
Definition: srb.h:584
VOID NTAPI ScsiPortCompleteRequest(IN PVOID HwDeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN UCHAR SrbStatus)
Definition: scsiport.c:505
ACCESS_RANGE(* AccessRanges)[]
Definition: srb.h:74
static VOID SpiParseDeviceInfo(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN HANDLE Key, IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, IN PCONFIGURATION_INFO InternalConfigInfo, IN PUCHAR Buffer)
Definition: scsiport.c:2615
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_opt_ PCUNICODE_STRING UnicodeString
Definition: wdfstring.h:64
IO_DPC_ROUTINE ScsiPortDpcForIsr
Definition: scsiport.h:451
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@378 u
if(dx==0 &&dy==0)
Definition: linetemp.h:174
_In_ ULONG TotalLength
Definition: usbdlib.h:158
#define SCSI_PORT_RESET
Definition: scsiport.h:35
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG _Out_ PPHYSICAL_ADDRESS TranslatedAddress
Definition: iofuncs.h:2272
#define SCSI_PORT_NOTIFICATION_NEEDED
Definition: scsiport.h:31
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_Out_ PKIRQL Irql
Definition: csq.h:179
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
UCHAR SrbStatus
Definition: srb.h:251
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
Definition: wdfresource.h:304
DRIVER_DISPATCH ScsiPortDispatchScsi
Definition: scsiport.h:452
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR CM_PARTIAL_RESOURCE_DESCRIPTOR
NTSTATUS PdoDispatchPnp(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: pdo.c:554
SCSI_PHYSICAL_ADDRESS NTAPI ScsiPortGetPhysicalAddress(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb OPTIONAL, IN PVOID VirtualAddress, OUT ULONG *Length)
Definition: scsiport.c:614
#define CM_RESOURCE_MEMORY_READ_WRITE
Definition: cmtypes.h:120
BOOLEAN AtDiskPrimaryAddressClaimed
Definition: iotypes.h:4482
#define CmResourceTypePort
Definition: hwresource.cpp:123
#define DEVICE_DESCRIPTION_VERSION
Definition: iotypes.h:2063
BOOLEAN AtDiskSecondaryAddressClaimed
Definition: iotypes.h:4483
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
ULONG NumberOfBytes
Definition: ntdddisk.h:759
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
BOOLEAN NTAPI ScsiPortIsr(_In_ PKINTERRUPT Interrupt, _In_ PVOID ServiceContext)
Definition: scsiport.c:2121
BOOLEAN AutoRequestSense
Definition: srb.h:583
BOOLEAN TaggedQueuing
Definition: srb.h:582
VOID NTAPI SpiMiniportTimerDpc(IN struct _KDPC *Dpc, IN PVOID DeviceObject, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: scsiport.c:2336
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define SP_UNTAGGED
Definition: srb.h:233
#define IRP_MJ_SCSI
PVOID NTAPI ScsiPortGetDeviceBase(IN PVOID HwDeviceExtension, IN INTERFACE_TYPE BusType, IN ULONG SystemIoBusNumber, IN SCSI_PHYSICAL_ADDRESS IoAddress, IN ULONG NumberOfBytes, IN BOOLEAN InIoSpace)
Definition: scsiport.c:569
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define sprintf(buf, format,...)
Definition: sprintf.c:55
_In_ WDF_SPECIAL_FILE_TYPE NotificationType
Definition: wdfdevice.h:1024
VOID NTAPI ScsiPortFreeDeviceBase(IN PVOID HwDeviceExtension, IN PVOID MappedAddress)
Definition: scsiport.c:547
UCHAR KIRQL
Definition: env_spec_w32.h:591
CM_PARTIAL_RESOURCE_LIST PartialResourceList
Definition: hwresource.cpp:160
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
static PCM_RESOURCE_LIST SpiConfigToResource(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, PPORT_CONFIGURATION_INFORMATION PortConfig)
Definition: scsiport.c:1739
#define L(x)
Definition: ntvdm.h:50
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING DeviceDescription
Definition: wdfpdo.h:430
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
BOOLEAN NeedPhysicalAddresses
Definition: srb.h:581
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FILE_DEVICE_CONTROLLER
Definition: winioctl.h:110
#define va_end(ap)
Definition: acmsvcex.h:90
IO_ALLOCATION_ACTION NTAPI SpiAdapterControl(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID MapRegisterBase, PVOID Context)
Definition: scsiport.c:2037
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
VOID NTAPI DbgBreakPoint(VOID)
BOOLEAN NTAPI SpiProcessTimeout(PVOID ServiceContext)
Definition: scsiport.c:2155
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@378::@380 Port
BOOLEAN NTAPI SpiResetBus(PVOID ServiceContext)
Definition: scsiport.c:2201
#define SCSI_MAXIMUM_TARGETS_PER_BUS
Definition: srb.h:22
NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: scsiport.c:113
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@378::@384 Dma
long LONG
Definition: pedump.c:60
#define SRB_FLAGS_SGLIST_FROM_POOL
Definition: srb.h:409
#define SCSI_PORT_NEXT_REQUEST_READY
Definition: scsiport.c:53
VOID NTAPI ScsiPortIoMapTransfer(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN PVOID LogicalAddress, IN ULONG Length)
Definition: scsiport.c:1278
UCHAR ScsiStatus
Definition: srb.h:252
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
#define SCSIOP_READ
Definition: cdrw_hw.h:905
struct _CM_SCSI_DEVICE_DATA * PCM_SCSI_DEVICE_DATA
PHW_INITIALIZE HwInitialize
Definition: scsiport.c:80
struct _SENSE_DATA SENSE_DATA
struct _CM_FULL_RESOURCE_DESCRIPTOR * PCM_FULL_RESOURCE_DESCRIPTOR
VOID __cdecl ScsiDebugPrint(IN ULONG DebugPrintLevel, IN PCCHAR DebugMessage, IN ...)
Definition: scsiport.c:469
ULONG NTAPI ScsiPortInitialize(IN PVOID Argument1, IN PVOID Argument2, IN PHW_INITIALIZATION_DATA HwInitializationData, IN PVOID HwContext OPTIONAL)
Definition: scsiport.c:1124
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:240
#define CM_RESOURCE_DMA_32
Definition: cmtypes.h:133
static NTSTATUS SpiCreatePortConfig(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, PHW_INITIALIZATION_DATA HwInitData, PCONFIGURATION_INFO InternalConfigInfo, PPORT_CONFIGURATION_INFORMATION ConfigInfo, BOOLEAN FirstCall)
Definition: scsiport.c:2369
KAFFINITY * PKAFFINITY
Definition: basetsd.h:197
VOID NTAPI IoStartPacket(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key, IN PDRIVER_CANCEL CancelFunction)
Definition: device.c:1876
#define SRB_STATUS_PENDING
Definition: srb.h:340
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
unsigned char BOOLEAN
#define CM_RESOURCE_DMA_8_AND_16
Definition: cmtypes.h:134
struct _SCSI_REQUEST_BLOCK_INFO * PSCSI_REQUEST_BLOCK_INFO
static WCHAR Address[46]
Definition: ping.c:68
PACCESS_RANGE AccessRanges
Definition: scsiport.h:97
PSCSI_SG_ADDRESS ScatterGather
Definition: scsiport.h:132
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@378::@383 Memory
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define _In_
Definition: ms_sal.h:308
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
struct _MAPPED_ADDRESS * NextMappedAddress
Definition: ntdddisk.h:757
char * va_list
Definition: acmsvcex.h:78
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFKEY * Key
Definition: wdfdevice.h:2654
KINTERRUPT_MODE InterruptMode2
Definition: srb.h:101
Definition: bufpool.h:45
NTHALAPI ULONG NTAPI HalGetInterruptVector(INTERFACE_TYPE, ULONG, ULONG, ULONG, PKIRQL, PKAFFINITY)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define BufSize
Definition: FsRtlTunnel.c:28
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
return Found
Definition: dirsup.c:1270
UCHAR QueueTag
Definition: srb.h:256
#define REG_FULL_RESOURCE_DESCRIPTOR
Definition: nt_native.h:1503
PSCSI_REQUEST_BLOCK NTAPI ScsiPortGetSrb(IN PVOID DeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN LONG QueueTag)
Definition: scsiport.c:650
NTHALAPI NTSTATUS NTAPI HalAssignSlotResources(PUNICODE_STRING, PUNICODE_STRING, PDRIVER_OBJECT, PDEVICE_OBJECT, INTERFACE_TYPE, ULONG, ULONG, PCM_RESOURCE_LIST *)
NTSTATUS NTAPI ScsiPortDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: ioctl.c:404
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
static NTSTATUS SpiAllocateCommonBuffer(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, ULONG NonCachedSize)
Definition: scsiport.c:690
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:156
_In_ PVOID Argument2
Definition: classpnp.h:721
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define PCHAR
Definition: match.c:90
KINTERRUPT_MODE InterruptMode
Definition: srb.h:64
Status
Definition: gdiplustypes.h:24
#define SCSI_PORT_RESET_REQUEST
Definition: scsiport.h:36
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:675
int64_t LONGLONG
Definition: typedefs.h:68
NTSTATUS NTAPI IoQueryDeviceDescription(PINTERFACE_TYPE BusType OPTIONAL, PULONG BusNumber OPTIONAL, PCONFIGURATION_TYPE ControllerType OPTIONAL, PULONG ControllerNumber OPTIONAL, PCONFIGURATION_TYPE PeripheralType OPTIONAL, PULONG PeripheralNumber OPTIONAL, PIO_QUERY_DEVICE_ROUTINE CalloutRoutine, PVOID Context)
Definition: iorsrce.c:1020
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
int Count
Definition: noreturn.cpp:7
BOOLEAN ReceiveEvent
Definition: srb.h:585
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3601
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG BusNumber
Definition: ntdddisk.h:761
char CCHAR
Definition: typedefs.h:51
_In_ WDFCOLLECTION _In_ ULONG Index
SCSI_REQUEST_BLOCK_INFO SrbInfo
Definition: scsiport.h:174
#define LUNEX_NEED_REQUEST_SENSE
Definition: scsiport.h:47
NTSTATUS NTAPI IoInitializeTimer(IN PDEVICE_OBJECT DeviceObject, IN PIO_TIMER_ROUTINE TimerRoutine, IN PVOID Context)
Definition: iotimer.c:92
PVOID NTAPI ScsiPortGetLogicalUnit(IN PVOID HwDeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun)
Definition: scsiport.c:601
UCHAR Function
Definition: srb.h:250
NTSTATUS FdoStartAdapter(_In_ PSCSI_PORT_DEVICE_EXTENSION PortExtension)
Definition: fdo.c:609
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:221
#define PCI_MAX_DEVICES
Definition: iotypes.h:3598
FORCEINLINE VOID IoRequestDpc(_Inout_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Irp, _In_opt_ __drv_aliasesMem PVOID Context)
Definition: iofuncs.h:2750
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:397
#define SP_RETURN_NOT_FOUND
Definition: srb.h:521
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
BOOLEAN AtdiskSecondaryClaimed
Definition: srb.h:83
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2977
va_start(ap, x)
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define SP_RETURN_FOUND
Definition: srb.h:522
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:800
ULONG NTAPI ScsiPortConvertPhysicalAddressToUlong(IN SCSI_PHYSICAL_ADDRESS Address)
Definition: scsiport.c:519
VOID NTAPI ScsiPortUnload(_In_ PDRIVER_OBJECT DriverObject)
Definition: scsiport.c:121
SCSI_PHYSICAL_ADDRESS RangeStart
Definition: srb.h:41
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define BYTES_TO_PAGES(Size)
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1098
#define SRB_FLAGS_DISABLE_DISCONNECT
Definition: srb.h:396
unsigned char UCHAR
Definition: xmlstorage.h:181
struct _PORT_CONFIGURATION_INFORMATION PORT_CONFIGURATION_INFORMATION
BOOLEAN RangeInMemory
Definition: srb.h:43
char * PBOOLEAN
Definition: retypes.h:11
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
PVOID MappedAddress
Definition: ntdddisk.h:758
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
#define IRP_MJ_POWER
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
VOID __cdecl ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension, IN ...)
Definition: scsiport.c:1315
#define CM_RESOURCE_DMA_8
Definition: cmtypes.h:131
Definition: ketypes.h:687
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2288
ULONG InternalDebugLevel
Definition: scsiport.c:17
signed long long INT64
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1875
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
CONFIGURATION_TYPE
Definition: iotypes.h:4393
struct _SCSI_PORT_LUN_EXTENSION * CompletedAbortRequests
Definition: scsiport.h:172
Definition: typedefs.h:119
struct _SCSI_PORT_DEVICE_EXTENSION SCSI_PORT_DEVICE_EXTENSION
VOID FdoScanAdapter(_In_ PSCSI_PORT_DEVICE_EXTENSION PortExtension)
Definition: fdo.c:222
int _cdecl swprintf(const WCHAR *,...)
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
PSCSI_REQUEST_BLOCK Srb
Definition: scsiport.h:119
struct _CM_RESOURCE_LIST CM_RESOURCE_LIST
ULONG NumberOfAccessRanges
Definition: srb.h:577
BOOLEAN NTAPI HalTranslateBusAddress(IN INTERFACE_TYPE InterfaceType, IN ULONG BusNumber, IN PHYSICAL_ADDRESS BusAddress, IN OUT PULONG AddressSpace, OUT PPHYSICAL_ADDRESS TranslatedAddress)
Definition: bus.c:140
#define FILE_WORD_ALIGNMENT
Definition: nt_native.h:787
NTSTATUS NTAPI IoReportDetectedDevice(_In_ PDRIVER_OBJECT DriverObject, _In_ INTERFACE_TYPE LegacyBusType, _In_ ULONG BusNumber, _In_ ULONG SlotNumber, _In_opt_ PCM_RESOURCE_LIST ResourceList, _In_opt_ PIO_RESOURCE_REQUIREMENTS_LIST ResourceRequirements, _In_ BOOLEAN ResourceAssigned, _Inout_ PDEVICE_OBJECT *DeviceObject)
Definition: pnpreport.c:148
#define PCI_MAX_FUNCTION
Definition: iotypes.h:3599
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:675
PDRIVER_OBJECT DriverObject
Definition: scsiport.h:334
PHYSICAL_ADDRESS PhysicalAddress
Definition: scsiport.h:112
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG _In_ BOOLEAN WriteToDevice
Definition: cdrom.h:989
#define SRB_FUNCTION_ABORT_COMMAND
Definition: srb.h:324
SCSI_SG_ADDRESS ScatterGatherList[MAX_SG_LIST]
Definition: scsiport.h:133
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
IO_ALLOCATION_ACTION NTAPI ScsiPortAllocateAdapterChannel(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID MapRegisterBase, IN PVOID Context)
Definition: scsiport.c:3020
ULONG NTAPI ScsiPortGetBusData(IN PVOID DeviceExtension, IN ULONG BusDataType, IN ULONG SystemIoBusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Length)
Definition: scsiport.c:556
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
ULONG_PTR SIZE_T
Definition: typedefs.h:80
ULONG LastAdapterNumber
Definition: scsiport.h:83
NTSTATUS FdoRemoveAdapter(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
Definition: fdo.c:510
#define va_arg(ap, T)
Definition: acmsvcex.h:89
PHW_RESET_BUS HwResetBus
Definition: scsiport.c:83
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@378::@381 Interrupt
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
Definition: iotypes.h:212
#define InterlockedIncrement
Definition: armddk.h:53
PADAPTER_OBJECT AdapterObject
Definition: scsiport.c:86
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
#define ROUND_TO_PAGES(Size)
#define CM_RESOURCE_PORT_IO
Definition: cmtypes.h:109
unsigned short USHORT
Definition: pedump.c:61
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
int __cdecl vsprintf(char *_Dest, const char *_Format, va_list _Args)
Definition: sprintf.c:733
ULONG RangeLength
Definition: srb.h:42
NTSTATUS NTAPI ScsiPortDispatchPnp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: scsiport.c:129
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFCOMMONBUFFER * CommonBuffer
#define ALIGN_UP_POINTER(ptr, type)
Definition: umtypes.h:97
PHW_INTERRUPT HwInterrupt
Definition: scsiport.c:82
static BOOLEAN SpiGetPciConfigData(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject, IN struct _HW_INITIALIZATION_DATA *HwInitializationData, IN OUT PPORT_CONFIGURATION_INFORMATION PortConfig, IN PUNICODE_STRING RegistryPath, IN ULONG BusNumber, IN OUT PPCI_SLOT_NUMBER NextSlotNumber)
Definition: scsiport.c:1891
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1035
unsigned int * PULONG
Definition: retypes.h:1
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:401
#define NULL
Definition: types.h:112
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
Definition: cmtypes.h:143
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
struct _SCSI_PORT_LUN_EXTENSION * ReadyLun
Definition: scsiport.h:171
#define DPRINT1
Definition: precomp.h:8
SCSI_PORT_COMMON_EXTENSION Common
Definition: scsiport.h:146
DRIVER_STARTIO ScsiPortStartIo
Definition: scsiport.h:454
static NTSTATUS NTAPI ScsiPortCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: scsiport.c:2024
LIST_ENTRY LunsListHead
Definition: scsiport.h:187
BOOLEAN NTAPI ScsiPortValidateRange(IN PVOID HwDeviceExtension, IN INTERFACE_TYPE BusType, IN ULONG SystemIoBusNumber, IN SCSI_PHYSICAL_ADDRESS IoAddress, IN ULONG NumberOfBytes, IN BOOLEAN InIoSpace)
Definition: scsiport.c:1488
PVOID SenseInfoBuffer
Definition: srb.h:264
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
#define SCSI_MINIMUM_PHYSICAL_BREAKS
Definition: srb.h:25
#define OUT
Definition: typedefs.h:40
VOID(NTAPI * PHW_TIMER)(IN PVOID DeviceExtension)
Definition: srb.h:456
#define CM_RESOURCE_INTERRUPT_LATCHED
Definition: cmtypes.h:144
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
PSCSI_REQUEST_BLOCK_INFO SpiGetSrbData(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _In_ PSCSI_PORT_LUN_EXTENSION LunExtension, _In_ UCHAR QueueTag)
Definition: pdo.c:102
INTERFACE_TYPE AdapterInterfaceType
Definition: srb.h:565
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:115
NTHALAPI ULONG NTAPI HalGetBusData(BUS_DATA_TYPE, ULONG, ULONG, PVOID, ULONG)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
#define SRB_STATUS_SUCCESS
Definition: srb.h:341
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:165
#define SCSISTAT_GOOD
Definition: cdrw_hw.h:1078
NTSTATUS FdoDispatchPnp(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: fdo.c:758
#define SCSI_MAXIMUM_PHYSICAL_BREAKS
Definition: srb.h:26
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
BOOLEAN MapBuffers
Definition: srb.h:580
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
static VOID SpiResourceToConfig(IN PHW_INITIALIZATION_DATA HwInitializationData, IN PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor, IN PPORT_CONFIGURATION_INFORMATION PortConfig)
Definition: scsiport.c:1619
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
VOID NTAPI ScsiPortLogError(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb OPTIONAL, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN ULONG ErrorCode, IN ULONG UniqueId)
Definition: scsiport.c:1290
PVOID NTAPI ScsiPortGetVirtualAddress(IN PVOID HwDeviceExtension, IN SCSI_PHYSICAL_ADDRESS PhysicalAddress)
Definition: scsiport.c:813
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1229
#define DPRINT
Definition: sndvol32.h:71
_In_ WDFDEVICE _In_ PPNP_BUS_INFORMATION BusInformation
Definition: wdfdevice.h:3912
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
#define CmResourceTypeMemory
Definition: hwresource.cpp:125
DRIVER_DISPATCH ScsiPortDispatchPower
Definition: scsiport.h:426
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
#define SCSI_PORT_TIMER_NEEDED
Definition: scsiport.h:43
ULONG NTAPI HalSetBusDataByOffset(IN BUS_DATA_TYPE BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: bus.c:123
PVOID NTAPI HalAllocateCommonBuffer(IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PPHYSICAL_ADDRESS LogicalAddress, IN BOOLEAN CacheEnabled)
Definition: dma.c:46
#define LUNEX_BUSY
Definition: scsiport.h:48
#define SCSI_PORT_RESET_REPORTED
Definition: scsiport.h:37
unsigned char UINT8
#define REG_DWORD
Definition: sdbapi.c:596
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
BOOLEAN DisableTaggedQueueing
Definition: scsiport.h:92
UNICODE_STRING RegistryPath
Definition: scsiport.h:335
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
struct _IO_SCSI_CAPABILITIES IO_SCSI_CAPABILITIES
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID InterfaceType
Definition: wdffdo.h:461
#define LUNEX_FROZEN_QUEUE
Definition: scsiport.h:46
NTSTATUS NTAPI ScsiPortAddDevice(_In_ PDRIVER_OBJECT DriverObject, _In_ PDEVICE_OBJECT PhysicalDeviceObject)
Definition: scsiport.c:145
struct _KEY_VALUE_FULL_INFORMATION * PKEY_VALUE_FULL_INFORMATION
struct _DRIVER_OBJECT * PDRIVER_OBJECT
#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:366
VOID NTAPI ScsiPortMoveMemory(IN PVOID WriteBuffer, IN PVOID ReadBuffer, IN ULONG Length)
Definition: scsiport.c:1305
_Must_inspect_result_ _In_ PVOID _In_ struct _HW_INITIALIZATION_DATA * HwInitializationData
Definition: srb.h:897
#define CmResourceTypeDma
Definition: hwresource.cpp:126
LONGLONG QuadPart
Definition: typedefs.h:114
PADAPTER_OBJECT NTAPI HalGetAdapter(IN PDEVICE_DESCRIPTION DeviceDescription, OUT PULONG NumberOfMapRegisters)
Definition: dma.c:22
VOID NTAPI ScsiPortFlushDma(IN PVOID DeviceExtension)
Definition: scsiport.c:538
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define REG_SZ
Definition: layer.c:22
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68