ReactOS  0.4.15-dev-1206-g731eddf
scsiport.h File Reference
#include <wdm.h>
#include <ntddk.h>
#include <stdio.h>
#include <scsi.h>
#include <ntddscsi.h>
#include <ntdddisk.h>
#include <mountdev.h>
Include dependency graph for scsiport.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _CONFIGURATION_INFO
 
struct  _SCSI_PORT_DEVICE_BASE
 
struct  _SCSI_SG_ADDRESS
 
struct  _SCSI_REQUEST_BLOCK_INFO
 
struct  _SCSI_PORT_LUN_EXTENSION
 
struct  _SCSI_LUN_INFO
 
struct  _SCSI_BUS_SCAN_INFO
 
struct  _BUSES_CONFIGURATION_INFORMATION
 
struct  _SCSI_PORT_INTERRUPT_DATA
 
struct  _SCSI_PORT_SAVE_INTERRUPT
 
struct  _SCSI_PORT_DEVICE_EXTENSION
 
struct  _RESETBUS_PARAMS
 

Macros

#define VERSION   "0.0.3"
 
#define TAG_SCSIPORT   'ISCS'
 
#define LUS_NUMBER   8
 
#define MAX_SG_LIST   17
 
#define SCSI_PORT_DEVICE_BUSY   0x0001
 
#define SCSI_PORT_LU_ACTIVE   0x0002
 
#define SCSI_PORT_NOTIFICATION_NEEDED   0x0004
 
#define SCSI_PORT_NEXT_REQUEST_READY   0x0008
 
#define SCSI_PORT_FLUSH_ADAPTERS   0x0010
 
#define SCSI_PORT_MAP_TRANSFER   0x0020
 
#define SCSI_PORT_RESET   0x0080
 
#define SCSI_PORT_RESET_REQUEST   0x0100
 
#define SCSI_PORT_RESET_REPORTED   0x0200
 
#define SCSI_PORT_REQUEST_PENDING   0x0800
 
#define SCSI_PORT_DISCONNECT_ALLOWED   0x1000
 
#define SCSI_PORT_DISABLE_INT_REQUESET   0x2000
 
#define SCSI_PORT_DISABLE_INTERRUPTS   0x4000
 
#define SCSI_PORT_ENABLE_INT_REQUEST   0x8000
 
#define SCSI_PORT_TIMER_NEEDED   0x10000
 
#define LUNEX_FROZEN_QUEUE   0x0001
 
#define LUNEX_NEED_REQUEST_SENSE   0x0004
 
#define LUNEX_BUSY   0x0008
 
#define LUNEX_FULL_QUEUE   0x0010
 
#define LUNEX_REQUEST_PENDING   0x0020
 
#define SCSI_PORT_SCAN_IN_PROGRESS   0x8000
 

Typedefs

typedef enum _SCSI_PORT_TIMER_STATES SCSI_PORT_TIMER_STATES
 
typedef struct _CONFIGURATION_INFO CONFIGURATION_INFO
 
typedef struct _CONFIGURATION_INFOPCONFIGURATION_INFO
 
typedef struct _SCSI_PORT_DEVICE_BASE SCSI_PORT_DEVICE_BASE
 
typedef struct _SCSI_PORT_DEVICE_BASEPSCSI_PORT_DEVICE_BASE
 
typedef struct _SCSI_SG_ADDRESS SCSI_SG_ADDRESS
 
typedef struct _SCSI_SG_ADDRESSPSCSI_SG_ADDRESS
 
typedef struct _SCSI_REQUEST_BLOCK_INFO SCSI_REQUEST_BLOCK_INFO
 
typedef struct _SCSI_REQUEST_BLOCK_INFOPSCSI_REQUEST_BLOCK_INFO
 
typedef struct _SCSI_PORT_LUN_EXTENSION SCSI_PORT_LUN_EXTENSION
 
typedef struct _SCSI_PORT_LUN_EXTENSIONPSCSI_PORT_LUN_EXTENSION
 
typedef struct _SCSI_LUN_INFO SCSI_LUN_INFO
 
typedef struct _SCSI_LUN_INFOPSCSI_LUN_INFO
 
typedef struct _SCSI_BUS_SCAN_INFO SCSI_BUS_SCAN_INFO
 
typedef struct _SCSI_BUS_SCAN_INFOPSCSI_BUS_SCAN_INFO
 
typedef struct _BUSES_CONFIGURATION_INFORMATION BUSES_CONFIGURATION_INFORMATION
 
typedef struct _BUSES_CONFIGURATION_INFORMATIONPBUSES_CONFIGURATION_INFORMATION
 
typedef struct _SCSI_PORT_INTERRUPT_DATA SCSI_PORT_INTERRUPT_DATA
 
typedef struct _SCSI_PORT_INTERRUPT_DATAPSCSI_PORT_INTERRUPT_DATA
 
typedef struct _SCSI_PORT_SAVE_INTERRUPT SCSI_PORT_SAVE_INTERRUPT
 
typedef struct _SCSI_PORT_SAVE_INTERRUPTPSCSI_PORT_SAVE_INTERRUPT
 
typedef struct _SCSI_PORT_DEVICE_EXTENSION SCSI_PORT_DEVICE_EXTENSION
 
typedef struct _SCSI_PORT_DEVICE_EXTENSIONPSCSI_PORT_DEVICE_EXTENSION
 
typedef struct _RESETBUS_PARAMS RESETBUS_PARAMS
 
typedef struct _RESETBUS_PARAMSPRESETBUS_PARAMS
 

Enumerations

enum  _SCSI_PORT_TIMER_STATES { IDETimerIdle, IDETimerCmdWait, IDETimerResetWaitForBusyNegate, IDETimerResetWaitForDrdyAssert }
 

Functions

