ReactOS  0.4.13-dev-259-g5ca9c9c
scsiport.c File Reference
#include "precomp.h"
#include <ntddk.h>
#include <stdio.h>
#include <scsi.h>
#include <ntddscsi.h>
#include <ntdddisk.h>
#include <mountdev.h>
#include <debug.h>
#include "scsiport_int.h"
Include dependency graph for scsiport.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

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)
 
static NTSTATUS NTAPI ScsiPortCreateClose (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static NTSTATUS NTAPI ScsiPortDispatchScsi (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static NTSTATUS NTAPI ScsiPortDeviceControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static VOID NTAPI ScsiPortStartIo (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
static BOOLEAN NTAPI ScsiPortStartPacket (IN OUT PVOID Context)
 
IO_ALLOCATION_ACTION NTAPI SpiAdapterControl (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID MapRegisterBase, PVOID Context)
 
static PSCSI_PORT_LUN_EXTENSION SpiAllocateLunExtension (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 
static PSCSI_PORT_LUN_EXTENSION SpiGetLunExtension (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun)
 
static PSCSI_REQUEST_BLOCK_INFO SpiAllocateSrbStructures (PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, PSCSI_PORT_LUN_EXTENSION LunExtension, PSCSI_REQUEST_BLOCK Srb)
 
static NTSTATUS SpiSendInquiry (IN PDEVICE_OBJECT DeviceObject, IN OUT PSCSI_LUN_INFO LunInfo)
 
static VOID SpiScanAdapter (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 
static NTSTATUS SpiGetInquiryData (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
 
static PSCSI_REQUEST_BLOCK_INFO SpiGetSrbData (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN UCHAR QueueTag)
 
static BOOLEAN NTAPI ScsiPortIsr (IN PKINTERRUPT Interrupt, IN PVOID ServiceContext)
 
static VOID NTAPI ScsiPortDpcForIsr (IN PKDPC Dpc, IN PDEVICE_OBJECT DpcDeviceObject, IN PIRP DpcIrp, IN PVOID DpcContext)
 
static VOID NTAPI ScsiPortIoTimer (PDEVICE_OBJECT DeviceObject, PVOID Context)
 
IO_ALLOCATION_ACTION NTAPI ScsiPortAllocateAdapterChannel (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID MapRegisterBase, IN PVOID Context)
 
static NTSTATUS SpiBuildDeviceMap (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING RegistryPath)
 
static NTSTATUS SpiStatusSrbToNt (UCHAR SrbStatus)
 
static VOID SpiSendRequestSense (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
NTSTATUS NTAPI SpiCompletionRoutine (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
static VOID NTAPI SpiProcessCompletedRequest (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN PSCSI_REQUEST_BLOCK_INFO SrbInfo, OUT PBOOLEAN NeedToCallStartIo)
 
VOID NTAPI SpiGetNextRequestFromLun (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN PSCSI_PORT_LUN_EXTENSION LunExtension)
 
VOID NTAPI SpiMiniportTimerDpc (IN struct _KDPC *Dpc, IN PVOID DeviceObject, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
 
static NTSTATUS SpiCreatePortConfig (PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, PHW_INITIALIZATION_DATA HwInitData, PCONFIGURATION_INFO InternalConfigInfo, PPORT_CONFIGURATION_INFORMATION ConfigInfo, BOOLEAN FirstCall)
 
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)
 
static VOID SpiParseDeviceInfo (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN HANDLE Key, IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, IN PCONFIGURATION_INFO InternalConfigInfo, IN PUCHAR Buffer)
 
static VOID SpiResourceToConfig (IN PHW_INITIALIZATION_DATA HwInitializationData, IN PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor, IN PPORT_CONFIGURATION_INFORMATION PortConfig)
 
static PCM_RESOURCE_LIST SpiConfigToResource (PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, PPORT_CONFIGURATION_INFORMATION PortConfig)
 
static VOID SpiCleanupAfterInit (PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 
static NTSTATUS SpiHandleAttachRelease (PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
 
static NTSTATUS SpiAllocateCommonBuffer (PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, ULONG NonCachedSize)
 
NTHALAPI ULONG NTAPI HalGetBusData (BUS_DATA_TYPE, ULONG, ULONG, PVOID, ULONG)
 
NTHALAPI ULONG NTAPI HalGetInterruptVector (INTERFACE_TYPE, ULONG, ULONG, ULONG, PKIRQL, PKAFFINITY)
 
NTHALAPI NTSTATUS NTAPI HalAssignSlotResources (PUNICODE_STRING, PUNICODE_STRING, PDRIVER_OBJECT, PDEVICE_OBJECT, INTERFACE_TYPE, ULONG, ULONG, PCM_RESOURCE_LIST *)
 
NTSTATUS NTAPI DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
 
VOID ScsiDebugPrint (IN ULONG DebugPrintLevel, IN PCHAR DebugMessage,...)
 
VOID NTAPI SpiCompleteRequest (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK_INFO SrbInfo, IN UCHAR SrbStatus)
 
VOID NTAPI ScsiPortCompleteRequest (IN PVOID HwDeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN UCHAR SrbStatus)
 
VOID NTAPI ScsiPortFlushDma (IN PVOID HwDeviceExtension)
 
VOID NTAPI ScsiPortFreeDeviceBase (IN PVOID HwDeviceExtension, IN PVOID MappedAddress)
 
ULONG NTAPI ScsiPortGetBusData (IN PVOID DeviceExtension, IN ULONG BusDataType, IN ULONG SystemIoBusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Length)
 
ULONG NTAPI ScsiPortSetBusDataByOffset (IN PVOID DeviceExtension, IN ULONG BusDataType, IN ULONG SystemIoBusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
 
PVOID NTAPI ScsiPortGetDeviceBase (IN PVOID HwDeviceExtension, IN INTERFACE_TYPE BusType, IN ULONG SystemIoBusNumber, IN SCSI_PHYSICAL_ADDRESS IoAddress, IN ULONG NumberOfBytes, IN BOOLEAN InIoSpace)
 
PVOID NTAPI ScsiPortGetLogicalUnit (IN PVOID HwDeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun)
 
SCSI_PHYSICAL_ADDRESS NTAPI ScsiPortGetPhysicalAddress (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb OPTIONAL, IN PVOID VirtualAddress, OUT ULONG *Length)
 
PSCSI_REQUEST_BLOCK NTAPI ScsiPortGetSrb (IN PVOID DeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN LONG QueueTag)
 
PVOID NTAPI ScsiPortGetUncachedExtension (IN PVOID HwDeviceExtension, IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, IN ULONG NumberOfBytes)
 
PVOID NTAPI ScsiPortGetVirtualAddress (IN PVOID HwDeviceExtension, IN SCSI_PHYSICAL_ADDRESS PhysicalAddress)
 
static VOID SpiInitOpenKeys (PCONFIGURATION_INFO ConfigInfo, PUNICODE_STRING RegistryPath)
 
ULONG NTAPI ScsiPortInitialize (IN PVOID Argument1, IN PVOID Argument2, IN struct _HW_INITIALIZATION_DATA *HwInitializationData, IN PVOID HwContext)
 
VOID NTAPI ScsiPortIoMapTransfer (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN PVOID LogicalAddress, IN ULONG Length)
 
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)
 
VOID NTAPI ScsiPortMoveMemory (OUT PVOID Destination, IN PVOID Source, IN ULONG Length)
 
VOID ScsiPortNotification (IN SCSI_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension,...)
 
BOOLEAN NTAPI ScsiPortValidateRange (IN PVOID HwDeviceExtension, IN INTERFACE_TYPE BusType, IN ULONG SystemIoBusNumber, IN SCSI_PHYSICAL_ADDRESS IoAddress, IN ULONG NumberOfBytes, IN BOOLEAN InIoSpace)
 
BOOLEAN NTAPI SpiSaveInterruptData (IN PVOID Context)
 
BOOLEAN NTAPI SpiProcessTimeout (PVOID ServiceContext)
 
BOOLEAN NTAPI SpiResetBus (PVOID ServiceContext)
 
ULONG NTAPI ScsiPortConvertPhysicalAddressToUlong (IN SCSI_PHYSICAL_ADDRESS Address)
 

Variables

ULONG InternalDebugLevel = 0x00
 
static DRIVER_DISPATCH ScsiPortDispatchScsi
 
static DRIVER_STARTIO ScsiPortStartIo
 
static IO_COMPLETION_ROUTINE SpiCompletionRoutine
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 39 of file scsiport.c.

Function Documentation

◆ DriverEntry()

NTSTATUS NTAPI DriverEntry ( IN PDRIVER_OBJECT  DriverObject,
IN PUNICODE_STRING  RegistryPath 
)

Definition at line 245 of file scsiport.c.

247 {
248  DPRINT("ScsiPort Driver %s\n", VERSION);
249  return(STATUS_SUCCESS);
250 }
void DPRINT(...)
Definition: polytest.cpp:61
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define VERSION
Definition: rdesktop.h:45

◆ HalAssignSlotResources()

◆ HalGetBusData()

◆ HalGetInterruptVector()

◆ ScsiDebugPrint()

VOID ScsiDebugPrint ( IN ULONG  DebugPrintLevel,
IN PCHAR  DebugMessage,
  ... 
)

Definition at line 280 of file scsiport.c.

283 {
284  char Buffer[256];
285  va_list ap;
286 
287  if (DebugPrintLevel > InternalDebugLevel)
288  return;
289 
290  va_start(ap, DebugMessage);
291  vsprintf(Buffer, DebugMessage, ap);
292  va_end(ap);
293 
294  DbgPrint(Buffer);
295 }
#define DbgPrint
Definition: loader.c:25
ULONG InternalDebugLevel
Definition: scsiport.c:44
#define va_end(ap)
Definition: acmsvcex.h:90
char * va_list
Definition: acmsvcex.h:78
Definition: bufpool.h:45
int __cdecl vsprintf(char *_Dest, const char *_Format, va_list _Args)
Definition: sprintf.c:733
#define va_start(ap, A)
Definition: acmsvcex.h:91
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32

◆ ScsiPortAllocateAdapterChannel()

IO_ALLOCATION_ACTION NTAPI ScsiPortAllocateAdapterChannel ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  MapRegisterBase,
IN PVOID  Context 
)

Definition at line 6384 of file scsiport.c.

6388 {
6389  KIRQL Irql;
6391 
6392  /* Guard access with the spinlock */
6393  KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql);
6394 
6395  /* Save MapRegisterBase we've got here */
6396  DeviceExtension->MapRegisterBase = MapRegisterBase;
6397 
6398  /* Start pending request */
6399  KeSynchronizeExecution(DeviceExtension->Interrupt[0],
6401 
6402  /* Release spinlock we took */
6403  KeReleaseSpinLock(&DeviceExtension->SpinLock, Irql);
6404 
6405  return KeepObject;
6406 }
_Out_ PKIRQL Irql
Definition: csq.h:179
UCHAR KIRQL
Definition: env_spec_w32.h:591
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
Definition: iotypes.h:189
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
static BOOLEAN NTAPI ScsiPortStartPacket(IN OUT PVOID Context)
Definition: scsiport.c:3087
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:142

Referenced by ScsiPortStartIo().

◆ ScsiPortCompleteRequest()

VOID NTAPI ScsiPortCompleteRequest ( IN PVOID  HwDeviceExtension,
IN UCHAR  PathId,
IN UCHAR  TargetId,
IN UCHAR  Lun,
IN UCHAR  SrbStatus 
)

Definition at line 328 of file scsiport.c.

333 {
334  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
335  PSCSI_PORT_LUN_EXTENSION LunExtension;
336  PSCSI_REQUEST_BLOCK_INFO SrbInfo;
337  PLIST_ENTRY ListEntry;
339  ULONG Target;
340 
341  DPRINT("ScsiPortCompleteRequest() called\n");
342 
343  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
345  MiniPortDeviceExtension);
346 
347  /* Go through all buses */
348  for (BusNumber = 0; BusNumber < 8; BusNumber++)
349  {
350  /* Go through all targets */
351  for (Target = 0; Target < DeviceExtension->MaxTargedIds; Target++)
352  {
353  /* Get logical unit list head */
354  LunExtension = DeviceExtension->LunExtensionList[Target % 8];
355 
356  /* Go through all logical units */
357  while (LunExtension)
358  {
359  /* Now match what caller asked with what we are at now */
360  if ((PathId == SP_UNTAGGED || PathId == LunExtension->PathId) &&
361  (TargetId == SP_UNTAGGED || TargetId == LunExtension->TargetId) &&
362  (Lun == SP_UNTAGGED || Lun == LunExtension->Lun))
363  {
364  /* Yes, that's what caller asked for. Complete abort requests */
365  if (LunExtension->CompletedAbortRequests)
366  {
367  /* TODO: Save SrbStatus in this request */
368  DPRINT1("Completing abort request without setting SrbStatus!\n");
369 
370  /* Issue a notification request */
372  HwDeviceExtension,
373  LunExtension->CompletedAbortRequests);
374  }
375 
376  /* Complete the request using our helper */
377  SpiCompleteRequest(HwDeviceExtension,
378  &LunExtension->SrbInfo,
379  SrbStatus);
380 
381  /* Go through the queue and complete everything there too */
382  ListEntry = LunExtension->SrbInfo.Requests.Flink;
383  while (ListEntry != &LunExtension->SrbInfo.Requests)
384  {
385  /* Get the actual SRB info entry */
386  SrbInfo = CONTAINING_RECORD(ListEntry,
388  Requests);
389 
390  /* Complete it */
391  SpiCompleteRequest(HwDeviceExtension,
392  SrbInfo,
393  SrbStatus);
394 
395  /* Advance to the next request in queue */
396  ListEntry = SrbInfo->Requests.Flink;
397  }
398  }
399 
400  /* Advance to the next one */
401  LunExtension = LunExtension->Next;
402  }
403  }
404  }
405 }
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1117
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1117
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1117
#define SP_UNTAGGED
Definition: srb.h:225
struct _SCSI_PORT_LUN_EXTENSION * Next
Definition: scsiport_int.h:125
VOID NTAPI SpiCompleteRequest(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK_INFO SrbInfo, IN UCHAR SrbStatus)
Definition: scsiport.c:300
void DPRINT(...)
Definition: polytest.cpp:61
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
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:156
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
SCSI_REQUEST_BLOCK_INFO SrbInfo
Definition: scsiport_int.h:146
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1067
VOID __cdecl ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension, IN ...)
Definition: scsiport.c:1280
struct _SCSI_PORT_LUN_EXTENSION * CompletedAbortRequests
Definition: scsiport_int.h:144
Definition: typedefs.h:117
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1

◆ ScsiPortConvertPhysicalAddressToUlong()

ULONG NTAPI ScsiPortConvertPhysicalAddressToUlong ( IN SCSI_PHYSICAL_ADDRESS  Address)

Definition at line 6447 of file scsiport.c.

6448 {
6449  DPRINT("ScsiPortConvertPhysicalAddressToUlong()\n");
6450  return(Address.u.LowPart);
6451 }
static WCHAR Address[46]
Definition: ping.c:68
void DPRINT(...)
Definition: polytest.cpp:61

◆ ScsiPortCreateClose()

static NTSTATUS NTAPI ScsiPortCreateClose ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)
static

Definition at line 2447 of file scsiport.c.

2449 {
2450  DPRINT("ScsiPortCreateClose()\n");
2451 
2452  Irp->IoStatus.Status = STATUS_SUCCESS;
2454 
2455  return STATUS_SUCCESS;
2456 }
_In_ PIRP Irp
Definition: csq.h:116
#define IoCompleteRequest
Definition: irp.c:1240
void DPRINT(...)
Definition: polytest.cpp:61
#define IO_NO_INCREMENT
Definition: iotypes.h:565
return STATUS_SUCCESS
Definition: btrfs.c:2745

Referenced by ScsiPortInitialize().

◆ ScsiPortDeviceControl()

static NTSTATUS NTAPI ScsiPortDeviceControl ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)
static

Definition at line 2801 of file scsiport.c.

2803 {
2804  PIO_STACK_LOCATION Stack;
2805  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
2806  PDUMP_POINTERS DumpPointers;
2807  NTSTATUS Status;
2808 
2809  DPRINT("ScsiPortDeviceControl()\n");
2810 
2811  Irp->IoStatus.Information = 0;
2812 
2814  DeviceExtension = DeviceObject->DeviceExtension;
2815 
2816  switch (Stack->Parameters.DeviceIoControl.IoControlCode)
2817  {
2819  DPRINT(" IOCTL_SCSI_GET_DUMP_POINTERS\n");
2820 
2821  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DUMP_POINTERS))
2822  {
2824  Irp->IoStatus.Information = sizeof(DUMP_POINTERS);
2825  break;
2826  }
2827 
2828  DumpPointers = Irp->AssociatedIrp.SystemBuffer;
2829  DumpPointers->DeviceObject = DeviceObject;
2830  /* More data.. ? */
2831 
2833  Irp->IoStatus.Information = sizeof(DUMP_POINTERS);
2834  break;
2835 
2837  DPRINT(" IOCTL_SCSI_GET_CAPABILITIES\n");
2838  if (Stack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(PVOID))
2839  {
2840  *((PVOID *)Irp->AssociatedIrp.SystemBuffer) = &DeviceExtension->PortCapabilities;
2841 
2842  Irp->IoStatus.Information = sizeof(PVOID);
2844  break;
2845  }
2846 
2847  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(IO_SCSI_CAPABILITIES))
2848  {
2850  break;
2851  }
2852 
2853  RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
2854  &DeviceExtension->PortCapabilities,
2855  sizeof(IO_SCSI_CAPABILITIES));
2856 
2857  Irp->IoStatus.Information = sizeof(IO_SCSI_CAPABILITIES);
2859  break;
2860 
2862  DPRINT(" IOCTL_SCSI_GET_INQUIRY_DATA\n");
2863 
2864  /* Copy inquiry data to the port device extension */
2865  Status = SpiGetInquiryData(DeviceExtension, Irp);
2866  break;
2867 
2868  case IOCTL_SCSI_MINIPORT:
2869  DPRINT1("IOCTL_SCSI_MINIPORT unimplemented!\n");
2871  break;
2872 
2874  DPRINT1("IOCTL_SCSI_PASS_THROUGH unimplemented!\n");
2876  break;
2877 
2878  default:
2879  if (DEVICE_TYPE_FROM_CTL_CODE(Stack->Parameters.DeviceIoControl.IoControlCode) == MOUNTDEVCONTROLTYPE)
2880  {
2881  switch (Stack->Parameters.DeviceIoControl.IoControlCode)
2882  {
2884  DPRINT1("Got unexpected IOCTL_MOUNTDEV_QUERY_DEVICE_NAME\n");
2885  break;
2887  DPRINT1("Got unexpected IOCTL_MOUNTDEV_QUERY_UNIQUE_ID\n");
2888  break;
2889  default:
2890  DPRINT1(" got ioctl intended for the mount manager: 0x%lX\n", Stack->Parameters.DeviceIoControl.IoControlCode);
2891  break;
2892  }
2893  } else {
2894  DPRINT1(" unknown ioctl code: 0x%lX\n", Stack->Parameters.DeviceIoControl.IoControlCode);
2895  }
2897  break;
2898  }
2899 
2900  /* Complete the request with the given status */
2901  Irp->IoStatus.Status = Status;
2903 
2904  return Status;
2905 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define IOCTL_SCSI_MINIPORT
Definition: scsi_port.h:48
_In_ PIRP Irp
Definition: csq.h:116
IO_SCSI_CAPABILITIES PortCapabilities
Definition: scsiport.c:80
#define IOCTL_SCSI_GET_DUMP_POINTERS
Definition: scsi_port.h:54
LONG NTSTATUS
Definition: precomp.h:26
struct _DUMP_POINTERS DUMP_POINTERS
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
static NTSTATUS SpiGetInquiryData(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: scsiport.c:3982
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define IoCompleteRequest
Definition: irp.c:1240
void DPRINT(...)
Definition: polytest.cpp:61
void * PVOID
Definition: retypes.h:9
#define MOUNTDEVCONTROLTYPE
Definition: imports.h:78
Status
Definition: gdiplustypes.h:24
#define IOCTL_SCSI_PASS_THROUGH
Definition: scsi_port.h:47
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define IOCTL_SCSI_GET_INQUIRY_DATA
Definition: scsi_port.h:49
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
#define DEVICE_TYPE_FROM_CTL_CODE(c)
Definition: winioctl.h:176
#define DPRINT1
Definition: precomp.h:8
#define IOCTL_SCSI_GET_CAPABILITIES
Definition: scsi_port.h:50
#define IO_NO_INCREMENT
Definition: iotypes.h:565
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
return STATUS_SUCCESS
Definition: btrfs.c:2745
struct _IO_SCSI_CAPABILITIES IO_SCSI_CAPABILITIES
PVOID DeviceObject
Definition: ntddscsi.h:259

Referenced by ScsiPortInitialize().

◆ ScsiPortDispatchScsi()

static NTSTATUS NTAPI ScsiPortDispatchScsi ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)
static

Definition at line 2559 of file scsiport.c.

2561 {
2562  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
2563  PSCSI_PORT_LUN_EXTENSION LunExtension;
2564  PIO_STACK_LOCATION Stack;
2566  KIRQL Irql;
2568  PIRP NextIrp, IrpList;
2570 
2571  DPRINT("ScsiPortDispatchScsi(DeviceObject %p Irp %p)\n",
2572  DeviceObject, Irp);
2573 
2574  DeviceExtension = DeviceObject->DeviceExtension;
2576 
2577  Srb = Stack->Parameters.Scsi.Srb;
2578  if (Srb == NULL)
2579  {
2580  DPRINT1("ScsiPortDispatchScsi() called with Srb = NULL!\n");
2582 
2583  Irp->IoStatus.Status = Status;
2584  Irp->IoStatus.Information = 0;
2585 
2587 
2588  return(Status);
2589  }
2590 
2591  DPRINT("Srb: %p\n", Srb);
2592  DPRINT("Srb->Function: %lu\n", Srb->Function);
2593  DPRINT("PathId: %lu TargetId: %lu Lun: %lu\n", Srb->PathId, Srb->TargetId, Srb->Lun);
2594 
2595  LunExtension = SpiGetLunExtension(DeviceExtension,
2596  Srb->PathId,
2597  Srb->TargetId,
2598  Srb->Lun);
2599  if (LunExtension == NULL)
2600  {
2601  DPRINT("ScsiPortDispatchScsi() called with an invalid LUN\n");
2603 
2604  Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
2605  Irp->IoStatus.Status = Status;
2606  Irp->IoStatus.Information = 0;
2607 
2609 
2610  return(Status);
2611  }
2612 
2613  switch (Srb->Function)
2614  {
2615  case SRB_FUNCTION_SHUTDOWN:
2616  case SRB_FUNCTION_FLUSH:
2617  DPRINT (" SRB_FUNCTION_SHUTDOWN or FLUSH\n");
2618  if (DeviceExtension->CachesData == FALSE)
2619  {
2620  /* All success here */
2621  Srb->SrbStatus = SRB_STATUS_SUCCESS;
2622  Irp->IoStatus.Status = STATUS_SUCCESS;
2624  return STATUS_SUCCESS;
2625  }
2626  /* Fall through to a usual execute operation */
2627 
2630  DPRINT(" SRB_FUNCTION_EXECUTE_SCSI or SRB_FUNCTION_IO_CONTROL\n");
2631  /* Mark IRP as pending in all cases */
2633 
2634  if (Srb->SrbFlags & SRB_FLAGS_BYPASS_FROZEN_QUEUE)
2635  {
2636  /* Start IO directly */
2638  }
2639  else
2640  {
2641  KIRQL oldIrql;
2642 
2643  /* We need to be at DISPATCH_LEVEL */
2644  KeRaiseIrql (DISPATCH_LEVEL, &oldIrql);
2645 
2646  /* Insert IRP into the queue */
2647  if (!KeInsertByKeyDeviceQueue(&LunExtension->DeviceQueue,
2648  &Irp->Tail.Overlay.DeviceQueueEntry,
2649  Srb->QueueSortKey))
2650  {
2651  /* It means the queue is empty, and we just start this request */
2653  }
2654 
2655  /* Back to the old IRQL */
2656  KeLowerIrql (oldIrql);
2657  }
2658  return STATUS_PENDING;
2659 
2662  DPRINT (" SRB_FUNCTION_CLAIM_DEVICE or ATTACH\n");
2663 
2664  /* Reference device object and keep the device object */
2665  Status = SpiHandleAttachRelease(DeviceExtension, Irp);
2666  break;
2667 
2669  DPRINT (" SRB_FUNCTION_RELEASE_DEVICE\n");
2670 
2671  /* Dereference device object and clear the device object */
2672  Status = SpiHandleAttachRelease(DeviceExtension, Irp);
2673  break;
2674 
2676  DPRINT(" SRB_FUNCTION_RELEASE_QUEUE\n");
2677 
2678  /* Guard with the spinlock */
2679  KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql);
2680 
2681  if (!(LunExtension->Flags & LUNEX_FROZEN_QUEUE))
2682  {
2683  DPRINT("Queue is not frozen really\n");
2684 
2685  KeReleaseSpinLock(&DeviceExtension->SpinLock, Irql);
2686  Srb->SrbStatus = SRB_STATUS_SUCCESS;
2688  break;
2689 
2690  }
2691 
2692  /* Unfreeze the queue */
2693  LunExtension->Flags &= ~LUNEX_FROZEN_QUEUE;
2694 
2695  if (LunExtension->SrbInfo.Srb == NULL)
2696  {
2697  /* Get next logical unit request */
2698  SpiGetNextRequestFromLun(DeviceExtension, LunExtension);
2699 
2700  /* SpiGetNextRequestFromLun() releases the spinlock */
2701  KeLowerIrql(Irql);
2702  }
2703  else
2704  {
2705  DPRINT("The queue has active request\n");
2706  KeReleaseSpinLock(&DeviceExtension->SpinLock, Irql);
2707  }
2708 
2709 
2710  Srb->SrbStatus = SRB_STATUS_SUCCESS;
2712  break;
2713 
2715  DPRINT(" SRB_FUNCTION_FLUSH_QUEUE\n");
2716 
2717  /* Guard with the spinlock */
2718  KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql);
2719 
2720  if (!(LunExtension->Flags & LUNEX_FROZEN_QUEUE))
2721  {
2722  DPRINT("Queue is not frozen really\n");
2723 
2724  KeReleaseSpinLock(&DeviceExtension->SpinLock, Irql);
2726  break;
2727  }
2728 
2729  /* Make sure there is no active request */
2730  ASSERT(LunExtension->SrbInfo.Srb == NULL);
2731 
2732  /* Compile a list from the device queue */
2733  IrpList = NULL;
2734  while ((Entry = KeRemoveDeviceQueue(&LunExtension->DeviceQueue)) != NULL)
2735  {
2736  NextIrp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.DeviceQueueEntry);
2737 
2738  /* Get the Srb */
2739  Stack = IoGetCurrentIrpStackLocation(NextIrp);
2740  Srb = Stack->Parameters.Scsi.Srb;
2741 
2742  /* Set statuse */
2743  Srb->SrbStatus = SRB_STATUS_REQUEST_FLUSHED;
2744  NextIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
2745 
2746  /* Add then to the list */
2747  NextIrp->Tail.Overlay.ListEntry.Flink = (PLIST_ENTRY)IrpList;
2748  IrpList = NextIrp;
2749  }
2750 
2751  /* Unfreeze the queue */
2752  LunExtension->Flags &= ~LUNEX_FROZEN_QUEUE;
2753 
2754  /* Release the spinlock */
2755  KeReleaseSpinLock(&DeviceExtension->SpinLock, Irql);
2756 
2757  /* Complete those requests */
2758  while (IrpList)
2759  {
2760  NextIrp = IrpList;
2761  IrpList = (PIRP)NextIrp->Tail.Overlay.ListEntry.Flink;
2762 
2763  IoCompleteRequest(NextIrp, 0);
2764  }
2765 
2767  break;
2768 
2769  default:
2770  DPRINT1("SRB function not implemented (Function %lu)\n", Srb->Function);
2772  break;
2773  }
2774 
2775  Irp->IoStatus.Status = Status;
2776 
2778 
2779  return(Status);
2780 }
struct _LIST_ENTRY * PLIST_ENTRY
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
KDEVICE_QUEUE DeviceQueue
Definition: scsiport_int.h:132
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
struct _Entry Entry
Definition: kefuncs.h:640
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
_In_ PIRP Irp
Definition: csq.h:116
static NTSTATUS SpiHandleAttachRelease(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
Definition: scsiport.c:2459
LONG NTSTATUS
Definition: precomp.h:26
#define SRB_STATUS_REQUEST_FLUSHED
Definition: srb.h:353
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define SRB_FUNCTION_FLUSH_QUEUE
Definition: srb.h:321
#define SRB_STATUS_NO_DEVICE
Definition: srb.h:340
#define SRB_FUNCTION_RELEASE_QUEUE
Definition: srb.h:311
#define SRB_FUNCTION_CLAIM_DEVICE
Definition: srb.h:308
IRP
Definition: iotypes.h:2462
_Out_ PKIRQL Irql
Definition: csq.h:179
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define LUNEX_FROZEN_QUEUE
Definition: scsiport_int.h:44
#define SRB_FLAGS_BYPASS_FROZEN_QUEUE
Definition: srb.h:390
BOOLEAN NTAPI KeInsertByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry, IN ULONG SortKey)
Definition: devqueue.c:83
VOID NTAPI IoStartPacket(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key, IN PDRIVER_CANCEL CancelFunction)
Definition: device.c:1875
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define SRB_FUNCTION_RELEASE_DEVICE
Definition: srb.h:313
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
void DPRINT(...)
Definition: polytest.cpp:61
static PSCSI_PORT_LUN_EXTENSION SpiGetLunExtension(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun)
Definition: scsiport.c:3365
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
#define SRB_FUNCTION_FLUSH
Definition: srb.h:315
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
SCSI_REQUEST_BLOCK_INFO SrbInfo
Definition: scsiport_int.h:146
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define SRB_FUNCTION_ATTACH_DEVICE
Definition: srb.h:312
#define SRB_FUNCTION_IO_CONTROL
Definition: srb.h:309
PSCSI_REQUEST_BLOCK Srb
Definition: scsiport_int.h:100
Status
Definition: gdiplustypes.h:24
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SRB_FUNCTION_SHUTDOWN
Definition: srb.h:314
Definition: ketypes.h:566
PKDEVICE_QUEUE_ENTRY NTAPI KeRemoveDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
Definition: devqueue.c:153
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define DPRINT1
Definition: precomp.h:8
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
PVOID PIRP
Definition: usb.h:38
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
return STATUS_SUCCESS
Definition: btrfs.c:2745
IoMarkIrpPending(Irp)
VOID NTAPI SpiGetNextRequestFromLun(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN PSCSI_PORT_LUN_EXTENSION LunExtension)
Definition: scsiport.c:4758
base of all file and directory entries
Definition: entries.h:82

