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