NTSTATUS NTAPI ScsiPortDeviceControl (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
VOID SpiScanAdapter (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 
NTSTATUS CallHWInitialize (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 Calls HwInitialize routine of the miniport and sets up interrupts Should be called inside ScsiPortInitialize (for legacy drivers) or inside IRP_MN_START_DEVICE for pnp drivers. More...
 
VOID SpiCleanupAfterInit (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 
PSCSI_PORT_LUN_EXTENSION SpiAllocateLunExtension (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 
PSCSI_PORT_LUN_EXTENSION SpiGetLunExtension (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _In_ UCHAR PathId, _In_ UCHAR TargetId, _In_ UCHAR Lun)
 
PSCSI_REQUEST_BLOCK_INFO SpiGetSrbData (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _In_ UCHAR PathId, _In_ UCHAR TargetId, _In_ UCHAR Lun, _In_ UCHAR QueueTag)
 
VOID SpiInitOpenKeys (_Inout_ PCONFIGURATION_INFO ConfigInfo, _In_ PUNICODE_STRING RegistryPath)
 
NTSTATUS SpiBuildDeviceMap (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _In_ PUNICODE_STRING RegistryPath)
 
VOID SpiGetNextRequestFromLun (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _Inout_ PSCSI_PORT_LUN_EXTENSION LunExtension)
 
IO_ALLOCATION_ACTION NTAPI SpiAdapterControl (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PVOID MapRegisterBase, _In_ PVOID Context)
 
IO_ALLOCATION_ACTION NTAPI ScsiPortAllocateAdapterChannel (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PVOID MapRegisterBase, _In_ PVOID Context)
 

Variables

IO_DPC_ROUTINE ScsiPortDpcForIsr
 
DRIVER_DISPATCH ScsiPortDispatchScsi
 
KSYNCHRONIZE_ROUTINE ScsiPortStartPacket
 
DRIVER_STARTIO ScsiPortStartIo
 
KSERVICE_ROUTINE ScsiPortIsr
 

Macro Definition Documentation

◆ LUNEX_BUSY

#define LUNEX_BUSY   0x0008

Definition at line 47 of file scsiport.h.

◆ LUNEX_FROZEN_QUEUE

#define LUNEX_FROZEN_QUEUE   0x0001

Definition at line 45 of file scsiport.h.

◆ LUNEX_FULL_QUEUE

#define LUNEX_FULL_QUEUE   0x0010

Definition at line 48 of file scsiport.h.

◆ LUNEX_NEED_REQUEST_SENSE

#define LUNEX_NEED_REQUEST_SENSE   0x0004

Definition at line 46 of file scsiport.h.

◆ LUNEX_REQUEST_PENDING

#define LUNEX_REQUEST_PENDING   0x0020

Definition at line 49 of file scsiport.h.

◆ LUS_NUMBER

#define LUS_NUMBER   8

Definition at line 23 of file scsiport.h.

◆ MAX_SG_LIST

#define MAX_SG_LIST   17

Definition at line 25 of file scsiport.h.

◆ SCSI_PORT_DEVICE_BUSY

#define SCSI_PORT_DEVICE_BUSY   0x0001

Definition at line 28 of file scsiport.h.

◆ SCSI_PORT_DISABLE_INT_REQUESET

#define SCSI_PORT_DISABLE_INT_REQUESET   0x2000

Definition at line 39 of file scsiport.h.

◆ SCSI_PORT_DISABLE_INTERRUPTS

#define SCSI_PORT_DISABLE_INTERRUPTS   0x4000

Definition at line 40 of file scsiport.h.

◆ SCSI_PORT_DISCONNECT_ALLOWED

#define SCSI_PORT_DISCONNECT_ALLOWED   0x1000

Definition at line 38 of file scsiport.h.

◆ SCSI_PORT_ENABLE_INT_REQUEST

#define SCSI_PORT_ENABLE_INT_REQUEST   0x8000

Definition at line 41 of file scsiport.h.

◆ SCSI_PORT_FLUSH_ADAPTERS

#define SCSI_PORT_FLUSH_ADAPTERS   0x0010

Definition at line 32 of file scsiport.h.

◆ SCSI_PORT_LU_ACTIVE

#define SCSI_PORT_LU_ACTIVE   0x0002

Definition at line 29 of file scsiport.h.

◆ SCSI_PORT_MAP_TRANSFER

#define SCSI_PORT_MAP_TRANSFER   0x0020

Definition at line 33 of file scsiport.h.

◆ SCSI_PORT_NEXT_REQUEST_READY

#define SCSI_PORT_NEXT_REQUEST_READY   0x0008

Definition at line 31 of file scsiport.h.

◆ SCSI_PORT_NOTIFICATION_NEEDED

#define SCSI_PORT_NOTIFICATION_NEEDED   0x0004

Definition at line 30 of file scsiport.h.

◆ SCSI_PORT_REQUEST_PENDING

#define SCSI_PORT_REQUEST_PENDING   0x0800

Definition at line 37 of file scsiport.h.

◆ SCSI_PORT_RESET

#define SCSI_PORT_RESET   0x0080

Definition at line 34 of file scsiport.h.

◆ SCSI_PORT_RESET_REPORTED

#define SCSI_PORT_RESET_REPORTED   0x0200

Definition at line 36 of file scsiport.h.

◆ SCSI_PORT_RESET_REQUEST

#define SCSI_PORT_RESET_REQUEST   0x0100

Definition at line 35 of file scsiport.h.

◆ SCSI_PORT_SCAN_IN_PROGRESS

#define SCSI_PORT_SCAN_IN_PROGRESS   0x8000

Definition at line 50 of file scsiport.h.

◆ SCSI_PORT_TIMER_NEEDED

#define SCSI_PORT_TIMER_NEEDED   0x10000

Definition at line 42 of file scsiport.h.

◆ TAG_SCSIPORT

#define TAG_SCSIPORT   'ISCS'

Definition at line 20 of file scsiport.h.

◆ VERSION

#define VERSION   "0.0.3"

Definition at line 18 of file scsiport.h.

Typedef Documentation

◆ BUSES_CONFIGURATION_INFORMATION

◆ CONFIGURATION_INFO

◆ PBUSES_CONFIGURATION_INFORMATION

◆ PCONFIGURATION_INFO

◆ PRESETBUS_PARAMS

◆ PSCSI_BUS_SCAN_INFO

◆ PSCSI_LUN_INFO

◆ PSCSI_PORT_DEVICE_BASE

◆ PSCSI_PORT_DEVICE_EXTENSION

◆ PSCSI_PORT_INTERRUPT_DATA

◆ PSCSI_PORT_LUN_EXTENSION

◆ PSCSI_PORT_SAVE_INTERRUPT

◆ PSCSI_REQUEST_BLOCK_INFO

◆ PSCSI_SG_ADDRESS

◆ RESETBUS_PARAMS

◆ SCSI_BUS_SCAN_INFO

◆ SCSI_LUN_INFO

◆ SCSI_PORT_DEVICE_BASE

◆ SCSI_PORT_DEVICE_EXTENSION

◆ SCSI_PORT_INTERRUPT_DATA

◆ SCSI_PORT_LUN_EXTENSION

◆ SCSI_PORT_SAVE_INTERRUPT

◆ SCSI_PORT_TIMER_STATES

◆ SCSI_REQUEST_BLOCK_INFO

◆ SCSI_SG_ADDRESS

Enumeration Type Documentation

◆ _SCSI_PORT_TIMER_STATES

Enumerator
IDETimerIdle 
IDETimerCmdWait 
IDETimerResetWaitForBusyNegate 
IDETimerResetWaitForDrdyAssert 

Definition at line 53 of file scsiport.h.

Function Documentation

◆ CallHWInitialize()

NTSTATUS CallHWInitialize ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension)

Calls HwInitialize routine of the miniport and sets up interrupts Should be called inside ScsiPortInitialize (for legacy drivers) or inside IRP_MN_START_DEVICE for pnp drivers.

Parameters
[in]DeviceExtensionThe device extension
Returns
NTSTATUS of the operation

Definition at line 459 of file fdo.c.

461 {
462  PPORT_CONFIGURATION_INFORMATION PortConfig = DeviceExtension->PortConfig;
464  KIRQL OldIrql;
465 
466  /* Deal with interrupts */
467  if (DeviceExtension->HwInterrupt == NULL ||
468  (PortConfig->BusInterruptLevel == 0 && PortConfig->BusInterruptVector == 0))
469  {
470  /* No interrupts */
471  DeviceExtension->InterruptCount = 0;
472 
473  DPRINT1("Interrupt Count: 0\n");
474 
476 
477  /* This code path will ALWAYS crash so stop it now */
478  __debugbreak();
479  }
480  else
481  {
482  BOOLEAN InterruptShareable;
484  ULONG InterruptVector[2], i, MappedIrq[2];
485  KIRQL Dirql[2], MaxDirql;
486  KAFFINITY Affinity[2];
487 
488  DeviceExtension->InterruptLevel[0] = PortConfig->BusInterruptLevel;
489  DeviceExtension->InterruptLevel[1] = PortConfig->BusInterruptLevel2;
490 
491  InterruptVector[0] = PortConfig->BusInterruptVector;
492  InterruptVector[1] = PortConfig->BusInterruptVector2;
493 
494  InterruptMode[0] = PortConfig->InterruptMode;
495  InterruptMode[1] = PortConfig->InterruptMode2;
496 
497  DeviceExtension->InterruptCount =
498  (PortConfig->BusInterruptLevel2 != 0 ||
499  PortConfig->BusInterruptVector2 != 0) ? 2 : 1;
500 
501  for (i = 0; i < DeviceExtension->InterruptCount; i++)
502  {
503  /* Register an interrupt handler for this device */
504  MappedIrq[i] = HalGetInterruptVector(
505  PortConfig->AdapterInterfaceType, PortConfig->SystemIoBusNumber,
506  DeviceExtension->InterruptLevel[i], InterruptVector[i], &Dirql[i],
507  &Affinity[i]);
508  }
509 
510  if (DeviceExtension->InterruptCount == 1 || Dirql[0] > Dirql[1])
511  MaxDirql = Dirql[0];
512  else
513  MaxDirql = Dirql[1];
514 
515  for (i = 0; i < DeviceExtension->InterruptCount; i++)
516  {
517  /* Determine IRQ sharability as usual */
518  if (PortConfig->AdapterInterfaceType == MicroChannel ||
520  {
521  InterruptShareable = TRUE;
522  }
523  else
524  {
525  InterruptShareable = FALSE;
526  }
527 
529  &DeviceExtension->Interrupt[i], (PKSERVICE_ROUTINE)ScsiPortIsr, DeviceExtension,
530  &DeviceExtension->IrqLock, MappedIrq[i], Dirql[i], MaxDirql, InterruptMode[i],
531  InterruptShareable, Affinity[i], FALSE);
532 
533  if (!(NT_SUCCESS(Status)))
534  {
535  DPRINT1("Could not connect interrupt %d\n", InterruptVector[i]);
536  DeviceExtension->Interrupt[i] = NULL;
537  return Status;
538  }
539  }
540 
541  if (!NT_SUCCESS(Status))
542  return Status;
543  }
544 
545  /* Save IoAddress (from access ranges) */
546  if (PortConfig->NumberOfAccessRanges != 0)
547  {
548  DeviceExtension->IoAddress = ((*(PortConfig->AccessRanges))[0]).RangeStart.LowPart;
549 
550  DPRINT("Io Address %x\n", DeviceExtension->IoAddress);
551  }
552 
553  /* Set flag that it's allowed to disconnect during this command */
554  DeviceExtension->Flags |= SCSI_PORT_DISCONNECT_ALLOWED;
555 
556  /* Initialize counter of active requests (-1 means there are none) */
557  DeviceExtension->ActiveRequestCounter = -1;
558 
559  /* Analyze what we have about DMA */
560  if (DeviceExtension->AdapterObject != NULL && PortConfig->Master &&
561  PortConfig->NeedPhysicalAddresses)
562  {
563  DeviceExtension->MapRegisters = TRUE;
564  }
565  else
566  {
567  DeviceExtension->MapRegisters = FALSE;
568  }
569 
570  /* Call HwInitialize at DISPATCH_LEVEL */
572 
574  DeviceExtension->Interrupt[0], DeviceExtension->HwInitialize,
575  DeviceExtension->MiniPortDeviceExtension))
576  {
577  DPRINT1("HwInitialize() failed!\n");
580  }
581 
582  /* Check if a notification is needed */
583  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
584  {
585  /* Call DPC right away, because we're already at DISPATCH_LEVEL */
586  ScsiPortDpcForIsr(NULL, DeviceExtension->DeviceObject, NULL, NULL);
587  }
588 
589  /* Lower irql back to what it was */
591 
592  return Status;
593 }
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
INTERFACE_TYPE AdapterInterfaceType
Definition: srb.h:55
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:798
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
KSERVICE_ROUTINE ScsiPortIsr
Definition: scsiport.h:377
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
ACCESS_RANGE(* AccessRanges)[]
Definition: srb.h:70
IO_DPC_ROUTINE ScsiPortDpcForIsr
Definition: scsiport.h:369
#define SCSI_PORT_NOTIFICATION_NEEDED
Definition: scsiport.h:30
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
KSERVICE_ROUTINE * PKSERVICE_ROUTINE
Definition: ketypes.h:500
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 FALSE
Definition: types.h:117
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
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
enum _KINTERRUPT_MODE KINTERRUPT_MODE
void DPRINT(...)
Definition: polytest.cpp:61
KINTERRUPT_MODE InterruptMode2
Definition: srb.h:97
NTHALAPI ULONG NTAPI HalGetInterruptVector(INTERFACE_TYPE, ULONG, ULONG, ULONG, PKIRQL, PKAFFINITY)
KINTERRUPT_MODE InterruptMode
Definition: srb.h:60
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:170
Status
Definition: gdiplustypes.h:24
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
ULONG_PTR KAFFINITY
Definition: compat.h:85
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:115
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:142
#define STATUS_ADAPTER_HARDWARE_ERROR
Definition: ntstatus.h:430
#define SCSI_PORT_DISCONNECT_ALLOWED
Definition: scsiport.h:38
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by ScsiPortInitialize().

◆ ScsiPortAllocateAdapterChannel()

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

◆ ScsiPortDeviceControl()

NTSTATUS NTAPI ScsiPortDeviceControl ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)

Definition at line 150 of file ioctl.c.

153 {
154  PIO_STACK_LOCATION Stack;
155  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
156  PDUMP_POINTERS DumpPointers;
158 
159  DPRINT("ScsiPortDeviceControl()\n");
160 
161  Irp->IoStatus.Information = 0;
162 
164  DeviceExtension = DeviceObject->DeviceExtension;
165 
166  switch (Stack->Parameters.DeviceIoControl.IoControlCode)
167  {
169  DPRINT(" IOCTL_SCSI_GET_DUMP_POINTERS\n");
170 
171  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DUMP_POINTERS))
172  {
174  Irp->IoStatus.Information = sizeof(DUMP_POINTERS);
175  break;
176  }
177 
178  DumpPointers = Irp->AssociatedIrp.SystemBuffer;
179  DumpPointers->DeviceObject = DeviceObject;
180  /* More data.. ? */
181 
183  Irp->IoStatus.Information = sizeof(DUMP_POINTERS);
184  break;
185 
187  DPRINT(" IOCTL_SCSI_GET_CAPABILITIES\n");
188  if (Stack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(PVOID))
189  {
190  *((PVOID *)Irp->AssociatedIrp.SystemBuffer) = &DeviceExtension->PortCapabilities;
191 
192  Irp->IoStatus.Information = sizeof(PVOID);
194  break;
195  }
196 
197  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(IO_SCSI_CAPABILITIES))
198  {
200  break;
201  }
202 
203  RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
204  &DeviceExtension->PortCapabilities,
205  sizeof(IO_SCSI_CAPABILITIES));
206 
207  Irp->IoStatus.Information = sizeof(IO_SCSI_CAPABILITIES);
209  break;
210 
212  DPRINT(" IOCTL_SCSI_GET_INQUIRY_DATA\n");
213 
214  /* Copy inquiry data to the port device extension */
215  Status = SpiGetInquiryData(DeviceExtension, Irp);
216  break;
217 
218  case IOCTL_SCSI_MINIPORT:
219  DPRINT1("IOCTL_SCSI_MINIPORT unimplemented!\n");
221  break;
222 
224  DPRINT1("IOCTL_SCSI_PASS_THROUGH unimplemented!\n");
226  break;
227 
228  default:
229  if (DEVICE_TYPE_FROM_CTL_CODE(Stack->Parameters.DeviceIoControl.IoControlCode) == MOUNTDEVCONTROLTYPE)
230  {
231  switch (Stack->Parameters.DeviceIoControl.IoControlCode)
232  {
234  DPRINT1("Got unexpected IOCTL_MOUNTDEV_QUERY_DEVICE_NAME\n");
235  break;
237  DPRINT1("Got unexpected IOCTL_MOUNTDEV_QUERY_UNIQUE_ID\n");
238  break;
239  default:
240  DPRINT(" got ioctl intended for the mount manager: 0x%lX\n", Stack->Parameters.DeviceIoControl.IoControlCode);
241  break;
242  }
243  } else {
244  DPRINT1(" unknown ioctl code: 0x%lX\n", Stack->Parameters.DeviceIoControl.IoControlCode);
245  }
247  break;
248  }
249 
250  /* Complete the request with the given status */
251  Irp->IoStatus.Status = Status;
253 
254  return Status;
255 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define IOCTL_SCSI_MINIPORT
Definition: scsi_port.h:48
_In_ PIRP Irp
Definition: csq.h:116
IO_SCSI_CAPABILITIES PortCapabilities
Definition: scsiport.c:79
#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:69
#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: ioctl.c:17
#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
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define IOCTL_SCSI_GET_INQUIRY_DATA
Definition: scsi_port.h:49
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
#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:581
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
struct _IO_SCSI_CAPABILITIES IO_SCSI_CAPABILITIES
PVOID DeviceObject
Definition: ntddscsi.h:259