◆ ScsiPortDpcForIsr()

static VOID NTAPI ScsiPortDpcForIsr ( IN PKDPC  Dpc,
IN PDEVICE_OBJECT  DpcDeviceObject,
IN PIRP  DpcIrp,
IN PVOID  DpcContext 
)
static

Definition at line 4865 of file scsiport.c.

4869 {
4870  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension = DpcDeviceObject->DeviceExtension;
4871  SCSI_PORT_INTERRUPT_DATA InterruptData;
4873  PSCSI_PORT_LUN_EXTENSION LunExtension;
4874  BOOLEAN NeedToStartIo;
4875  PSCSI_REQUEST_BLOCK_INFO SrbInfo;
4876  LARGE_INTEGER TimerValue;
4877 
4878  DPRINT("ScsiPortDpcForIsr(Dpc %p DpcDeviceObject %p DpcIrp %p DpcContext %p)\n",
4879  Dpc, DpcDeviceObject, DpcIrp, DpcContext);
4880 
4881  /* We need to acquire spinlock */
4882  KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
4883 
4884  RtlZeroMemory(&InterruptData, sizeof(SCSI_PORT_INTERRUPT_DATA));
4885 
4886 TryAgain:
4887 
4888  /* Interrupt structure must be snapshotted, and only then analyzed */
4889  Context.InterruptData = &InterruptData;
4890  Context.DeviceExtension = DeviceExtension;
4891 
4892  if (!KeSynchronizeExecution(DeviceExtension->Interrupt[0],
4894  &Context))
4895  {
4896  /* Nothing - just return (don't forget to release the spinlock */
4897  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
4898  DPRINT("ScsiPortDpcForIsr() done\n");
4899  return;
4900  }
4901 
4902  /* If flush of adapters is needed - do it */
4903  if (InterruptData.Flags & SCSI_PORT_FLUSH_ADAPTERS)
4904  {
4905  /* TODO: Implement */
4906  ASSERT(FALSE);
4907  }
4908 
4909  /* Check for IoMapTransfer */
4910  if (InterruptData.Flags & SCSI_PORT_MAP_TRANSFER)
4911  {
4912  /* TODO: Implement */
4913  ASSERT(FALSE);
4914  }
4915 
4916  /* Check if timer is needed */
4917  if (InterruptData.Flags & SCSI_PORT_TIMER_NEEDED)
4918  {
4919  /* Save the timer routine */
4920  DeviceExtension->HwScsiTimer = InterruptData.HwScsiTimer;
4921 
4922  if (InterruptData.MiniportTimerValue == 0)
4923  {
4924  /* Cancel the timer */
4925  KeCancelTimer(&DeviceExtension->MiniportTimer);
4926  }
4927  else
4928  {
4929  /* Convert timer value */
4930  TimerValue.QuadPart = Int32x32To64(InterruptData.MiniportTimerValue, -10);
4931 
4932  /* Set the timer */
4933  KeSetTimer(&DeviceExtension->MiniportTimer,
4934  TimerValue,
4935  &DeviceExtension->MiniportTimerDpc);
4936  }
4937  }
4938 
4939  /* If it's ready for the next request */
4940  if (InterruptData.Flags & SCSI_PORT_NEXT_REQUEST_READY)
4941  {
4942  /* Check for a duplicate request (NextRequest+NextLuRequest) */
4943  if ((DeviceExtension->Flags &
4946  {
4947  /* Clear busy flag set by ScsiPortStartPacket() */
4948  DeviceExtension->Flags &= ~SCSI_PORT_DEVICE_BUSY;
4949 
4950  if (!(InterruptData.Flags & SCSI_PORT_RESET))
4951  {
4952  /* Ready for next, and no reset is happening */
4953  DeviceExtension->TimerCount = -1;
4954  }
4955  }
4956  else
4957  {
4958  /* Not busy, but not ready for the next request */
4959  DeviceExtension->Flags &= ~SCSI_PORT_DEVICE_BUSY;
4960  InterruptData.Flags &= ~SCSI_PORT_NEXT_REQUEST_READY;
4961  }
4962  }
4963 
4964  /* Any resets? */
4965  if (InterruptData.Flags & SCSI_PORT_RESET_REPORTED)
4966  {
4967  /* Hold for a bit */
4968  DeviceExtension->TimerCount = 4;
4969  }
4970 
4971  /* Any ready LUN? */
4972  if (InterruptData.ReadyLun != NULL)
4973  {
4974 
4975  /* Process all LUNs from the list*/
4976  while (TRUE)
4977  {
4978  /* Remove it from the list first (as processed) */
4979  LunExtension = InterruptData.ReadyLun;
4980  InterruptData.ReadyLun = LunExtension->ReadyLun;
4981  LunExtension->ReadyLun = NULL;
4982 
4983  /* Get next request for this LUN */
4984  SpiGetNextRequestFromLun(DeviceExtension, LunExtension);
4985 
4986  /* Still ready requests exist?
4987  If yes - get spinlock, if no - stop here */
4988  if (InterruptData.ReadyLun != NULL)
4989  KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
4990  else
4991  break;
4992  }
4993  }
4994  else
4995  {
4996  /* Release the spinlock */
4997  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
4998  }
4999 
5000  /* If we ready for next packet, start it */
5001  if (InterruptData.Flags & SCSI_PORT_NEXT_REQUEST_READY)
5002  IoStartNextPacket(DeviceExtension->DeviceObject, FALSE);
5003 
5004  NeedToStartIo = FALSE;
5005 
5006  /* Loop the completed request list */
5007  while (InterruptData.CompletedRequests)
5008  {
5009  /* Remove the request */
5010  SrbInfo = InterruptData.CompletedRequests;
5011  InterruptData.CompletedRequests = SrbInfo->CompletedRequests;
5012  SrbInfo->CompletedRequests = NULL;
5013 
5014  /* Process it */
5015  SpiProcessCompletedRequest(DeviceExtension,
5016  SrbInfo,
5017  &NeedToStartIo);
5018  }
5019 
5020  /* Loop abort request list */
5021  while (InterruptData.CompletedAbort)
5022  {
5023  LunExtension = InterruptData.CompletedAbort;
5024 
5025  /* Remove the request */
5026  InterruptData.CompletedAbort = LunExtension->CompletedAbortRequests;
5027 
5028  /* Get spinlock since we're going to change flags */
5029  KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
5030 
5031  /* TODO: Put SrbExtension to the list of free extensions */
5032  ASSERT(FALSE);
5033  }
5034 
5035  /* If we need - call StartIo routine */
5036  if (NeedToStartIo)
5037  {
5038  /* Make sure CurrentIrp is not null! */
5039  ASSERT(DpcDeviceObject->CurrentIrp != NULL);
5040  ScsiPortStartIo(DpcDeviceObject, DpcDeviceObject->CurrentIrp);
5041  }
5042 
5043  /* Everything has been done, check */
5044  if (InterruptData.Flags & SCSI_PORT_ENABLE_INT_REQUEST)
5045  {
5046  /* Synchronize using spinlock */
5047  KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
5048 
5049  /* Request an interrupt */
5050  DeviceExtension->HwInterrupt(DeviceExtension->MiniPortDeviceExtension);
5051 
5052  ASSERT(DeviceExtension->Flags & SCSI_PORT_DISABLE_INT_REQUESET);
5053 
5054  /* Should interrupts be enabled again? */
5055  if (DeviceExtension->Flags & SCSI_PORT_DISABLE_INT_REQUESET)
5056  {
5057  /* Clear this flag */
5058  DeviceExtension->Flags &= ~SCSI_PORT_DISABLE_INT_REQUESET;
5059 
5060  /* Call a special routine to do this */
5061  ASSERT(FALSE);
5062 #if 0
5063  KeSynchronizeExecution(DeviceExtension->Interrupt,
5064  SpiEnableInterrupts,
5065  DeviceExtension);
5066 #endif
5067  }
5068 
5069  /* If we need a notification again - loop */
5070  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
5071  goto TryAgain;
5072 
5073  /* Release the spinlock */
5074  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
5075  }
5076 
5077  DPRINT("ScsiPortDpcForIsr() done\n");
5078 }
struct _SCSI_REQUEST_BLOCK_INFO * CompletedRequests
Definition: scsiport_int.h:110
#define SCSI_PORT_RESET_REPORTED
Definition: scsiport_int.h:35
#define SCSI_PORT_DISABLE_INT_REQUESET
Definition: scsiport_int.h:38
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
#define SCSI_PORT_RESET
Definition: scsiport_int.h:33
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
PSCSI_REQUEST_BLOCK_INFO CompletedRequests
Definition: scsiport_int.h:184
#define SCSI_PORT_NOTIFICATION_NEEDED
Definition: scsiport_int.h:29
#define SCSI_PORT_NEXT_REQUEST_READY
Definition: scsiport.c:53
Definition: bl.h:897
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
_In_ LARGE_INTEGER _In_opt_ PKDPC Dpc
Definition: kefuncs.h:524
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
#define SCSI_PORT_DISCONNECT_ALLOWED
Definition: scsiport_int.h:37
#define SCSI_PORT_MAP_TRANSFER
Definition: scsiport_int.h:32
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static DRIVER_STARTIO ScsiPortStartIo
Definition: scsiport.c:72
PSCSI_PORT_LUN_EXTENSION CompletedAbort
Definition: scsiport_int.h:185
#define SCSI_PORT_TIMER_NEEDED
Definition: scsiport_int.h:41
struct _SCSI_PORT_LUN_EXTENSION * CompletedAbortRequests
Definition: scsiport_int.h:144
#define SCSI_PORT_DEVICE_BUSY
Definition: scsiport_int.h:27
static VOID NTAPI SpiProcessCompletedRequest(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN PSCSI_REQUEST_BLOCK_INFO SrbInfo, OUT PBOOLEAN NeedToCallStartIo)
Definition: scsiport.c:4235
PHW_INTERRUPT HwInterrupt
Definition: scsiport.c:84
BOOLEAN NTAPI SpiSaveInterruptData(IN PVOID Context)
Definition: scsiport.c:4640
struct _SCSI_PORT_LUN_EXTENSION * ReadyLun
Definition: scsiport_int.h:143
PSCSI_PORT_LUN_EXTENSION ReadyLun
Definition: scsiport_int.h:186
struct tagContext Context
Definition: acpixf.h:1012
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:142
VOID NTAPI SpiGetNextRequestFromLun(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN PSCSI_PORT_LUN_EXTENSION LunExtension)
Definition: scsiport.c:4758
#define Int32x32To64(a, b)
#define SCSI_PORT_ENABLE_INT_REQUEST
Definition: scsiport_int.h:40
LONGLONG QuadPart
Definition: typedefs.h:112
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1846
#define SCSI_PORT_FLUSH_ADAPTERS
Definition: scsiport_int.h:31

Referenced by ScsiPortInitialize(), and SpiMiniportTimerDpc().

◆ ScsiPortFlushDma()

VOID NTAPI ScsiPortFlushDma ( IN PVOID  HwDeviceExtension)

Definition at line 411 of file scsiport.c.

412 {
413  DPRINT("ScsiPortFlushDma()\n");
415 }
void DPRINT(...)
Definition: polytest.cpp:61
#define UNIMPLEMENTED
Definition: debug.h:114

◆ ScsiPortFreeDeviceBase()

VOID NTAPI ScsiPortFreeDeviceBase ( IN PVOID  HwDeviceExtension,
IN PVOID  MappedAddress 
)

Definition at line 422 of file scsiport.c.

424 {
425  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
426  PMAPPED_ADDRESS NextMa, LastMa;
427 
428  //DPRINT("ScsiPortFreeDeviceBase() called\n");
429 
430  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
432  MiniPortDeviceExtension);
433 
434  /* Initialize our pointers */
435  NextMa = DeviceExtension->MappedAddressList;
436  LastMa = NextMa;
437 
438  while (NextMa)
439  {
440  if (NextMa->MappedAddress == MappedAddress)
441  {
442  /* Unmap it first */
443  MmUnmapIoSpace(MappedAddress, NextMa->NumberOfBytes);
444 
445  /* Remove it from the list */
446  if (NextMa == DeviceExtension->MappedAddressList)
447  {
448  /* Remove the first entry */
449  DeviceExtension->MappedAddressList = NextMa->NextMappedAddress;
450  }
451  else
452  {
453  LastMa->NextMappedAddress = NextMa->NextMappedAddress;
454  }
455 
456  /* Free the resources and quit */
457  ExFreePool(NextMa);
458 
459  return;
460  }
461  else
462  {
463  LastMa = NextMa;
464  NextMa = NextMa->NextMappedAddress;
465  }
466  }
467 }
ULONG NumberOfBytes
Definition: ntdddisk.h:639
struct _MAPPED_ADDRESS * NextMappedAddress
Definition: ntdddisk.h:637
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
PVOID MappedAddress
Definition: ntdddisk.h:638
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

◆ ScsiPortGetBusData()

ULONG NTAPI ScsiPortGetBusData ( IN PVOID  DeviceExtension,
IN ULONG  BusDataType,
IN ULONG  SystemIoBusNumber,
IN ULONG  SlotNumber,
IN PVOID  Buffer,
IN ULONG  Length 
)

Definition at line 474 of file scsiport.c.

480 {
481  DPRINT("ScsiPortGetBusData()\n");
482 
483  if (Length)
484  {
485  /* If Length is non-zero, just forward the call to
486  HalGetBusData() function */
487  return HalGetBusData(BusDataType,
488  SystemIoBusNumber,
489  SlotNumber,
490  Buffer,
491  Length);
492  }
493 
494  /* We have a more complex case here */
496  return 0;
497 }
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
NTHALAPI ULONG NTAPI HalGetBusData(BUS_DATA_TYPE, ULONG, ULONG, PVOID, ULONG)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG _In_ ULONG SlotNumber
Definition: halfuncs.h:156
#define UNIMPLEMENTED
Definition: debug.h:114

◆ ScsiPortGetDeviceBase()

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 at line 524 of file scsiport.c.

530 {
531  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
533  PMAPPED_ADDRESS DeviceBase;
535  PVOID MappedAddress;
536 
537  //DPRINT ("ScsiPortGetDeviceBase() called\n");
538 
539  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
541  MiniPortDeviceExtension);
542 
543  AddressSpace = (ULONG)InIoSpace;
545  SystemIoBusNumber,
546  IoAddress,
547  &AddressSpace,
549  {
550  return NULL;
551  }
552 
553  /* i/o space */
554  if (AddressSpace != 0)
556 
557  MappedAddress = MmMapIoSpace(TranslatedAddress,
559  FALSE);
560 
561  DeviceBase = ExAllocatePoolWithTag(NonPagedPool,
562  sizeof(MAPPED_ADDRESS), TAG_SCSIPORT);
563 
564  if (DeviceBase == NULL)
565  return MappedAddress;
566 
567  DeviceBase->MappedAddress = MappedAddress;
568  DeviceBase->NumberOfBytes = NumberOfBytes;
569  DeviceBase->IoAddress = IoAddress;
570  DeviceBase->BusNumber = SystemIoBusNumber;
571 
572  /* Link it to the Device Extension list */
573  DeviceBase->NextMappedAddress = DeviceExtension->MappedAddressList;
574  DeviceExtension->MappedAddressList = DeviceBase;
575 
576  return MappedAddress;
577 }
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE BusType
Definition: halfuncs.h:156
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
LARGE_INTEGER IoAddress
Definition: ntdddisk.h:640
PVOID NTAPI MmMapIoSpace(IN PHYSICAL_ADDRESS PhysicalAddress, IN SIZE_T NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition: iosup.c:47
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG _Out_ PPHYSICAL_ADDRESS TranslatedAddress
Definition: iofuncs.h:2268
ULONG NumberOfBytes
Definition: ntdddisk.h:639
smooth NULL
Definition: ftsmooth.c:416
struct _MAPPED_ADDRESS * NextMappedAddress
Definition: ntdddisk.h:637
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
ULONG BusNumber
Definition: ntdddisk.h:641
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
PVOID MappedAddress
Definition: ntdddisk.h:638
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
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:997
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define TAG_SCSIPORT
Definition: scsiport_int.h:19
LONGLONG QuadPart
Definition: typedefs.h:112

◆ ScsiPortGetLogicalUnit()

PVOID NTAPI ScsiPortGetLogicalUnit ( IN PVOID  HwDeviceExtension,
IN UCHAR  PathId,
IN UCHAR  TargetId,
IN UCHAR  Lun 
)

Definition at line 583 of file scsiport.c.

587 {
588  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
589  PSCSI_PORT_LUN_EXTENSION LunExtension;
590 
591  DPRINT("ScsiPortGetLogicalUnit() called\n");
592 
593  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
595  MiniPortDeviceExtension);
596 
597  /* Check the extension size */
598  if (!DeviceExtension->LunExtensionSize)
599  {
600  /* They didn't want one */
601  return NULL;
602  }
603 
604  LunExtension = SpiGetLunExtension(DeviceExtension,
605  PathId,
606  TargetId,
607  Lun);
608  /* Check that the logical unit exists */
609  if (!LunExtension)
610  {
611  /* Nope, return NULL */
612  return NULL;
613  }
614 
615  /* Return the logical unit miniport extension */
616  return (LunExtension + 1);
617 }
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1117
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1117
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1117
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
static PSCSI_PORT_LUN_EXTENSION SpiGetLunExtension(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun)
Definition: scsiport.c:3365
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

