ReactOS  0.4.15-dev-2153-g62b4c61
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  {
548  PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Srb->OriginalRequest);
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 */
558  Offset = (PCHAR)VirtualAddress - (PCHAR)Srb->DataBuffer;
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  DPRINT1("Created device: %wZ (%p)\n", &DeviceName, PortDeviceObject);
985 
986  /* Set the buffering strategy here... */
987  PortDeviceObject->Flags |= DO_DIRECT_IO;
988  PortDeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT; /* FIXME: Is this really needed? */
989 
990  /* Fill Device Extension */
991  DeviceExtension = PortDeviceObject->DeviceExtension;
992  RtlZeroMemory(DeviceExtension, DeviceExtensionSize);
993  DeviceExtension->Common.DeviceObject = PortDeviceObject;
994  DeviceExtension->Common.IsFDO = TRUE;
995  DeviceExtension->Length = DeviceExtensionSize;
996  DeviceExtension->PortNumber = SystemConfig->ScsiPortCount;
997  DeviceExtension->DeviceName = DeviceName;
998 
999  /* Driver's routines... */
1000  DeviceExtension->HwInitialize = HwInitializationData->HwInitialize;
1001  DeviceExtension->HwStartIo = HwInitializationData->HwStartIo;
1002  DeviceExtension->HwInterrupt = HwInitializationData->HwInterrupt;
1003  DeviceExtension->HwResetBus = HwInitializationData->HwResetBus;
1004  DeviceExtension->HwDmaStarted = HwInitializationData->HwDmaStarted;
1005 
1006  /* Extensions sizes */
1007  DeviceExtension->MiniPortExtensionSize = HwInitializationData->DeviceExtensionSize;
1008  DeviceExtension->LunExtensionSize =
1009  ALIGN_UP(HwInitializationData->SpecificLuExtensionSize, INT64);
1010  DeviceExtension->SrbExtensionSize =
1011  ALIGN_UP(HwInitializationData->SrbExtensionSize, INT64);
1012 
1013  /* Fill some numbers (bus count, lun count, etc) */
1014  DeviceExtension->MaxLunCount = SCSI_MAXIMUM_LOGICAL_UNITS;
1015  DeviceExtension->RequestsNumber = 16;
1016 
1017  /* Initialize the spin lock in the controller extension */
1018  KeInitializeSpinLock(&DeviceExtension->IrqLock);
1019  KeInitializeSpinLock(&DeviceExtension->SpinLock);
1020 
1021  /* Initialize the DPC object */
1022  IoInitializeDpcRequest(PortDeviceObject,
1024 
1025  /* Initialize the device timer */
1026  DeviceExtension->TimerCount = -1;
1027  IoInitializeTimer(PortDeviceObject,
1029  DeviceExtension);
1030 
1031  /* Initialize miniport timer */
1032  KeInitializeTimer(&DeviceExtension->MiniportTimer);
1033  KeInitializeDpc(&DeviceExtension->MiniportTimerDpc,
1035  PortDeviceObject);
1036 
1037 CreatePortConfig:
1038 
1039  /* Allocate and initialize port configuration info */
1040  PortConfigSize = sizeof(PORT_CONFIGURATION_INFORMATION) +
1041  HwInitializationData->NumberOfAccessRanges * sizeof(ACCESS_RANGE);
1042  PortConfigSize = ALIGN_UP(PortConfigSize, INT64);
1043  DeviceExtension->PortConfig = ExAllocatePoolWithTag(NonPagedPool, PortConfigSize, TAG_SCSIPORT);
1044 
1045  /* Fail if failed */
1046  if (DeviceExtension->PortConfig == NULL)
1047  {
1049  break;
1050  }
1051 
1052  Status = SpiCreatePortConfig(DeviceExtension,
1054  &ConfigInfo,
1055  DeviceExtension->PortConfig,
1056  FirstConfigCall);
1057 
1058  if (!NT_SUCCESS(Status))
1059  {
1060  DPRINT("SpiCreatePortConfig() failed with Status 0x%08X\n", Status);
1061  break;
1062  }
1063 
1064  PortConfig = DeviceExtension->PortConfig;
1065 
1066  /* Copy extension sizes into the PortConfig */
1067  PortConfig->SpecificLuExtensionSize = DeviceExtension->LunExtensionSize;
1068  PortConfig->SrbExtensionSize = DeviceExtension->SrbExtensionSize;
1069 
1070  /* Initialize Access ranges */
1071  if (HwInitializationData->NumberOfAccessRanges != 0)
1072  {
1073  PortConfig->AccessRanges = ALIGN_UP_POINTER(PortConfig + 1, INT64);
1074 
1075  /* Copy the data */
1076  RtlCopyMemory(PortConfig->AccessRanges,
1077  ConfigInfo.AccessRanges,
1078  HwInitializationData->NumberOfAccessRanges * sizeof(ACCESS_RANGE));
1079  }
1080 
1081  /* Search for matching PCI device */
1082  if ((HwInitializationData->AdapterInterfaceType == PCIBus) &&
1083  (HwInitializationData->VendorIdLength > 0) &&
1084  (HwInitializationData->VendorId != NULL) &&
1085  (HwInitializationData->DeviceIdLength > 0) && (HwInitializationData->DeviceId != NULL))
1086  {
1087  PortConfig->BusInterruptLevel = 0;
1088 
1089  /* Get PCI device data */
1090  DPRINT(
1091  "VendorId '%.*s' DeviceId '%.*s'\n", HwInitializationData->VendorIdLength,
1092  HwInitializationData->VendorId, HwInitializationData->DeviceIdLength,
1093  HwInitializationData->DeviceId);
1094 
1095  if (!SpiGetPciConfigData(
1096  DriverObject, PortDeviceObject, HwInitializationData, PortConfig, RegistryPath,
1097  ConfigInfo.BusNumber, &SlotNumber))
1098  {
1099  /* Continue to the next bus, nothing here */
1100  ConfigInfo.BusNumber++;
1101  DeviceExtension->PortConfig = NULL;
1102  ExFreePool(PortConfig);
1103  Again = FALSE;
1104  goto CreatePortConfig;
1105  }
1106 
1107  if (!PortConfig->BusInterruptLevel)
1108  {
1109  /* Bypass this slot, because no interrupt was assigned */
1110  DeviceExtension->PortConfig = NULL;
1111  ExFreePool(PortConfig);
1112  goto CreatePortConfig;
1113  }
1114  }
1115  else
1116  {
1117  DPRINT("Non-pci bus\n");
1118  }
1119 
1120  /* Note: HwFindAdapter is called once for each bus */
1121  Again = FALSE;
1122  DPRINT("Calling HwFindAdapter() for Bus %lu\n", PortConfig->SystemIoBusNumber);
1123  Result = (HwInitializationData->HwFindAdapter)(
1124  &DeviceExtension->MiniPortDeviceExtension, HwContext, 0, /* BusInformation */
1125  ConfigInfo.Parameter, /* ArgumentString */
1126  PortConfig, &Again);
1127 
1128  DPRINT("HwFindAdapter() Result: %lu Again: %s\n", Result, (Again) ? "True" : "False");
1129 
1130  /* Free MapRegisterBase, it's not needed anymore */
1131  if (DeviceExtension->MapRegisterBase != NULL)
1132  {
1133  ExFreePool(DeviceExtension->MapRegisterBase);
1134  DeviceExtension->MapRegisterBase = NULL;
1135  }
1136 
1137  /* If result is nothing good... */
1138  if (Result != SP_RETURN_FOUND)
1139  {
1140  DPRINT("HwFindAdapter() Result: %lu\n", Result);
1141 
1142  if (Result == SP_RETURN_NOT_FOUND)
1143  {
1144  /* We can continue on the next bus */
1145  ConfigInfo.BusNumber++;
1146  Again = FALSE;
1147 
1148  DeviceExtension->PortConfig = NULL;
1149  ExFreePool(PortConfig);
1150  goto CreatePortConfig;
1151  }
1152 
1153  /* Otherwise, break */
1155  break;
1156  }
1157 
1158  DPRINT(
1159  "ScsiPortInitialize(): Found HBA! (%x), adapter Id %d\n",
1160  PortConfig->BusInterruptVector, PortConfig->InitiatorBusId[0]);
1161 
1162  /* If the SRB extension size was updated */
1163  if (!DeviceExtension->NonCachedExtension &&
1164  (PortConfig->SrbExtensionSize != DeviceExtension->SrbExtensionSize))
1165  {
1166  /* Set it (rounding to LONGLONG again) */
1167  DeviceExtension->SrbExtensionSize = ALIGN_UP(PortConfig->SrbExtensionSize, INT64);
1168  }
1169 
1170  /* The same with LUN extension size */
1171  if (PortConfig->SpecificLuExtensionSize != DeviceExtension->LunExtensionSize)
1172  DeviceExtension->LunExtensionSize = PortConfig->SpecificLuExtensionSize;
1173 
1174  /* Construct a resource list */
1175  ResourceList = SpiConfigToResource(DeviceExtension, PortConfig);
1176 
1177  PDEVICE_OBJECT LowerPDO = NULL;
1178 
1180  HwInitializationData->AdapterInterfaceType,
1181  ConfigInfo.BusNumber,
1182  PortConfig->SlotNumber,
1183  ResourceList,
1184  NULL,
1185  TRUE,
1186  &LowerPDO);
1187 
1188  if (!NT_SUCCESS(Status))
1189  {
1190  DPRINT1("IoReportDetectedDevice failed. Status: 0x%x\n", Status);
1191  __debugbreak();
1192  break;
1193  }
1194 
1195  DeviceExtension->Common.LowerDevice = IoAttachDeviceToDeviceStack(PortDeviceObject, LowerPDO);
1196 
1197  ASSERT(DeviceExtension->Common.LowerDevice);
1198 
1199  PortDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
1200 
1201  if (ResourceList)
1202  {
1204  }
1205 
1206  /* Copy all stuff which we ever need from PortConfig to the DeviceExtension */
1208  DeviceExtension->MaxTargedIds = SCSI_MAXIMUM_TARGETS_PER_BUS;
1209  else
1210  DeviceExtension->MaxTargedIds = PortConfig->MaximumNumberOfTargets;
1211 
1212  DeviceExtension->NumberOfBuses = PortConfig->NumberOfBuses;
1213  DeviceExtension->CachesData = PortConfig->CachesData;
1214  DeviceExtension->ReceiveEvent = PortConfig->ReceiveEvent;
1215  DeviceExtension->SupportsTaggedQueuing = PortConfig->TaggedQueuing;
1216  DeviceExtension->MultipleReqsPerLun = PortConfig->MultipleRequestPerLu;
1217 
1218  /* Initialize bus scanning information */
1219  size_t BusConfigSize = DeviceExtension->NumberOfBuses * sizeof(*DeviceExtension->Buses);
1220  DeviceExtension->Buses = ExAllocatePoolZero(NonPagedPool, BusConfigSize, TAG_SCSIPORT);
1221  if (!DeviceExtension->Buses)
1222  {
1223  DPRINT1("Out of resources!\n");
1225  break;
1226  }
1227 
1228  // initialize bus data
1229  for (UINT8 pathId = 0; pathId < DeviceExtension->NumberOfBuses; pathId++)
1230  {
1231  DeviceExtension->Buses[pathId].BusIdentifier =
1232  DeviceExtension->PortConfig->InitiatorBusId[pathId];
1233  InitializeListHead(&DeviceExtension->Buses[pathId].LunsListHead);
1234  }
1235 
1236  /* If something was disabled via registry - apply it */
1237  if (ConfigInfo.DisableMultipleLun)
1238  DeviceExtension->MultipleReqsPerLun = PortConfig->MultipleRequestPerLu = FALSE;
1239 
1240  if (ConfigInfo.DisableTaggedQueueing)
1241  DeviceExtension->SupportsTaggedQueuing = PortConfig->MultipleRequestPerLu = FALSE;
1242 
1243  /* Check if we need to alloc SRB data */
1244  if (DeviceExtension->SupportsTaggedQueuing || DeviceExtension->MultipleReqsPerLun)
1245  {
1246  DeviceExtension->NeedSrbDataAlloc = TRUE;
1247  }
1248  else
1249  {
1250  DeviceExtension->NeedSrbDataAlloc = FALSE;
1251  }
1252 
1253  /* Get a pointer to the port capabilities */
1254  PortCapabilities = &DeviceExtension->PortCapabilities;
1255 
1256  /* Copy one field there */
1257  DeviceExtension->MapBuffers = PortConfig->MapBuffers;
1258  PortCapabilities->AdapterUsesPio = PortConfig->MapBuffers;
1259 
1260  if (DeviceExtension->AdapterObject == NULL &&
1261  (PortConfig->DmaChannel != SP_UNINITIALIZED_VALUE || PortConfig->Master))
1262  {
1263  DPRINT1("DMA is not supported yet\n");
1264  ASSERT(FALSE);
1265  }
1266 
1267  if (DeviceExtension->SrbExtensionBuffer == NULL &&
1268  (DeviceExtension->SrbExtensionSize != 0 || PortConfig->AutoRequestSense))
1269  {
1270  DeviceExtension->SupportsAutoSense = PortConfig->AutoRequestSense;
1271  DeviceExtension->NeedSrbExtensionAlloc = TRUE;
1272 
1273  /* Allocate common buffer */
1274  Status = SpiAllocateCommonBuffer(DeviceExtension, 0);
1275 
1276  /* Check for failure */
1277  if (!NT_SUCCESS(Status))
1278  break;
1279  }
1280 
1281  /* Allocate SrbData, if needed */
1282  if (DeviceExtension->NeedSrbDataAlloc)
1283  {
1284  ULONG Count;
1285  PSCSI_REQUEST_BLOCK_INFO SrbData;
1286 
1287  if (DeviceExtension->SrbDataCount != 0)
1288  Count = DeviceExtension->SrbDataCount;
1289  else
1290  Count = DeviceExtension->RequestsNumber * 2;
1291 
1292  /* Allocate the data */
1293  SrbData = ExAllocatePoolWithTag(
1295  if (SrbData == NULL)
1297 
1298  RtlZeroMemory(SrbData, Count * sizeof(SCSI_REQUEST_BLOCK_INFO));
1299 
1300  DeviceExtension->SrbInfo = SrbData;
1301  DeviceExtension->FreeSrbInfo = SrbData;
1302  DeviceExtension->SrbDataCount = Count;
1303 
1304  /* Link it to the list */
1305  while (Count > 0)
1306  {
1307  SrbData->Requests.Flink = (PLIST_ENTRY)(SrbData + 1);
1308  SrbData++;
1309  Count--;
1310  }
1311 
1312  /* Mark the last entry of the list */
1313  SrbData--;
1314  SrbData->Requests.Flink = NULL;
1315  }
1316 
1317  /* Initialize port capabilities */
1318  PortCapabilities = &DeviceExtension->PortCapabilities;
1319  PortCapabilities->Length = sizeof(IO_SCSI_CAPABILITIES);
1320  PortCapabilities->MaximumTransferLength = PortConfig->MaximumTransferLength;
1321 
1322  if (PortConfig->ReceiveEvent)
1324 
1325  PortCapabilities->TaggedQueuing = DeviceExtension->SupportsTaggedQueuing;
1326  PortCapabilities->AdapterScansDown = PortConfig->AdapterScansDown;
1327 
1328  if (PortConfig->AlignmentMask > PortDeviceObject->AlignmentRequirement)
1329  PortDeviceObject->AlignmentRequirement = PortConfig->AlignmentMask;
1330 
1331  PortCapabilities->AlignmentMask = PortDeviceObject->AlignmentRequirement;
1332 
1333  if (PortCapabilities->MaximumPhysicalPages == 0)
1334  {
1335  PortCapabilities->MaximumPhysicalPages =
1336  BYTES_TO_PAGES(PortCapabilities->MaximumTransferLength);
1337 
1338  /* Apply miniport's limits */
1339  if (PortConfig->NumberOfPhysicalBreaks < PortCapabilities->MaximumPhysicalPages)
1340  {
1341  PortCapabilities->MaximumPhysicalPages = PortConfig->NumberOfPhysicalBreaks;
1342  }
1343  }
1344 
1345  FdoCallHWInitialize(DeviceExtension);
1346 
1347  Status = FdoStartAdapter(DeviceExtension);
1348 
1349  if (!NT_SUCCESS(Status))
1350  {
1351  DPRINT1("Failed to start the legacy adapter. Status 0x%x\n", Status);
1352  break;
1353  }
1354 
1355  FdoScanAdapter(DeviceExtension);
1356 
1357  FirstConfigCall = FALSE;
1358 
1359  /* Increase adapter number and bus number respectively */
1360  ConfigInfo.AdapterNumber++;
1361 
1362  if (!Again)
1363  ConfigInfo.BusNumber++;
1364 
1365  DPRINT("Bus: %lu MaxBus: %lu\n", ConfigInfo.BusNumber, MaxBus);
1366 
1367  DeviceFound = TRUE;
1368  }
1369 
1370  /* Clean up the mess */
1371  if (!NT_SUCCESS(Status) && PortDeviceObject)
1372  {
1373  FdoRemoveAdapter(DeviceExtension);
1374  }
1375 
1376  /* Close registry keys */
1377  if (ConfigInfo.ServiceKey != NULL)
1378  ZwClose(ConfigInfo.ServiceKey);
1379 
1380  if (ConfigInfo.DeviceKey != NULL)
1381  ZwClose(ConfigInfo.DeviceKey);
1382 
1383  if (ConfigInfo.BusKey != NULL)
1384  ZwClose(ConfigInfo.BusKey);
1385 
1386  if (ConfigInfo.AccessRanges != NULL)
1387  ExFreePool(ConfigInfo.AccessRanges);
1388 
1389  if (ConfigInfo.Parameter != NULL)
1390  ExFreePool(ConfigInfo.Parameter);
1391 
1392  DPRINT("ScsiPortInitialize() done, Status = 0x%08X, DeviceFound = %d!\n",
1393  Status, DeviceFound);
1394 
1395  return (DeviceFound == FALSE) ? Status : STATUS_SUCCESS;
1396 }
1397 
1398 /*
1399  * @unimplemented
1400  */
1401 VOID NTAPI
1402 ScsiPortIoMapTransfer(IN PVOID HwDeviceExtension,
1404  IN PVOID LogicalAddress,
1405  IN ULONG Length)
1406 {
1407  DPRINT1("ScsiPortIoMapTransfer()\n");
1408  UNIMPLEMENTED;
1409 }
1410 
1411 /*
1412  * @unimplemented
1413  */
1414 VOID NTAPI
1415 ScsiPortLogError(IN PVOID HwDeviceExtension,
1417  IN UCHAR PathId,
1418  IN UCHAR TargetId,
1419  IN UCHAR Lun,
1420  IN ULONG ErrorCode,
1421  IN ULONG UniqueId)
1422 {
1423  //PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
1424 
1425  DPRINT1("ScsiPortLogError() called\n");
1426  DPRINT1("PathId: 0x%02x TargetId: 0x%02x Lun: 0x%02x ErrorCode: 0x%08lx UniqueId: 0x%08lx\n",
1427  PathId, TargetId, Lun, ErrorCode, UniqueId);
1428 
1429  //DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, SCSI_PORT_DEVICE_EXTENSION, MiniPortDeviceExtension);
1430 
1431 
1432  DPRINT("ScsiPortLogError() done\n");
1433 }
1434 
1435 /*
1436  * @implemented
1437  */
1438 VOID NTAPI
1440  IN PVOID Source,
1441  IN ULONG Length)
1442 {
1444  Source,
1445  Length);
1446 }
1447 
1448 
1449 /*
1450  * @implemented
1451  */
1452 VOID
1454 {
1455  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
1456  va_list ap;
1457 
1458  DPRINT("ScsiPortNotification() called\n");
1459 
1460  DeviceExtension =
1461  CONTAINING_RECORD(HwDeviceExtension, SCSI_PORT_DEVICE_EXTENSION, MiniPortDeviceExtension);
1462 
1463  DPRINT("DeviceExtension %p\n", DeviceExtension);
1464 
1465  va_start(ap, HwDeviceExtension);
1466 
1467  switch (NotificationType)
1468  {
1469  case RequestComplete:
1470  {
1472  PSCSI_REQUEST_BLOCK_INFO SrbData;
1473 
1475 
1476  DPRINT("Notify: RequestComplete (Srb %p)\n", Srb);
1477 
1478  /* Make sure Srb is alright */
1479  ASSERT(Srb->SrbStatus != SRB_STATUS_PENDING);
1480  ASSERT(
1481  Srb->Function != SRB_FUNCTION_EXECUTE_SCSI ||
1482  Srb->SrbStatus != SRB_STATUS_SUCCESS || Srb->ScsiStatus == SCSISTAT_GOOD);
1483 
1484  if (!(Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE))
1485  {
1486  /* It's been already completed */
1487  va_end(ap);
1488  return;
1489  }
1490 
1491  /* It's not active anymore */
1492  Srb->SrbFlags &= ~SRB_FLAGS_IS_ACTIVE;
1493 
1494  if (Srb->Function == SRB_FUNCTION_ABORT_COMMAND)
1495  {
1496  /* TODO: Treat it specially */
1497  ASSERT(FALSE);
1498  }
1499  else
1500  {
1501  PIO_STACK_LOCATION IoStack = IoGetCurrentIrpStackLocation(Srb->OriginalRequest);
1502  PSCSI_PORT_LUN_EXTENSION LunExtension = IoStack->DeviceObject->DeviceExtension;
1503  ASSERT(LunExtension && !LunExtension->Common.IsFDO);
1504 
1505  /* Get the SRB data */
1506  SrbData = SpiGetSrbData(DeviceExtension, LunExtension, Srb->QueueTag);
1507 
1508  /* Make sure there are no CompletedRequests and there is a Srb */
1509  ASSERT(SrbData->CompletedRequests == NULL && SrbData->Srb != NULL);
1510 
1511  /* If it's a read/write request, make sure it has data inside it */
1512  if ((Srb->SrbStatus == SRB_STATUS_SUCCESS) &&
1513  ((Srb->Cdb[0] == SCSIOP_READ) || (Srb->Cdb[0] == SCSIOP_WRITE)))
1514  {
1515  ASSERT(Srb->DataTransferLength);
1516  }
1517 
1518  SrbData->CompletedRequests = DeviceExtension->InterruptData.CompletedRequests;
1519  DeviceExtension->InterruptData.CompletedRequests = SrbData;
1520  }
1521  }
1522  break;
1523 
1524  case NextRequest:
1525  DPRINT("Notify: NextRequest\n");
1526  DeviceExtension->InterruptData.Flags |= SCSI_PORT_NEXT_REQUEST_READY;
1527  break;
1528 
1529  case NextLuRequest:
1530  {
1531  UCHAR PathId;
1532  UCHAR TargetId;
1533  UCHAR Lun;
1534  PSCSI_PORT_LUN_EXTENSION LunExtension;
1535 
1536  PathId = (UCHAR)va_arg(ap, int);
1537  TargetId = (UCHAR)va_arg(ap, int);
1538  Lun = (UCHAR)va_arg(ap, int);
1539 
1540  DPRINT(
1541  "Notify: NextLuRequest(PathId %u TargetId %u Lun %u)\n", PathId, TargetId, Lun);
1542 
1543  /* Mark it in the flags field */
1544  DeviceExtension->InterruptData.Flags |= SCSI_PORT_NEXT_REQUEST_READY;
1545 
1546  /* Get the LUN extension */
1547  LunExtension = GetLunByPath(DeviceExtension, PathId, TargetId, Lun);
1548 
1549  /* If returned LunExtension is NULL, break out */
1550  if (!LunExtension)
1551  break;
1552 
1553  /* This request should not be processed if */
1554  if ((LunExtension->ReadyLun) || (LunExtension->SrbInfo.Srb))
1555  {
1556  /* Nothing to do here */
1557  break;
1558  }
1559 
1560  /* Add this LUN to the list */
1561  LunExtension->ReadyLun = DeviceExtension->InterruptData.ReadyLun;
1562  DeviceExtension->InterruptData.ReadyLun = LunExtension;
1563  }
1564  break;
1565 
1566  case ResetDetected:
1567  DPRINT("Notify: ResetDetected\n");
1568  /* Add RESET flags */
1569  DeviceExtension->InterruptData.Flags |= SCSI_PORT_RESET | SCSI_PORT_RESET_REPORTED;
1570  break;
1571 
1572  case CallDisableInterrupts:
1573  DPRINT1("UNIMPLEMENTED SCSI Notification called: CallDisableInterrupts!\n");
1574  break;
1575 
1576  case CallEnableInterrupts:
1577  DPRINT1("UNIMPLEMENTED SCSI Notification called: CallEnableInterrupts!\n");
1578  break;
1579 
1580  case RequestTimerCall:
1581  DPRINT("Notify: RequestTimerCall\n");
1582  DeviceExtension->InterruptData.Flags |= SCSI_PORT_TIMER_NEEDED;
1583  DeviceExtension->InterruptData.HwScsiTimer = (PHW_TIMER)va_arg(ap, PHW_TIMER);
1584  DeviceExtension->InterruptData.MiniportTimerValue = (ULONG)va_arg(ap, ULONG);
1585  break;
1586 
1587  case BusChangeDetected:
1588  DPRINT1("UNIMPLEMENTED SCSI Notification called: BusChangeDetected!\n");
1589  break;
1590 
1591  default:
1592  DPRINT1("Unsupported notification from WMI: %lu\n", NotificationType);
1593  break;
1594  }
1595 
1596  va_end(ap);
1597 
1598  /* Request a DPC after we're done with the interrupt */
1599  DeviceExtension->InterruptData.Flags |= SCSI_PORT_NOTIFICATION_NEEDED;
1600 }
1601 
1602 /*
1603  * @implemented
1604  */
1605 BOOLEAN NTAPI
1606 ScsiPortValidateRange(IN PVOID HwDeviceExtension,
1608  IN ULONG SystemIoBusNumber,
1609  IN SCSI_PHYSICAL_ADDRESS IoAddress,
1611  IN BOOLEAN InIoSpace)
1612 {
1613  DPRINT("ScsiPortValidateRange()\n");
1614  return(TRUE);
1615 }
1616 
1617 
1618 /* INTERNAL FUNCTIONS ********************************************************/
1619 
1620 static VOID
1622  IN PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor,
1624 {
1625  PACCESS_RANGE AccessRange;
1626  PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialData;
1627  ULONG RangeNumber;
1628  ULONG Index;
1629  ULONG Interrupt = 0;
1630  ULONG Dma = 0;
1631 
1632  RangeNumber = 0;
1633 
1634  /* Loop through all entries */
1635  for (Index = 0; Index < ResourceDescriptor->PartialResourceList.Count; Index++)
1636  {
1637  PartialData = &ResourceDescriptor->PartialResourceList.PartialDescriptors[Index];
1638 
1639  switch (PartialData->Type)
1640  {
1641  case CmResourceTypePort:
1642  /* Copy access ranges */
1643  if (RangeNumber < HwInitializationData->NumberOfAccessRanges)
1644  {
1645  AccessRange = &((*(PortConfig->AccessRanges))[RangeNumber]);
1646 
1647  AccessRange->RangeStart = PartialData->u.Port.Start;
1648  AccessRange->RangeLength = PartialData->u.Port.Length;
1649 
1650  AccessRange->RangeInMemory = FALSE;
1651  RangeNumber++;
1652  }
1653  break;
1654 
1655  case CmResourceTypeMemory:
1656  /* Copy access ranges */
1657  if (RangeNumber < HwInitializationData->NumberOfAccessRanges)
1658  {
1659  AccessRange = &((*(PortConfig->AccessRanges))[RangeNumber]);
1660 
1661  AccessRange->RangeStart = PartialData->u.Memory.Start;
1662  AccessRange->RangeLength = PartialData->u.Memory.Length;
1663 
1664  AccessRange->RangeInMemory = TRUE;
1665  RangeNumber++;
1666  }
1667  break;
1668 
1670 
1671  if (Interrupt == 0)
1672  {
1673  /* Copy interrupt data */
1674  PortConfig->BusInterruptLevel = PartialData->u.Interrupt.Level;
1675  PortConfig->BusInterruptVector = PartialData->u.Interrupt.Vector;
1676 
1677  /* Set interrupt mode accordingly to the resource */
1678  if (PartialData->Flags == CM_RESOURCE_INTERRUPT_LATCHED)
1679  {
1680  PortConfig->InterruptMode = Latched;
1681  }
1682  else if (PartialData->Flags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE)
1683  {
1684  PortConfig->InterruptMode = LevelSensitive;
1685  }
1686  }
1687  else if (Interrupt == 1)
1688  {
1689  /* Copy interrupt data */
1690  PortConfig->BusInterruptLevel2 = PartialData->u.Interrupt.Level;
1691  PortConfig->BusInterruptVector2 = PartialData->u.Interrupt.Vector;
1692 
1693  /* Set interrupt mode accordingly to the resource */
1694  if (PartialData->Flags == CM_RESOURCE_INTERRUPT_LATCHED)
1695  {
1696  PortConfig->InterruptMode2 = Latched;
1697  }
1698  else if (PartialData->Flags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE)
1699  {
1700  PortConfig->InterruptMode2 = LevelSensitive;
1701  }
1702  }
1703 
1704  Interrupt++;
1705  break;
1706 
1707  case CmResourceTypeDma:
1708 
1709  if (Dma == 0)
1710  {
1711  PortConfig->DmaChannel = PartialData->u.Dma.Channel;
1712  PortConfig->DmaPort = PartialData->u.Dma.Port;
1713 
1714  if (PartialData->Flags & CM_RESOURCE_DMA_8)
1715  PortConfig->DmaWidth = Width8Bits;
1716  else if ((PartialData->Flags & CM_RESOURCE_DMA_16) ||
1717  (PartialData->Flags & CM_RESOURCE_DMA_8_AND_16)) //???
1718  PortConfig->DmaWidth = Width16Bits;
1719  else if (PartialData->Flags & CM_RESOURCE_DMA_32)
1720  PortConfig->DmaWidth = Width32Bits;
1721  }
1722  else if (Dma == 1)
1723  {
1724  PortConfig->DmaChannel2 = PartialData->u.Dma.Channel;
1725  PortConfig->DmaPort2 = PartialData->u.Dma.Port;
1726 
1727  if (PartialData->Flags & CM_RESOURCE_DMA_8)
1728  PortConfig->DmaWidth2 = Width8Bits;
1729  else if ((PartialData->Flags & CM_RESOURCE_DMA_16) ||
1730  (PartialData->Flags & CM_RESOURCE_DMA_8_AND_16)) //???
1731  PortConfig->DmaWidth2 = Width16Bits;
1732  else if (PartialData->Flags & CM_RESOURCE_DMA_32)
1733  PortConfig->DmaWidth2 = Width32Bits;
1734  }
1735  break;
1736  }
1737  }
1738 }
1739 
1740 static PCM_RESOURCE_LIST
1743 {
1744  PCONFIGURATION_INFORMATION ConfigInfo;
1746  PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
1747  PACCESS_RANGE AccessRange;
1748  ULONG ListLength = 0, i, FullSize;
1749  ULONG Interrupt, Dma;
1750 
1751  /* Get current Atdisk usage from the system */
1752  ConfigInfo = IoGetConfigurationInformation();
1753 
1754  if (PortConfig->AtdiskPrimaryClaimed)
1755  ConfigInfo->AtDiskPrimaryAddressClaimed = TRUE;
1756 
1757  if (PortConfig->AtdiskSecondaryClaimed)
1758  ConfigInfo->AtDiskSecondaryAddressClaimed = TRUE;
1759 
1760  /* Do we use DMA? */
1761  if (PortConfig->DmaChannel != SP_UNINITIALIZED_VALUE ||
1762  PortConfig->DmaPort != SP_UNINITIALIZED_VALUE)
1763  {
1764  Dma = 1;
1765 
1766  if (PortConfig->DmaChannel2 != SP_UNINITIALIZED_VALUE ||
1767  PortConfig->DmaPort2 != SP_UNINITIALIZED_VALUE)
1768  Dma++;
1769  }
1770  else
1771  {
1772  Dma = 0;
1773  }
1774  ListLength += Dma;
1775 
1776  /* How many interrupts to we have? */
1777  Interrupt = DeviceExtension->InterruptCount;
1778  ListLength += Interrupt;
1779 
1780  /* How many access ranges do we use? */
1781  AccessRange = &((*(PortConfig->AccessRanges))[0]);
1782  for (i = 0; i < PortConfig->NumberOfAccessRanges; i++)
1783  {
1784  if (AccessRange->RangeLength != 0)
1785  ListLength++;
1786 
1787  AccessRange++;
1788  }
1789 
1790  /* Allocate the resource list, since we know its size now */
1791  FullSize = sizeof(CM_RESOURCE_LIST) + (ListLength - 1) *
1793 
1795 
1796  if (!ResourceList)
1797  return NULL;
1798 
1799  /* Zero it */
1800  RtlZeroMemory(ResourceList, FullSize);
1801 
1802  /* Initialize it */
1803  ResourceList->Count = 1;
1804  ResourceList->List[0].InterfaceType = PortConfig->AdapterInterfaceType;
1805  ResourceList->List[0].BusNumber = PortConfig->SystemIoBusNumber;
1806  ResourceList->List[0].PartialResourceList.Count = ListLength;
1807  ResourceDescriptor = ResourceList->List[0].PartialResourceList.PartialDescriptors;
1808 
1809  /* Copy access ranges array over */
1810  for (i = 0; i < PortConfig->NumberOfAccessRanges; i++)
1811  {
1812  AccessRange = &((*(PortConfig->AccessRanges))[i]);
1813 
1814  /* If the range is empty - skip it */
1815  if (AccessRange->RangeLength == 0)
1816  continue;
1817 
1818  if (AccessRange->RangeInMemory)
1819  {
1820  ResourceDescriptor->Type = CmResourceTypeMemory;
1821  ResourceDescriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
1822  }
1823  else
1824  {
1825  ResourceDescriptor->Type = CmResourceTypePort;
1826  ResourceDescriptor->Flags = CM_RESOURCE_PORT_IO;
1827  }
1828 
1829  ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1830 
1831  ResourceDescriptor->u.Memory.Start = AccessRange->RangeStart;
1832  ResourceDescriptor->u.Memory.Length = AccessRange->RangeLength;
1833 
1834  ResourceDescriptor++;
1835  }
1836 
1837  /* If we use interrupt(s), copy them */
1838  while (Interrupt)
1839  {
1840  ResourceDescriptor->Type = CmResourceTypeInterrupt;
1841 
1842  if (PortConfig->AdapterInterfaceType == MicroChannel ||
1843  ((Interrupt == 2) ? PortConfig->InterruptMode2 : PortConfig->InterruptMode) == LevelSensitive)
1844  {
1845  ResourceDescriptor->ShareDisposition = CmResourceShareShared;
1846  ResourceDescriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
1847  }
1848  else
1849  {
1850  ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1851  ResourceDescriptor->Flags = CM_RESOURCE_INTERRUPT_LATCHED;
1852  }
1853 
1854  ResourceDescriptor->u.Interrupt.Level = (Interrupt == 2) ? PortConfig->BusInterruptLevel2 : PortConfig->BusInterruptLevel;
1855  ResourceDescriptor->u.Interrupt.Vector = (Interrupt == 2) ? PortConfig->BusInterruptVector2 : PortConfig->BusInterruptVector;
1856  ResourceDescriptor->u.Interrupt.Affinity = 0;
1857 
1858  ResourceDescriptor++;
1859  Interrupt--;
1860  }
1861 
1862  /* Copy DMA data */
1863  while (Dma)
1864  {
1865  ResourceDescriptor->Type = CmResourceTypeDma;
1866  ResourceDescriptor->ShareDisposition = CmResourceShareDeviceExclusive;
1867  ResourceDescriptor->u.Dma.Channel = (Dma == 2) ? PortConfig->DmaChannel2 : PortConfig->DmaChannel;
1868  ResourceDescriptor->u.Dma.Port = (Dma == 2) ? PortConfig->DmaPort2 : PortConfig->DmaPort;
1869  ResourceDescriptor->Flags = 0;
1870 
1871  if (((Dma == 2) ? PortConfig->DmaWidth2 : PortConfig->DmaWidth) == Width8Bits)
1872  ResourceDescriptor->Flags |= CM_RESOURCE_DMA_8;
1873  else if (((Dma == 2) ? PortConfig->DmaWidth2 : PortConfig->DmaWidth) == Width16Bits)
1874  ResourceDescriptor->Flags |= CM_RESOURCE_DMA_16;
1875  else
1876  ResourceDescriptor->Flags |= CM_RESOURCE_DMA_32;
1877 
1878  if (((Dma == 2) ? PortConfig->DmaChannel2 : PortConfig->DmaChannel) == SP_UNINITIALIZED_VALUE)
1879  ResourceDescriptor->u.Dma.Channel = 0;
1880 
1881  if (((Dma == 2) ? PortConfig->DmaPort2 : PortConfig->DmaPort) == SP_UNINITIALIZED_VALUE)
1882  ResourceDescriptor->u.Dma.Port = 0;
1883 
1884  ResourceDescriptor++;
1885  Dma--;
1886  }
1887 
1888  return ResourceList;
1889 }
1890 
1891 
1892 static BOOLEAN
1898  IN ULONG BusNumber,
1899  IN OUT PPCI_SLOT_NUMBER NextSlotNumber)
1900 {
1901  PCI_COMMON_CONFIG PciConfig;
1903  ULONG DataSize;
1905  ULONG FunctionNumber;
1906  CHAR VendorIdString[8];
1907  CHAR DeviceIdString[8];
1908  UNICODE_STRING UnicodeStr;
1910  NTSTATUS Status;
1911 
1912  DPRINT ("SpiGetPciConfiguration() called\n");
1913 
1914  SlotNumber.u.AsULONG = 0;
1915 
1916  /* Loop through all devices */
1917  for (DeviceNumber = NextSlotNumber->u.bits.DeviceNumber; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++)
1918  {
1919  SlotNumber.u.bits.DeviceNumber = DeviceNumber;
1920 
1921  /* Loop through all functions */
1922  for (FunctionNumber = NextSlotNumber->u.bits.FunctionNumber; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++)
1923  {
1924  SlotNumber.u.bits.FunctionNumber = FunctionNumber;
1925 
1926  /* Get PCI config bytes */
1928  BusNumber,
1929  SlotNumber.u.AsULONG,
1930  &PciConfig,
1931  sizeof(ULONG));
1932 
1933  /* If result of HalGetBusData is 0, then the bus is wrong */
1934  if (DataSize == 0)
1935  return FALSE;
1936 
1937  /* Check if result is PCI_INVALID_VENDORID or too small */
1938  if ((DataSize < sizeof(ULONG)) ||
1939  (PciConfig.VendorID == PCI_INVALID_VENDORID))
1940  {
1941  /* Continue to try the next function */
1942  continue;
1943  }
1944 
1945  sprintf (VendorIdString, "%04hx", PciConfig.VendorID);
1946  sprintf (DeviceIdString, "%04hx", PciConfig.DeviceID);
1947 
1948  if (_strnicmp(VendorIdString, HwInitializationData->VendorId, HwInitializationData->VendorIdLength) ||
1949  _strnicmp(DeviceIdString, HwInitializationData->DeviceId, HwInitializationData->DeviceIdLength))
1950  {
1951  /* It is not our device */
1952  continue;
1953  }
1954 
1955  DPRINT("Found device 0x%04hx 0x%04hx at %1lu %2lu %1lu\n",
1956  PciConfig.VendorID,
1957  PciConfig.DeviceID,
1958  BusNumber,
1959  SlotNumber.u.bits.DeviceNumber,
1960  SlotNumber.u.bits.FunctionNumber);
1961 
1962 
1963  RtlInitUnicodeString(&UnicodeStr, L"ScsiAdapter");
1965  &UnicodeStr,
1966  DriverObject,
1967  DeviceObject,
1968  PCIBus,
1969  BusNumber,
1970  SlotNumber.u.AsULONG,
1971  &ResourceList);
1972 
1973  if (!NT_SUCCESS(Status))
1974  break;
1975 
1976  /* Create configuration information */
1978  ResourceList->List,
1979  PortConfig);
1980 
1981  /* Free the resource list */
1983 
1984  /* Set dev & fn numbers */
1985  NextSlotNumber->u.bits.DeviceNumber = DeviceNumber;
1986  NextSlotNumber->u.bits.FunctionNumber = FunctionNumber + 1;
1987 
1988  /* Save the slot number */
1989  PortConfig->SlotNumber = SlotNumber.u.AsULONG;
1990 
1991  return TRUE;
1992  }
1993  NextSlotNumber->u.bits.FunctionNumber = 0;
1994  }
1995 
1996  NextSlotNumber->u.bits.DeviceNumber = 0;
1997  DPRINT ("No device found\n");
1998 
1999  return FALSE;
2000 }
2001 
2002 
2003 
2004 /**********************************************************************
2005  * NAME INTERNAL
2006  * ScsiPortCreateClose
2007  *
2008  * DESCRIPTION
2009  * Answer requests for Create/Close calls: a null operation.
2010  *
2011  * RUN LEVEL
2012  * PASSIVE_LEVEL
2013  *
2014  * ARGUMENTS
2015  * DeviceObject
2016  * Pointer to a device object.
2017  *
2018  * Irp
2019  * Pointer to an IRP.
2020  *
2021  * RETURN VALUE
2022  * Status.
2023  */
2024 
2025 static NTSTATUS NTAPI
2027  IN PIRP Irp)
2028 {
2029  DPRINT("ScsiPortCreateClose()\n");
2030 
2031  Irp->IoStatus.Status = STATUS_SUCCESS;
2033 
2034  return STATUS_SUCCESS;
2035 }
2036 
2038 NTAPI
2040  PIRP Irp,
2042  PVOID Context)
2043 {
2045  PSCSI_SG_ADDRESS ScatterGatherList;
2046  KIRQL CurrentIrql;
2047  PIO_STACK_LOCATION IrpStack;
2048  ULONG TotalLength = 0;
2049  PSCSI_REQUEST_BLOCK_INFO SrbInfo;
2050  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
2051  PUCHAR DataVA;
2053 
2054  /* Get pointers to SrbInfo and DeviceExtension */
2055  SrbInfo = (PSCSI_REQUEST_BLOCK_INFO)Context;
2056  DeviceExtension = DeviceObject->DeviceExtension;
2057 
2058  /* Get pointer to SRB */
2059  IrpStack = IoGetCurrentIrpStackLocation(Irp);
2060  Srb = (PSCSI_REQUEST_BLOCK)IrpStack->Parameters.Others.Argument1;
2061 
2062  /* Depending on the map registers number, we allocate
2063  either from NonPagedPool, or from our static list */
2064  if (SrbInfo->NumberOfMapRegisters > MAX_SG_LIST)
2065  {
2068 
2069  if (SrbInfo->ScatterGather == NULL)
2070  ASSERT(FALSE);
2071 
2072  Srb->SrbFlags |= SRB_FLAGS_SGLIST_FROM_POOL;
2073  }
2074  else
2075  {
2076  SrbInfo->ScatterGather = SrbInfo->ScatterGatherList;
2077  }
2078 
2079  /* Use chosen SG list source */
2080  ScatterGatherList = SrbInfo->ScatterGather;
2081 
2082  /* Save map registers base */
2084 
2085  /* Determine WriteToDevice flag */
2087 
2088  /* Get virtual address of the data buffer */
2089  DataVA = (PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress) +
2090  ((PCHAR)Srb->DataBuffer - SrbInfo->DataOffset);
2091 
2092  /* Build the actual SG list */
2093  while (TotalLength < Srb->DataTransferLength)
2094  {
2095  if (!ScatterGatherList)
2096  break;
2097 
2098  ScatterGatherList->Length = Srb->DataTransferLength - TotalLength;
2099  ScatterGatherList->PhysicalAddress = IoMapTransfer(DeviceExtension->AdapterObject,
2100  Irp->MdlAddress,
2102  DataVA + TotalLength,
2103  &ScatterGatherList->Length,
2104  WriteToDevice);
2105 
2106  TotalLength += ScatterGatherList->Length;
2107  ScatterGatherList++;
2108  }
2109 
2110  /* Schedule an active request */
2111  InterlockedIncrement(&DeviceExtension->ActiveRequestCounter );
2112  KeAcquireSpinLock(&DeviceExtension->SpinLock, &CurrentIrql);
2113  KeSynchronizeExecution(DeviceExtension->Interrupt[0],
2115  DeviceObject);
2116  KeReleaseSpinLock(&DeviceExtension->SpinLock, CurrentIrql);
2117 
2119 }
2120 
2121 BOOLEAN
2122 NTAPI
2126 {
2127  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
2128 
2129  DPRINT("ScsiPortIsr() called!\n");
2130 
2131  DeviceExtension = (PSCSI_PORT_DEVICE_EXTENSION)ServiceContext;
2132 
2133  /* If interrupts are disabled - we don't expect any */
2134  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_DISABLE_INTERRUPTS)
2135  return FALSE;
2136 
2137  /* Call miniport's HwInterrupt routine */
2138  if (DeviceExtension->HwInterrupt(&DeviceExtension->MiniPortDeviceExtension) == FALSE)
2139  {
2140  /* This interrupt doesn't belong to us */
2141  return FALSE;
2142  }
2143 
2144  /* If flag of notification is set - queue a DPC */
2145  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
2146  {
2147  IoRequestDpc(DeviceExtension->Common.DeviceObject,
2148  DeviceExtension->CurrentIrp,
2149  DeviceExtension);
2150  }
2151 
2152  return TRUE;
2153 }
2154 
2155 BOOLEAN
2156 NTAPI
2158 {
2160  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
2161  ULONG Bus;
2162 
2163  DPRINT("SpiProcessTimeout() entered\n");
2164 
2165  DeviceExtension->TimerCount = -1;
2166 
2167  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_RESET)
2168  {
2169  DeviceExtension->InterruptData.Flags &= ~SCSI_PORT_RESET;
2170 
2171  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_RESET_REQUEST)
2172  {
2173  DeviceExtension->InterruptData.Flags &= ~SCSI_PORT_RESET_REQUEST;
2175  }
2176 
2177  return FALSE;
2178  }
2179  else
2180  {
2181  DPRINT("Resetting the bus\n");
2182 
2183  for (Bus = 0; Bus < DeviceExtension->NumberOfBuses; Bus++)
2184  {
2185  DeviceExtension->HwResetBus(DeviceExtension->MiniPortDeviceExtension, Bus);
2186 
2187  /* Reset flags and set reset timeout to 4 seconds */
2188  DeviceExtension->InterruptData.Flags |= SCSI_PORT_RESET;
2189  DeviceExtension->TimerCount = 4;
2190  }
2191 
2192  /* If miniport requested - request a dpc for it */
2193  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
2194  IoRequestDpc(DeviceExtension->Common.DeviceObject, NULL, NULL);
2195  }
2196 
2197  return TRUE;
2198 }
2199 
2200 
2201 BOOLEAN
2202 NTAPI
2204 {
2206  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
2207 
2208  /* Perform the bus reset */
2209  DeviceExtension = (PSCSI_PORT_DEVICE_EXTENSION)ResetParams->DeviceExtension;
2210  DeviceExtension->HwResetBus(DeviceExtension->MiniPortDeviceExtension,
2211  ResetParams->PathId);
2212 
2213  /* Set flags and start the timer */
2214  DeviceExtension->InterruptData.Flags |= SCSI_PORT_RESET;
2215  DeviceExtension->TimerCount = 4;
2216 
2217  /* If miniport requested - give him a DPC */
2218  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
2219  IoRequestDpc(DeviceExtension->Common.DeviceObject, NULL, NULL);
2220 
2221  return TRUE;
2222 }
2223 
2224 // ScsiPortIoTimer
2225 // DESCRIPTION:
2226 // This function handles timeouts and other time delayed processing
2227 //
2228 // RUN LEVEL:
2229 //
2230 // ARGUMENTS:
2231 // IN PDEVICE_OBJECT DeviceObject Device object registered with timer
2232 // IN PVOID Context the Controller extension for the
2233 // controller the device is on
2234 //
2235 static VOID NTAPI
2237  PVOID Context)
2238 {
2239  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
2240  PSCSI_PORT_LUN_EXTENSION LunExtension;
2241  PIRP Irp;
2242 
2243  DPRINT("ScsiPortIoTimer()\n");
2244 
2245  DeviceExtension = (PSCSI_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
2246 
2247  /* Protect with the spinlock */
2248  KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
2249 
2250  /* Check timeouts */
2251  if (DeviceExtension->TimerCount > 0)
2252  {
2253  /* Decrease the timeout counter */
2254  DeviceExtension->TimerCount--;
2255 
2256  if (DeviceExtension->TimerCount == 0)
2257  {
2258  /* Timeout, process it */
2259  if (KeSynchronizeExecution(DeviceExtension->Interrupt[0],
2261  DeviceExtension->Common.DeviceObject))
2262  {
2263  DPRINT("Error happened during processing timeout, but nothing critical\n");
2264  }
2265  }
2266 
2267  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
2268 
2269  /* We should exit now, since timeout is processed */
2270  return;
2271  }
2272 
2273  /* Per-Lun scanning of timeouts is needed... */
2274  for (UINT8 pathId = 0; pathId < DeviceExtension->NumberOfBuses; pathId++)
2275  {
2276  PSCSI_BUS_INFO bus = &DeviceExtension->Buses[pathId];
2277 
2278  for (PLIST_ENTRY lunEntry = bus->LunsListHead.Flink;
2279  lunEntry != &bus->LunsListHead;
2280  lunEntry = lunEntry->Flink)
2281  {
2282  LunExtension = CONTAINING_RECORD(lunEntry, SCSI_PORT_LUN_EXTENSION, LunEntry);
2283 
2284  if (LunExtension->Flags & LUNEX_BUSY)
2285  {
2286  if (!(LunExtension->Flags &
2288  {
2289  DPRINT("Retrying busy request\n");
2290 
2291  /* Clear flags, and retry busy request */
2292  LunExtension->Flags &= ~(LUNEX_BUSY | LUNEX_FULL_QUEUE);
2293  Irp = LunExtension->BusyRequest;
2294 
2295  /* Clearing busy request */
2296  LunExtension->BusyRequest = NULL;
2297 
2298  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
2299 
2301 
2302  KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
2303  }
2304  }
2305  else if (LunExtension->RequestTimeout == 0)
2306  {
2307  RESETBUS_PARAMS ResetParams;
2308 
2309  LunExtension->RequestTimeout = -1;
2310 
2311  DPRINT("Request timed out, resetting bus\n");
2312 
2313  /* Pass params to the bus reset routine */
2314  ResetParams.PathId = LunExtension->PathId;
2315  ResetParams.DeviceExtension = DeviceExtension;
2316 
2317  if (!KeSynchronizeExecution(DeviceExtension->Interrupt[0],
2318  SpiResetBus,
2319  &ResetParams))
2320  {
2321  DPRINT1("Reset failed\n");
2322  }
2323  }
2324  else if (LunExtension->RequestTimeout > 0)
2325  {
2326  /* Decrement the timeout counter */
2327  LunExtension->RequestTimeout--;
2328  }
2329  }
2330  }
2331 
2332  /* Release the spinlock */
2333  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
2334 }
2335 
2336 VOID
2337 NTAPI
2342 {
2343  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
2344 
2345  DPRINT("Miniport timer DPC\n");
2346 
2347  DeviceExtension = ((PDEVICE_OBJECT)DeviceObject)->DeviceExtension;
2348 
2349  /* Acquire the spinlock */
2350  KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
2351 
2352  /* Call the timer routine */
2353  if (DeviceExtension->HwScsiTimer != NULL)
2354  {
2355  DeviceExtension->HwScsiTimer(&DeviceExtension->MiniPortDeviceExtension);
2356  }
2357 
2358  /* Release the spinlock */
2359  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
2360 
2361  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
2362  {
2364  DeviceExtension->Common.DeviceObject,
2365  NULL,
2366  NULL);
2367  }
2368 }
2369 
2370 static NTSTATUS
2372  PHW_INITIALIZATION_DATA HwInitData,
2373  PCONFIGURATION_INFO InternalConfigInfo,
2375  BOOLEAN ZeroStruct)
2376 {
2379  PCONFIGURATION_INFORMATION DdkConfigInformation;
2380  HANDLE RootKey, Key;
2381  BOOLEAN Found;
2382  WCHAR DeviceBuffer[16];
2383  WCHAR StrBuffer[512];
2384  ULONG Bus;
2385  NTSTATUS Status;
2386 
2387  /* Zero out the struct if told so */
2388  if (ZeroStruct)
2389  {
2390  /* First zero the portconfig */
2391  RtlZeroMemory(ConfigInfo, sizeof(PORT_CONFIGURATION_INFORMATION));
2392 
2393  /* Then access ranges */
2394  RtlZeroMemory(InternalConfigInfo->AccessRanges,
2395  HwInitData->NumberOfAccessRanges * sizeof(ACCESS_RANGE));
2396 
2397  /* Initialize the struct */
2398  ConfigInfo->Length = sizeof(PORT_CONFIGURATION_INFORMATION);
2399  ConfigInfo->AdapterInterfaceType = HwInitData->AdapterInterfaceType;
2400  ConfigInfo->InterruptMode = Latched;
2401  ConfigInfo->DmaChannel = SP_UNINITIALIZED_VALUE;
2402  ConfigInfo->DmaPort = SP_UNINITIALIZED_VALUE;
2403  ConfigInfo->DmaChannel2 = SP_UNINITIALIZED_VALUE;
2404  ConfigInfo->DmaPort2 = SP_UNINITIALIZED_VALUE;
2406  ConfigInfo->NumberOfAccessRanges = HwInitData->NumberOfAccessRanges;
2407  ConfigInfo->MaximumNumberOfTargets = 8;
2408 
2409  /* Store parameters */
2410  ConfigInfo->NeedPhysicalAddresses = HwInitData->NeedPhysicalAddresses;
2411  ConfigInfo->MapBuffers = HwInitData->MapBuffers;
2412  ConfigInfo->AutoRequestSense = HwInitData->AutoRequestSense;
2413  ConfigInfo->ReceiveEvent = HwInitData->ReceiveEvent;
2414  ConfigInfo->TaggedQueuing = HwInitData->TaggedQueuing;
2415  ConfigInfo->MultipleRequestPerLu = HwInitData->MultipleRequestPerLu;
2416 
2417  /* Get the disk usage */
2418  DdkConfigInformation = IoGetConfigurationInformation();
2419  ConfigInfo->AtdiskPrimaryClaimed = DdkConfigInformation->AtDiskPrimaryAddressClaimed;
2420  ConfigInfo->AtdiskSecondaryClaimed = DdkConfigInformation->AtDiskSecondaryAddressClaimed;
2421 
2422  /* Initiator bus id is not set */
2423  for (Bus = 0; Bus < 8; Bus++)
2424  ConfigInfo->InitiatorBusId[Bus] = (CCHAR)SP_UNINITIALIZED_VALUE;
2425  }
2426 
2427  ConfigInfo->NumberOfPhysicalBreaks = 17;
2428 
2429  /* Clear this information */
2430  InternalConfigInfo->DisableTaggedQueueing = FALSE;
2431  InternalConfigInfo->DisableMultipleLun = FALSE;
2432 
2433  /* Store Bus Number */
2434  ConfigInfo->SystemIoBusNumber = InternalConfigInfo->BusNumber;
2435 
2436 TryNextAd:
2437 
2438  if (ConfigInfo->AdapterInterfaceType == Internal)
2439  {
2440  /* Open registry key for HW database */
2442  DeviceExtension->Common.DeviceObject->DriverObject->HardwareDatabase,
2444  NULL,
2445  NULL);
2446 
2447  Status = ZwOpenKey(&RootKey,
2448  KEY_READ,
2449  &ObjectAttributes);
2450 
2451  if (NT_SUCCESS(Status))
2452  {
2453  /* Create name for it */
2454  swprintf(StrBuffer, L"ScsiAdapter\\%lu",
2455  InternalConfigInfo->AdapterNumber);
2456 
2457  RtlInitUnicodeString(&UnicodeString, StrBuffer);
2458 
2459  /* Open device key */
2461  &UnicodeString,
2463  RootKey,
2464  NULL);
2465 
2466  Status = ZwOpenKey(&Key,
2467  KEY_READ,
2468  &ObjectAttributes);
2469 
2470  ZwClose(RootKey);
2471 
2472  if (NT_SUCCESS(Status))
2473  {
2474  if (InternalConfigInfo->LastAdapterNumber != InternalConfigInfo->AdapterNumber)
2475  {
2476  DPRINT("Hardware info found at %S\n", StrBuffer);
2477 
2478  /* Parse it */
2479  SpiParseDeviceInfo(DeviceExtension,
2480  Key,
2481  ConfigInfo,
2482  InternalConfigInfo,
2483  (PUCHAR)StrBuffer);
2484 
2485  InternalConfigInfo->BusNumber = 0;
2486  }
2487  else
2488  {
2489  /* Try the next adapter */
2490  InternalConfigInfo->AdapterNumber++;
2491  goto TryNextAd;
2492  }
2493  }
2494  else
2495  {
2496  /* Info was not found, exit */
2497  DPRINT1("ZwOpenKey() failed with Status=0x%08X\n", Status);
2499  }
2500  }
2501  else
2502  {
2503  DPRINT1("ZwOpenKey() failed with Status=0x%08X\n", Status);
2504  }
2505  }
2506 
2507  /* Look at device params */
2508  Key = NULL;
2509  if (InternalConfigInfo->Parameter)
2510  {
2511  ExFreePool(InternalConfigInfo->Parameter);
2512  InternalConfigInfo->Parameter = NULL;
2513  }
2514 
2515  if (InternalConfigInfo->ServiceKey != NULL)
2516  {
2517  swprintf(DeviceBuffer, L"Device%lu", InternalConfigInfo->AdapterNumber);
2518  RtlInitUnicodeString(&UnicodeString, DeviceBuffer);
2519 
2520  /* Open the service key */
2522  &UnicodeString,
2524  InternalConfigInfo->ServiceKey,
2525  NULL);
2526 
2527  Status = ZwOpenKey(&Key,
2528  KEY_READ,
2529  &ObjectAttributes);
2530  }
2531 
2532  /* Parse device key */
2533  if (InternalConfigInfo->DeviceKey != NULL)
2534  {
2535  SpiParseDeviceInfo(DeviceExtension,
2536  InternalConfigInfo->DeviceKey,
2537  ConfigInfo,
2538  InternalConfigInfo,
2539  (PUCHAR)StrBuffer);
2540  }
2541 
2542  /* Then parse hw info */
2543  if (Key != NULL)
2544  {
2545  if (InternalConfigInfo->LastAdapterNumber != InternalConfigInfo->AdapterNumber)
2546  {
2547  SpiParseDeviceInfo(DeviceExtension,
2548  Key,
2549  ConfigInfo,
2550  InternalConfigInfo,
2551  (PUCHAR)StrBuffer);
2552 
2553  /* Close the key */
2554  ZwClose(Key);
2555  }
2556  else
2557  {
2558  /* Adapter not found, go try the next one */
2559  InternalConfigInfo->AdapterNumber++;
2560 
2561  /* Close the key */
2562  ZwClose(Key);
2563 
2564  goto TryNextAd;
2565  }
2566  }
2567 
2568  /* Update the last adapter number */
2569  InternalConfigInfo->LastAdapterNumber = InternalConfigInfo->AdapterNumber;
2570 
2571  /* Do we have this kind of bus at all? */
2572  Found = FALSE;
2574  &InternalConfigInfo->BusNumber,
2575  NULL,
2576  NULL,
2577  NULL,
2578  NULL,
2580  &Found);
2581 
2582  /* This bus was not found */
2583  if (!Found)
2584  {
2586 
2587  /* Check for EISA */
2588  if (HwInitData->AdapterInterfaceType == Isa)
2589  {
2591  &InternalConfigInfo->BusNumber,
2592  NULL,
2593  NULL,
2594  NULL,
2595  NULL,
2597  &Found);
2598 
2599  /* Return respectively */
2600  if (Found)
2601  return STATUS_SUCCESS;
2602  else
2604  }
2605  else
2606  {
2608  }
2609  }
2610  else
2611  {
2612  return STATUS_SUCCESS;
2613  }
2614 }
2615 
2616 static VOID
2618  IN HANDLE Key,
2620  IN PCONFIGURATION_INFO InternalConfigInfo,
2621  IN PUCHAR Buffer)
2622 {
2623  PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
2624  PCM_FULL_RESOURCE_DESCRIPTOR FullResource;
2625  PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
2626  PCM_SCSI_DEVICE_DATA ScsiDeviceData;
2627  ULONG Length, Count, Dma = 0, Interrupt = 0;
2628  ULONG Index = 0, RangeCount = 0;
2632 
2633 
2634  KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION) Buffer;
2635 
2636  /* Loop through all values in the device node */
2637  while(TRUE)
2638  {
2639  Status = ZwEnumerateValueKey(Key,
2640  Index,
2642  Buffer,
2643  512,
2644  &Length);
2645 
2646  if (!NT_SUCCESS(Status))
2647  return;
2648 
2649  Index++;
2650 
2651  /* Length for DWORD is ok? */
2652  if (KeyValueInformation->Type == REG_DWORD &&
2653  KeyValueInformation->DataLength != sizeof(ULONG))
2654  {
2655  continue;
2656  }
2657 
2658  /* Get MaximumLogicalUnit */
2659  if (_wcsnicmp(KeyValueInformation->Name, L"MaximumLogicalUnit",
2660  KeyValueInformation->NameLength/2) == 0)
2661  {
2662 
2663  if (KeyValueInformation->Type != REG_DWORD)
2664  {
2665  DPRINT("Bad data type for MaximumLogicalUnit\n");
2666  continue;
2667  }
2668 
2669  DeviceExtension->MaxLunCount = *((PUCHAR)
2670  (Buffer + KeyValueInformation->DataOffset));
2671 
2672  /* Check / reset if needed */
2673  if (DeviceExtension->MaxLunCount > SCSI_MAXIMUM_LOGICAL_UNITS)
2674  DeviceExtension->MaxLunCount = SCSI_MAXIMUM_LOGICAL_UNITS;
2675 
2676  DPRINT("MaximumLogicalUnit = %d\n", DeviceExtension->MaxLunCount);
2677  }
2678 
2679  /* Get InitiatorTargetId */
2680  if (_wcsnicmp(KeyValueInformation->Name, L"InitiatorTargetId",
2681  KeyValueInformation->NameLength / 2) == 0)
2682  {
2683 
2684  if (KeyValueInformation->Type != REG_DWORD)
2685  {
2686  DPRINT("Bad data type for InitiatorTargetId\n");
2687  continue;
2688  }
2689 
2690  ConfigInfo->InitiatorBusId[0] = *((PUCHAR)
2691  (Buffer + KeyValueInformation->DataOffset));
2692 
2693  /* Check / reset if needed */
2694  if (ConfigInfo->InitiatorBusId[0] > ConfigInfo->MaximumNumberOfTargets - 1)
2695  ConfigInfo->InitiatorBusId[0] = (CCHAR)-1;
2696 
2697  DPRINT("InitiatorTargetId = %d\n", ConfigInfo->InitiatorBusId[0]);
2698  }
2699 
2700  /* Get ScsiDebug */
2701  if (_wcsnicmp(KeyValueInformation->Name, L"ScsiDebug",
2702  KeyValueInformation->NameLength/2) == 0)
2703  {
2704  DPRINT("ScsiDebug key not supported\n");
2705  }
2706 
2707  /* Check for a breakpoint */
2708  if (_wcsnicmp(KeyValueInformation->Name, L"BreakPointOnEntry",
2709  KeyValueInformation->NameLength/2) == 0)
2710  {
2711  DPRINT1("Breakpoint on entry requested!\n");
2712  DbgBreakPoint();
2713  }
2714 
2715  /* Get DisableSynchronousTransfers */
2716  if (_wcsnicmp(KeyValueInformation->Name, L"DisableSynchronousTransfers",
2717  KeyValueInformation->NameLength/2) == 0)
2718  {
2719  DeviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
2720  DPRINT("Synch transfers disabled\n");
2721  }
2722 
2723  /* Get DisableDisconnects */
2724  if (_wcsnicmp(KeyValueInformation->Name, L"DisableDisconnects",
2725  KeyValueInformation->NameLength/2) == 0)
2726  {
2727  DeviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_DISCONNECT;
2728  DPRINT("Disconnects disabled\n");
2729  }
2730 
2731  /* Get DisableTaggedQueuing */
2732  if (_wcsnicmp(KeyValueInformation->Name, L"DisableTaggedQueuing",
2733  KeyValueInformation->NameLength/2) == 0)
2734  {
2735  InternalConfigInfo->DisableTaggedQueueing = TRUE;
2736  DPRINT("Tagged queueing disabled\n");
2737  }
2738 
2739  /* Get DisableMultipleRequests */
2740  if (_wcsnicmp(KeyValueInformation->Name, L"DisableMultipleRequests",
2741  KeyValueInformation->NameLength/2) == 0)
2742  {
2743  InternalConfigInfo->DisableMultipleLun = TRUE;
2744  DPRINT("Multiple requests disabled\n");
2745  }
2746 
2747  /* Get DriverParameters */
2748  if (_wcsnicmp(KeyValueInformation->Name, L"DriverParameters",
2749  KeyValueInformation->NameLength/2) == 0)
2750  {
2751  /* Skip if nothing */
2752  if (KeyValueInformation->DataLength == 0)
2753  continue;
2754 
2755  /* If there was something previously allocated - free it */
2756  if (InternalConfigInfo->Parameter != NULL)
2757  ExFreePool(InternalConfigInfo->Parameter);
2758 
2759  /* Allocate it */
2760  InternalConfigInfo->Parameter = ExAllocatePoolWithTag(NonPagedPool,
2761  KeyValueInformation->DataLength, TAG_SCSIPORT);
2762 
2763  if (InternalConfigInfo->Parameter != NULL)
2764  {
2765  if (KeyValueInformation->Type != REG_SZ)
2766  {
2767  /* Just copy */
2768  RtlCopyMemory(
2769  InternalConfigInfo->Parameter,
2770  (PCCHAR)KeyValueInformation + KeyValueInformation->DataOffset,
2771  KeyValueInformation->DataLength);
2772  }
2773  else
2774  {
2775  /* If it's a unicode string, convert it to ansi */
2776  UnicodeString.Length = (USHORT)KeyValueInformation->DataLength;
2777  UnicodeString.MaximumLength = (USHORT)KeyValueInformation->DataLength;
2778  UnicodeString.Buffer =
2779  (PWSTR)((PCCHAR)KeyValueInformation + KeyValueInformation->DataOffset);
2780 
2781  AnsiString.Length = 0;
2782  AnsiString.MaximumLength = (USHORT)KeyValueInformation->DataLength;
2783  AnsiString.Buffer = (PCHAR)InternalConfigInfo->Parameter;
2784 
2786  &UnicodeString,
2787  FALSE);
2788 
2789  /* In case of error, free the allocated space */
2790  if (!NT_SUCCESS(Status))
2791  {
2792  ExFreePool(InternalConfigInfo->Parameter);
2793  InternalConfigInfo->Parameter = NULL;
2794  }
2795 
2796  }
2797  }
2798 
2799  DPRINT("Found driver parameter\n");
2800  }
2801 
2802  /* Get MaximumSGList */
2803  if (_wcsnicmp(KeyValueInformation->Name, L"MaximumSGList",
2804  KeyValueInformation->NameLength/2) == 0)
2805  {
2806  if (KeyValueInformation->Type != REG_DWORD)
2807  {
2808  DPRINT("Bad data type for MaximumSGList\n");
2809  continue;
2810  }
2811 
2812  ConfigInfo->NumberOfPhysicalBreaks = *((PUCHAR)(Buffer + KeyValueInformation->DataOffset));
2813 
2814  /* Check / fix */
2815  if (ConfigInfo->NumberOfPhysicalBreaks > SCSI_MAXIMUM_PHYSICAL_BREAKS)
2816  {
2817  ConfigInfo->NumberOfPhysicalBreaks = SCSI_MAXIMUM_PHYSICAL_BREAKS;
2818  }
2819  else if (ConfigInfo->NumberOfPhysicalBreaks < SCSI_MINIMUM_PHYSICAL_BREAKS)
2820  {
2821  ConfigInfo->NumberOfPhysicalBreaks = SCSI_MINIMUM_PHYSICAL_BREAKS;
2822  }
2823 
2824  DPRINT("MaximumSGList = %d\n", ConfigInfo->NumberOfPhysicalBreaks);
2825  }
2826 
2827  /* Get NumberOfRequests */
2828  if (_wcsnicmp(KeyValueInformation->Name, L"NumberOfRequests",
2829  KeyValueInformation->NameLength/2) == 0)
2830  {
2831  if (KeyValueInformation->Type != REG_DWORD)
2832  {
2833  DPRINT("NumberOfRequests has wrong data type\n");
2834  continue;
2835  }
2836 
2837  DeviceExtension->RequestsNumber = *((PUCHAR)(Buffer + KeyValueInformation->DataOffset));
2838 
2839  /* Check / fix */
2840  if (DeviceExtension->RequestsNumber < 16)
2841  {
2842  DeviceExtension->RequestsNumber = 16;
2843  }
2844  else if (DeviceExtension->RequestsNumber > 512)
2845  {
2846  DeviceExtension->RequestsNumber = 512;
2847  }
2848 
2849  DPRINT("Number Of Requests = %d\n", DeviceExtension->RequestsNumber);
2850  }
2851 
2852  /* Get resource list */
2853  if (_wcsnicmp(KeyValueInformation->Name, L"ResourceList",
2854  KeyValueInformation->NameLength/2) == 0 ||
2855  _wcsnicmp(KeyValueInformation->Name, L"Configuration Data",
2856  KeyValueInformation->NameLength/2) == 0 )
2857  {
2858  if (KeyValueInformation->Type != REG_FULL_RESOURCE_DESCRIPTOR ||
2859  KeyValueInformation->DataLength < sizeof(REG_FULL_RESOURCE_DESCRIPTOR))
2860  {
2861  DPRINT("Bad data type for ResourceList\n");
2862  continue;
2863  }
2864  else
2865  {
2866  DPRINT("Found ResourceList\n");
2867  }
2868 
2869  FullResource = (PCM_FULL_RESOURCE_DESCRIPTOR)(Buffer + KeyValueInformation->DataOffset);
2870 
2871  /* Copy some info from it */
2872  InternalConfigInfo->BusNumber = FullResource->BusNumber;
2873  ConfigInfo->SystemIoBusNumber = FullResource->BusNumber;
2874 
2875  /* Loop through it */
2876  for (Count = 0; Count < FullResource->PartialResourceList.Count; Count++)
2877  {
2878  /* Get partial descriptor */
2879  PartialDescriptor =
2881 
2882  /* Check datalength */
2883  if ((ULONG)((PCHAR)(PartialDescriptor + 1) -
2884  (PCHAR)FullResource) > KeyValueInformation->DataLength)
2885  {
2886  DPRINT("Resource data is of incorrect size\n");
2887  break;
2888  }
2889 
2890  switch (PartialDescriptor->Type)
2891  {
2892  case CmResourceTypePort:
2893  if (RangeCount >= ConfigInfo->NumberOfAccessRanges)
2894  {
2895  DPRINT("Too many access ranges\n");
2896  continue;
2897  }
2898 
2899  InternalConfigInfo->AccessRanges[RangeCount].RangeInMemory = FALSE;
2900  InternalConfigInfo->AccessRanges[RangeCount].RangeStart = PartialDescriptor->u.Port.Start;
2901  InternalConfigInfo->AccessRanges[RangeCount].RangeLength = PartialDescriptor->u.Port.Length;
2902  RangeCount++;
2903 
2904  break;
2905 
2906  case CmResourceTypeMemory:
2907  if (RangeCount >= ConfigInfo->NumberOfAccessRanges)
2908  {
2909  DPRINT("Too many access ranges\n");
2910  continue;
2911  }
2912 
2913  InternalConfigInfo->AccessRanges[RangeCount].RangeInMemory = TRUE;
2914  InternalConfigInfo->AccessRanges[RangeCount].RangeStart = PartialDescriptor->u.Memory.Start;
2915  InternalConfigInfo->AccessRanges[RangeCount].RangeLength = PartialDescriptor->u.Memory.Length;
2916  RangeCount++;
2917 
2918  break;
2919 
2921 
2922  if (Interrupt == 0)
2923  {
2924  ConfigInfo->BusInterruptLevel =
2925  PartialDescriptor->u.Interrupt.Level;
2926 
2927  ConfigInfo->BusInterruptVector =
2928  PartialDescriptor->u.Interrupt.Vector;
2929 
2930  ConfigInfo->InterruptMode = (PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED) ? Latched : LevelSensitive;
2931  }
2932  else if (Interrupt == 1)
2933  {
2934  ConfigInfo->BusInterruptLevel2 =
2935  PartialDescriptor->u.Interrupt.Level;
2936 
2937  ConfigInfo->BusInterruptVector2 =
2938  PartialDescriptor->u.Interrupt.Vector;
2939 
2940  ConfigInfo->InterruptMode2 = (PartialDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED) ? Latched : LevelSensitive;
2941  }
2942 
2943  Interrupt++;
2944  break;
2945 
2946  case CmResourceTypeDma:
2947 
2948  if (Dma == 0)
2949  {
2950  ConfigInfo->DmaChannel = PartialDescriptor->u.Dma.Channel;
2951  ConfigInfo->DmaPort = PartialDescriptor->u.Dma.Port;
2952 
2953  if (PartialDescriptor->Flags & CM_RESOURCE_DMA_8)
2954  ConfigInfo->DmaWidth = Width8Bits;
2955  else if ((PartialDescriptor->Flags & CM_RESOURCE_DMA_16) ||
2956  (PartialDescriptor->Flags & CM_RESOURCE_DMA_8_AND_16)) //???
2957  ConfigInfo->DmaWidth = Width16Bits;
2958  else if (PartialDescriptor->Flags & CM_RESOURCE_DMA_32)
2959  ConfigInfo->DmaWidth = Width32Bits;
2960  }
2961  else if (Dma == 1)
2962  {
2963  ConfigInfo->DmaChannel2 = PartialDescriptor->u.Dma.Channel;
2964  ConfigInfo->DmaPort2 = PartialDescriptor->u.Dma.Port;
2965 
2966  if (PartialDescriptor->Flags & CM_RESOURCE_DMA_8)
2967  ConfigInfo->DmaWidth2 = Width8Bits;
2968  else if ((PartialDescriptor->Flags & CM_RESOURCE_DMA_16) ||
2969  (PartialDescriptor->Flags & CM_RESOURCE_DMA_8_AND_16)) //???
2970  ConfigInfo->DmaWidth2 = Width16Bits;
2971  else if (PartialDescriptor->Flags & CM_RESOURCE_DMA_32)
2972  ConfigInfo->DmaWidth2 = Width32Bits;
2973  }
2974 
2975  Dma++;
2976  break;
2977 
2979  if (PartialDescriptor->u.DeviceSpecificData.DataSize <
2980  sizeof(CM_SCSI_DEVICE_DATA) ||
2981  (PCHAR) (PartialDescriptor + 1) - (PCHAR)FullResource +
2982  PartialDescriptor->u.DeviceSpecificData.DataSize >
2983  KeyValueInformation->DataLength)
2984  {
2985  DPRINT("Resource data length is incorrect");
2986  break;
2987  }
2988 
2989  /* Set only one field from it */
2990  ScsiDeviceData = (PCM_SCSI_DEVICE_DATA) (PartialDescriptor+1);
2991  ConfigInfo->InitiatorBusId[0] = ScsiDeviceData->HostIdentifier;
2992  break;
2993  }
2994  }
2995  }
2996  }
2997 }
2998 
2999 NTSTATUS
3000 NTAPI
3002  IN PUNICODE_STRING PathName,
3004  IN ULONG BusNumber,
3006  IN CONFIGURATION_TYPE ControllerType,
3007  IN ULONG ControllerNumber,
3008  IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
3009  IN CONFIGURATION_TYPE PeripheralType,
3010  IN ULONG PeripheralNumber,
3011  IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation)
3012 {
3014  /* We just set our Found variable to TRUE */
3015 
3016  *Found = TRUE;
3017  return STATUS_SUCCESS;
3018 }
3019 
3021 NTAPI
3023  IN PIRP Irp,
3025  IN PVOID Context)
3026 {
3027  KIRQL Irql;
3028  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
3029 
3030  /* Guard access with the spinlock */
3031  KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql);
3032 
3033  /* Save MapRegisterBase we've got here */
3034  DeviceExtension->MapRegisterBase = MapRegisterBase;
3035 
3036  /* Start pending request */
3037  KeSynchronizeExecution(DeviceExtension->Interrupt[0],
3039 
3040  /* Release spinlock we took */
3041  KeReleaseSpinLock(&DeviceExtension->SpinLock, Irql);
3042 
3043  return KeepObject;
3044 }
3045 
3046 #undef ScsiPortConvertPhysicalAddressToUlong
3047 /*
3048  * @implemented
3049  */
3050 ULONG NTAPI
3052 {
3053  DPRINT("ScsiPortConvertPhysicalAddressToUlong()\n");
3054  return(Address.u.LowPart);
3055 }
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:232
FORCEINLINE VOID IoInitializeDpcRequest(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIO_DPC_ROUTINE DpcRoutine)
Definition: iofuncs.h:2836
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:721
#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:224
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
INTERFACE_TYPE AdapterInterfaceType
Definition: srb.h:55
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:252
_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
#define ALIGN_UP(size, type)
Definition: umtypes.h:91
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:1756
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define DbgPrint
Definition: loader.c:25
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
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@375::@380 Memory
_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:399
struct _DEVICE_OBJECT * PDEVICE_OBJECT
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:79
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:2268
_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
#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:3001
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
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:2236
_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:1457
#define TAG_SCSIPORT
Definition: scsiport.h:21
BOOLEAN MultipleRequestPerLu
Definition: srb.h:576
VOID NTAPI ScsiPortCompleteRequest(IN PVOID HwDeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN UCHAR SrbStatus)
Definition: scsiport.c:498
ACCESS_RANGE(* AccessRanges)[]
Definition: srb.h:70
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:2617
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
#define swprintf
Definition: precomp.h:40
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1155
_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:2268
void DbgBreakPoint()
Definition: mach.c:553
#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:243
_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:607
#define CM_RESOURCE_MEMORY_READ_WRITE
Definition: cmtypes.h:120
BOOLEAN AtDiskPrimaryAddressClaimed
Definition: iotypes.h:4478
#define CmResourceTypePort
Definition: hwresource.cpp:123
#define DEVICE_DESCRIPTION_VERSION
Definition: iotypes.h:2060
BOOLEAN AtDiskSecondaryAddressClaimed
Definition: iotypes.h:4479
#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:2123
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@375::@381 Dma
BOOLEAN AutoRequestSense
Definition: srb.h:575
BOOLEAN TaggedQueuing
Definition: srb.h:574
VOID NTAPI SpiMiniportTimerDpc(IN struct _KDPC *Dpc, IN PVOID DeviceObject, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: scsiport.c:2338
uint32_t ULONG_PTR
Definition: typedefs.h:65
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@375::@378 Interrupt
#define SP_UNTAGGED
Definition: srb.h:225
#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:562
#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:540
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:1741
_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:573
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:2039
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
BOOLEAN NTAPI SpiProcessTimeout(PVOID ServiceContext)
Definition: scsiport.c:2157
BOOLEAN NTAPI SpiResetBus(PVOID ServiceContext)
Definition: scsiport.c:2203
#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
long LONG
Definition: pedump.c:60
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@375 u
#define SRB_FLAGS_SGLIST_FROM_POOL
Definition: srb.h:401
#define SCSI_PORT_NEXT_REQUEST_READY
Definition: scsiport.c:54
VOID NTAPI ScsiPortIoMapTransfer(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN PVOID LogicalAddress, IN ULONG Length)
Definition: scsiport.c:1271
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:81
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:462
ULONG NTAPI ScsiPortInitialize(IN PVOID Argument1, IN PVOID Argument2, IN PHW_INITIALIZATION_DATA HwInitializationData, IN PVOID HwContext OPTIONAL)
Definition: scsiport.c:1117
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
#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:2371
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:332
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
_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 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:97
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
#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:643
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:60
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:1011
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
int Count
Definition: noreturn.cpp:7
BOOLEAN ReceiveEvent
Definition: srb.h:577
#define PCI_INVALID_VENDORID
Definition: iotypes.h:3597
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@375::@384 DeviceSpecificData
#define ASSERT(a)
Definition: mode.c:45
if(!(yy_init))
Definition: macro.lex.yy.c:714
__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:594
NTSTATUS FdoStartAdapter(_In_ PSCSI_PORT_DEVICE_EXTENSION PortExtension)
Definition: fdo.c:605
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define PCI_MAX_DEVICES
Definition: iotypes.h:3594
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@375::@377 Port
FORCEINLINE VOID IoRequestDpc(_Inout_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Irp, _In_opt_ __drv_aliasesMem PVOID Context)
Definition: iofuncs.h:2746
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
#define SP_RETURN_NOT_FOUND
Definition: srb.h:513
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3219
BOOLEAN AtdiskSecondaryClaimed
Definition: srb.h:79
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2937
va_start(ap, x)
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
#define SP_RETURN_FOUND
Definition: srb.h:514
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:798
ULONG NTAPI ScsiPortConvertPhysicalAddressToUlong(IN SCSI_PHYSICAL_ADDRESS Address)
Definition: scsiport.c:512
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:388
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:1308
static const WCHAR L[]
Definition: oid.c:1250
#define CM_RESOURCE_DMA_8
Definition: cmtypes.h:131
Definition: ketypes.h:687
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2285
ULONG InternalDebugLevel
Definition: scsiport.c:17
signed long long INT64
PVOID NTAPI IoGetDriverObjectExtension(IN PDRIVER_OBJECT DriverObject, IN PVOID ClientIdentificationAddress)
Definition: driver.c:1834
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
CONFIGURATION_TYPE
Definition: iotypes.h:4389
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
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:569
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:3595
_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:316
SCSI_SG_ADDRESS ScatterGatherList[MAX_SG_LIST]
Definition: scsiport.h:133
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define _In_
Definition: no_sal2.h:158
IO_ALLOCATION_ACTION NTAPI ScsiPortAllocateAdapterChannel(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID MapRegisterBase, IN PVOID Context)
Definition: scsiport.c:3022
ULONG NTAPI ScsiPortGetBusData(IN PVOID DeviceExtension, IN ULONG BusDataType, IN ULONG SystemIoBusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Length)
Definition: scsiport.c:549
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
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:506
#define va_arg(ap, T)
Definition: acmsvcex.h:89
PHW_RESET_BUS HwResetBus
Definition: scsiport.c:84
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
Definition: iotypes.h:212
#define InterlockedIncrement
Definition: armddk.h:53
PADAPTER_OBJECT AdapterObject
Definition: scsiport.c:87
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:83
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:1893
_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:393
#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:2026
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:1481
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:448
#define CM_RESOURCE_INTERRUPT_LATCHED
Definition: cmtypes.h:144
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
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:557
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:333
#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:142
#define SCSISTAT_GOOD
Definition: cdrw_hw.h:1078
NTSTATUS FdoDispatchPnp(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: fdo.c:754
#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:572
#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:1621
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:1283
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
PVOID NTAPI ScsiPortGetVirtualAddress(IN PVOID HwDeviceExtension, IN SCSI_PHYSICAL_ADDRESS PhysicalAddress)
Definition: scsiport.c:806
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1229
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
#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:3124
#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:711
#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
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:362
VOID NTAPI ScsiPortMoveMemory(IN PVOID WriteBuffer, IN PVOID ReadBuffer, IN ULONG Length)
Definition: scsiport.c:1298
_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:531
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define REG_SZ
Definition: layer.c:22
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68