Referenced by ScsiPortInitialize().

◆ SpiAdapterControl()

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

◆ SpiAllocateLunExtension()

PSCSI_PORT_LUN_EXTENSION SpiAllocateLunExtension ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension)

Definition at line 16 of file pdo.c.

18 {
19  PSCSI_PORT_LUN_EXTENSION LunExtension;
20  ULONG LunExtensionSize;
21 
22  DPRINT("SpiAllocateLunExtension(%p)\n", DeviceExtension);
23 
24  /* Round LunExtensionSize first to the sizeof LONGLONG */
25  LunExtensionSize = (DeviceExtension->LunExtensionSize +
26  sizeof(LONGLONG) - 1) & ~(sizeof(LONGLONG) - 1);
27 
28  LunExtensionSize += sizeof(SCSI_PORT_LUN_EXTENSION);
29  DPRINT("LunExtensionSize %lu\n", LunExtensionSize);
30 
31  LunExtension = ExAllocatePoolWithTag(NonPagedPool, LunExtensionSize, TAG_SCSIPORT);
32  if (LunExtension == NULL)
33  {
34  DPRINT1("Out of resources!\n");
35  return NULL;
36  }
37 
38  /* Zero everything */
39  RtlZeroMemory(LunExtension, LunExtensionSize);
40 
41  /* Initialize a list of requests */
42  InitializeListHead(&LunExtension->SrbInfo.Requests);
43 
44  /* Initialize timeout counter */
45  LunExtension->RequestTimeout = -1;
46 
47  /* Set maximum queue size */
48  LunExtension->MaxQueueCount = 256;
49 
50  /* Initialize request queue */
51  KeInitializeDeviceQueue(&LunExtension->DeviceQueue);
52 
53  return LunExtension;
54 }
KDEVICE_QUEUE DeviceQueue
Definition: scsiport.h:133
VOID NTAPI KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
Definition: devqueue.c:22
#define TAG_SCSIPORT
Definition: scsiport.h:20
struct _SCSI_PORT_LUN_EXTENSION SCSI_PORT_LUN_EXTENSION
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
int64_t LONGLONG
Definition: typedefs.h:68
SCSI_REQUEST_BLOCK_INFO SrbInfo
Definition: scsiport.h:147
#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:262