◆ ScsiPortGetPhysicalAddress()

SCSI_PHYSICAL_ADDRESS NTAPI ScsiPortGetPhysicalAddress ( IN PVOID  HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb  OPTIONAL,
IN PVOID  VirtualAddress,
OUT ULONG Length 
)

Definition at line 624 of file scsiport.c.

628 {
629  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
631  SIZE_T BufferLength = 0;
633  PSCSI_SG_ADDRESS SGList;
634  PSCSI_REQUEST_BLOCK_INFO SrbInfo;
635 
636  DPRINT("ScsiPortGetPhysicalAddress(%p %p %p %p)\n",
637  HwDeviceExtension, Srb, VirtualAddress, Length);
638 
639  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
641  MiniPortDeviceExtension);
642 
643  if (Srb == NULL || Srb->SenseInfoBuffer == VirtualAddress)
644  {
645  /* Simply look it up in the allocated common buffer */
646  Offset = (PUCHAR)VirtualAddress - (PUCHAR)DeviceExtension->SrbExtensionBuffer;
647 
648  BufferLength = DeviceExtension->CommonBufferLength - Offset;
649  PhysicalAddress.QuadPart = DeviceExtension->PhysicalAddress.QuadPart + Offset;
650  }
651  else if (DeviceExtension->MapRegisters)
652  {
653  /* Scatter-gather list must be used */
654  SrbInfo = SpiGetSrbData(DeviceExtension,
655  Srb->PathId,
656  Srb->TargetId,
657  Srb->Lun,
658  Srb->QueueTag);
659 
660  SGList = SrbInfo->ScatterGather;
661 
662  /* Find needed item in the SG list */
663  Offset = (PCHAR)VirtualAddress - (PCHAR)Srb->DataBuffer;
664  while (Offset >= SGList->Length)
665  {
666  Offset -= SGList->Length;
667  SGList++;
668  }
669 
670  /* We're done, store length and physical address */
671  BufferLength = SGList->Length - Offset;
673  }
674  else
675  {
676  /* Nothing */
678  }
679 
681  return PhysicalAddress;
682 }
signed char * PCHAR
Definition: retypes.h:7
#define SP_UNINITIALIZED_VALUE
Definition: srb.h:224
unsigned char * PUCHAR
Definition: retypes.h:3
static PSCSI_REQUEST_BLOCK_INFO SpiGetSrbData(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN UCHAR QueueTag)
Definition: scsiport.c:4096
uint32_t ULONG_PTR
Definition: typedefs.h:63
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG BufferLength
Definition: usbdlib.h:225
smooth NULL
Definition: ftsmooth.c:416
PSCSI_SG_ADDRESS ScatterGather
Definition: scsiport_int.h:113
void DPRINT(...)
Definition: polytest.cpp:61
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
#define PCHAR
Definition: match.c:90
int64_t LONGLONG
Definition: typedefs.h:66
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1060
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
PHYSICAL_ADDRESS PhysicalAddress
Definition: scsiport_int.h:93
ULONG_PTR SIZE_T
Definition: typedefs.h:78
unsigned int ULONG
Definition: retypes.h:1
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
LONGLONG QuadPart
Definition: typedefs.h:112

◆ ScsiPortGetSrb()

PSCSI_REQUEST_BLOCK NTAPI ScsiPortGetSrb ( IN PVOID  DeviceExtension,
IN UCHAR  PathId,
IN UCHAR  TargetId,
IN UCHAR  Lun,
IN LONG  QueueTag 
)

Definition at line 689 of file scsiport.c.

694 {
695  DPRINT1("ScsiPortGetSrb() unimplemented\n");
697  return NULL;
698 }
smooth NULL
Definition: ftsmooth.c:416
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: debug.h:114

◆ ScsiPortGetUncachedExtension()

PVOID NTAPI ScsiPortGetUncachedExtension ( IN PVOID  HwDeviceExtension,
IN PPORT_CONFIGURATION_INFORMATION  ConfigInfo,
IN ULONG  NumberOfBytes 
)

Definition at line 705 of file scsiport.c.