Referenced by SpiScanAdapter().

◆ SpiBuildDeviceMap()

NTSTATUS SpiBuildDeviceMap ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension,
_In_ PUNICODE_STRING  RegistryPath 
)

Definition at line 107 of file registry.c.

110 {
111  PSCSI_PORT_LUN_EXTENSION LunExtension;
115  WCHAR NameBuffer[64];
117  HANDLE ScsiKey;
118  HANDLE ScsiPortKey = NULL;
119  HANDLE ScsiBusKey = NULL;
120  HANDLE ScsiInitiatorKey = NULL;
121  HANDLE ScsiTargetKey = NULL;
122  HANDLE ScsiLunKey = NULL;
124  ULONG Target;
125  ULONG CurrentTarget;
126  ULONG Lun;
127  PWCHAR DriverName;
128  ULONG UlongData;
129  PWCHAR TypeName;
131 
132  DPRINT("SpiBuildDeviceMap() called\n");
133 
134  if (DeviceExtension == NULL || RegistryPath == NULL)
135  {
136  DPRINT1("Invalid parameter\n");
138  }
139 
140  /* Open or create the 'Scsi' subkey */
142  L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi");
144  &KeyName,
146  0,
147  NULL);
148  Status = ZwCreateKey(&ScsiKey,
151  0,
152  NULL,
154  &Disposition);
155  if (!NT_SUCCESS(Status))
156  {
157  DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
158  return Status;
159  }
160 
161  /* Create new 'Scsi Port X' subkey */
162  DPRINT("Scsi Port %lu\n", DeviceExtension->PortNumber);
163 
164  swprintf(NameBuffer,
165  L"Scsi Port %lu",
166  DeviceExtension->PortNumber);
167  RtlInitUnicodeString(&KeyName, NameBuffer);
169  &KeyName,
171  ScsiKey,
172  NULL);
173  Status = ZwCreateKey(&ScsiPortKey,
176  0,
177  NULL,
179  &Disposition);
180  ZwClose(ScsiKey);
181  if (!NT_SUCCESS(Status))
182  {
183  DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
184  return Status;
185  }
186 
187  /*
188  * Create port-specific values
189  */
190 
191  /* Set 'DMA Enabled' (REG_DWORD) value */
192  UlongData = (ULONG)!DeviceExtension->PortCapabilities.AdapterUsesPio;
193  DPRINT(" DMA Enabled = %s\n", UlongData ? "TRUE" : "FALSE");
194  RtlInitUnicodeString(&ValueName, L"DMA Enabled");
195  Status = ZwSetValueKey(ScsiPortKey,
196  &ValueName,
197  0,
198  REG_DWORD,
199  &UlongData,
200  sizeof(UlongData));
201  if (!NT_SUCCESS(Status))
202  {
203  DPRINT("ZwSetValueKey('DMA Enabled') failed (Status %lx)\n", Status);
204  ZwClose(ScsiPortKey);
205  return Status;
206  }
207 
208  /* Set 'Driver' (REG_SZ) value */
209  DriverName = wcsrchr(RegistryPath->Buffer, L'\\') + 1;
210  RtlInitUnicodeString(&ValueName, L"Driver");
211  Status = ZwSetValueKey(ScsiPortKey,
212  &ValueName,
213  0,
214  REG_SZ,
215  DriverName,
216  (ULONG)((wcslen(DriverName) + 1) * sizeof(WCHAR)));
217  if (!NT_SUCCESS(Status))
218  {
219  DPRINT("ZwSetValueKey('Driver') failed (Status %lx)\n", Status);
220  ZwClose(ScsiPortKey);
221  return Status;
222  }
223 
224  /* Set 'Interrupt' (REG_DWORD) value (NT4 only) */
225  UlongData = (ULONG)DeviceExtension->PortConfig->BusInterruptLevel;
226  DPRINT(" Interrupt = %lu\n", UlongData);
227  RtlInitUnicodeString(&ValueName, L"Interrupt");
228  Status = ZwSetValueKey(ScsiPortKey,
229  &ValueName,
230  0,
231  REG_DWORD,
232  &UlongData,
233  sizeof(UlongData));
234  if (!NT_SUCCESS(Status))
235  {
236  DPRINT("ZwSetValueKey('Interrupt') failed (Status %lx)\n", Status);
237  ZwClose(ScsiPortKey);
238  return Status;
239  }
240 
241  /* Set 'IOAddress' (REG_DWORD) value (NT4 only) */
242  UlongData = ScsiPortConvertPhysicalAddressToUlong((*DeviceExtension->PortConfig->AccessRanges)[0].RangeStart);
243  DPRINT(" IOAddress = %lx\n", UlongData);
244  RtlInitUnicodeString(&ValueName, L"IOAddress");
245  Status = ZwSetValueKey(ScsiPortKey,
246  &ValueName,
247  0,
248  REG_DWORD,
249  &UlongData,
250  sizeof(UlongData));
251  if (!NT_SUCCESS(Status))
252  {
253  DPRINT("ZwSetValueKey('IOAddress') failed (Status %lx)\n", Status);
254  ZwClose(ScsiPortKey);
255  return Status;
256  }
257 
258  /* Enumerate buses */
259  for (BusNumber = 0; BusNumber < DeviceExtension->PortConfig->NumberOfBuses; BusNumber++)
260  {
261  /* Create 'Scsi Bus X' key */
262  DPRINT(" Scsi Bus %lu\n", BusNumber);
263  swprintf(NameBuffer,
264  L"Scsi Bus %lu",
265  BusNumber);
266  RtlInitUnicodeString(&KeyName, NameBuffer);
268  &KeyName,
269  0,
270  ScsiPortKey,
271  NULL);
272  Status = ZwCreateKey(&ScsiBusKey,
275  0,
276  NULL,
278  &Disposition);
279  if (!NT_SUCCESS(Status))
280  {
281  DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
282  goto ByeBye;
283  }
284 
285  /* Create 'Initiator Id X' key */
286  DPRINT(" Initiator Id %lu\n",
287  DeviceExtension->PortConfig->InitiatorBusId[BusNumber]);
288  swprintf(NameBuffer,
289  L"Initiator Id %lu",
290  (ULONG)(UCHAR)DeviceExtension->PortConfig->InitiatorBusId[BusNumber]);
291  RtlInitUnicodeString(&KeyName, NameBuffer);
293  &KeyName,
294  0,
295  ScsiBusKey,
296  NULL);
297  Status = ZwCreateKey(&ScsiInitiatorKey,
300  0,
301  NULL,
303  &Disposition);
304  if (!NT_SUCCESS(Status))
305  {
306  DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
307  goto ByeBye;
308  }
309 
310  /* FIXME: Are there any initiator values (??) */
311 
312  ZwClose(ScsiInitiatorKey);
313  ScsiInitiatorKey = NULL;
314 
315 
316  /* Enumerate targets */
317  CurrentTarget = (ULONG)-1;
318  ScsiTargetKey = NULL;
319  for (Target = 0; Target < DeviceExtension->PortConfig->MaximumNumberOfTargets; Target++)
320  {
321  for (Lun = 0; Lun < SCSI_MAXIMUM_LOGICAL_UNITS; Lun++)
322  {
323  LunExtension = SpiGetLunExtension(DeviceExtension,
324  (UCHAR)BusNumber,
325  (UCHAR)Target,
326  (UCHAR)Lun);
327  if (LunExtension == NULL)
328  continue;
329 
330  if (Target != CurrentTarget)
331  {
332  /* Close old target key */
333  if (ScsiTargetKey != NULL)
334  {
335  ZwClose(ScsiTargetKey);
336  ScsiTargetKey = NULL;
337  }
338 
339  /* Create 'Target Id X' key */
340  DPRINT(" Target Id %lu\n", Target);
341  swprintf(NameBuffer,
342  L"Target Id %lu",
343  Target);
344  RtlInitUnicodeString(&KeyName, NameBuffer);
346  &KeyName,
347  0,
348  ScsiBusKey,
349  NULL);
350  Status = ZwCreateKey(&ScsiTargetKey,
353  0,
354  NULL,
356  &Disposition);
357  if (!NT_SUCCESS(Status))
358  {
359  DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
360  goto ByeBye;
361  }
362 
363  CurrentTarget = Target;
364  }
365 
366  /* Create 'Logical Unit Id X' key */
367  DPRINT(" Logical Unit Id %lu\n", Lun);
368  swprintf(NameBuffer,
369  L"Logical Unit Id %lu",
370  Lun);
371  RtlInitUnicodeString(&KeyName, NameBuffer);
373  &KeyName,
374  0,
375  ScsiTargetKey,
376  NULL);
377  Status = ZwCreateKey(&ScsiLunKey,
380  0,
381  NULL,
383  &Disposition);
384  if (!NT_SUCCESS(Status))
385  {
386  DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
387  goto ByeBye;
388  }
389 
390  /* Set 'Identifier' (REG_SZ) value */
391  swprintf(NameBuffer,
392  L"%.8S%.16S%.4S",
393  LunExtension->InquiryData.VendorId,
394  LunExtension->InquiryData.ProductId,
395  LunExtension->InquiryData.ProductRevisionLevel);
396  DPRINT(" Identifier = '%S'\n", NameBuffer);
397  RtlInitUnicodeString(&ValueName, L"Identifier");
398  Status = ZwSetValueKey(ScsiLunKey,
399  &ValueName,
400  0,
401  REG_SZ,
402  NameBuffer,
403  (ULONG)((wcslen(NameBuffer) + 1) * sizeof(WCHAR)));
404  if (!NT_SUCCESS(Status))
405  {
406  DPRINT("ZwSetValueKey('Identifier') failed (Status %lx)\n", Status);
407  goto ByeBye;
408  }
409 
410  /* Set 'Type' (REG_SZ) value */
411  /*
412  * See https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-ide-devices
413  * and https://docs.microsoft.com/en-us/windows-hardware/drivers/install/identifiers-for-scsi-devices
414  * for a list of types with their human-readable forms.
415  */
416  switch (LunExtension->InquiryData.DeviceType)
417  {
418  case 0:
419  TypeName = L"DiskPeripheral";
420  break;
421  case 1:
422  TypeName = L"TapePeripheral";
423  break;
424  case 2:
425  TypeName = L"PrinterPeripheral";
426  break;
427  // case 3: "ProcessorPeripheral", classified as 'other': fall back to default case.
428  case 4:
429  TypeName = L"WormPeripheral";
430  break;
431  case 5:
432  TypeName = L"CdRomPeripheral";
433  break;
434  case 6:
435  TypeName = L"ScannerPeripheral";
436  break;
437  case 7:
438  TypeName = L"OpticalDiskPeripheral";
439  break;
440  case 8:
441  TypeName = L"MediumChangerPeripheral";
442  break;
443  case 9:
444  TypeName = L"CommunicationsPeripheral";
445  break;
446 
447  /* New peripheral types (SCSI only) */
448  case 10: case 11:
449  TypeName = L"ASCPrePressGraphicsPeripheral";
450  break;
451  case 12:
452  TypeName = L"ArrayPeripheral";
453  break;
454  case 13:
455  TypeName = L"EnclosurePeripheral";
456  break;
457  case 14:
458  TypeName = L"RBCPeripheral";
459  break;
460  case 15:
461  TypeName = L"CardReaderPeripheral";
462  break;
463  case 16:
464  TypeName = L"BridgePeripheral";
465  break;
466 
467  default:
468  TypeName = L"OtherPeripheral";
469  break;
470  }
471  DPRINT(" Type = '%S'\n", TypeName);
473  Status = ZwSetValueKey(ScsiLunKey,
474  &ValueName,
475  0,
476  REG_SZ,
477  TypeName,
478  (ULONG)((wcslen(TypeName) + 1) * sizeof(WCHAR)));
479  if (!NT_SUCCESS(Status))
480  {
481  DPRINT("ZwSetValueKey('Type') failed (Status %lx)\n", Status);
482  goto ByeBye;
483  }
484 
485  ZwClose(ScsiLunKey);
486  ScsiLunKey = NULL;
487  }
488 
489  /* Close old target key */
490  if (ScsiTargetKey != NULL)
491  {
492  ZwClose(ScsiTargetKey);
493  ScsiTargetKey = NULL;
494  }
495  }
496 
497  ZwClose(ScsiBusKey);
498  ScsiBusKey = NULL;
499  }
500 
501 ByeBye:
502  if (ScsiLunKey != NULL)
503  ZwClose(ScsiLunKey);
504 
505  if (ScsiInitiatorKey != NULL)
506  ZwClose(ScsiInitiatorKey);
507 
508  if (ScsiTargetKey != NULL)
509  ZwClose(ScsiTargetKey);
510 
511  if (ScsiBusKey != NULL)
512  ZwClose(ScsiBusKey);
513 
514  if (ScsiPortKey != NULL)
515  ZwClose(ScsiPortKey);
516 
517  DPRINT("SpiBuildDeviceMap() done\n");
518 
519  return Status;
520 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
UCHAR ProductRevisionLevel[4]
Definition: cdrw_hw.h:1134
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1310
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define SCSI_MAXIMUM_LOGICAL_UNITS
Definition: srb.h:21
PSCSI_PORT_LUN_EXTENSION SpiGetLunExtension(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _In_ UCHAR PathId, _In_ UCHAR TargetId, _In_ UCHAR Lun)
Definition: pdo.c:57
#define ScsiPortConvertPhysicalAddressToUlong(Address)
Definition: srb.h:949
LONG NTSTATUS
Definition: precomp.h:26
UCHAR ProductId[16]
Definition: cdrw_hw.h:1133
uint16_t * PWCHAR
Definition: typedefs.h:56
UCHAR VendorId[8]
Definition: cdrw_hw.h:1132
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Reserved_ ULONG _In_opt_ PUNICODE_STRING _In_ ULONG _Out_opt_ PULONG Disposition
Definition: cmfuncs.h:50
#define OBJ_OPENIF
Definition: winternl.h:229
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:156
_In_z_ PWSTR RegistryPath
Definition: classp.h:1930
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define swprintf(buf, format,...)
Definition: sprintf.c:56
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1088
unsigned char UCHAR
Definition: xmlstorage.h:181
Status
Definition: gdiplustypes.h:24
static const WCHAR L[]
Definition: oid.c:1250
#define wcsrchr
Definition: compat.h:16
UCHAR DeviceType
Definition: cdrw_hw.h:1116
INQUIRYDATA InquiryData
Definition: scsiport.h:131
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define REG_DWORD
Definition: sdbapi.c:596
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define REG_SZ
Definition: layer.c:22

Referenced by ScsiPortInitialize().

◆ SpiCleanupAfterInit()

VOID SpiCleanupAfterInit ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension)

Definition at line 596 of file fdo.c.

598 {
599  PSCSI_LUN_INFO LunInfo;
600  PVOID Ptr;
601  ULONG Bus, Lun;
602 
603  /* Check if we have something to clean up */
604  if (DeviceExtension == NULL)
605  return;
606 
607  /* Stop the timer */
608  IoStopTimer(DeviceExtension->DeviceObject);
609 
610  /* Disconnect the interrupts */
611  while (DeviceExtension->InterruptCount)
612  {
613  if (DeviceExtension->Interrupt[--DeviceExtension->InterruptCount])
614  IoDisconnectInterrupt(DeviceExtension->Interrupt[DeviceExtension->InterruptCount]);
615  }
616 
617  /* Delete ConfigInfo */
618  if (DeviceExtension->BusesConfig)
619  {
620  for (Bus = 0; Bus < DeviceExtension->BusNum; Bus++)
621  {
622  if (!DeviceExtension->BusesConfig->BusScanInfo[Bus])
623  continue;
624 
625  LunInfo = DeviceExtension->BusesConfig->BusScanInfo[Bus]->LunInfo;
626 
627  while (LunInfo)
628  {
629  /* Free current, but save pointer to the next one */
630  Ptr = LunInfo->Next;
631  ExFreePool(LunInfo);
632  LunInfo = Ptr;
633  }
634 
635  ExFreePool(DeviceExtension->BusesConfig->BusScanInfo[Bus]);
636  }
637 
638  ExFreePool(DeviceExtension->BusesConfig);
639  }
640 
641  /* Free PortConfig */
642  if (DeviceExtension->PortConfig)
643  ExFreePool(DeviceExtension->PortConfig);
644 
645  /* Free LUNs*/
646  for(Lun = 0; Lun < LUS_NUMBER; Lun++)
647  {
648  while (DeviceExtension->LunExtensionList[Lun])
649  {
650  Ptr = DeviceExtension->LunExtensionList[Lun];
651  DeviceExtension->LunExtensionList[Lun] = DeviceExtension->LunExtensionList[Lun]->Next;
652 
653  ExFreePool(Ptr);
654  }
655  }
656 
657  /* Free common buffer (if it exists) */
658  if (DeviceExtension->SrbExtensionBuffer != NULL &&
659  DeviceExtension->CommonBufferLength != 0)
660  {
661  if (!DeviceExtension->AdapterObject)
662  {
663  ExFreePool(DeviceExtension->SrbExtensionBuffer);
664  }
665  else
666  {
667  HalFreeCommonBuffer(DeviceExtension->AdapterObject,
668  DeviceExtension->CommonBufferLength,
669  DeviceExtension->PhysicalAddress,
670  DeviceExtension->SrbExtensionBuffer,
671  FALSE);
672  }
673  }
674 
675  /* Free SRB info */
676  if (DeviceExtension->SrbInfo != NULL)
677  ExFreePool(DeviceExtension->SrbInfo);
678 
679  /* Unmap mapped addresses */
680  while (DeviceExtension->MappedAddressList != NULL)
681  {
682  MmUnmapIoSpace(DeviceExtension->MappedAddressList->MappedAddress,
683  DeviceExtension->MappedAddressList->NumberOfBytes);
684 
685  Ptr = DeviceExtension->MappedAddressList;
686  DeviceExtension->MappedAddressList = DeviceExtension->MappedAddressList->NextMappedAddress;
687 
688  ExFreePool(Ptr);
689  }
690 
691  /* Finally delete the device object */
692  DPRINT("Deleting device %p\n", DeviceExtension->DeviceObject);
693  IoDeleteDevice(DeviceExtension->DeviceObject);
694 }
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1310
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define LUS_NUMBER
Definition: scsiport.h:23
#define FALSE
Definition: types.h:117
VOID NTAPI IoStopTimer(PDEVICE_OBJECT DeviceObject)
Definition: iotimer.c:166
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:140
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
struct _SCSI_LUN_INFO * Next
Definition: scsiport.h:163
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI HalFreeCommonBuffer(IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PHYSICAL_ADDRESS LogicalAddress, IN PVOID VirtualAddress, IN BOOLEAN CacheEnabled)
Definition: dma.c:61
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by ScsiPortInitialize().