708 {
709  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
711  ULONG MapRegistersCount;
713 
714  DPRINT("ScsiPortGetUncachedExtension(%p %p %lu)\n",
715  HwDeviceExtension, ConfigInfo, NumberOfBytes);
716 
717  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
719  MiniPortDeviceExtension);
720 
721  /* Check for allocated common DMA buffer */
722  if (DeviceExtension->SrbExtensionBuffer != NULL)
723  {
724  DPRINT1("The HBA has already got a common DMA buffer!\n");
725  return NULL;
726  }
727 
728  /* Check for DMA adapter object */
729  if (DeviceExtension->AdapterObject == NULL)
730  {
731  /* Initialize DMA adapter description */
733 
735  DeviceDescription.Master = ConfigInfo->Master;
736  DeviceDescription.ScatterGather = ConfigInfo->ScatterGather;
737  DeviceDescription.DemandMode = ConfigInfo->DemandMode;
738  DeviceDescription.Dma32BitAddresses = ConfigInfo->Dma32BitAddresses;
739  DeviceDescription.BusNumber = ConfigInfo->SystemIoBusNumber;
740  DeviceDescription.DmaChannel = ConfigInfo->DmaChannel;
741  DeviceDescription.InterfaceType = ConfigInfo->AdapterInterfaceType;
742  DeviceDescription.DmaWidth = ConfigInfo->DmaWidth;
743  DeviceDescription.DmaSpeed = ConfigInfo->DmaSpeed;
744  DeviceDescription.MaximumLength = ConfigInfo->MaximumTransferLength;
745  DeviceDescription.DmaPort = ConfigInfo->DmaPort;
746 
747  /* Get a DMA adapter object */
748  DeviceExtension->AdapterObject =
749  HalGetAdapter(&DeviceDescription, &MapRegistersCount);
750 
751  /* Fail in case of error */
752  if (DeviceExtension->AdapterObject == NULL)
753  {
754  DPRINT1("HalGetAdapter() failed\n");
755  return NULL;
756  }
757 
758  /* Set number of physical breaks */
759  if (ConfigInfo->NumberOfPhysicalBreaks != 0 &&
760  MapRegistersCount > ConfigInfo->NumberOfPhysicalBreaks)
761  {
762  DeviceExtension->PortCapabilities.MaximumPhysicalPages =
763  ConfigInfo->NumberOfPhysicalBreaks;
764  }
765  else
766  {
767  DeviceExtension->PortCapabilities.MaximumPhysicalPages = MapRegistersCount;
768  }
769  }
770 
771  /* Update auto request sense feature */
772  DeviceExtension->SupportsAutoSense = ConfigInfo->AutoRequestSense;
773 
774  /* Update Srb extension size */
775  if (DeviceExtension->SrbExtensionSize != ConfigInfo->SrbExtensionSize)
776  DeviceExtension->SrbExtensionSize = ConfigInfo->SrbExtensionSize;
777 
778  /* Update Srb extension alloc flag */
779  if (ConfigInfo->AutoRequestSense || DeviceExtension->SrbExtensionSize)
780  DeviceExtension->NeedSrbExtensionAlloc = TRUE;
781 
782  /* Allocate a common DMA buffer */
783  Status = SpiAllocateCommonBuffer(DeviceExtension, NumberOfBytes);
784 
785  if (!NT_SUCCESS(Status))
786  {
787  DPRINT1("SpiAllocateCommonBuffer() failed with Status = 0x%08X!\n", Status);
788  return NULL;
789  }
790 
791  return DeviceExtension->NonCachedExtension;
792 }
#define TRUE
Definition: types.h:120
IO_SCSI_CAPABILITIES PortCapabilities
Definition: scsiport.c:80
LONG NTSTATUS
Definition: precomp.h:26
DMA_SPEED DmaSpeed
Definition: iotypes.h:2037
#define DEVICE_DESCRIPTION_VERSION
Definition: iotypes.h:2019
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
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
BOOLEAN Dma32BitAddresses
Definition: iotypes.h:2029
_Must_inspect_result_ _In_ PDEVICE_DESCRIPTION DeviceDescription
Definition: iofuncs.h:1015
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN DemandMode
Definition: iotypes.h:2027
BOOLEAN ScatterGather
Definition: iotypes.h:2026
DMA_WIDTH DmaWidth
Definition: iotypes.h:2036
static NTSTATUS SpiAllocateCommonBuffer(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, ULONG NonCachedSize)
Definition: scsiport.c:795
Status
Definition: gdiplustypes.h:24
PADAPTER_OBJECT AdapterObject
Definition: scsiport.c:88
#define DPRINT1
Definition: precomp.h:8
INTERFACE_TYPE InterfaceType
Definition: iotypes.h:2035
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:997
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PADAPTER_OBJECT NTAPI HalGetAdapter(IN PDEVICE_DESCRIPTION DeviceDescription, OUT PULONG NumberOfMapRegisters)
Definition: dma.c:22

◆ ScsiPortGetVirtualAddress()

PVOID NTAPI ScsiPortGetVirtualAddress ( IN PVOID  HwDeviceExtension,
IN SCSI_PHYSICAL_ADDRESS  PhysicalAddress 
)

Definition at line 887 of file scsiport.c.

889 {
890  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
891  ULONG Offset;
892 
893  DPRINT("ScsiPortGetVirtualAddress(%p %I64x)\n",
894  HwDeviceExtension, PhysicalAddress.QuadPart);
895 
896  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
898  MiniPortDeviceExtension);
899 
900  if (DeviceExtension->PhysicalAddress.QuadPart > PhysicalAddress.QuadPart)
901  return NULL;
902 
903  Offset = (ULONG)(PhysicalAddress.QuadPart - DeviceExtension->PhysicalAddress.QuadPart);
904 
905  if (Offset >= DeviceExtension->CommonBufferLength)
906  return NULL;
907 
908  return (PVOID)((ULONG_PTR)DeviceExtension->SrbExtensionBuffer + Offset);
909 }
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
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
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS PhysicalAddress
Definition: iotypes.h:1060
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
LONGLONG QuadPart
Definition: typedefs.h:112

◆ ScsiPortInitialize()

ULONG NTAPI ScsiPortInitialize ( IN PVOID  Argument1,
IN PVOID  Argument2,
IN struct _HW_INITIALIZATION_DATA HwInitializationData,
IN PVOID  HwContext 
)

Definition at line 1008 of file scsiport.c.