◆ SpiGetLunExtension()

PSCSI_PORT_LUN_EXTENSION SpiGetLunExtension ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension,
_In_ UCHAR  PathId,
_In_ UCHAR  TargetId,
_In_ UCHAR  Lun 
)

Definition at line 57 of file pdo.c.

62 {
63  PSCSI_PORT_LUN_EXTENSION LunExtension;
64 
65  DPRINT("SpiGetLunExtension(%p %u %u %u) called\n",
66  DeviceExtension, PathId, TargetId, Lun);
67 
68  /* Get appropriate list */
69  LunExtension = DeviceExtension->LunExtensionList[(TargetId + Lun) % LUS_NUMBER];
70 
71  /* Iterate it until we find what we need */
72  while (LunExtension)
73  {
74  if (LunExtension->TargetId == TargetId &&
75  LunExtension->Lun == Lun &&
76  LunExtension->PathId == PathId)
77  {
78  /* All matches, return */
79  return LunExtension;
80  }
81 
82  /* Advance to the next item */
83  LunExtension = LunExtension->Next;
84  }
85 
86  /* We did not find anything */
87  DPRINT("Nothing found\n");
88  return NULL;
89 }
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1310
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1310
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1310
#define LUS_NUMBER
Definition: scsiport.h:23
struct _SCSI_PORT_LUN_EXTENSION * Next
Definition: scsiport.h:126
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61

Referenced by ScsiPortDispatchScsi(), ScsiPortGetLogicalUnit(), ScsiPortNotification(), ScsiPortStartIo(), ScsiPortStartPacket(), SpiBuildDeviceMap(), SpiGetSrbData(), SpiProcessCompletedRequest(), SpiSaveInterruptData(), and SpiSendInquiry().

◆ SpiGetNextRequestFromLun()

VOID SpiGetNextRequestFromLun ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension,
_Inout_ PSCSI_PORT_LUN_EXTENSION  LunExtension 
)

Definition at line 372 of file scsi.c.

375 {
376  PIO_STACK_LOCATION IrpStack;
377  PIRP NextIrp;
380 
381 
382  /* If LUN is not active or queue is more than maximum allowed */
383  if (LunExtension->QueueCount >= LunExtension->MaxQueueCount ||
384  !(LunExtension->Flags & SCSI_PORT_LU_ACTIVE))
385  {
386  /* Release the spinlock and exit */
387  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
388  return;
389  }
390 
391  /* Check if we can get a next request */
392  if (LunExtension->Flags &
395  {
396  /* Pending requests can only be started if the queue is empty */
397  if (IsListEmpty(&LunExtension->SrbInfo.Requests) &&
398  !(LunExtension->Flags &
400  {
401  /* Make sure we have SRB */
402  ASSERT(LunExtension->SrbInfo.Srb == NULL);
403 
404  /* Clear active and pending flags */
405  LunExtension->Flags &= ~(LUNEX_REQUEST_PENDING | SCSI_PORT_LU_ACTIVE);
406 
407  /* Get next Irp, and clear pending requests list */
408  NextIrp = LunExtension->PendingRequest;
409  LunExtension->PendingRequest = NULL;
410 
411  /* Set attempt counter to zero */
412  LunExtension->AttemptCount = 0;
413 
414  /* Release the spinlock */
415  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
416 
417  /* Start the next pending request */
418  IoStartPacket(DeviceExtension->DeviceObject, NextIrp, (PULONG)NULL, NULL);
419 
420  return;
421  }
422  else
423  {
424  /* Release the spinlock, without clearing any flags and exit */
425  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
426 
427  return;
428  }
429  }
430 
431  /* Reset active flag */
432  LunExtension->Flags &= ~SCSI_PORT_LU_ACTIVE;
433 
434  /* Set attempt counter to zero */
435  LunExtension->AttemptCount = 0;
436 
437  /* Remove packet from the device queue */
438  Entry = KeRemoveByKeyDeviceQueue(&LunExtension->DeviceQueue, LunExtension->SortKey);
439 
440  if (Entry != NULL)
441  {
442  /* Get pointer to the next irp */
443  NextIrp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.DeviceQueueEntry);
444 
445  /* Get point to the SRB */
446  IrpStack = IoGetCurrentIrpStackLocation(NextIrp);
447  Srb = (PSCSI_REQUEST_BLOCK)IrpStack->Parameters.Others.Argument1;
448 
449  /* Set new key*/
450  LunExtension->SortKey = Srb->QueueSortKey;
451  LunExtension->SortKey++;
452 
453  /* Release the spinlock */
454  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
455 
456  /* Start the next pending request */
457  IoStartPacket(DeviceExtension->DeviceObject, NextIrp, (PULONG)NULL, NULL);
458  }
459  else
460  {
461  /* Release the spinlock */
462  KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
463  }
464 }
#define LUNEX_FULL_QUEUE
Definition: scsiport.h:48
struct _Entry Entry
Definition: kefuncs.h:627
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
#define SCSI_PORT_LU_ACTIVE
Definition: scsiport.h:29
#define LUNEX_REQUEST_PENDING
Definition: scsiport.h:49
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
VOID NTAPI IoStartPacket(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key, IN PDRIVER_CANCEL CancelFunction)
Definition: device.c:1876
smooth NULL
Definition: ftsmooth.c:416
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 LUNEX_NEED_REQUEST_SENSE
Definition: scsiport.h:46
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
Definition: ketypes.h:566
unsigned int * PULONG
Definition: retypes.h:1
PKDEVICE_QUEUE_ENTRY NTAPI KeRemoveByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, IN ULONG SortKey)
Definition: devqueue.c:197
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
#define LUNEX_BUSY
Definition: scsiport.h:47
base of all file and directory entries
Definition: entries.h:82
#define LUNEX_FROZEN_QUEUE
Definition: scsiport.h:45

Referenced by ScsiPortDispatchScsi(), ScsiPortDpcForIsr(), SpiProcessCompletedRequest(), and SpiSendInquiry().

◆ SpiGetSrbData()

PSCSI_REQUEST_BLOCK_INFO SpiGetSrbData ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension,
_In_ UCHAR  PathId,
_In_ UCHAR  TargetId,
_In_ UCHAR  Lun,
_In_ UCHAR  QueueTag 
)

Definition at line 92 of file pdo.c.

98 {
99  PSCSI_PORT_LUN_EXTENSION LunExtension;
100 
101  if (QueueTag == SP_UNTAGGED)
102  {
103  /* Untagged request, get LU and return pointer to SrbInfo */
104  LunExtension = SpiGetLunExtension(DeviceExtension,
105  PathId,
106  TargetId,
107  Lun);
108 
109  /* Return NULL in case of error */
110  if (!LunExtension)
111  return(NULL);
112 
113  /* Return the pointer to SrbInfo */
114  return &LunExtension->SrbInfo;
115  }
116  else
117  {
118  /* Make sure the tag is valid, if it is - return the data */
119  if (QueueTag > DeviceExtension->SrbDataCount || QueueTag < 1)
120  return NULL;
121  else
122  return &DeviceExtension->SrbInfo[QueueTag -1];
123  }
124 }
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1310
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1310
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1310
PSCSI_PORT_LUN_EXTENSION SpiGetLunExtension(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _In_ UCHAR PathId, _In_ UCHAR TargetId, _In_ UCHAR Lun)
Definition: pdo.c:57
#define SP_UNTAGGED
Definition: srb.h:225
smooth NULL
Definition: ftsmooth.c:416
SCSI_REQUEST_BLOCK_INFO SrbInfo
Definition: scsiport.h:147

Referenced by ScsiPortGetPhysicalAddress(), ScsiPortNotification(), ScsiPortStartPacket(), and SpiAllocateSrbStructures().

◆ SpiInitOpenKeys()

VOID SpiInitOpenKeys ( _Inout_ PCONFIGURATION_INFO  ConfigInfo,
_In_ PUNICODE_STRING  RegistryPath 
)

Definition at line 16 of file registry.c.