1012 {
1015  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension = NULL;
1016  PCONFIGURATION_INFORMATION SystemConfig;
1018  PORT_CONFIGURATION_INFORMATION InitialPortConfig;
1019  CONFIGURATION_INFO ConfigInfo;
1020  ULONG DeviceExtensionSize;
1021  ULONG PortConfigSize;
1022  BOOLEAN Again;
1023  BOOLEAN DeviceFound = FALSE;
1024  BOOLEAN FirstConfigCall = TRUE;
1025  ULONG Result;
1026  NTSTATUS Status;
1027  ULONG MaxBus;
1029 
1030  PDEVICE_OBJECT PortDeviceObject;
1031  WCHAR NameBuffer[80];
1033  WCHAR DosNameBuffer[80];
1035  PIO_SCSI_CAPABILITIES PortCapabilities;
1036 
1037  KIRQL OldIrql;
1039  BOOLEAN Conflict;
1040  SIZE_T BusConfigSize;
1041 
1042 
1043  DPRINT ("ScsiPortInitialize() called!\n");
1044 
1045  /* Check params for validity */
1046  if ((HwInitializationData->HwInitialize == NULL) ||
1047  (HwInitializationData->HwStartIo == NULL) ||
1048  (HwInitializationData->HwInterrupt == NULL) ||
1049  (HwInitializationData->HwFindAdapter == NULL) ||
1050  (HwInitializationData->HwResetBus == NULL))
1051  {
1052  return STATUS_INVALID_PARAMETER;
1053  }
1054 
1055  /* Set handlers */
1061 
1062  /* Obtain configuration information */
1063  SystemConfig = IoGetConfigurationInformation();
1064 
1065  /* Zero the internal configuration info structure */
1066  RtlZeroMemory(&ConfigInfo, sizeof(CONFIGURATION_INFO));
1067 
1068  /* Zero starting slot number */
1069  SlotNumber.u.AsULONG = 0;
1070 
1071  /* Allocate space for access ranges */
1072  if (HwInitializationData->NumberOfAccessRanges)
1073  {
1074  ConfigInfo.AccessRanges =
1076  HwInitializationData->NumberOfAccessRanges * sizeof(ACCESS_RANGE), TAG_SCSIPORT);
1077 
1078  /* Fail if failed */
1079  if (ConfigInfo.AccessRanges == NULL)
1081  }
1082 
1083  /* Open registry keys */
1084  SpiInitOpenKeys(&ConfigInfo, (PUNICODE_STRING)Argument2);
1085 
1086  /* Last adapter number = not known */
1088 
1089  /* Calculate sizes of DeviceExtension and PortConfig */
1090  DeviceExtensionSize = sizeof(SCSI_PORT_DEVICE_EXTENSION) +
1091  HwInitializationData->DeviceExtensionSize;
1092 
1093  MaxBus = (HwInitializationData->AdapterInterfaceType == PCIBus) ? 8 : 1;
1094  DPRINT("MaxBus: %lu\n", MaxBus);
1095 
1096  while (TRUE)
1097  {
1098  /* Create a unicode device name */
1099  swprintf(NameBuffer,
1100  L"\\Device\\ScsiPort%lu",
1101  SystemConfig->ScsiPortCount);
1102  RtlInitUnicodeString(&DeviceName, NameBuffer);
1103 
1104  DPRINT("Creating device: %wZ\n", &DeviceName);
1105 
1106  /* Create the port device */
1108  DeviceExtensionSize,
1109  &DeviceName,
1111  0,
1112  FALSE,
1113  &PortDeviceObject);
1114 
1115  if (!NT_SUCCESS(Status))
1116  {
1117  DPRINT1("IoCreateDevice call failed! (Status 0x%lX)\n", Status);
1118  PortDeviceObject = NULL;
1119  break;
1120  }
1121 
1122  DPRINT ("Created device: %wZ (%p)\n", &DeviceName, PortDeviceObject);
1123 
1124  /* Set the buffering strategy here... */
1125  PortDeviceObject->Flags |= DO_DIRECT_IO;
1126  PortDeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT; /* FIXME: Is this really needed? */
1127 
1128  /* Fill Device Extension */
1129  DeviceExtension = PortDeviceObject->DeviceExtension;
1130  RtlZeroMemory(DeviceExtension, DeviceExtensionSize);
1131  DeviceExtension->Length = DeviceExtensionSize;
1132  DeviceExtension->DeviceObject = PortDeviceObject;
1133  DeviceExtension->PortNumber = SystemConfig->ScsiPortCount;
1134 
1135  /* Driver's routines... */
1136  DeviceExtension->HwInitialize = HwInitializationData->HwInitialize;
1137  DeviceExtension->HwStartIo = HwInitializationData->HwStartIo;
1138  DeviceExtension->HwInterrupt = HwInitializationData->HwInterrupt;
1139  DeviceExtension->HwResetBus = HwInitializationData->HwResetBus;
1140  DeviceExtension->HwDmaStarted = HwInitializationData->HwDmaStarted;
1141 
1142  /* Extensions sizes */
1143  DeviceExtension->MiniPortExtensionSize = HwInitializationData->DeviceExtensionSize;
1144  DeviceExtension->LunExtensionSize = HwInitializationData->SpecificLuExtensionSize;
1145  DeviceExtension->SrbExtensionSize = HwInitializationData->SrbExtensionSize;
1146 
1147  /* Round Srb extension size to the quadword */
1148  DeviceExtension->SrbExtensionSize =
1149  ~(sizeof(LONGLONG) - 1) & (DeviceExtension->SrbExtensionSize +
1150  sizeof(LONGLONG) - 1);
1151 
1152  /* Fill some numbers (bus count, lun count, etc) */
1153  DeviceExtension->MaxLunCount = SCSI_MAXIMUM_LOGICAL_UNITS;
1154  DeviceExtension->RequestsNumber = 16;
1155 
1156  /* Initialize the spin lock in the controller extension */
1157  KeInitializeSpinLock(&DeviceExtension->IrqLock);
1158  KeInitializeSpinLock(&DeviceExtension->SpinLock);
1159 
1160  /* Initialize the DPC object */
1161  IoInitializeDpcRequest(PortDeviceObject,
1163 
1164  /* Initialize the device timer */
1165  DeviceExtension->TimerCount = -1;
1166  IoInitializeTimer(PortDeviceObject,
1168  DeviceExtension);
1169 
1170  /* Initialize miniport timer */
1171  KeInitializeTimer(&DeviceExtension->MiniportTimer);
1172  KeInitializeDpc(&DeviceExtension->MiniportTimerDpc,
1174  PortDeviceObject);
1175 
1176 CreatePortConfig:
1177 
1178  Status = SpiCreatePortConfig(DeviceExtension,
1180  &ConfigInfo,
1181  &InitialPortConfig,
1182  FirstConfigCall);
1183 
1184  if (!NT_SUCCESS(Status))
1185  {
1186  DPRINT("SpiCreatePortConfig() failed with Status 0x%08X\n", Status);
1187  break;
1188  }
1189 
1190  /* Allocate and initialize port configuration info */
1191  PortConfigSize = (sizeof(PORT_CONFIGURATION_INFORMATION) +
1192  HwInitializationData->NumberOfAccessRanges *
1193  sizeof(ACCESS_RANGE) + 7) & ~7;
1194  DeviceExtension->PortConfig = ExAllocatePoolWithTag(NonPagedPool, PortConfigSize, TAG_SCSIPORT);
1195 
1196  /* Fail if failed */
1197  if (DeviceExtension->PortConfig == NULL)
1198  {
1200  break;
1201  }
1202 
1203  PortConfig = DeviceExtension->PortConfig;
1204 
1205  /* Copy information here */
1206  RtlCopyMemory(PortConfig,
1207  &InitialPortConfig,
1209 
1210 
1211  /* Copy extension sizes into the PortConfig */
1212  PortConfig->SpecificLuExtensionSize = DeviceExtension->LunExtensionSize;
1213  PortConfig->SrbExtensionSize = DeviceExtension->SrbExtensionSize;
1214 
1215  /* Initialize Access ranges */
1216  if (HwInitializationData->NumberOfAccessRanges != 0)
1217  {
1218  PortConfig->AccessRanges = (PVOID)(PortConfig+1);
1219 
1220  /* Align to LONGLONG */
1221  PortConfig->AccessRanges = (PVOID)((ULONG_PTR)(PortConfig->AccessRanges) + 7);
1222  PortConfig->AccessRanges = (PVOID)((ULONG_PTR)(PortConfig->AccessRanges) & ~7);
1223 
1224  /* Copy the data */
1225  RtlCopyMemory(PortConfig->AccessRanges,
1226  ConfigInfo.AccessRanges,
1227  HwInitializationData->NumberOfAccessRanges * sizeof(ACCESS_RANGE));
1228  }
1229 
1230  /* Search for matching PCI device */
1231  if ((HwInitializationData->AdapterInterfaceType == PCIBus) &&
1232  (HwInitializationData->VendorIdLength > 0) &&
1233  (HwInitializationData->VendorId != NULL) &&
1234  (HwInitializationData->DeviceIdLength > 0) &&
1235  (HwInitializationData->DeviceId != NULL))
1236  {
1237  PortConfig->BusInterruptLevel = 0;
1238 
1239  /* Get PCI device data */
1240  DPRINT("VendorId '%.*s' DeviceId '%.*s'\n",
1241  HwInitializationData->VendorIdLength,
1242  HwInitializationData->VendorId,
1243  HwInitializationData->DeviceIdLength,
1244  HwInitializationData->DeviceId);
1245 
1247  PortDeviceObject,
1249  PortConfig,
1250  RegistryPath,
1251  ConfigInfo.BusNumber,
1252  &SlotNumber))
1253  {
1254  /* Continue to the next bus, nothing here */
1255  ConfigInfo.BusNumber++;
1256  DeviceExtension->PortConfig = NULL;
1257  ExFreePool(PortConfig);
1258  Again = FALSE;
1259  goto CreatePortConfig;
1260  }
1261 
1262  if (!PortConfig->BusInterruptLevel)
1263  {
1264  /* Bypass this slot, because no interrupt was assigned */
1265  DeviceExtension->PortConfig = NULL;
1266  ExFreePool(PortConfig);
1267  goto CreatePortConfig;
1268  }
1269  }
1270  else
1271  {
1272  DPRINT("Non-pci bus\n");
1273  }
1274 
1275  /* Note: HwFindAdapter is called once for each bus */
1276  Again = FALSE;
1277  DPRINT("Calling HwFindAdapter() for Bus %lu\n", PortConfig->SystemIoBusNumber);
1278  Result = (HwInitializationData->HwFindAdapter)(&DeviceExtension->MiniPortDeviceExtension,
1279  HwContext,
1280  0, /* BusInformation */
1281  ConfigInfo.Parameter, /* ArgumentString */
1282  PortConfig,
1283  &Again);
1284 
1285  DPRINT("HwFindAdapter() Result: %lu Again: %s\n",
1286  Result, (Again) ? "True" : "False");
1287 
1288  /* Free MapRegisterBase, it's not needed anymore */
1289  if (DeviceExtension->MapRegisterBase != NULL)
1290  {
1291  ExFreePool(DeviceExtension->MapRegisterBase);
1292  DeviceExtension->MapRegisterBase = NULL;
1293  }
1294 
1295  /* If result is nothing good... */
1296  if (Result != SP_RETURN_FOUND)
1297  {
1298  DPRINT("HwFindAdapter() Result: %lu\n", Result);
1299 
1300  if (Result == SP_RETURN_NOT_FOUND)
1301  {
1302  /* We can continue on the next bus */
1303  ConfigInfo.BusNumber++;
1304  Again = FALSE;
1305 
1306  DeviceExtension->PortConfig = NULL;
1307  ExFreePool(PortConfig);
1308  goto CreatePortConfig;
1309  }
1310 
1311  /* Otherwise, break */
1313  break;
1314  }
1315 
1316  DPRINT("ScsiPortInitialize(): Found HBA! (%x), adapter Id %d\n",
1317  PortConfig->BusInterruptVector, PortConfig->InitiatorBusId[0]);
1318 
1319  /* If the SRB extension size was updated */
1320  if (!DeviceExtension->NonCachedExtension &&
1321  (PortConfig->SrbExtensionSize != DeviceExtension->SrbExtensionSize))
1322  {
1323  /* Set it (rounding to LONGLONG again) */
1324  DeviceExtension->SrbExtensionSize =
1325  (PortConfig->SrbExtensionSize +
1326  sizeof(LONGLONG)) & ~(sizeof(LONGLONG) - 1);
1327  }
1328 
1329  /* The same with LUN extension size */
1330  if (PortConfig->SpecificLuExtensionSize != DeviceExtension->LunExtensionSize)
1331  DeviceExtension->LunExtensionSize = PortConfig->SpecificLuExtensionSize;
1332 
1333 
1334  if (!((HwInitializationData->AdapterInterfaceType == PCIBus) &&
1335  (HwInitializationData->VendorIdLength > 0) &&
1336  (HwInitializationData->VendorId != NULL) &&
1337  (HwInitializationData->DeviceIdLength > 0) &&
1338  (HwInitializationData->DeviceId != NULL)))
1339  {
1340  /* Construct a resource list */
1341  ResourceList = SpiConfigToResource(DeviceExtension,
1342  PortConfig);
1343 
1344  if (ResourceList)
1345  {
1347  RtlInitUnicodeString(&UnicodeString, L"ScsiAdapter");
1348  DPRINT("Reporting resources\n");
1350  DriverObject,
1351  NULL,
1352  0,
1353  PortDeviceObject,
1354  ResourceList,
1356  List[0].PartialResourceList.PartialDescriptors) +
1357  ResourceList->List[0].PartialResourceList.Count
1359  FALSE,
1360  &Conflict);
1362 
1363  /* In case of a failure or a conflict, break */
1364  if (Conflict || (!NT_SUCCESS(Status)))
1365  {
1366  if (Conflict)
1368  break;
1369  }
1370  }
1371  }
1372 
1373  /* Reset the Conflict var */
1374  Conflict = FALSE;
1375 
1376  /* Copy all stuff which we ever need from PortConfig to the DeviceExtension */
1378  DeviceExtension->MaxTargedIds = SCSI_MAXIMUM_TARGETS_PER_BUS;
1379  else
1380  DeviceExtension->MaxTargedIds = PortConfig->MaximumNumberOfTargets;
1381 
1382  DeviceExtension->BusNum = PortConfig->NumberOfBuses;
1383  DeviceExtension->CachesData = PortConfig->CachesData;
1384  DeviceExtension->ReceiveEvent = PortConfig->ReceiveEvent;
1385  DeviceExtension->SupportsTaggedQueuing = PortConfig->TaggedQueuing;
1386  DeviceExtension->MultipleReqsPerLun = PortConfig->MultipleRequestPerLu;
1387 
1388  /* If something was disabled via registry - apply it */
1389  if (ConfigInfo.DisableMultipleLun)
1390  DeviceExtension->MultipleReqsPerLun = PortConfig->MultipleRequestPerLu = FALSE;
1391 
1392  if (ConfigInfo.DisableTaggedQueueing)
1393  DeviceExtension->SupportsTaggedQueuing = PortConfig->MultipleRequestPerLu = FALSE;
1394 
1395  /* Check if we need to alloc SRB data */
1396  if (DeviceExtension->SupportsTaggedQueuing ||
1397  DeviceExtension->MultipleReqsPerLun)
1398  {
1399  DeviceExtension->NeedSrbDataAlloc = TRUE;
1400  }
1401  else
1402  {
1403  DeviceExtension->NeedSrbDataAlloc = FALSE;
1404  }
1405 
1406  /* Get a pointer to the port capabilities */
1407  PortCapabilities = &DeviceExtension->PortCapabilities;
1408 
1409  /* Copy one field there */
1410  DeviceExtension->MapBuffers = PortConfig->MapBuffers;
1411  PortCapabilities->AdapterUsesPio = PortConfig->MapBuffers;
1412 
1413  if (DeviceExtension->AdapterObject == NULL &&
1414  (PortConfig->DmaChannel != SP_UNINITIALIZED_VALUE || PortConfig->Master))
1415  {
1416  DPRINT1("DMA is not supported yet\n");
1417  ASSERT(FALSE);
1418  }
1419 
1420  if (DeviceExtension->SrbExtensionBuffer == NULL &&
1421  (DeviceExtension->SrbExtensionSize != 0 ||
1422  PortConfig->AutoRequestSense))
1423  {
1424  DeviceExtension->SupportsAutoSense = PortConfig->AutoRequestSense;
1425  DeviceExtension->NeedSrbExtensionAlloc = TRUE;
1426 
1427  /* Allocate common buffer */
1428  Status = SpiAllocateCommonBuffer(DeviceExtension, 0);
1429 
1430  /* Check for failure */
1431  if (!NT_SUCCESS(Status))
1432  break;
1433  }
1434 
1435  /* Allocate SrbData, if needed */
1436  if (DeviceExtension->NeedSrbDataAlloc)
1437  {
1438  ULONG Count;
1439  PSCSI_REQUEST_BLOCK_INFO SrbData;
1440 
1441  if (DeviceExtension->SrbDataCount != 0)
1442  Count = DeviceExtension->SrbDataCount;
1443  else
1444  Count = DeviceExtension->RequestsNumber * 2;
1445 
1446  /* Allocate the data */
1448  if (SrbData == NULL)
1450 
1451  RtlZeroMemory(SrbData, Count * sizeof(SCSI_REQUEST_BLOCK_INFO));
1452 
1453  DeviceExtension->SrbInfo = SrbData;
1454  DeviceExtension->FreeSrbInfo = SrbData;
1455  DeviceExtension->SrbDataCount = Count;
1456 
1457  /* Link it to the list */
1458  while (Count > 0)
1459  {
1460  SrbData->Requests.Flink = (PLIST_ENTRY)(SrbData + 1);
1461  SrbData++;
1462  Count--;
1463  }
1464 
1465  /* Mark the last entry of the list */
1466  SrbData--;
1467  SrbData->Requests.Flink = NULL;
1468  }
1469 
1470  /* Initialize port capabilities */
1471  PortCapabilities = &DeviceExtension->PortCapabilities;
1472  PortCapabilities->Length = sizeof(IO_SCSI_CAPABILITIES);
1473  PortCapabilities->MaximumTransferLength = PortConfig->MaximumTransferLength;
1474 
1475  if (PortConfig->ReceiveEvent)
1477 
1478  PortCapabilities->TaggedQueuing = DeviceExtension->SupportsTaggedQueuing;
1479  PortCapabilities->AdapterScansDown = PortConfig->AdapterScansDown;
1480 
1481  if (PortConfig->AlignmentMask > PortDeviceObject->AlignmentRequirement)
1482  PortDeviceObject->AlignmentRequirement = PortConfig->AlignmentMask;
1483 
1484  PortCapabilities->AlignmentMask = PortDeviceObject->AlignmentRequirement;
1485 
1486  if (PortCapabilities->MaximumPhysicalPages == 0)
1487  {
1488  PortCapabilities->MaximumPhysicalPages =
1489  BYTES_TO_PAGES(PortCapabilities->MaximumTransferLength);
1490 
1491  /* Apply miniport's limits */
1492  if (PortConfig->NumberOfPhysicalBreaks < PortCapabilities->MaximumPhysicalPages)
1493  {
1494  PortCapabilities->MaximumPhysicalPages = PortConfig->NumberOfPhysicalBreaks;
1495  }
1496  }
1497 
1498  /* Deal with interrupts */
1499  if (DeviceExtension->HwInterrupt == NULL ||
1500  (PortConfig->BusInterruptLevel == 0 && PortConfig->BusInterruptVector == 0))
1501  {
1502  /* No interrupts */
1503  DeviceExtension->InterruptCount = 0;
1504 
1505  DPRINT1("Interrupt Count: 0\n");
1506 
1507  UNIMPLEMENTED;
1508 
1509  /* This code path will ALWAYS crash so stop it now */
1510  while(TRUE);
1511  }
1512  else
1513  {
1514  BOOLEAN InterruptShareable;
1516  ULONG InterruptVector[2], i, MappedIrq[2];
1517  KIRQL Dirql[2], MaxDirql;
1518  KAFFINITY Affinity[2];
1519 
1520  DeviceExtension->InterruptLevel[0] = PortConfig->BusInterruptLevel;
1521  DeviceExtension->InterruptLevel[1] = PortConfig->BusInterruptLevel2;
1522 
1523  InterruptVector[0] = PortConfig->BusInterruptVector;
1524  InterruptVector[1] = PortConfig->BusInterruptVector2;
1525 
1526  InterruptMode[0] = PortConfig->InterruptMode;
1527  InterruptMode[1] = PortConfig->InterruptMode2;
1528 
1529  DeviceExtension->InterruptCount = (PortConfig->BusInterruptLevel2 != 0 || PortConfig->BusInterruptVector2 != 0) ? 2 : 1;
1530 
1531  for (i = 0; i < DeviceExtension->InterruptCount; i++)
1532  {
1533  /* Register an interrupt handler for this device */
1534  MappedIrq[i] = HalGetInterruptVector(PortConfig->AdapterInterfaceType,
1535  PortConfig->SystemIoBusNumber,
1536  DeviceExtension->InterruptLevel[i],
1537  InterruptVector[i],
1538  &Dirql[i],
1539  &Affinity[i]);
1540  }
1541 
1542  if (DeviceExtension->InterruptCount == 1 || Dirql[0] > Dirql[1])
1543  MaxDirql = Dirql[0];
1544  else
1545  MaxDirql = Dirql[1];
1546 
1547  for (i = 0; i < DeviceExtension->InterruptCount; i++)
1548  {
1549  /* Determine IRQ sharability as usual */
1550  if (PortConfig->AdapterInterfaceType == MicroChannel ||
1552  {
1553  InterruptShareable = TRUE;
1554  }
1555  else
1556  {
1557  InterruptShareable = FALSE;
1558  }
1559 
1560  Status = IoConnectInterrupt(&DeviceExtension->Interrupt[i],
1562  DeviceExtension,
1563  &DeviceExtension->IrqLock,
1564  MappedIrq[i],
1565  Dirql[i],
1566  MaxDirql,
1567  InterruptMode[i],
1568  InterruptShareable,
1569  Affinity[i],
1570  FALSE);
1571 
1572  if (!(NT_SUCCESS(Status)))
1573  {
1574  DPRINT1("Could not connect interrupt %d\n",
1575  InterruptVector[i]);
1576  DeviceExtension->Interrupt[i] = NULL;
1577  break;
1578  }
1579  }
1580 
1581  if (!NT_SUCCESS(Status))
1582  break;
1583  }
1584 
1585  /* Save IoAddress (from access ranges) */
1586  if (HwInitializationData->NumberOfAccessRanges != 0)
1587  {
1588  DeviceExtension->IoAddress =
1589  ((*(PortConfig->AccessRanges))[0]).RangeStart.LowPart;
1590 
1591  DPRINT("Io Address %x\n", DeviceExtension->IoAddress);
1592  }
1593 
1594  /* Set flag that it's allowed to disconnect during this command */
1595  DeviceExtension->Flags |= SCSI_PORT_DISCONNECT_ALLOWED;
1596 
1597  /* Initialize counter of active requests (-1 means there are none) */
1598  DeviceExtension->ActiveRequestCounter = -1;
1599 
1600  /* Analyze what we have about DMA */
1601  if (DeviceExtension->AdapterObject != NULL &&
1602  PortConfig->Master &&
1603  PortConfig->NeedPhysicalAddresses)
1604  {
1605  DeviceExtension->MapRegisters = TRUE;
1606  }
1607  else
1608  {
1609  DeviceExtension->MapRegisters = FALSE;
1610  }
1611 
1612  /* Call HwInitialize at DISPATCH_LEVEL */
1614 
1615  if (!KeSynchronizeExecution(DeviceExtension->Interrupt[0],
1616  DeviceExtension->HwInitialize,
1617  DeviceExtension->MiniPortDeviceExtension))
1618  {
1619  DPRINT1("HwInitialize() failed!\n");
1622  break;
1623  }
1624 
1625  /* Check if a notification is needed */
1626  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
1627  {
1628  /* Call DPC right away, because we're already at DISPATCH_LEVEL */
1630  DeviceExtension->DeviceObject,
1631  NULL,
1632  NULL);
1633  }
1634 
1635  /* Lower irql back to what it was */
1637 
1638  /* Start our timer */
1639  IoStartTimer(PortDeviceObject);
1640 
1641  /* Initialize bus scanning information */
1643  BusScanInfo[DeviceExtension->PortConfig->NumberOfBuses]);
1644  DeviceExtension->BusesConfig = ExAllocatePoolWithTag(PagedPool,
1645  BusConfigSize,
1646  TAG_SCSIPORT);
1647  if (!DeviceExtension->BusesConfig)
1648  {
1649  DPRINT1("Out of resources!\n");
1651  break;
1652  }
1653 
1654  /* Zero it */
1655  RtlZeroMemory(DeviceExtension->BusesConfig, BusConfigSize);
1656 
1657  /* Store number of buses there */
1658  DeviceExtension->BusesConfig->NumberOfBuses = (UCHAR)DeviceExtension->BusNum;
1659 
1660  /* Scan the adapter for devices */
1661  SpiScanAdapter(DeviceExtension);
1662 
1663  /* Build the registry device map */
1664  SpiBuildDeviceMap(DeviceExtension,
1666 
1667  /* Create the dos device link */
1668  swprintf(DosNameBuffer,
1669  L"\\??\\Scsi%lu:",
1670  SystemConfig->ScsiPortCount);
1671  RtlInitUnicodeString(&DosDeviceName, DosNameBuffer);
1673 
1674  /* Increase the port count */
1675  SystemConfig->ScsiPortCount++;
1676  FirstConfigCall = FALSE;
1677 
1678  /* Increase adapter number and bus number respectively */
1679  ConfigInfo.AdapterNumber++;
1680 
1681  if (!Again)
1682  ConfigInfo.BusNumber++;
1683 
1684  DPRINT("Bus: %lu MaxBus: %lu\n", ConfigInfo.BusNumber, MaxBus);
1685 
1686  DeviceFound = TRUE;
1687  }
1688 
1689  /* Clean up the mess */
1690  SpiCleanupAfterInit(DeviceExtension);
1691 
1692  /* Close registry keys */
1693  if (ConfigInfo.ServiceKey != NULL)
1694  ZwClose(ConfigInfo.ServiceKey);
1695 
1696  if (ConfigInfo.DeviceKey != NULL)
1697  ZwClose(ConfigInfo.DeviceKey);
1698 
1699  if (ConfigInfo.BusKey != NULL)
1700  ZwClose(ConfigInfo.BusKey);
1701 
1702  if (ConfigInfo.AccessRanges != NULL)
1703  ExFreePool(ConfigInfo.AccessRanges);
1704 
1705  if (ConfigInfo.Parameter != NULL)
1706  ExFreePool(ConfigInfo.Parameter);
1707 
1708  DPRINT("ScsiPortInitialize() done, Status = 0x%08X, DeviceFound = %d!\n",
1709  Status, DeviceFound);
1710 
1711  return (DeviceFound == FALSE) ? Status : STATUS_SUCCESS;
1712 }
struct _LIST_ENTRY * PLIST_ENTRY
#define SRBEV_SCSI_ASYNC_NOTIFICATION
Definition: srb.h:232
FORCEINLINE VOID IoInitializeDpcRequest(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIO_DPC_ROUTINE DpcRoutine)
Definition: iofuncs.h:2792
static NTSTATUS NTAPI ScsiPortDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: scsiport.c:2801
#define SP_UNINITIALIZED_VALUE
Definition: srb.h:224
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
INTERFACE_TYPE AdapterInterfaceType
Definition: srb.h:55
ULONG SupportedAsynchronousEvents
Definition: scsi_port.h:139
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:798
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
*BytesInUnicodeString PWCH UnicodeString
Definition: rtlfuncs.h:1980
_IRQL_requires_same_ _In_opt_ PVOID Argument1
Definition: cmtypes.h:694
BOOLEAN DisableMultipleLun
Definition: scsiport_int.h:74
VOID NTAPI SpiMiniportTimerDpc(IN struct _KDPC *Dpc, IN PVOID DeviceObject, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
Definition: scsiport.c:5700
NTHALAPI ULONG NTAPI HalGetInterruptVector(INTERFACE_TYPE, ULONG, ULONG, ULONG, PKIRQL, PKAFFINITY)
VOID NTAPI IoStartTimer(IN PDEVICE_OBJECT DeviceObject)
Definition: iotimer.c:133
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Definition: iorsrce.c:830
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
IO_SCSI_CAPABILITIES PortCapabilities
Definition: scsiport.c:80
#define SCSI_MAXIMUM_LOGICAL_UNITS
Definition: srb.h:21
BOOLEAN AdapterScansDown
Definition: scsi_port.h:142
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PVOID _In_ struct _HW_INITIALIZATION_DATA _In_ PVOID HwContext
Definition: srb.h:664
static VOID NTAPI ScsiPortDpcForIsr(IN PKDPC Dpc, IN PDEVICE_OBJECT DpcDeviceObject, IN PIRP DpcIrp, IN PVOID DpcContext)
Definition: scsiport.c:4865
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
struct _SCSI_PORT_DEVICE_EXTENSION SCSI_PORT_DEVICE_EXTENSION
static PCM_RESOURCE_LIST SpiConfigToResource(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, PPORT_CONFIGURATION_INFORMATION PortConfig)
Definition: scsiport.c:2162
ACCESS_RANGE(* AccessRanges)[]
Definition: srb.h:70
WCHAR DeviceName[]
Definition: adapter.cpp:21
const MUI_LANGUAGE_RESOURCE ResourceList[]
Definition: muilanguages.h:414
#define SCSI_PORT_NOTIFICATION_NEEDED
Definition: scsiport_int.h:29
static VOID SpiInitOpenKeys(PCONFIGURATION_INFO ConfigInfo, PUNICODE_STRING RegistryPath)
Definition: scsiport.c:912
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
KSERVICE_ROUTINE * PKSERVICE_ROUTINE
Definition: ketypes.h:500
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define IRP_MJ_SCSI
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:451
UCHAR KIRQL
Definition: env_spec_w32.h:591
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 FILE_DEVICE_CONTROLLER
Definition: winioctl.h:109
#define SCSI_MAXIMUM_TARGETS_PER_BUS
Definition: srb.h:22
NTSTATUS NTAPI IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN KAFFINITY ProcessorEnableMask, IN BOOLEAN FloatingSave)
Definition: irq.c:22
static NTSTATUS SpiBuildDeviceMap(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING RegistryPath)
Definition: scsiport.c:5284
PHW_INITIALIZE HwInitialize
Definition: scsiport.c:82
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
enum _KINTERRUPT_MODE KINTERRUPT_MODE
PACCESS_RANGE AccessRanges
Definition: scsiport_int.h:78
_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
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
VOID NTAPI KeInitializeTimer(OUT PKTIMER Timer)
Definition: timerobj.c:233
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:2314
void DPRINT(...)
Definition: polytest.cpp:61
KINTERRUPT_MODE InterruptMode2
Definition: srb.h:97
void * PVOID
Definition: retypes.h:9
_In_ PVOID Argument2
Definition: classpnp.h:680
static NTSTATUS NTAPI ScsiPortCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: scsiport.c:2447
KINTERRUPT_MODE InterruptMode
Definition: srb.h:60
int64_t LONGLONG
Definition: typedefs.h:66
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
LIST_ENTRY List
Definition: psmgr.c:57
static VOID SpiCleanupAfterInit(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
Definition: scsiport.c:1715
#define SCSI_PORT_DISCONNECT_ALLOWED
Definition: scsiport_int.h:37
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI IoInitializeTimer(IN PDEVICE_OBJECT DeviceObject, IN PIO_TIMER_ROUTINE TimerRoutine, IN PVOID Context)
Definition: iotimer.c:92
static VOID NTAPI ScsiPortIoTimer(PDEVICE_OBJECT DeviceObject, PVOID Context)
Definition: scsiport.c:5161
static DRIVER_DISPATCH ScsiPortDispatchScsi
Definition: scsiport.c:63
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define SP_RETURN_NOT_FOUND
Definition: srb.h:513
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:170
#define SP_RETURN_FOUND
Definition: srb.h:514
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG _In_ ULONG SlotNumber
Definition: halfuncs.h:156
static char DosDeviceName[DEVICE_SIZE]
Definition: lsdd.c:26
#define BYTES_TO_PAGES(Size)
unsigned char UCHAR
Definition: xmlstorage.h:181
struct _PORT_CONFIGURATION_INFORMATION PORT_CONFIGURATION_INFORMATION
static DRIVER_STARTIO ScsiPortStartIo
Definition: scsiport.c:72
static VOID SpiScanAdapter(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
Definition: scsiport.c:3763
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
static const WCHAR L[]
Definition: oid.c:1250
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
static NTSTATUS SpiAllocateCommonBuffer(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, ULONG NonCachedSize)
Definition: scsiport.c:795
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
#define FILE_WORD_ALIGNMENT
Definition: nt_native.h:787
Status
Definition: gdiplustypes.h:24
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
ULONG_PTR SIZE_T
Definition: typedefs.h:78
PHW_RESET_BUS HwResetBus
Definition: scsiport.c:85
PADAPTER_OBJECT AdapterObject
Definition: scsiport.c:88
static BOOLEAN NTAPI ScsiPortIsr(IN PKINTERRUPT Interrupt, IN PVOID ServiceContext)
Definition: scsiport.c:4607
ULONG_PTR KAFFINITY
Definition: compat.h:75
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
PHW_INTERRUPT HwInterrupt
Definition: scsiport.c:84
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
#define DPRINT1
Definition: precomp.h:8
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2180
unsigned int ULONG
Definition: retypes.h:1
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:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:142
PDRIVER_STARTIO DriverStartIo
Definition: iotypes.h:2178
#define TAG_SCSIPORT
Definition: scsiport_int.h:19
static NTSTATUS SpiCreatePortConfig(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, PHW_INITIALIZATION_DATA HwInitData, PCONFIGURATION_INFO InternalConfigInfo, PPORT_CONFIGURATION_INFORMATION ConfigInfo, BOOLEAN FirstCall)
Definition: scsiport.c:5733
#define STATUS_ADAPTER_HARDWARE_ERROR
Definition: ntstatus.h:416
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:711
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:247
return STATUS_SUCCESS
Definition: btrfs.c:2745
BOOLEAN DisableTaggedQueueing
Definition: scsiport_int.h:73
struct _IO_SCSI_CAPABILITIES IO_SCSI_CAPABILITIES
struct _DRIVER_OBJECT * PDRIVER_OBJECT
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
_Must_inspect_result_ _In_ PVOID _In_ struct _HW_INITIALIZATION_DATA * HwInitializationData
Definition: srb.h:664
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52

◆ ScsiPortIoMapTransfer()

VOID NTAPI ScsiPortIoMapTransfer ( IN PVOID  HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK  Srb,
IN PVOID  LogicalAddress,
IN ULONG  Length 
)

Definition at line 1818 of file scsiport.c.

1822 {
1823  DPRINT1("ScsiPortIoMapTransfer()\n");
1824  UNIMPLEMENTED;
1825 }
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: debug.h:114

◆ ScsiPortIoTimer()

static VOID NTAPI ScsiPortIoTimer ( PDEVICE_OBJECT  DeviceObject,
PVOID  Context 
)
static

Definition at line 5161 of file scsiport.c.

5163 {
5164  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
5165  PSCSI_PORT_LUN_EXTENSION LunExtension;
5166  ULONG Lun;
5167  PIRP Irp;
5168 
5169  DPRINT("ScsiPortIoTimer()\n");
5170 
5172 
5173  /* Protect with the spinlock */
5174  KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
5175 
5176  /* Check timeouts */
5177  if (DeviceExtension->TimerCount > 0)
5178  {
5179  /* Decrease the timeout counter */
5180  DeviceExtension->TimerCount--;
5181 
5182  if (DeviceExtension->TimerCount == 0)
5183  {
5184  /* Timeout, process it */
5185  if (KeSynchronizeExecution(DeviceExtension->Interrupt[0],
5187  DeviceExtension->DeviceObject))
5188  {
5189  DPRINT("Error happened during processing timeout, but nothing critical\n");
5190  }
5191  }
5192 
5193  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
5194 
5195  /* We should exit now, since timeout is processed */
5196  return;
5197  }
5198 
5199  /* Per-Lun scanning of timeouts is needed... */
5200  for (Lun = 0; Lun < LUS_NUMBER; Lun++)
5201  {
5202  LunExtension = DeviceExtension->LunExtensionList[Lun];
5203 
5204  while (LunExtension)
5205  {
5206  if (LunExtension->Flags & LUNEX_BUSY)
5207  {
5208  if (!(LunExtension->Flags &
5210  {
5211  DPRINT("Retrying busy request\n");
5212 
5213  /* Clear flags, and retry busy request */
5214  LunExtension->Flags &= ~(LUNEX_BUSY | LUNEX_FULL_QUEUE);
5215  Irp = LunExtension->BusyRequest;
5216 
5217  /* Clearing busy request */
5218  LunExtension->BusyRequest = NULL;
5219 
5220  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
5221 
5223 
5224  KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
5225  }
5226  }
5227  else if (LunExtension->RequestTimeout == 0)
5228  {
5229  RESETBUS_PARAMS ResetParams;
5230 
5231  LunExtension->RequestTimeout = -1;
5232 
5233  DPRINT("Request timed out, resetting bus\n");
5234 
5235  /* Pass params to the bus reset routine */
5236  ResetParams.PathId = LunExtension->PathId;
5237  ResetParams.DeviceExtension = DeviceExtension;
5238 
5239  if (!KeSynchronizeExecution(DeviceExtension->Interrupt[0],
5240  SpiResetBus,
5241  &ResetParams))
5242  {
5243  DPRINT1("Reset failed\n");
5244  }
5245  }
5246  else if (LunExtension->RequestTimeout > 0)
5247  {
5248  /* Decrement the timeout counter */
5249  LunExtension->RequestTimeout--;
5250  }
5251 
5252  LunExtension = LunExtension->Next;
5253  }
5254  }
5255 
5256  /* Release the spinlock */
5257  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
5258 }
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1117
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension
Definition: scsiport_int.h:302
_In_ PIRP Irp
Definition: csq.h:116
struct SCSI_PORT_DEVICE_EXTENSION * PSCSI_PORT_DEVICE_EXTENSION
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
struct _SCSI_PORT_LUN_EXTENSION * Next
Definition: scsiport_int.h:125
BOOLEAN NTAPI SpiResetBus(PVOID ServiceContext)
Definition: scsiport.c:5128
#define LUNEX_FROZEN_QUEUE
Definition: scsiport_int.h:44
VOID NTAPI IoStartPacket(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key, IN PDRIVER_CANCEL CancelFunction)
Definition: device.c:1875
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
#define LUNEX_FULL_QUEUE
Definition: scsiport_int.h:47
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
unsigned int * PULONG
Definition: retypes.h:1
#define DPRINT1
Definition: precomp.h:8
#define LUNEX_BUSY
Definition: scsiport_int.h:46
BOOLEAN NTAPI SpiProcessTimeout(PVOID ServiceContext)
Definition: scsiport.c:5082
unsigned int ULONG
Definition: retypes.h:1
#define LUNEX_NEED_REQUEST_SENSE
Definition: scsiport_int.h:45
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:142
#define LUS_NUMBER
Definition: scsiport_int.h:22

Referenced by ScsiPortInitialize().

◆ ScsiPortIsr()

static BOOLEAN NTAPI ScsiPortIsr ( IN PKINTERRUPT  Interrupt,
IN PVOID  ServiceContext 
)
static

Definition at line 4607 of file scsiport.c.

4609 {
4610  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
4611 
4612  DPRINT("ScsiPortIsr() called!\n");
4613 
4614  DeviceExtension = (PSCSI_PORT_DEVICE_EXTENSION)ServiceContext;
4615 
4616  /* If interrupts are disabled - we don't expect any */
4617  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_DISABLE_INTERRUPTS)
4618  return FALSE;
4619 
4620  /* Call miniport's HwInterrupt routine */
4621  if (DeviceExtension->HwInterrupt(&DeviceExtension->MiniPortDeviceExtension) == FALSE)
4622  {
4623  /* This interrupt doesn't belong to us */
4624  return FALSE;
4625  }
4626 
4627  /* If flag of notification is set - queue a DPC */
4628  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
4629  {
4630  IoRequestDpc(DeviceExtension->DeviceObject,
4631  DeviceExtension->CurrentIrp,
4632  DeviceExtension);
4633  }
4634 
4635  return TRUE;
4636 }
#define TRUE
Definition: types.h:120
struct SCSI_PORT_DEVICE_EXTENSION * PSCSI_PORT_DEVICE_EXTENSION
#define SCSI_PORT_NOTIFICATION_NEEDED
Definition: scsiport_int.h:29
#define SCSI_PORT_DISABLE_INTERRUPTS
Definition: scsiport_int.h:39
void DPRINT(...)
Definition: polytest.cpp:61
FORCEINLINE VOID IoRequestDpc(_Inout_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Irp, _In_opt_ __drv_aliasesMem PVOID Context)
Definition: iofuncs.h:2702
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:798
PHW_INTERRUPT HwInterrupt
Definition: scsiport.c:84

Referenced by ScsiPortInitialize().

◆ ScsiPortLogError()

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 at line 1831 of file scsiport.c.

1838 {
1839  //PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
1840 
1841  DPRINT1("ScsiPortLogError() called\n");
1842  DPRINT1("PathId: 0x%02x TargetId: 0x%02x Lun: 0x%02x ErrorCode: 0x%08lx UniqueId: 0x%08lx\n",
1843  PathId, TargetId, Lun, ErrorCode, UniqueId);
1844 
1845  //DeviceExtension = CONTAINING_RECORD(HwDeviceExtension, SCSI_PORT_DEVICE_EXTENSION, MiniPortDeviceExtension);
1846 
1847 
1848  DPRINT("ScsiPortLogError() done\n");
1849 }
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1117
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1117
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1117
void DPRINT(...)
Definition: polytest.cpp:61
#define DPRINT1
Definition: precomp.h:8

◆ ScsiPortMoveMemory()

VOID NTAPI ScsiPortMoveMemory ( OUT PVOID  Destination,
IN PVOID  Source,
IN ULONG  Length 
)

Definition at line 1855 of file scsiport.c.

1858 {
1860  Source,
1861  Length);
1862 }
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2875
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167

◆ ScsiPortNotification()

VOID ScsiPortNotification ( IN SCSI_NOTIFICATION_TYPE  NotificationType,
IN PVOID  HwDeviceExtension,
  ... 
)

Definition at line 1869 of file scsiport.c.

1872 {
1873  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
1874  va_list ap;
1875 
1876  DPRINT("ScsiPortNotification() called\n");
1877 
1878  DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
1880  MiniPortDeviceExtension);
1881 
1882  DPRINT("DeviceExtension %p\n", DeviceExtension);
1883 
1884  va_start(ap, HwDeviceExtension);
1885 
1886  switch (NotificationType)
1887  {
1888  case RequestComplete:
1889  {
1891  PSCSI_REQUEST_BLOCK_INFO SrbData;
1892 
1894 
1895  DPRINT("Notify: RequestComplete (Srb %p)\n", Srb);
1896 
1897  /* Make sure Srb is alright */
1898  ASSERT(Srb->SrbStatus != SRB_STATUS_PENDING);
1899  ASSERT(Srb->Function != SRB_FUNCTION_EXECUTE_SCSI || Srb->SrbStatus != SRB_STATUS_SUCCESS || Srb->ScsiStatus == SCSISTAT_GOOD);
1900 
1901  if (!(Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE))
1902  {
1903  /* It's been already completed */
1904  va_end(ap);
1905  return;
1906  }
1907 
1908  /* It's not active anymore */
1909  Srb->SrbFlags &= ~SRB_FLAGS_IS_ACTIVE;
1910 
1911  if (Srb->Function == SRB_FUNCTION_ABORT_COMMAND)
1912  {
1913  /* TODO: Treat it specially */
1914  ASSERT(FALSE);
1915  }
1916  else
1917  {
1918  /* Get the SRB data */
1919  SrbData = SpiGetSrbData(DeviceExtension,
1920  Srb->PathId,
1921  Srb->TargetId,
1922  Srb->Lun,
1923  Srb->QueueTag);
1924 
1925  /* Make sure there are no CompletedRequests and there is a Srb */
1926  ASSERT(SrbData->CompletedRequests == NULL && SrbData->Srb != NULL);
1927 
1928  /* If it's a read/write request, make sure it has data inside it */
1929  if ((Srb->SrbStatus == SRB_STATUS_SUCCESS) &&
1930  ((Srb->Cdb[0] == SCSIOP_READ) || (Srb->Cdb[0] == SCSIOP_WRITE)))
1931  {
1932  ASSERT(Srb->DataTransferLength);
1933  }
1934 
1935  SrbData->CompletedRequests = DeviceExtension->InterruptData.CompletedRequests;
1936  DeviceExtension->InterruptData.CompletedRequests = SrbData;
1937  }
1938  }
1939  break;
1940 
1941  case NextRequest:
1942  DPRINT("Notify: NextRequest\n");
1943  DeviceExtension->InterruptData.Flags |= SCSI_PORT_NEXT_REQUEST_READY;
1944  break;
1945 
1946  case NextLuRequest:
1947  {
1948  UCHAR PathId;
1949  UCHAR TargetId;
1950  UCHAR Lun;
1951  PSCSI_PORT_LUN_EXTENSION LunExtension;
1952 
1953  PathId = (UCHAR) va_arg (ap, int);
1954  TargetId = (UCHAR) va_arg (ap, int);
1955  Lun = (UCHAR) va_arg (ap, int);
1956 
1957  DPRINT("Notify: NextLuRequest(PathId %u TargetId %u Lun %u)\n",
1958  PathId, TargetId, Lun);
1959 
1960  /* Mark it in the flags field */
1961  DeviceExtension->InterruptData.Flags |= SCSI_PORT_NEXT_REQUEST_READY;
1962 
1963  /* Get the LUN extension */
1964  LunExtension = SpiGetLunExtension(DeviceExtension,
1965  PathId,
1966  TargetId,
1967  Lun);
1968 
1969  /* If returned LunExtension is NULL, break out */
1970  if (!LunExtension) break;
1971 
1972  /* This request should not be processed if */
1973  if ((LunExtension->ReadyLun) ||
1974  (LunExtension->SrbInfo.Srb))
1975  {
1976  /* Nothing to do here */
1977  break;
1978  }
1979 
1980  /* Add this LUN to the list */
1981  LunExtension->ReadyLun = DeviceExtension->InterruptData.ReadyLun;
1982  DeviceExtension->InterruptData.ReadyLun = LunExtension;
1983  }
1984  break;
1985 
1986  case ResetDetected:
1987  DPRINT("Notify: ResetDetected\n");
1988  /* Add RESET flags */
1989  DeviceExtension->InterruptData.Flags |=
1991  break;
1992 
1993  case CallDisableInterrupts:
1994  DPRINT1("UNIMPLEMENTED SCSI Notification called: CallDisableInterrupts!\n");
1995  break;
1996 
1997  case CallEnableInterrupts:
1998  DPRINT1("UNIMPLEMENTED SCSI Notification called: CallEnableInterrupts!\n");
1999  break;
2000 
2001  case RequestTimerCall:
2002  DPRINT("Notify: RequestTimerCall\n");
2003  DeviceExtension->InterruptData.Flags |= SCSI_PORT_TIMER_NEEDED;
2004  DeviceExtension->InterruptData.HwScsiTimer = (PHW_TIMER)va_arg(ap, PHW_TIMER);
2005  DeviceExtension->InterruptData.MiniportTimerValue = (ULONG)va_arg(ap, ULONG);
2006  break;
2007 
2008  case BusChangeDetected:
2009  DPRINT1("UNIMPLEMENTED SCSI Notification called: BusChangeDetected!\n");
2010  break;
2011 
2012  default:
2013  DPRINT1 ("Unsupported notification from WMI: %lu\n", NotificationType);
2014  break;
2015  }
2016 
2017  va_end(ap);
2018 
2019  /* Request a DPC after we're done with the interrupt */
2020  DeviceExtension->InterruptData.Flags |= SCSI_PORT_NOTIFICATION_NEEDED;
2021 }
struct _SCSI_REQUEST_BLOCK_INFO * CompletedRequests
Definition: scsiport_int.h:110
#define SCSI_PORT_RESET_REPORTED
Definition: scsiport_int.h:35
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1117
#define SCSI_PORT_RESET
Definition: scsiport_int.h:33
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1117
#define SRB_FLAGS_IS_ACTIVE
Definition: srb.h:399
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1117
static PSCSI_REQUEST_BLOCK_INFO SpiGetSrbData(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN UCHAR QueueTag)
Definition: scsiport.c:4096
#define SCSI_PORT_NOTIFICATION_NEEDED
Definition: scsiport_int.h:29
#define va_end(ap)
Definition: acmsvcex.h:90
#define SCSI_PORT_NEXT_REQUEST_READY
Definition: scsiport.c:53
#define SCSIOP_READ
Definition: cdrw_hw.h:905
#define SRB_STATUS_PENDING
Definition: srb.h:332
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
smooth NULL
Definition: ftsmooth.c:416
char * va_list
Definition: acmsvcex.h:78
void DPRINT(...)
Definition: polytest.cpp:61
static PSCSI_PORT_LUN_EXTENSION SpiGetLunExtension(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun)
Definition: scsiport.c:3365
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
SCSI_REQUEST_BLOCK_INFO SrbInfo
Definition: scsiport_int.h:146
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SCSI_PORT_TIMER_NEEDED
Definition: scsiport_int.h:41
PSCSI_REQUEST_BLOCK Srb
Definition: scsiport_int.h:100
#define SRB_FUNCTION_ABORT_COMMAND
Definition: srb.h:316
#define va_arg(ap, T)
Definition: acmsvcex.h:89
#define va_start(ap, A)
Definition: acmsvcex.h:91
struct _SCSI_PORT_LUN_EXTENSION * ReadyLun
Definition: scsiport_int.h:143
#define DPRINT1
Definition: precomp.h:8
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
VOID(NTAPI * PHW_TIMER)(IN PVOID DeviceExtension)
Definition: srb.h:448
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
unsigned int ULONG
Definition: retypes.h:1
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
#define SCSISTAT_GOOD
Definition: cdrw_hw.h:1078
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49

◆ ScsiPortSetBusDataByOffset()

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 at line 503 of file scsiport.c.

510 {
511  DPRINT("ScsiPortSetBusDataByOffset()\n");
512  return HalSetBusDataByOffset(BusDataType,
513  SystemIoBusNumber,
514  SlotNumber,
515  Buffer,
516  Offset,
517  Length);
518 }
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG _In_ ULONG SlotNumber
Definition: halfuncs.h:156
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

◆ ScsiPortStartIo()

static VOID NTAPI ScsiPortStartIo ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)
static

Definition at line 2909 of file scsiport.c.

2911 {
2912  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
2913  PSCSI_PORT_LUN_EXTENSION LunExtension;
2914  PIO_STACK_LOCATION IrpStack;
2916  PSCSI_REQUEST_BLOCK_INFO SrbInfo;
2917  LONG CounterResult;
2918  NTSTATUS Status;
2919 
2920  DPRINT("ScsiPortStartIo() called!\n");
2921 
2922  DeviceExtension = DeviceObject->DeviceExtension;
2923  IrpStack = IoGetCurrentIrpStackLocation(Irp);
2924 
2925  DPRINT("DeviceExtension %p\n", DeviceExtension);
2926 
2927  Srb = IrpStack->Parameters.Scsi.Srb;
2928 
2929  /* Apply "default" flags */
2930  Srb->SrbFlags |= DeviceExtension->SrbFlags;
2931 
2932  /* Get LUN extension */
2933  LunExtension = SpiGetLunExtension(DeviceExtension,
2934  Srb->PathId,
2935  Srb->TargetId,
2936  Srb->Lun);
2937 
2938  if (DeviceExtension->NeedSrbDataAlloc ||
2939  DeviceExtension->NeedSrbExtensionAlloc)
2940  {
2941  /* Allocate them */
2942  SrbInfo = SpiAllocateSrbStructures(DeviceExtension,
2943  LunExtension,
2944  Srb);
2945 
2946  /* Couldn't alloc one or both data structures, return */
2947  if (SrbInfo == NULL)
2948  {
2949  /* We have to call IoStartNextPacket, because this request
2950  was not started */
2951  if (LunExtension->Flags & LUNEX_REQUEST_PENDING)
2953 
2954  return;
2955  }
2956  }
2957  else
2958  {
2959  /* No allocations are needed */
2960  SrbInfo = &LunExtension->SrbInfo;
2961  Srb->SrbExtension = NULL;
2962  Srb->QueueTag = SP_UNTAGGED;
2963  }
2964 
2965  /* Increase sequence number of SRB */
2966  if (!SrbInfo->SequenceNumber)
2967  {
2968  /* Increase global sequence number */
2969  DeviceExtension->SequenceNumber++;
2970 
2971  /* Assign it */
2972  SrbInfo->SequenceNumber = DeviceExtension->SequenceNumber;
2973  }
2974 
2975  /* Check some special SRBs */
2976  if (Srb->Function == SRB_FUNCTION_ABORT_COMMAND)
2977  {
2978  /* Some special handling */
2979  DPRINT1("Abort command! Unimplemented now\n");
2980  }
2981  else
2982  {
2983  SrbInfo->Srb = Srb;
2984  }
2985 
2986  if (Srb->SrbFlags & SRB_FLAGS_UNSPECIFIED_DIRECTION)
2987  {
2988  // Store the MDL virtual address in SrbInfo structure
2989  SrbInfo->DataOffset = MmGetMdlVirtualAddress(Irp->MdlAddress);
2990 
2991  if (DeviceExtension->MapBuffers)
2992  {
2993  /* Calculate offset within DataBuffer */
2994  SrbInfo->DataOffset = MmGetSystemAddressForMdl(Irp->MdlAddress);
2995  Srb->DataBuffer = SrbInfo->DataOffset +
2996  (ULONG)((PUCHAR)Srb->DataBuffer -
2997  (PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress));
2998  }
2999 
3000  if (DeviceExtension->AdapterObject)
3001  {
3002  /* Flush buffers */
3003  KeFlushIoBuffers(Irp->MdlAddress,
3004  Srb->SrbFlags & SRB_FLAGS_DATA_IN ? TRUE : FALSE,
3005  TRUE);
3006  }
3007 
3008  if (DeviceExtension->MapRegisters)
3009  {
3010  /* Calculate number of needed map registers */
3012  Srb->DataBuffer,
3013  Srb->DataTransferLength);
3014 
3015  /* Allocate adapter channel */
3016  Status = IoAllocateAdapterChannel(DeviceExtension->AdapterObject,
3017  DeviceExtension->DeviceObject,
3018  SrbInfo->NumberOfMapRegisters,
3020  SrbInfo);
3021 
3022  if (!NT_SUCCESS(Status))
3023  {
3024  DPRINT1("IoAllocateAdapterChannel() failed!\n");
3025 
3026  Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
3028  DeviceExtension + 1,
3029  Srb);
3030 
3032  DeviceExtension + 1);
3033 
3034  /* Request DPC for that work */
3035  IoRequestDpc(DeviceExtension->DeviceObject, NULL, NULL);
3036  }
3037 
3038  /* Control goes to SpiAdapterControl */
3039  return;
3040  }
3041  }
3042 
3043  /* Increase active request counter */
3044  CounterResult = InterlockedIncrement(&DeviceExtension->ActiveRequestCounter);
3045 
3046  if (CounterResult == 0 &&
3047  DeviceExtension->AdapterObject != NULL &&
3048  !DeviceExtension->MapRegisters)
3049  {
3051  DeviceExtension->AdapterObject,
3052  DeviceObject,
3053  DeviceExtension->PortCapabilities.MaximumPhysicalPages,
3055  LunExtension
3056  );
3057 
3058  return;
3059  }
3060 
3061  KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
3062 
3063  if (!KeSynchronizeExecution(DeviceExtension->Interrupt[0],
3065  DeviceObject))
3066  {
3067  DPRINT("Synchronization failed!\n");
3068 
3069  Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
3070  Irp->IoStatus.Information = 0;
3071  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
3072 
3074  }
3075  else
3076  {
3077  /* Release the spinlock only */
3078  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
3079  }
3080 
3081 
3082  DPRINT("ScsiPortStartIo() done\n");
3083 }
static PSCSI_REQUEST_BLOCK_INFO SpiAllocateSrbStructures(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, PSCSI_PORT_LUN_EXTENSION LunExtension, PSCSI_REQUEST_BLOCK Srb)
Definition: scsiport.c:3399
#define SRB_STATUS_INVALID_REQUEST
Definition: srb.h:338
#define SRB_FLAGS_UNSPECIFIED_DIRECTION
Definition: srb.h:395
#define TRUE
Definition: types.h:120
#define MmGetMdlVirtualAddress(_Mdl)
#define LUNEX_REQUEST_PENDING
Definition: scsiport_int.h:48
_In_ PIRP Irp
Definition: csq.h:116
IO_SCSI_CAPABILITIES PortCapabilities
Definition: scsiport.c:80
unsigned char * PUCHAR
Definition: retypes.h:3
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
LONG NTSTATUS
Definition: precomp.h:26
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
#define SP_UNTAGGED
Definition: srb.h:225
long LONG
Definition: pedump.c:60
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
void DPRINT(...)
Definition: polytest.cpp:61
static PSCSI_PORT_LUN_EXTENSION SpiGetLunExtension(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun)
Definition: scsiport.c:3365
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
NTSTATUS NTAPI IoAllocateAdapterChannel(IN PADAPTER_OBJECT AdapterObject, IN PDEVICE_OBJECT DeviceObject, IN ULONG NumberOfMapRegisters, IN PDRIVER_CONTROL ExecutionRoutine, IN PVOID Context)
Definition: adapter.c:30
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
SCSI_REQUEST_BLOCK_INFO SrbInfo
Definition: scsiport_int.h:146
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
FORCEINLINE VOID IoRequestDpc(_Inout_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Irp, _In_opt_ __drv_aliasesMem PVOID Context)
Definition: iofuncs.h:2702
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
VOID __cdecl ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension, IN ...)
Definition: scsiport.c:1280
IO_ALLOCATION_ACTION NTAPI ScsiPortAllocateAdapterChannel(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID MapRegisterBase, IN PVOID Context)
Definition: scsiport.c:6384
IO_ALLOCATION_ACTION NTAPI SpiAdapterControl(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID MapRegisterBase, PVOID Context)
Definition: scsiport.c:3242
PSCSI_REQUEST_BLOCK Srb
Definition: scsiport_int.h:100
Status
Definition: gdiplustypes.h:24
#define SRB_FUNCTION_ABORT_COMMAND
Definition: srb.h:316
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define KeFlushIoBuffers(_Mdl, _ReadOperation, _DmaOperation)
Definition: ke.h:161
#define InterlockedIncrement
Definition: armddk.h:53
PADAPTER_OBJECT AdapterObject
Definition: scsiport.c:88
static BOOLEAN NTAPI ScsiPortStartPacket(IN OUT PVOID Context)
Definition: scsiport.c:3087
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define MmGetSystemAddressForMdl(Mdl)
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:142
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1846