19 {
23 
24  /* Open the service key */
28  NULL,
29  NULL);
30 
31  Status = ZwOpenKey(&ConfigInfo->ServiceKey,
32  KEY_READ,
34 
35  if (!NT_SUCCESS(Status))
36  {
37  DPRINT("Unable to open driver's registry key %wZ, status 0x%08x\n", RegistryPath, Status);
38  ConfigInfo->ServiceKey = NULL;
39  }
40 
41  /* If we could open driver's service key, then proceed to the Parameters key */
42  if (ConfigInfo->ServiceKey != NULL)
43  {
44  RtlInitUnicodeString(&KeyName, L"Parameters");
46  &KeyName,
48  ConfigInfo->ServiceKey,
50 
51  /* Try to open it */
52  Status = ZwOpenKey(&ConfigInfo->DeviceKey,
53  KEY_READ,
55 
56  if (NT_SUCCESS(Status))
57  {
58  /* Yes, Parameters key exist, and it must be used instead of
59  the Service key */
60  ZwClose(ConfigInfo->ServiceKey);
61  ConfigInfo->ServiceKey = ConfigInfo->DeviceKey;
62  ConfigInfo->DeviceKey = NULL;
63  }
64  }
65 
66  if (ConfigInfo->ServiceKey != NULL)
67  {
68  /* Open the Device key */
69  RtlInitUnicodeString(&KeyName, L"Device");
71  &KeyName,
73  ConfigInfo->ServiceKey,
74  NULL);
75 
76  /* We don't check for failure here - not needed */
77  ZwOpenKey(&ConfigInfo->DeviceKey,
78  KEY_READ,
80  }
81 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
_In_z_ PWSTR RegistryPath
Definition: classp.h:1930
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
static const WCHAR L[]
Definition: oid.c:1250
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106

Referenced by ScsiPortInitialize().

◆ SpiScanAdapter()

VOID SpiScanAdapter ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension)

Definition at line 231 of file fdo.c.

233 {
234  PSCSI_PORT_LUN_EXTENSION LunExtension;
235  ULONG Bus;
236  ULONG Target;
237  ULONG Lun;
238  PSCSI_BUS_SCAN_INFO BusScanInfo;
239  PSCSI_LUN_INFO LastLunInfo, LunInfo, LunInfoExists;
240  BOOLEAN DeviceExists;
241  ULONG Hint;
243  ULONG DevicesFound;
244 
245  DPRINT("SpiScanAdapter() called\n");
246 
247  /* Scan all buses */
248  for (Bus = 0; Bus < DeviceExtension->BusNum; Bus++)
249  {
250  DPRINT(" Scanning bus %d\n", Bus);
251  DevicesFound = 0;
252 
253  /* Get pointer to the scan information */
254  BusScanInfo = DeviceExtension->BusesConfig->BusScanInfo[Bus];
255 
256  if (BusScanInfo)
257  {
258  /* Find the last LUN info in the list */
259  LunInfo = DeviceExtension->BusesConfig->BusScanInfo[Bus]->LunInfo;
260  LastLunInfo = LunInfo;
261 
262  while (LunInfo != NULL)
263  {
264  LastLunInfo = LunInfo;
265  LunInfo = LunInfo->Next;
266  }
267  }
268  else
269  {
270  /* We need to allocate this buffer */
272  if (!BusScanInfo)
273  {
274  DPRINT1("Out of resources!\n");
275  return;
276  }
277 
278  /* Store the pointer in the BusScanInfo array */
279  DeviceExtension->BusesConfig->BusScanInfo[Bus] = BusScanInfo;
280 
281  /* Fill this struct (length and bus ids for now) */
282  BusScanInfo->Length = sizeof(SCSI_BUS_SCAN_INFO);
283  BusScanInfo->LogicalUnitsCount = 0;
284  BusScanInfo->BusIdentifier = DeviceExtension->PortConfig->InitiatorBusId[Bus];
285  BusScanInfo->LunInfo = NULL;
286 
287  /* Set pointer to the last LUN info to NULL */
288  LastLunInfo = NULL;
289  }
290 
291  /* Create LUN information structure */
293  if (!LunInfo)
294  {
295  DPRINT1("Out of resources!\n");
296  return;
297  }
298 
299  RtlZeroMemory(LunInfo, sizeof(SCSI_LUN_INFO));
300 
301  /* Create LunExtension */
302  LunExtension = SpiAllocateLunExtension(DeviceExtension);
303 
304  /* And send INQUIRY to every target */
305  for (Target = 0; Target < DeviceExtension->PortConfig->MaximumNumberOfTargets; Target++)
306  {
307  /* TODO: Support scan bottom-up */
308 
309  /* Skip if it's the same address */
310  if (Target == BusScanInfo->BusIdentifier)
311  continue;
312 
313  /* Try to find an existing device here */
314  DeviceExists = FALSE;
315  LunInfoExists = BusScanInfo->LunInfo;
316 
317  /* Find matching address on this bus */
318  while (LunInfoExists)
319  {
320  if (LunInfoExists->TargetId == Target)
321  {
322  DeviceExists = TRUE;
323  break;
324  }
325 
326  /* Advance to the next one */
327  LunInfoExists = LunInfoExists->Next;
328  }
329 
330  /* No need to bother rescanning, since we already did that before */
331  if (DeviceExists)
332  continue;
333 
334  /* Scan all logical units */
335  for (Lun = 0; Lun < SCSI_MAXIMUM_LOGICAL_UNITS; Lun++)
336  {
337  if ((!LunExtension) || (!LunInfo))
338  break;
339 
340  /* Add extension to the list */
341  Hint = (Target + Lun) % LUS_NUMBER;
342  LunExtension->Next = DeviceExtension->LunExtensionList[Hint];
343  DeviceExtension->LunExtensionList[Hint] = LunExtension;
344 
345  /* Fill Path, Target, Lun fields */
346  LunExtension->PathId = LunInfo->PathId = (UCHAR)Bus;
347  LunExtension->TargetId = LunInfo->TargetId = (UCHAR)Target;
348  LunExtension->Lun = LunInfo->Lun = (UCHAR)Lun;
349 
350  /* Set flag to prevent race conditions */
351  LunExtension->Flags |= SCSI_PORT_SCAN_IN_PROGRESS;
352 
353  /* Zero LU extension contents */
354  if (DeviceExtension->LunExtensionSize)
355  {
356  RtlZeroMemory(LunExtension + 1,
357  DeviceExtension->LunExtensionSize);
358  }
359 
360  /* Finally send the inquiry command */
361  Status = SpiSendInquiry(DeviceExtension->DeviceObject, LunInfo);
362 
363  if (NT_SUCCESS(Status))
364  {
365  /* Let's see if we really found a device */
366  PINQUIRYDATA InquiryData = (PINQUIRYDATA)LunInfo->InquiryData;
367 
368  /* Check if this device is unsupported */
370  {
371  DeviceExtension->LunExtensionList[Hint] =
372  DeviceExtension->LunExtensionList[Hint]->Next;
373 
374  continue;
375  }
376 
377  /* Clear the "in scan" flag */
378  LunExtension->Flags &= ~SCSI_PORT_SCAN_IN_PROGRESS;
379 
380  DPRINT("SpiScanAdapter(): Found device of type %d at bus %d tid %d lun %d\n",
381  InquiryData->DeviceType, Bus, Target, Lun);
382 
383  /*
384  * Cache the inquiry data into the LUN extension (or alternatively
385  * we could save a pointer to LunInfo within the LunExtension?)
386  */
387  RtlCopyMemory(&LunExtension->InquiryData,
388  InquiryData,
390 
391  /* Add this info to the linked list */
392  LunInfo->Next = NULL;
393  if (LastLunInfo)
394  LastLunInfo->Next = LunInfo;
395  else
396  BusScanInfo->LunInfo = LunInfo;
397 
398  /* Store the last LUN info */
399  LastLunInfo = LunInfo;
400 
401  /* Store DeviceObject */
402  LunInfo->DeviceObject = DeviceExtension->DeviceObject;
403 
404  /* Allocate another buffer */
406  if (!LunInfo)
407  {
408  DPRINT1("Out of resources!\n");
409  break;
410  }
411 
412  RtlZeroMemory(LunInfo, sizeof(SCSI_LUN_INFO));
413 
414  /* Create a new LU extension */
415  LunExtension = SpiAllocateLunExtension(DeviceExtension);
416 
417  DevicesFound++;
418  }
419  else
420  {
421  /* Remove this LUN from the list */
422  DeviceExtension->LunExtensionList[Hint] =
423  DeviceExtension->LunExtensionList[Hint]->Next;
424 
425  /* Decide whether we are continuing or not */
427  continue;
428  else
429  break;
430  }
431  }
432  }
433 
434  /* Free allocated buffers */
435  if (LunExtension)
436  ExFreePoolWithTag(LunExtension, TAG_SCSIPORT);
437 
438  if (LunInfo)
440 
441  /* Sum what we found */
442  BusScanInfo->LogicalUnitsCount += (UCHAR)DevicesFound;
443  DPRINT(" Found %d devices on bus %d\n", DevicesFound, Bus);
444  }
445 
446  DPRINT("SpiScanAdapter() done\n");
447 }
PSCSI_LUN_INFO LunInfo
Definition: scsiport.h:172
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1310
#define TRUE
Definition: types.h:120
#define SCSI_MAXIMUM_LOGICAL_UNITS
Definition: srb.h:21
LONG NTSTATUS
Definition: precomp.h:26
#define TAG_SCSIPORT
Definition: scsiport.h:20
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
PSCSI_PORT_LUN_EXTENSION SpiAllocateLunExtension(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
Definition: pdo.c:16
#define SCSI_PORT_SCAN_IN_PROGRESS
Definition: scsiport.h:50
PVOID DeviceObject
Definition: scsiport.h:162
struct _INQUIRYDATA * PINQUIRYDATA
#define LUS_NUMBER
Definition: scsiport.h:23
struct _SCSI_PORT_LUN_EXTENSION * Next
Definition: scsiport.h:126
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define INQUIRYDATABUFFERSIZE
Definition: cdrw_hw.h:1113
void DPRINT(...)
Definition: polytest.cpp:61
UCHAR DeviceTypeQualifier
Definition: cdrw_hw.h:1117
UCHAR InquiryData[INQUIRYDATABUFFERSIZE]
Definition: scsiport.h:164
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
UCHAR PathId
Definition: scsiport.h:158
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1088
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
Status
Definition: gdiplustypes.h:24
#define DEVICE_QUALIFIER_NOT_SUPPORTED
Definition: cdrw_hw.h:1155
UCHAR DeviceType
Definition: cdrw_hw.h:1116
INQUIRYDATA InquiryData
Definition: scsiport.h:131
UCHAR TargetId
Definition: scsiport.h:159
UCHAR LogicalUnitsCount
Definition: scsiport.h:170
struct _SCSI_LUN_INFO * Next
Definition: scsiport.h:163
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _SCSI_BUS_SCAN_INFO SCSI_BUS_SCAN_INFO
static NTSTATUS SpiSendInquiry(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PSCSI_LUN_INFO LunInfo)
Definition: fdo.c:17

Variable Documentation

◆ ScsiPortDispatchScsi

DRIVER_DISPATCH ScsiPortDispatchScsi

Definition at line 370 of file scsiport.h.

Referenced by ScsiPortInitialize().

◆ ScsiPortDpcForIsr

IO_DPC_ROUTINE ScsiPortDpcForIsr

Definition at line 369 of file scsiport.h.

Referenced by CallHWInitialize(), ScsiPortInitialize(), and SpiMiniportTimerDpc().

◆ ScsiPortIsr

KSERVICE_ROUTINE ScsiPortIsr

Definition at line 377 of file scsiport.h.

Referenced by CallHWInitialize().

◆ ScsiPortStartIo

DRIVER_STARTIO ScsiPortStartIo

Definition at line 372 of file scsiport.h.

Referenced by ScsiPortInitialize().

◆ ScsiPortStartPacket

KSYNCHRONIZE_ROUTINE ScsiPortStartPacket