◆ ScsiPortStartPacket()

static BOOLEAN NTAPI ScsiPortStartPacket ( IN OUT PVOID  Context)
static

Definition at line 3087 of file scsiport.c.

3088 {
3089  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
3090  PIO_STACK_LOCATION IrpStack;
3093  PSCSI_PORT_LUN_EXTENSION LunExtension;
3094  PSCSI_REQUEST_BLOCK_INFO SrbInfo;
3095  BOOLEAN Result;
3096  BOOLEAN StartTimer;
3097 
3098  DPRINT("ScsiPortStartPacket() called\n");
3099 
3101 
3102  IrpStack = IoGetCurrentIrpStackLocation(DeviceObject->CurrentIrp);
3103  Srb = IrpStack->Parameters.Scsi.Srb;
3104 
3105  /* Get LUN extension */
3106  LunExtension = SpiGetLunExtension(DeviceExtension,
3107  Srb->PathId,
3108  Srb->TargetId,
3109  Srb->Lun);
3110 
3111  /* Check if we are in a reset state */
3112  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_RESET)
3113  {
3114  /* Mark the we've got requests while being in the reset state */
3115  DeviceExtension->InterruptData.Flags |= SCSI_PORT_RESET_REQUEST;
3116  return TRUE;
3117  }
3118 
3119  /* Set the time out value */
3120  DeviceExtension->TimerCount = Srb->TimeOutValue;
3121 
3122  /* We are busy */
3123  DeviceExtension->Flags |= SCSI_PORT_DEVICE_BUSY;
3124 
3125  if (LunExtension->RequestTimeout != -1)
3126  {
3127  /* Timer already active */
3128  StartTimer = FALSE;
3129  }
3130  else
3131  {
3132  /* It hasn't been initialized yet */
3133  LunExtension->RequestTimeout = Srb->TimeOutValue;
3134  StartTimer = TRUE;
3135  }
3136 
3137  if (Srb->SrbFlags & SRB_FLAGS_BYPASS_FROZEN_QUEUE)
3138  {
3139  /* Handle bypass-requests */
3140 
3141  /* Is this an abort request? */
3142  if (Srb->Function == SRB_FUNCTION_ABORT_COMMAND)
3143  {
3144  /* Get pointer to SRB info structure */
3145  SrbInfo = SpiGetSrbData(DeviceExtension,
3146  Srb->PathId,
3147  Srb->TargetId,
3148  Srb->Lun,
3149  Srb->QueueTag);
3150 
3151  /* Check if the request is still "active" */
3152  if (SrbInfo == NULL ||
3153  SrbInfo->Srb == NULL ||
3154  !(SrbInfo->Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE))
3155  {
3156  /* It's not, mark it as active then */
3157  Srb->SrbFlags |= SRB_FLAGS_IS_ACTIVE;
3158 
3159  if (StartTimer)
3160  LunExtension->RequestTimeout = -1;
3161 
3162  DPRINT("Request has been already completed, but abort request came\n");
3163  Srb->SrbStatus = SRB_STATUS_ABORT_FAILED;
3164 
3165  /* Notify about request complete */
3167  DeviceExtension->MiniPortDeviceExtension,
3168  Srb);
3169 
3170  /* and about readiness for the next request */
3172  DeviceExtension->MiniPortDeviceExtension);
3173 
3174  /* They might ask for some work, so queue the DPC for them */
3175  IoRequestDpc(DeviceExtension->DeviceObject, NULL, NULL);
3176 
3177  /* We're done in this branch */
3178  return TRUE;
3179  }
3180  }
3181  else
3182  {
3183  /* Add number of queued requests */
3184  LunExtension->QueueCount++;
3185  }
3186 
3187  /* Bypass requests don't need request sense */
3188  LunExtension->Flags &= ~LUNEX_NEED_REQUEST_SENSE;
3189 
3190  /* Is disconnect disabled for this request? */
3191  if (Srb->SrbFlags & SRB_FLAGS_DISABLE_DISCONNECT)
3192  {
3193  /* Set the corresponding flag */
3194  DeviceExtension->Flags &= ~SCSI_PORT_DISCONNECT_ALLOWED;
3195  }
3196 
3197  /* Transfer timeout value from Srb to Lun */
3198  LunExtension->RequestTimeout = Srb->TimeOutValue;
3199  }
3200  else
3201  {
3202  if (Srb->SrbFlags & SRB_FLAGS_DISABLE_DISCONNECT)
3203  {
3204  /* It's a disconnect, so no more requests can go */
3205  DeviceExtension->Flags &= ~SCSI_PORT_DISCONNECT_ALLOWED;
3206  }
3207 
3208  LunExtension->Flags |= SCSI_PORT_LU_ACTIVE;
3209 
3210  /* Increment queue count */
3211  LunExtension->QueueCount++;
3212 
3213  /* If it's tagged - special thing */
3214  if (Srb->QueueTag != SP_UNTAGGED)
3215  {
3216  SrbInfo = &DeviceExtension->SrbInfo[Srb->QueueTag - 1];
3217 
3218  /* Chek for consistency */
3219  ASSERT(SrbInfo->Requests.Blink == NULL);
3220 
3221  /* Insert it into the list of requests */
3222  InsertTailList(&LunExtension->SrbInfo.Requests, &SrbInfo->Requests);
3223  }
3224  }
3225 
3226  /* Mark this Srb active */
3227  Srb->SrbFlags |= SRB_FLAGS_IS_ACTIVE;
3228 
3229  /* Call HwStartIo routine */
3230  Result = DeviceExtension->HwStartIo(&DeviceExtension->MiniPortDeviceExtension,
3231  Srb);
3232 
3233  /* If notification is needed, then request a DPC */
3234  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
3235  IoRequestDpc(DeviceExtension->DeviceObject, NULL, NULL);
3236 
3237  return Result;
3238 }
#define TRUE
Definition: types.h:120
ULONG SrbFlags
Definition: srb.h:252
#define SCSI_PORT_RESET
Definition: scsiport_int.h:33
#define SRB_FLAGS_IS_ACTIVE
Definition: srb.h:399
struct _DEVICE_OBJECT * PDEVICE_OBJECT
#define SRB_STATUS_ABORT_FAILED
Definition: srb.h:335
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
struct SCSI_PORT_DEVICE_EXTENSION * PSCSI_PORT_DEVICE_EXTENSION
static PSCSI_REQUEST_BLOCK_INFO SpiGetSrbData(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN UCHAR QueueTag)
Definition: scsiport.c:4096
#define InsertTailList(ListHead, Entry)
#define SCSI_PORT_NOTIFICATION_NEEDED
Definition: scsiport_int.h:29
#define SP_UNTAGGED
Definition: srb.h:225
#define SRB_FLAGS_BYPASS_FROZEN_QUEUE
Definition: srb.h:390
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_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
void DPRINT(...)
Definition: polytest.cpp:61
static PSCSI_PORT_LUN_EXTENSION SpiGetLunExtension(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun)
Definition: scsiport.c:3365
#define SCSI_PORT_DISCONNECT_ALLOWED
Definition: scsiport_int.h:37
SCSI_REQUEST_BLOCK_INFO SrbInfo
Definition: scsiport_int.h:146
FORCEINLINE VOID IoRequestDpc(_Inout_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Irp, _In_opt_ __drv_aliasesMem PVOID Context)
Definition: iofuncs.h:2702
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SRB_FLAGS_DISABLE_DISCONNECT
Definition: srb.h:388
VOID __cdecl ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension, IN ...)
Definition: scsiport.c:1280
PSCSI_REQUEST_BLOCK Srb
Definition: scsiport_int.h:100
#define SCSI_PORT_DEVICE_BUSY
Definition: scsiport_int.h:27
#define SRB_FUNCTION_ABORT_COMMAND
Definition: srb.h:316
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define LUNEX_NEED_REQUEST_SENSE
Definition: scsiport_int.h:45
#define SCSI_PORT_RESET_REQUEST
Definition: scsiport_int.h:34
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
#define SCSI_PORT_LU_ACTIVE
Definition: scsiport_int.h:28

Referenced by ScsiPortAllocateAdapterChannel(), ScsiPortStartIo(), SpiAdapterControl(), and SpiProcessTimeout().

◆ ScsiPortValidateRange()

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 at line 2027 of file scsiport.c.

2033 {
2034  DPRINT("ScsiPortValidateRange()\n");
2035  return(TRUE);
2036 }
#define TRUE
Definition: types.h:120
void DPRINT(...)
Definition: polytest.cpp:61

◆ SpiAdapterControl()

IO_ALLOCATION_ACTION NTAPI SpiAdapterControl ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PVOID  MapRegisterBase,
PVOID  Context 
)

Definition at line 3242 of file scsiport.c.

3246 {
3248  PSCSI_SG_ADDRESS ScatterGatherList;
3249  KIRQL CurrentIrql;
3250  PIO_STACK_LOCATION IrpStack;
3251  ULONG TotalLength = 0;
3252  PSCSI_REQUEST_BLOCK_INFO SrbInfo;
3253  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
3254  PUCHAR DataVA;
3255  BOOLEAN WriteToDevice;
3256 
3257  /* Get pointers to SrbInfo and DeviceExtension */
3258  SrbInfo = (PSCSI_REQUEST_BLOCK_INFO)Context;
3259  DeviceExtension = DeviceObject->DeviceExtension;
3260 
3261  /* Get pointer to SRB */
3262  IrpStack = IoGetCurrentIrpStackLocation(Irp);
3263  Srb = (PSCSI_REQUEST_BLOCK)IrpStack->Parameters.Others.Argument1;
3264 
3265  /* Depending on the map registers number, we allocate
3266  either from NonPagedPool, or from our static list */
3267  if (SrbInfo->NumberOfMapRegisters > MAX_SG_LIST)
3268  {
3271 
3272  if (SrbInfo->ScatterGather == NULL)
3273  ASSERT(FALSE);
3274 
3275  Srb->SrbFlags |= SRB_FLAGS_SGLIST_FROM_POOL;
3276  }
3277  else
3278  {
3279  SrbInfo->ScatterGather = SrbInfo->ScatterGatherList;
3280  }
3281 
3282  /* Use chosen SG list source */
3283  ScatterGatherList = SrbInfo->ScatterGather;
3284 
3285  /* Save map registers base */
3287 
3288  /* Determine WriteToDevice flag */
3289  WriteToDevice = Srb->SrbFlags & SRB_FLAGS_DATA_OUT ? TRUE : FALSE;
3290 
3291  /* Get virtual address of the data buffer */
3292  DataVA = (PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress) +
3293  ((PCHAR)Srb->DataBuffer - SrbInfo->DataOffset);
3294 
3295  /* Build the actual SG list */
3296  while (TotalLength < Srb->DataTransferLength)
3297  {
3298  if (!ScatterGatherList)
3299  break;
3300 
3301  ScatterGatherList->Length = Srb->DataTransferLength - TotalLength;
3302  ScatterGatherList->PhysicalAddress = IoMapTransfer(DeviceExtension->AdapterObject,
3303  Irp->MdlAddress,
3305  DataVA + TotalLength,
3306  &ScatterGatherList->Length,
3307  WriteToDevice);
3308 
3309  TotalLength += ScatterGatherList->Length;
3310  ScatterGatherList++;
3311  }
3312 
3313  /* Schedule an active request */
3314  InterlockedIncrement(&DeviceExtension->ActiveRequestCounter );
3315  KeAcquireSpinLock(&DeviceExtension->SpinLock, &CurrentIrql);
3316  KeSynchronizeExecution(DeviceExtension->Interrupt[0],
3318  DeviceObject);
3319  KeReleaseSpinLock(&DeviceExtension->SpinLock, CurrentIrql);
3320 
3322 }
#define MAX_SG_LIST
Definition: scsiport_int.h:24
#define TRUE
Definition: types.h:120
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
#define MmGetMdlVirtualAddress(_Mdl)
_In_ PIRP Irp
Definition: csq.h:116
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
unsigned char * PUCHAR
Definition: retypes.h:3
_In_ ULONG TotalLength
Definition: usbdlib.h:145
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define SRB_FLAGS_SGLIST_FROM_POOL
Definition: srb.h:401
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PSCSI_SG_ADDRESS ScatterGather
Definition: scsiport_int.h:113
#define PCHAR
Definition: match.c:90
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
struct _SCSI_REQUEST_BLOCK_INFO * PSCSI_REQUEST_BLOCK_INFO
PHYSICAL_ADDRESS PhysicalAddress
Definition: scsiport_int.h:93
SCSI_SG_ADDRESS ScatterGatherList[MAX_SG_LIST]
Definition: scsiport_int.h:114
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
_Inout_ struct _IRP _In_ PVOID MapRegisterBase
Definition: iotypes.h:189
#define InterlockedIncrement
Definition: armddk.h:53
PADAPTER_OBJECT AdapterObject
Definition: scsiport.c:88
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:393
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
static BOOLEAN NTAPI ScsiPortStartPacket(IN OUT PVOID Context)
Definition: scsiport.c:3087
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:142
#define TAG_SCSIPORT
Definition: scsiport_int.h:19
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771

Referenced by ScsiPortStartIo().

◆ SpiAllocateCommonBuffer()

static NTSTATUS SpiAllocateCommonBuffer ( PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension,
ULONG  NonCachedSize 
)
static

Definition at line 795 of file scsiport.c.

796 {
797  PVOID *SrbExtension, CommonBuffer;
798  ULONG CommonBufferLength, BufSize;
799 
800  /* If size is 0, set it to 16 */
801  if (!DeviceExtension->SrbExtensionSize)
802  DeviceExtension->SrbExtensionSize = 16;
803 
804  /* Calculate size */
805  BufSize = DeviceExtension->SrbExtensionSize;
806 
807  /* Add autosense data size if needed */
808  if (DeviceExtension->SupportsAutoSense)
809  BufSize += sizeof(SENSE_DATA);
810 
811 
812  /* Round it */
813  BufSize = (BufSize + sizeof(LONGLONG) - 1) & ~(sizeof(LONGLONG) - 1);
814 
815  /* Sum up into the total common buffer length, and round it to page size */
816  CommonBufferLength =
817  ROUND_TO_PAGES(NonCachedSize + BufSize * DeviceExtension->RequestsNumber);
818 
819  /* Allocate it */
820  if (!DeviceExtension->AdapterObject)
821  {
822  /* From nonpaged pool if there is no DMA */
823  CommonBuffer = ExAllocatePoolWithTag(NonPagedPool, CommonBufferLength, TAG_SCSIPORT);
824  }
825  else
826  {
827  /* Perform a full request since we have a DMA adapter*/
828  CommonBuffer = HalAllocateCommonBuffer(DeviceExtension->AdapterObject,
829  CommonBufferLength,
830  &DeviceExtension->PhysicalAddress,
831  FALSE );
832  }
833 
834  /* Fail in case of error */
835  if (!CommonBuffer)
837 
838  /* Zero it */
839  RtlZeroMemory(CommonBuffer, CommonBufferLength);
840 
841  /* Store its size in Device Extension */
842  DeviceExtension->CommonBufferLength = CommonBufferLength;
843 
844  /* SrbExtension buffer is located at the beginning of the buffer */
845  DeviceExtension->SrbExtensionBuffer = CommonBuffer;
846 
847  /* Non-cached extension buffer is located at the end of
848  the common buffer */
849  if (NonCachedSize)
850  {
851  CommonBufferLength -= NonCachedSize;
852  DeviceExtension->NonCachedExtension = (PUCHAR)CommonBuffer + CommonBufferLength;
853  }
854  else
855  {
856  DeviceExtension->NonCachedExtension = NULL;
857  }
858 
859  if (DeviceExtension->NeedSrbExtensionAlloc)
860  {
861  /* Look up how many SRB data structures we need */
862  DeviceExtension->SrbDataCount = CommonBufferLength / BufSize;
863 
864  /* Initialize the free SRB extensions list */
865  SrbExtension = (PVOID *)CommonBuffer;
866  DeviceExtension->FreeSrbExtensions = SrbExtension;
867 
868  /* Fill the remaining pointers (if we have more than 1 SRB) */
869  while (CommonBufferLength >= 2 * BufSize)
870  {
871  *SrbExtension = (PVOID*)((PCHAR)SrbExtension + BufSize);
872  SrbExtension = *SrbExtension;
873 
874  CommonBufferLength -= BufSize;
875  }
876  }
877 
878  return STATUS_SUCCESS;
879 }
signed char * PCHAR
Definition: retypes.h:7
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
unsigned char * PUCHAR
Definition: retypes.h:3
struct _SENSE_DATA SENSE_DATA
smooth NULL
Definition: ftsmooth.c:416
#define BufSize
Definition: FsRtlTunnel.c:28
int64_t LONGLONG
Definition: typedefs.h:66
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
PADAPTER_OBJECT AdapterObject
Definition: scsiport.c:88
#define ROUND_TO_PAGES(Size)
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define TAG_SCSIPORT
Definition: scsiport_int.h:19
PVOID NTAPI HalAllocateCommonBuffer(IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PPHYSICAL_ADDRESS LogicalAddress, IN BOOLEAN CacheEnabled)
Definition: dma.c:46
return STATUS_SUCCESS
Definition: btrfs.c:2745

Referenced by ScsiPortGetUncachedExtension(), and ScsiPortInitialize().

◆ SpiAllocateLunExtension()

static PSCSI_PORT_LUN_EXTENSION SpiAllocateLunExtension ( IN PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension)
static

Definition at line 3325 of file scsiport.c.

3326 {
3327  PSCSI_PORT_LUN_EXTENSION LunExtension;
3328  ULONG LunExtensionSize;
3329 
3330  DPRINT("SpiAllocateLunExtension(%p)\n", DeviceExtension);
3331 
3332  /* Round LunExtensionSize first to the sizeof LONGLONG */
3333  LunExtensionSize = (DeviceExtension->LunExtensionSize +
3334  sizeof(LONGLONG) - 1) & ~(sizeof(LONGLONG) - 1);
3335 
3336  LunExtensionSize += sizeof(SCSI_PORT_LUN_EXTENSION);
3337  DPRINT("LunExtensionSize %lu\n", LunExtensionSize);
3338 
3339  LunExtension = ExAllocatePoolWithTag(NonPagedPool, LunExtensionSize, TAG_SCSIPORT);
3340  if (LunExtension == NULL)
3341  {
3342  DPRINT1("Out of resources!\n");
3343  return NULL;
3344  }
3345 
3346  /* Zero everything */
3347  RtlZeroMemory(LunExtension, LunExtensionSize);
3348 
3349  /* Initialize a list of requests */
3350  InitializeListHead(&LunExtension->SrbInfo.Requests);
3351 
3352  /* Initialize timeout counter */
3353  LunExtension->RequestTimeout = -1;
3354 
3355  /* Set maximum queue size */
3356  LunExtension->MaxQueueCount = 256;
3357 
3358  /* Initialize request queue */
3359  KeInitializeDeviceQueue(&LunExtension->DeviceQueue);
3360 
3361  return LunExtension;
3362 }
KDEVICE_QUEUE DeviceQueue
Definition: scsiport_int.h:132
VOID NTAPI KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
Definition: devqueue.c:22
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
struct _SCSI_PORT_LUN_EXTENSION SCSI_PORT_LUN_EXTENSION
int64_t LONGLONG
Definition: typedefs.h:66
SCSI_REQUEST_BLOCK_INFO SrbInfo
Definition: scsiport_int.h:146
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define TAG_SCSIPORT
Definition: scsiport_int.h:19

Referenced by SpiScanAdapter().

◆ SpiAllocateSrbStructures()

static PSCSI_REQUEST_BLOCK_INFO SpiAllocateSrbStructures ( PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension,
PSCSI_PORT_LUN_EXTENSION  LunExtension,
PSCSI_REQUEST_BLOCK  Srb 
)
static

Definition at line 3399 of file scsiport.c.

3402 {
3403  PCHAR SrbExtension;
3404  PSCSI_REQUEST_BLOCK_INFO SrbInfo;
3405 
3406  /* Spinlock must be held while this function executes */
3407  KeAcquireSpinLockAtDpcLevel(&DeviceExtension->SpinLock);
3408 
3409  /* Allocate SRB data structure */
3410  if (DeviceExtension->NeedSrbDataAlloc)
3411  {
3412  /* Treat the abort request in a special way */
3413  if (Srb->Function == SRB_FUNCTION_ABORT_COMMAND)
3414  {
3415  SrbInfo = SpiGetSrbData(DeviceExtension,
3416  Srb->PathId,
3417  Srb->TargetId,
3418  Srb->Lun,
3419  Srb->QueueTag);
3420  }
3421  else if (Srb->SrbFlags &
3423  !(Srb->SrbFlags & SRB_FLAGS_DISABLE_DISCONNECT)
3424  )
3425  {
3426  /* Do not process tagged commands if need request sense is set */
3427  if (LunExtension->Flags & LUNEX_NEED_REQUEST_SENSE)
3428  {
3429  ASSERT(!(LunExtension->Flags & LUNEX_REQUEST_PENDING));
3430 
3431  LunExtension->PendingRequest = Srb->OriginalRequest;
3432  LunExtension->Flags |= LUNEX_REQUEST_PENDING | SCSI_PORT_LU_ACTIVE;
3433 
3434  /* Release the spinlock and return */
3435  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
3436  return NULL;
3437  }
3438 
3439  ASSERT(LunExtension->SrbInfo.Srb == NULL);
3440  SrbInfo = DeviceExtension->FreeSrbInfo;
3441 
3442  if (SrbInfo == NULL)
3443  {
3444  /* No SRB structures left in the list. We have to leave
3445  and wait while we are called again */
3446 
3447  DeviceExtension->Flags |= SCSI_PORT_REQUEST_PENDING;
3448  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
3449  return NULL;
3450  }
3451 
3452  DeviceExtension->FreeSrbInfo = (PSCSI_REQUEST_BLOCK_INFO)SrbInfo->Requests.Flink;
3453 
3454  /* QueueTag must never be 0, so +1 to it */
3455  Srb->QueueTag = (UCHAR)(SrbInfo - DeviceExtension->SrbInfo) + 1;
3456  }
3457  else
3458  {
3459  /* Usual untagged command */
3460  if (
3461  (!IsListEmpty(&LunExtension->SrbInfo.Requests) ||
3462  LunExtension->Flags & LUNEX_NEED_REQUEST_SENSE) &&
3463  !(Srb->SrbFlags & SRB_FLAGS_BYPASS_FROZEN_QUEUE)
3464  )
3465  {
3466  /* Mark it as pending and leave */
3467  ASSERT(!(LunExtension->Flags & LUNEX_REQUEST_PENDING));
3468  LunExtension->Flags |= LUNEX_REQUEST_PENDING | SCSI_PORT_LU_ACTIVE;
3469  LunExtension->PendingRequest = Srb->OriginalRequest;
3470 
3471  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
3472  return(NULL);
3473  }
3474 
3475  Srb->QueueTag = SP_UNTAGGED;
3476  SrbInfo = &LunExtension->SrbInfo;
3477  }
3478  }
3479  else
3480  {
3481  Srb->QueueTag = SP_UNTAGGED;
3482  SrbInfo = &LunExtension->SrbInfo;
3483  }
3484 
3485  /* Allocate SRB extension structure */
3486  if (DeviceExtension->NeedSrbExtensionAlloc)
3487  {
3488  /* Check the list of free extensions */
3489  SrbExtension = DeviceExtension->FreeSrbExtensions;
3490 
3491  /* If no free extensions... */
3492  if (SrbExtension == NULL)
3493  {
3494  /* Free SRB data */
3495  if (Srb->Function != SRB_FUNCTION_ABORT_COMMAND &&
3496  Srb->QueueTag != SP_UNTAGGED)
3497  {
3498  SrbInfo->Requests.Blink = NULL;
3499  SrbInfo->Requests.Flink = (PLIST_ENTRY)DeviceExtension->FreeSrbInfo;
3500  DeviceExtension->FreeSrbInfo = SrbInfo;
3501  }
3502 
3503  /* Return, in order to be called again later */
3504  DeviceExtension->Flags |= SCSI_PORT_REQUEST_PENDING;
3505  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
3506  return NULL;
3507  }
3508 
3509  /* Remove that free SRB extension from the list (since
3510  we're going to use it) */
3511  DeviceExtension->FreeSrbExtensions = *((PVOID *)SrbExtension);
3512 
3513  /* Spinlock can be released now */
3514  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
3515 
3516  Srb->SrbExtension = SrbExtension;
3517 
3518  if (Srb->SenseInfoBuffer != NULL &&
3519  DeviceExtension->SupportsAutoSense)
3520  {
3521  /* Store pointer to the SenseInfo buffer */