ReactOS 0.4.16-dev-340-g0540c21
scsiport.h File Reference
#include <ntifs.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  _STORAGE_ADAPTER_DESCRIPTOR_WIN8
 
struct  _CONFIGURATION_INFO
 
struct  _SCSI_PORT_DEVICE_BASE
 
struct  _SCSI_SG_ADDRESS
 
struct  _SCSI_REQUEST_BLOCK_INFO
 
struct  _SCSI_PORT_COMMON_EXTENSION
 
struct  _SCSI_PORT_LUN_EXTENSION
 
struct  _SCSI_BUS_INFO
 
struct  _SCSI_PORT_INTERRUPT_DATA
 
struct  _SCSI_PORT_SAVE_INTERRUPT
 
struct  _SCSI_PORT_DEVICE_EXTENSION
 
struct  _RESETBUS_PARAMS
 
struct  _SCSIPORT_DRIVER_EXTENSION
 

Macros

#define TAG_SCSIPORT   'ISCS'
 
#define LUS_NUMBER   8
 
#define MAX_SG_LIST   17
 
#define SCSI_PORT_DEVICE_BUSY   0x00001
 
#define SCSI_PORT_LU_ACTIVE   0x00002
 
#define SCSI_PORT_NOTIFICATION_NEEDED   0x00004
 
#define SCSI_PORT_NEXT_REQUEST_READY   0x00008
 
#define SCSI_PORT_FLUSH_ADAPTERS   0x00010
 
#define SCSI_PORT_MAP_TRANSFER   0x00020
 
#define SCSI_PORT_RESET   0x00080
 
#define SCSI_PORT_RESET_REQUEST   0x00100
 
#define SCSI_PORT_RESET_REPORTED   0x00200
 
#define SCSI_PORT_REQUEST_PENDING   0x00800
 
#define SCSI_PORT_DISCONNECT_ALLOWED   0x01000
 
#define SCSI_PORT_DISABLE_INT_REQUESET   0x02000
 
#define SCSI_PORT_DISABLE_INTERRUPTS   0x04000
 
#define SCSI_PORT_ENABLE_INT_REQUEST   0x08000
 
#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
 
#define ALIGNAS_PTR   DECLSPEC_ALIGN(4)
 

Typedefs

typedef struct _STORAGE_ADAPTER_DESCRIPTOR_WIN8 STORAGE_ADAPTER_DESCRIPTOR_WIN8
 
typedef struct _STORAGE_ADAPTER_DESCRIPTOR_WIN8PSTORAGE_ADAPTER_DESCRIPTOR_WIN8
 
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_COMMON_EXTENSION SCSI_PORT_COMMON_EXTENSION
 
typedef struct _SCSI_PORT_COMMON_EXTENSIONPSCSI_PORT_COMMON_EXTENSION
 
typedef struct _SCSI_PORT_LUN_EXTENSION SCSI_PORT_LUN_EXTENSION
 
typedef struct _SCSI_PORT_LUN_EXTENSIONPSCSI_PORT_LUN_EXTENSION
 
typedef struct _SCSI_BUS_INFO SCSI_BUS_INFO
 
typedef struct _SCSI_BUS_INFOPSCSI_BUS_INFO
 
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
 
typedef struct _SCSIPORT_DRIVER_EXTENSION SCSI_PORT_DRIVER_EXTENSION
 
typedef struct _SCSIPORT_DRIVER_EXTENSIONPSCSI_PORT_DRIVER_EXTENSION
 

Enumerations

enum  _SCSI_PORT_TIMER_STATES { IDETimerIdle , IDETimerCmdWait , IDETimerResetWaitForBusyNegate , IDETimerResetWaitForDrdyAssert }
 

Functions

FORCEINLINE BOOLEAN VerifyIrpOutBufferSize (_In_ PIRP Irp, _In_ SIZE_T Size)
 
FORCEINLINE BOOLEAN VerifyIrpInBufferSize (_In_ PIRP Irp, _In_ SIZE_T Size)
 
NTSTATUS NTAPI ScsiPortDeviceControl (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
VOID FdoScanAdapter (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 
NTSTATUS FdoCallHWInitialize (_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.
 
NTSTATUS FdoRemoveAdapter (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 
NTSTATUS FdoStartAdapter (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 
NTSTATUS FdoDispatchPnp (_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
 
PDEVICE_OBJECT PdoCreateLunDevice (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 
PSCSI_PORT_LUN_EXTENSION GetLunByPath (_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_ PSCSI_PORT_LUN_EXTENSION LunExtension, _In_ UCHAR QueueTag)
 
NTSTATUS PdoDispatchPnp (_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
 
VOID SpiInitOpenKeys (_Inout_ PCONFIGURATION_INFO ConfigInfo, _In_ PSCSI_PORT_DRIVER_EXTENSION DriverExtension)
 
NTSTATUS RegistryInitAdapterKey (_Inout_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 
NTSTATUS RegistryInitLunKey (_Inout_ PSCSI_PORT_LUN_EXTENSION LunExtension)
 
VOID SpiGetNextRequestFromLun (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _Inout_ PSCSI_PORT_LUN_EXTENSION LunExtension, _Inout_opt_ PKIRQL OldIrql)
 
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

DRIVER_DISPATCH ScsiPortDispatchPower
 
IO_DPC_ROUTINE ScsiPortDpcForIsr
 
DRIVER_DISPATCH ScsiPortDispatchScsi
 
KSYNCHRONIZE_ROUTINE ScsiPortStartPacket
 
DRIVER_STARTIO ScsiPortStartIo
 
KSERVICE_ROUTINE ScsiPortIsr
 

Macro Definition Documentation

◆ ALIGNAS_PTR

#define ALIGNAS_PTR   DECLSPEC_ALIGN(4)

Definition at line 223 of file scsiport.h.

◆ LUNEX_BUSY

#define LUNEX_BUSY   0x0008

Definition at line 48 of file scsiport.h.

◆ LUNEX_FROZEN_QUEUE

#define LUNEX_FROZEN_QUEUE   0x0001

Definition at line 46 of file scsiport.h.

◆ LUNEX_FULL_QUEUE

#define LUNEX_FULL_QUEUE   0x0010

Definition at line 49 of file scsiport.h.

◆ LUNEX_NEED_REQUEST_SENSE

#define LUNEX_NEED_REQUEST_SENSE   0x0004

Definition at line 47 of file scsiport.h.

◆ LUNEX_REQUEST_PENDING

#define LUNEX_REQUEST_PENDING   0x0020

Definition at line 50 of file scsiport.h.

◆ LUS_NUMBER

#define LUS_NUMBER   8

Definition at line 24 of file scsiport.h.

◆ MAX_SG_LIST

#define MAX_SG_LIST   17

Definition at line 26 of file scsiport.h.

◆ SCSI_PORT_DEVICE_BUSY

#define SCSI_PORT_DEVICE_BUSY   0x00001

Definition at line 29 of file scsiport.h.

◆ SCSI_PORT_DISABLE_INT_REQUESET

#define SCSI_PORT_DISABLE_INT_REQUESET   0x02000

Definition at line 40 of file scsiport.h.

◆ SCSI_PORT_DISABLE_INTERRUPTS

#define SCSI_PORT_DISABLE_INTERRUPTS   0x04000

Definition at line 41 of file scsiport.h.

◆ SCSI_PORT_DISCONNECT_ALLOWED

#define SCSI_PORT_DISCONNECT_ALLOWED   0x01000

Definition at line 39 of file scsiport.h.

◆ SCSI_PORT_ENABLE_INT_REQUEST

#define SCSI_PORT_ENABLE_INT_REQUEST   0x08000

Definition at line 42 of file scsiport.h.

◆ SCSI_PORT_FLUSH_ADAPTERS

#define SCSI_PORT_FLUSH_ADAPTERS   0x00010

Definition at line 33 of file scsiport.h.

◆ SCSI_PORT_LU_ACTIVE

#define SCSI_PORT_LU_ACTIVE   0x00002

Definition at line 30 of file scsiport.h.

◆ SCSI_PORT_MAP_TRANSFER

#define SCSI_PORT_MAP_TRANSFER   0x00020

Definition at line 34 of file scsiport.h.

◆ SCSI_PORT_NEXT_REQUEST_READY

#define SCSI_PORT_NEXT_REQUEST_READY   0x00008

Definition at line 32 of file scsiport.h.

◆ SCSI_PORT_NOTIFICATION_NEEDED

#define SCSI_PORT_NOTIFICATION_NEEDED   0x00004

Definition at line 31 of file scsiport.h.

◆ SCSI_PORT_REQUEST_PENDING

#define SCSI_PORT_REQUEST_PENDING   0x00800

Definition at line 38 of file scsiport.h.

◆ SCSI_PORT_RESET

#define SCSI_PORT_RESET   0x00080

Definition at line 35 of file scsiport.h.

◆ SCSI_PORT_RESET_REPORTED

#define SCSI_PORT_RESET_REPORTED   0x00200

Definition at line 37 of file scsiport.h.

◆ SCSI_PORT_RESET_REQUEST

#define SCSI_PORT_RESET_REQUEST   0x00100

Definition at line 36 of file scsiport.h.

◆ SCSI_PORT_SCAN_IN_PROGRESS

#define SCSI_PORT_SCAN_IN_PROGRESS   0x8000

Definition at line 51 of file scsiport.h.

◆ SCSI_PORT_TIMER_NEEDED

#define SCSI_PORT_TIMER_NEEDED   0x10000

Definition at line 43 of file scsiport.h.

◆ TAG_SCSIPORT

#define TAG_SCSIPORT   'ISCS'

Definition at line 21 of file scsiport.h.

Typedef Documentation

◆ CONFIGURATION_INFO

◆ PCONFIGURATION_INFO

◆ PRESETBUS_PARAMS

◆ PSCSI_BUS_INFO

◆ PSCSI_PORT_COMMON_EXTENSION

◆ PSCSI_PORT_DEVICE_BASE

◆ PSCSI_PORT_DEVICE_EXTENSION

◆ PSCSI_PORT_DRIVER_EXTENSION

◆ PSCSI_PORT_INTERRUPT_DATA

◆ PSCSI_PORT_LUN_EXTENSION

◆ PSCSI_PORT_SAVE_INTERRUPT

◆ PSCSI_REQUEST_BLOCK_INFO

◆ PSCSI_SG_ADDRESS

◆ PSTORAGE_ADAPTER_DESCRIPTOR_WIN8

◆ RESETBUS_PARAMS

◆ SCSI_BUS_INFO

◆ SCSI_PORT_COMMON_EXTENSION

◆ SCSI_PORT_DEVICE_BASE

◆ SCSI_PORT_DEVICE_EXTENSION

◆ SCSI_PORT_DRIVER_EXTENSION

◆ SCSI_PORT_INTERRUPT_DATA

◆ SCSI_PORT_LUN_EXTENSION

◆ SCSI_PORT_SAVE_INTERRUPT

◆ SCSI_PORT_TIMER_STATES

◆ SCSI_REQUEST_BLOCK_INFO

◆ SCSI_SG_ADDRESS

◆ STORAGE_ADAPTER_DESCRIPTOR_WIN8

Enumeration Type Documentation

◆ _SCSI_PORT_TIMER_STATES

Enumerator
IDETimerIdle 
IDETimerCmdWait 
IDETimerResetWaitForBusyNegate 
IDETimerResetWaitForDrdyAssert 

Definition at line 71 of file scsiport.h.

72{
enum _SCSI_PORT_TIMER_STATES SCSI_PORT_TIMER_STATES
@ IDETimerCmdWait
Definition: scsiport.h:74
@ IDETimerResetWaitForDrdyAssert
Definition: scsiport.h:76
@ IDETimerIdle
Definition: scsiport.h:73
@ IDETimerResetWaitForBusyNegate
Definition: scsiport.h:75

Function Documentation

◆ FdoCallHWInitialize()

NTSTATUS FdoCallHWInitialize ( _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 366 of file fdo.c.

368{
369 PPORT_CONFIGURATION_INFORMATION PortConfig = DeviceExtension->PortConfig;
372
373 /* Deal with interrupts */
374 if (DeviceExtension->HwInterrupt == NULL ||
375 (PortConfig->BusInterruptLevel == 0 && PortConfig->BusInterruptVector == 0))
376 {
377 /* No interrupts */
378 DeviceExtension->InterruptCount = 0;
379
380 DPRINT1("Interrupt Count: 0\n");
381
383
384 /* This code path will ALWAYS crash so stop it now */
385 __debugbreak();
386 }
387 else
388 {
389 BOOLEAN InterruptShareable;
391 ULONG InterruptVector[2], i, MappedIrq[2];
392 KIRQL Dirql[2], MaxDirql;
394
395 DeviceExtension->InterruptLevel[0] = PortConfig->BusInterruptLevel;
396 DeviceExtension->InterruptLevel[1] = PortConfig->BusInterruptLevel2;
397
398 InterruptVector[0] = PortConfig->BusInterruptVector;
399 InterruptVector[1] = PortConfig->BusInterruptVector2;
400
401 InterruptMode[0] = PortConfig->InterruptMode;
402 InterruptMode[1] = PortConfig->InterruptMode2;
403
404 DeviceExtension->InterruptCount =
405 (PortConfig->BusInterruptLevel2 != 0 ||
406 PortConfig->BusInterruptVector2 != 0) ? 2 : 1;
407
408 for (i = 0; i < DeviceExtension->InterruptCount; i++)
409 {
410 /* Register an interrupt handler for this device */
411 MappedIrq[i] = HalGetInterruptVector(
412 PortConfig->AdapterInterfaceType, PortConfig->SystemIoBusNumber,
413 DeviceExtension->InterruptLevel[i], InterruptVector[i], &Dirql[i],
414 &Affinity[i]);
415 }
416
417 if (DeviceExtension->InterruptCount == 1 || Dirql[0] > Dirql[1])
418 {
419 MaxDirql = Dirql[0];
420 }
421 else
422 {
423 MaxDirql = Dirql[1];
424 }
425
426 for (i = 0; i < DeviceExtension->InterruptCount; i++)
427 {
428 /* Determine IRQ sharability as usual */
429 if (PortConfig->AdapterInterfaceType == MicroChannel ||
431 {
432 InterruptShareable = TRUE;
433 }
434 else
435 {
436 InterruptShareable = FALSE;
437 }
438
439 Status = IoConnectInterrupt(&DeviceExtension->Interrupt[i],
441 DeviceExtension,
442 &DeviceExtension->IrqLock,
443 MappedIrq[i], Dirql[i],
444 MaxDirql,
446 InterruptShareable,
447 Affinity[i],
448 FALSE);
449
450 if (!(NT_SUCCESS(Status)))
451 {
452 DPRINT1("Could not connect interrupt %d\n", InterruptVector[i]);
453 DeviceExtension->Interrupt[i] = NULL;
454 return Status;
455 }
456 }
457 }
458
459 /* Save IoAddress (from access ranges) */
460 if (PortConfig->NumberOfAccessRanges != 0)
461 {
462 DeviceExtension->IoAddress = ((*(PortConfig->AccessRanges))[0]).RangeStart.LowPart;
463
464 DPRINT("Io Address %x\n", DeviceExtension->IoAddress);
465 }
466
467 /* Set flag that it's allowed to disconnect during this command */
468 DeviceExtension->Flags |= SCSI_PORT_DISCONNECT_ALLOWED;
469
470 /* Initialize counter of active requests (-1 means there are none) */
471 DeviceExtension->ActiveRequestCounter = -1;
472
473 /* Analyze what we have about DMA */
474 if (DeviceExtension->AdapterObject != NULL && PortConfig->Master &&
475 PortConfig->NeedPhysicalAddresses)
476 {
477 DeviceExtension->MapRegisters = TRUE;
478 }
479 else
480 {
481 DeviceExtension->MapRegisters = FALSE;
482 }
483
484 /* Call HwInitialize at DISPATCH_LEVEL */
486
488 DeviceExtension->Interrupt[0], DeviceExtension->HwInitialize,
489 DeviceExtension->MiniPortDeviceExtension))
490 {
491 DPRINT1("HwInitialize() failed!\n");
494 }
495
496 /* Check if a notification is needed */
497 if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
498 {
499 /* Call DPC right away, because we're already at DISPATCH_LEVEL */
500 ScsiPortDpcForIsr(NULL, DeviceExtension->Common.DeviceObject, NULL, NULL);
501 }
502
503 /* Lower irql back to what it was */
505
506 return STATUS_SUCCESS;
507}
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
ULONG_PTR KAFFINITY
Definition: compat.h:85
NTHALAPI ULONG NTAPI HalGetInterruptVector(INTERFACE_TYPE, ULONG, ULONG, ULONG, PKIRQL, PKAFFINITY)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
Status
Definition: gdiplustypes.h:25
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
@ MicroChannel
Definition: hwresource.cpp:140
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
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:23
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:237
#define STATUS_ADAPTER_HARDWARE_ERROR
Definition: ntstatus.h:430
#define SCSI_PORT_DISCONNECT_ALLOWED
Definition: scsiport.h:39
#define SCSI_PORT_NOTIFICATION_NEEDED
Definition: scsiport.h:31
KSERVICE_ROUTINE ScsiPortIsr
Definition: scsiport.h:459
IO_DPC_ROUTINE ScsiPortDpcForIsr
Definition: scsiport.h:451
@ LevelSensitive
Definition: miniport.h:80
enum _KINTERRUPT_MODE KINTERRUPT_MODE
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
ACCESS_RANGE(* AccessRanges)[]
Definition: srb.h:74
KINTERRUPT_MODE InterruptMode
Definition: srb.h:64
INTERFACE_TYPE AdapterInterfaceType
Definition: srb.h:59
KINTERRUPT_MODE InterruptMode2
Definition: srb.h:101
uint32_t ULONG
Definition: typedefs.h:59
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:174
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:806
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by ScsiPortInitialize().

◆ FdoDispatchPnp()

NTSTATUS FdoDispatchPnp ( _In_ PDEVICE_OBJECT  DeviceObject,
_Inout_ PIRP  Irp 
)

Definition at line 758 of file fdo.c.

761{
763 PSCSI_PORT_DEVICE_EXTENSION portExt = DeviceObject->DeviceExtension;
765
766 ASSERT(portExt->Common.IsFDO);
767
768 DPRINT("FDO PnP request %s\n", GetIRPMinorFunctionString(ioStack->MinorFunction));
769
770 switch (ioStack->MinorFunction)
771 {
773 {
774 // as we don't support PnP yet, this is a no-op for us
775 // (FdoStartAdapter is being called during initialization for legacy miniports)
777 // status = FdoStartAdapter(DeviceExtension);
778 break;
779 }
781 {
782 return FdoHandleDeviceRelations(portExt, Irp);
783 }
784 case IRP_MN_QUERY_ID:
785 {
786 if (ioStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
787 {
788 Irp->IoStatus.Information = 0;
789 IoForwardIrpSynchronously(portExt->Common.LowerDevice, Irp);
790 status = FdoHandleQueryCompatibleId((PZZWSTR*)&Irp->IoStatus.Information);
791 break;
792 }
793 // otherwise fall through the default case
794 }
795 default:
796 {
797 // forward irp to next device object
799 return IoCallDriver(portExt->Common.LowerDevice, Irp);
800 }
801 }
802
803 if (status != STATUS_PENDING)
804 {
805 Irp->IoStatus.Status = status;
807 }
808
809 return status;
810}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_PENDING
Definition: d3dkmdt.h:43
FORCEINLINE PCHAR GetIRPMinorFunctionString(UCHAR MinorFunction)
Definition: driverdbg.h:13
#define ASSERT(a)
Definition: mode.c:44
_NullNull_terminated_ WCHAR * PZZWSTR
Definition: ntbasedef.h:428
#define IoCopyCurrentIrpStackLocationToNext(Irp)
Definition: ntifs_ex.h:413
#define IoCompleteRequest
Definition: irp.c:1240
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1625
#define IoCallDriver
Definition: irp.c:1225
static NTSTATUS FdoHandleDeviceRelations(_In_ PSCSI_PORT_DEVICE_EXTENSION PortExtension, _Inout_ PIRP Irp)
Definition: fdo.c:655
static NTSTATUS FdoHandleQueryCompatibleId(_Inout_ PZZWSTR *PwIds)
Definition: fdo.c:714
union _IO_STACK_LOCATION::@1581 Parameters
struct _IO_STACK_LOCATION::@3980::@4011 QueryId
Definition: ps.c:97
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_START_DEVICE
#define IRP_MN_QUERY_ID
#define IRP_MN_QUERY_DEVICE_RELATIONS
@ BusQueryCompatibleIDs
Definition: iotypes.h:2938

Referenced by ScsiPortDispatchPnp().

◆ FdoRemoveAdapter()

NTSTATUS FdoRemoveAdapter ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension)

Definition at line 510 of file fdo.c.

512{
513 IoStopTimer(DeviceExtension->Common.DeviceObject);
514
515 // release device interface
516 if (DeviceExtension->InterfaceName.Buffer)
517 {
518 IoSetDeviceInterfaceState(&DeviceExtension->InterfaceName, FALSE);
519
520 RtlFreeUnicodeString(&DeviceExtension->InterfaceName);
521 RtlInitUnicodeString(&DeviceExtension->InterfaceName, NULL);
522 }
523
524 // remove the dos device link
525 WCHAR dosNameBuffer[12];
526 UNICODE_STRING dosDeviceName;
527
528 swprintf(dosNameBuffer, L"\\??\\Scsi%lu:", DeviceExtension->PortNumber);
529 RtlInitUnicodeString(&dosDeviceName, dosNameBuffer);
530
531 IoDeleteSymbolicLink(&dosDeviceName); // don't check the result
532
533 // decrease the port count
534 if (DeviceExtension->DeviceStarted)
535 {
537 sysConfig->ScsiPortCount--;
538 }
539
540 // disconnect the interrupts
541 while (DeviceExtension->InterruptCount)
542 {
543 if (DeviceExtension->Interrupt[--DeviceExtension->InterruptCount])
544 IoDisconnectInterrupt(DeviceExtension->Interrupt[DeviceExtension->InterruptCount]);
545 }
546
547 // FIXME: delete LUNs
548 if (DeviceExtension->Buses)
549 {
550 for (UINT8 pathId = 0; pathId < DeviceExtension->NumberOfBuses; pathId++)
551 {
552 PSCSI_BUS_INFO bus = &DeviceExtension->Buses[pathId];
553 if (bus->RegistryMapKey)
554 {
555 ZwDeleteKey(bus->RegistryMapKey);
557 bus->RegistryMapKey = NULL;
558 }
559 }
560
561 ExFreePoolWithTag(DeviceExtension->Buses, TAG_SCSIPORT);
562 }
563
564 /* Free PortConfig */
565 if (DeviceExtension->PortConfig)
566 {
567 ExFreePoolWithTag(DeviceExtension->PortConfig, TAG_SCSIPORT);
568 }
569
570 /* Free common buffer (if it exists) */
571 if (DeviceExtension->SrbExtensionBuffer != NULL && DeviceExtension->CommonBufferLength != 0)
572 {
573 if (!DeviceExtension->AdapterObject)
574 {
575 ExFreePoolWithTag(DeviceExtension->SrbExtensionBuffer, TAG_SCSIPORT);
576 }
577 else
578 {
579 HalFreeCommonBuffer(DeviceExtension->AdapterObject,
580 DeviceExtension->CommonBufferLength,
581 DeviceExtension->PhysicalAddress,
582 DeviceExtension->SrbExtensionBuffer,
583 FALSE);
584 }
585 }
586
587 /* Free SRB info */
588 if (DeviceExtension->SrbInfo != NULL)
589 ExFreePoolWithTag(DeviceExtension->SrbInfo, TAG_SCSIPORT);
590
591 /* Unmap mapped addresses */
592 while (DeviceExtension->MappedAddressList != NULL)
593 {
594 MmUnmapIoSpace(DeviceExtension->MappedAddressList->MappedAddress,
595 DeviceExtension->MappedAddressList->NumberOfBytes);
596
597 PVOID ptr = DeviceExtension->MappedAddressList;
598 DeviceExtension->MappedAddressList = DeviceExtension->MappedAddressList->NextMappedAddress;
599
601 }
602
603 IoDeleteDevice(DeviceExtension->Common.DeviceObject);
604
605 return STATUS_SUCCESS;
606}
unsigned char UINT8
#define swprintf
Definition: precomp.h:40
VOID NTAPI HalFreeCommonBuffer(IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PHYSICAL_ADDRESS LogicalAddress, IN PVOID VirtualAddress, IN BOOLEAN CacheEnabled)
Definition: dma.c:61
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Returns a pointer to the I/O manager's global configuration information structure.
Definition: iorsrce.c:998
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
VOID NTAPI IoStopTimer(PDEVICE_OBJECT DeviceObject)
Definition: iotimer.c:166
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static PVOID ptr
Definition: dispmode.c:27
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:142
#define L(x)
Definition: ntvdm.h:50
#define TAG_SCSIPORT
Definition: scsiport.h:21
HANDLE RegistryMapKey
Definition: scsiport.h:191
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by ScsiPortInitialize().

◆ FdoScanAdapter()

VOID FdoScanAdapter ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension)

Definition at line 222 of file fdo.c.

224{
226 UINT32 totalLUNs = PortExtension->TotalLUCount;
227
228 DPRINT("FdoScanAdapter() called\n");
229
230 /* Scan all buses */
231 for (UINT8 pathId = 0; pathId < PortExtension->NumberOfBuses; pathId++)
232 {
233 DPRINT(" Scanning bus/pathID %u\n", pathId);
234
235 /* Get pointer to the scan information */
236 PSCSI_BUS_INFO currentBus = &PortExtension->Buses[pathId];
237
238 /* And send INQUIRY to every target */
239 for (UINT8 targetId = 0;
240 targetId < PortExtension->PortConfig->MaximumNumberOfTargets;
241 targetId++)
242 {
243 BOOLEAN targetFound = FALSE;
244
245 /* TODO: Support scan bottom-up */
246
247 /* Skip if it's the same address */
248 if (targetId == currentBus->BusIdentifier)
249 continue;
250
251 /* Scan all logical units */
252 for (UINT8 lun = 0; lun < PortExtension->MaxLunCount; lun++)
253 {
255
256 /* Skip invalid lun values */
257 if (lun >= PortExtension->PortConfig->MaximumNumberOfLogicalUnits)
258 continue;
259
260 // try to find an existing device
261 lunExt = GetLunByPath(PortExtension,
262 pathId,
263 targetId,
264 lun);
265
266 if (lunExt)
267 {
268 // check if the device still exists
270 if (!NT_SUCCESS(status))
271 {
272 // remove the device
274 __debugbreak();
275 }
276
278 {
279 // remove the device
281 __debugbreak();
282 }
283
284 /* Decide whether we are continuing or not */
286 continue;
287 else
288 break;
289 }
290
291 // create a new LUN device
292 PDEVICE_OBJECT lunPDO = PdoCreateLunDevice(PortExtension);
293 if (!lunPDO)
294 {
295 continue;
296 }
297
298 lunExt = lunPDO->DeviceExtension;
299
300 lunExt->PathId = pathId;
301 lunExt->TargetId = targetId;
302 lunExt->Lun = lun;
303
304 DPRINT("Add PDO to list: PDO: %p, FDOExt: %p, PDOExt: %p\n", lunPDO, PortExtension, lunExt);
305
306 /* Set flag to prevent race conditions */
308
309 /* Finally send the inquiry command */
310 status = FdoSendInquiry(lunPDO);
311
312 if (NT_SUCCESS(status))
313 {
314 /* Let's see if we really found a device */
315 PINQUIRYDATA InquiryData = &lunExt->InquiryData;
316
317 /* Check if this device is unsupported */
319 {
320 IoDeleteDevice(lunPDO);
321 continue;
322 }
323
324 /* Clear the "in scan" flag */
325 lunExt->Flags &= ~SCSI_PORT_SCAN_IN_PROGRESS;
326
327 DPRINT1("Found device of type %d at controller %d bus %d tid %d lun %d, PDO: %p\n",
328 InquiryData->DeviceType, PortExtension->PortNumber, pathId, targetId, lun, lunPDO);
329
330 InsertTailList(&currentBus->LunsListHead, &lunExt->LunEntry);
331
332 totalLUNs++;
333 currentBus->LogicalUnitsCount++;
334 targetFound = TRUE;
335 }
336 else
337 {
338 /* Decide whether we are continuing or not */
340 continue;
341 else
342 break;
343 }
344 }
345
346 if (targetFound)
347 {
348 currentBus->TargetsCount++;
349 }
350 }
351 }
352
353 PortExtension->TotalLUCount = totalLUNs;
354}
unsigned int UINT32
#define DEVICE_QUALIFIER_NOT_SUPPORTED
Definition: cdrw_hw.h:1155
#define InsertTailList(ListHead, Entry)
#define SCSI_PORT_SCAN_IN_PROGRESS
Definition: scsiport.h:51
static NTSTATUS FdoSendInquiry(_In_ PDEVICE_OBJECT DeviceObject)
Definition: fdo.c:18
PDEVICE_OBJECT PdoCreateLunDevice(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
Definition: pdo.c:18
PSCSI_PORT_LUN_EXTENSION GetLunByPath(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _In_ UCHAR PathId, _In_ UCHAR TargetId, _In_ UCHAR Lun)
Definition: pdo.c:68
PVOID DeviceExtension
Definition: env_spec_w32.h:418
UCHAR DeviceType
Definition: cdrw_hw.h:1116
UCHAR DeviceTypeQualifier
Definition: cdrw_hw.h:1117
UCHAR BusIdentifier
Definition: scsiport.h:190
UCHAR TargetsCount
Definition: scsiport.h:189
UCHAR LogicalUnitsCount
Definition: scsiport.h:188
LIST_ENTRY LunsListHead
Definition: scsiport.h:187
PDEVICE_OBJECT DeviceObject
Definition: scsiport.h:138
SCSI_PORT_COMMON_EXTENSION Common
Definition: scsiport.h:146
INQUIRYDATA InquiryData
Definition: scsiport.h:158
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138

Referenced by FdoHandleDeviceRelations(), and ScsiPortInitialize().

◆ FdoStartAdapter()

NTSTATUS FdoStartAdapter ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension)

Definition at line 609 of file fdo.c.

611{
612 WCHAR dosNameBuffer[12];
613 UNICODE_STRING dosDeviceName;
615
616 // Start our timer
617 IoStartTimer(PortExtension->Common.DeviceObject);
618
619 // Create the dos device link
620 swprintf(dosNameBuffer, L"\\??\\Scsi%u:", PortExtension->PortNumber);
621 RtlInitUnicodeString(&dosDeviceName, dosNameBuffer);
622 status = IoCreateSymbolicLink(&dosDeviceName, &PortExtension->DeviceName);
623 if (!NT_SUCCESS(status))
624 {
625 return status;
626 }
627
628 // start building a device map
629 RegistryInitAdapterKey(PortExtension);
630
631 // increase the port count
633 sysConfig->ScsiPortCount++;
634
635 // Register and enable the device interface
636 status = IoRegisterDeviceInterface(PortExtension->Common.DeviceObject,
637 &StoragePortClassGuid,
638 NULL,
639 &PortExtension->InterfaceName);
640 DPRINT("IoRegisterDeviceInterface status: %x, InterfaceName: %wZ\n",
641 status, &PortExtension->InterfaceName);
642
643 if (NT_SUCCESS(status))
644 {
645 IoSetDeviceInterfaceState(&PortExtension->InterfaceName, TRUE);
646 }
647
648 PortExtension->DeviceStarted = TRUE;
649
650 return STATUS_SUCCESS;
651}
NTSTATUS RegistryInitAdapterKey(_Inout_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
Definition: registry.c:127
VOID NTAPI IoStartTimer(IN PDEVICE_OBJECT DeviceObject)
Definition: iotimer.c:133
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955

Referenced by ScsiPortInitialize().

◆ GetLunByPath()

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

Definition at line 68 of file pdo.c.

73{
74 if (PathId >= DeviceExtension->NumberOfBuses)
75 {
76 DPRINT1("Invalid PathId: %u\n", PathId);
77 return NULL;
78 }
79
80 PSCSI_BUS_INFO bus = &DeviceExtension->Buses[PathId];
81
82 for (PLIST_ENTRY lunEntry = bus->LunsListHead.Flink;
83 lunEntry != &bus->LunsListHead;
84 lunEntry = lunEntry->Flink)
85 {
87 CONTAINING_RECORD(lunEntry, SCSI_PORT_LUN_EXTENSION, LunEntry);
88
89 if (lunExt->PathId == PathId &&
90 lunExt->TargetId == TargetId &&
91 lunExt->Lun == Lun)
92 {
93 return lunExt;
94 }
95 }
96
97 DPRINT("SCSI LUN (%u, %u, %u) was not found\n", PathId, TargetId, Lun);
98 return NULL;
99}
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1315
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1313
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1314
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by FdoScanAdapter(), ScsiPortGetLogicalUnit(), and ScsiPortNotification().

◆ PdoCreateLunDevice()

PDEVICE_OBJECT PdoCreateLunDevice ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension)

Definition at line 18 of file pdo.c.

20{
21 PSCSI_PORT_LUN_EXTENSION LunExtension;
22 PDEVICE_OBJECT LunPDO;
23
24 ULONG LunExtensionSize = DeviceExtension->LunExtensionSize + sizeof(SCSI_PORT_LUN_EXTENSION);
25
26 NTSTATUS Status = IoCreateDevice(DeviceExtension->Common.DeviceObject->DriverObject,
27 LunExtensionSize,
28 NULL,
31 FALSE,
32 &LunPDO);
33
34 if (!NT_SUCCESS(Status))
35 {
36 DPRINT1("Failed to create a Lun PDO, status: %x\n", Status);
37 return NULL;
38 }
39
40 LunExtension = LunPDO->DeviceExtension;
41
42 /* Zero everything */
43 RtlZeroMemory(LunExtension, LunExtensionSize);
44
45 LunExtension->Common.IsFDO = FALSE;
46 LunExtension->Common.DeviceObject = LunPDO;
47 LunExtension->Common.LowerDevice = DeviceExtension->Common.DeviceObject;
48
49 /* Initialize a list of requests */
50 InitializeListHead(&LunExtension->SrbInfo.Requests);
51
52 /* Initialize timeout counter */
53 LunExtension->RequestTimeout = -1;
54
55 /* Set maximum queue size */
56 LunExtension->MaxQueueCount = 256;
57
58 /* Initialize request queue */
60
61 LunPDO->Flags |= DO_DIRECT_IO;
62 LunPDO->Flags &= ~DO_DEVICE_INITIALIZING;
63
64 return LunPDO;
65}
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
VOID NTAPI KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
Definition: devqueue.c:22
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
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
#define FILE_DEVICE_DISK
Definition: winioctl.h:52
struct _SCSI_PORT_LUN_EXTENSION SCSI_PORT_LUN_EXTENSION
PDEVICE_OBJECT LowerDevice
Definition: scsiport.h:139
KDEVICE_QUEUE DeviceQueue
Definition: scsiport.h:160
SCSI_REQUEST_BLOCK_INFO SrbInfo
Definition: scsiport.h:174
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by FdoScanAdapter().

◆ PdoDispatchPnp()

NTSTATUS PdoDispatchPnp ( _In_ PDEVICE_OBJECT  DeviceObject,
_Inout_ PIRP  Irp 
)

Definition at line 554 of file pdo.c.

557{
559 PSCSI_PORT_LUN_EXTENSION lunExt = DeviceObject->DeviceExtension;
561
562 DPRINT("PDO PnP request %s\n", GetIRPMinorFunctionString(ioStack->MinorFunction));
563
564 ASSERT(!lunExt->Common.IsFDO);
565
566 switch (ioStack->MinorFunction)
567 {
569 {
570 RegistryInitLunKey(lunExt);
572 break;
573 }
579 {
581 break;
582 }
584 {
586 break;
587 }
589 {
591 break;
592 }
593 case IRP_MN_QUERY_ID:
594 {
595 DPRINT("IRP_MN_QUERY_ID IdType %s\n",
596 DbgGetDeviceIDString(ioStack->Parameters.QueryId.IdType));
597
598 if (ioStack->Parameters.QueryId.IdType == BusQueryDeviceID)
599 {
601 break;
602 }
603 else if (ioStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
604 {
606 break;
607 }
608 else if (ioStack->Parameters.QueryId.IdType == BusQueryInstanceID)
609 {
611 break;
612 }
613 else if (ioStack->Parameters.QueryId.IdType == BusQueryCompatibleIDs)
614 {
616 break;
617 }
618
619 // fallthrough
620 }
621 default:
622 {
623 // do nothing
624 status = Irp->IoStatus.Status;
625 }
626 }
627
628 if (status != STATUS_PENDING)
629 {
630 Irp->IoStatus.Status = status;
632 }
633
634 return status;
635}
PCHAR DbgGetDeviceIDString(BUS_QUERY_ID_TYPE Type)
Definition: driverdbg.h:93
NTSTATUS RegistryInitLunKey(_Inout_ PSCSI_PORT_LUN_EXTENSION LunExtension)
Definition: registry.c:359
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
static NTSTATUS PdoHandleDeviceRelations(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: pdo.c:524
static NTSTATUS PdoHandleQueryDeviceText(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: pdo.c:168
static NTSTATUS PdoHandleQueryHardwareId(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: pdo.c:346
static NTSTATUS PdoHandleQueryInstanceId(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: pdo.c:493
static NTSTATUS PdoHandleQueryCompatibleId(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: pdo.c:457
static NTSTATUS PdoHandleQueryDeviceId(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: pdo.c:263
#define IRP_MN_REMOVE_DEVICE
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_QUERY_DEVICE_TEXT
#define IRP_MN_QUERY_CAPABILITIES
@ BusQueryInstanceID
Definition: iotypes.h:2939
@ BusQueryDeviceID
Definition: iotypes.h:2936
@ BusQueryHardwareIDs
Definition: iotypes.h:2937
#define IRP_MN_QUERY_REMOVE_DEVICE

Referenced by ScsiPortDispatchPnp().

◆ RegistryInitAdapterKey()

NTSTATUS RegistryInitAdapterKey ( _Inout_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension)

Definition at line 127 of file registry.c.

129{
133 WCHAR NameBuffer[64];
134 HANDLE ScsiKey;
135 HANDLE ScsiPortKey = NULL;
136 HANDLE ScsiBusKey = NULL;
137 HANDLE ScsiInitiatorKey = NULL;
139 ULONG UlongData;
141
142 DPRINT("SpiBuildDeviceMap() called\n");
143
144 if (DeviceExtension == NULL)
145 {
146 DPRINT1("Invalid parameter\n");
148 }
149
150 /* Open or create the 'Scsi' subkey */
152 L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi");
154 &KeyName,
156 0,
157 NULL);
158 Status = ZwCreateKey(&ScsiKey,
161 0,
162 NULL,
164 NULL);
165 if (!NT_SUCCESS(Status))
166 {
167 DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
168 return Status;
169 }
170
171 /* Create new 'Scsi Port X' subkey */
172 DPRINT("Scsi Port %lu\n", DeviceExtension->PortNumber);
173
174 swprintf(NameBuffer,
175 L"Scsi Port %lu",
176 DeviceExtension->PortNumber);
177 RtlInitUnicodeString(&KeyName, NameBuffer);
179 Status = ZwCreateKey(&ScsiPortKey,
182 0,
183 NULL,
185 NULL);
186 ZwClose(ScsiKey);
187 if (!NT_SUCCESS(Status))
188 {
189 DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
190 return Status;
191 }
192
193 /*
194 * Create port-specific values
195 */
196
197 /* Set 'DMA Enabled' (REG_DWORD) value */
198 UlongData = (ULONG)!DeviceExtension->PortCapabilities.AdapterUsesPio;
199 DPRINT(" DMA Enabled = %s\n", UlongData ? "TRUE" : "FALSE");
200 RtlInitUnicodeString(&ValueName, L"DMA Enabled");
201 Status = ZwSetValueKey(ScsiPortKey,
202 &ValueName,
203 0,
204 REG_DWORD,
205 &UlongData,
206 sizeof(UlongData));
207 if (!NT_SUCCESS(Status))
208 {
209 DPRINT("ZwSetValueKey('DMA Enabled') failed (Status %lx)\n", Status);
210 ZwClose(ScsiPortKey);
211 return Status;
212 }
213
214 /* Set 'Driver' (REG_SZ) value */
215 PUNICODE_STRING driverNameU = &DeviceExtension->Common.DeviceObject->DriverObject
216 ->DriverExtension->ServiceKeyName;
217
219 driverNameU->Length + sizeof(UNICODE_NULL),
221 if (!driverName)
222 {
223 DPRINT("Failed to allocate driverName!\n");
224 ZwClose(ScsiPortKey);
226 }
227
228 RtlCopyMemory(driverName, driverNameU->Buffer, driverNameU->Length);
229 driverName[driverNameU->Length / sizeof(WCHAR)] = UNICODE_NULL;
230
232 Status = ZwSetValueKey(ScsiPortKey,
233 &ValueName,
234 0,
235 REG_SZ,
236 driverName,
237 driverNameU->Length + sizeof(UNICODE_NULL));
238
239 ExFreePoolWithTag(driverName, TAG_SCSIPORT);
240
241 if (!NT_SUCCESS(Status))
242 {
243 DPRINT("ZwSetValueKey('Driver') failed (Status %lx)\n", Status);
244 ZwClose(ScsiPortKey);
245 return Status;
246 }
247
248 /* Set 'Interrupt' (REG_DWORD) value (NT4 only) */
249 UlongData = (ULONG)DeviceExtension->PortConfig->BusInterruptLevel;
250 DPRINT(" Interrupt = %lu\n", UlongData);
251 RtlInitUnicodeString(&ValueName, L"Interrupt");
252 Status = ZwSetValueKey(ScsiPortKey,
253 &ValueName,
254 0,
255 REG_DWORD,
256 &UlongData,
257 sizeof(UlongData));
258 if (!NT_SUCCESS(Status))
259 {
260 DPRINT("ZwSetValueKey('Interrupt') failed (Status %lx)\n", Status);
261 ZwClose(ScsiPortKey);
262 return Status;
263 }
264
265 /* Set 'IOAddress' (REG_DWORD) value (NT4 only) */
266 UlongData = ScsiPortConvertPhysicalAddressToUlong((*DeviceExtension->PortConfig->AccessRanges)[0].RangeStart);
267 DPRINT(" IOAddress = %lx\n", UlongData);
268 RtlInitUnicodeString(&ValueName, L"IOAddress");
269 Status = ZwSetValueKey(ScsiPortKey,
270 &ValueName,
271 0,
272 REG_DWORD,
273 &UlongData,
274 sizeof(UlongData));
275 if (!NT_SUCCESS(Status))
276 {
277 DPRINT("ZwSetValueKey('IOAddress') failed (Status %lx)\n", Status);
278 ZwClose(ScsiPortKey);
279 return Status;
280 }
281
282 /* Enumerate buses */
283 for (BusNumber = 0; BusNumber < DeviceExtension->NumberOfBuses; BusNumber++)
284 {
285 /* Create 'Scsi Bus X' key */
286 DPRINT(" Scsi Bus %lu\n", BusNumber);
287 swprintf(NameBuffer,
288 L"Scsi Bus %lu",
289 BusNumber);
290 RtlInitUnicodeString(&KeyName, NameBuffer);
292 &KeyName,
294 ScsiPortKey,
295 NULL);
296 Status = ZwCreateKey(&ScsiBusKey,
299 0,
300 NULL,
302 NULL);
303 if (!NT_SUCCESS(Status))
304 {
305 DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
306 goto ByeBye;
307 }
308
309 /* Create 'Initiator Id X' key */
310 DPRINT(" Initiator Id %lu\n",
311 DeviceExtension->PortConfig->InitiatorBusId[BusNumber]);
312 swprintf(NameBuffer,
313 L"Initiator Id %lu",
314 (ULONG)(UCHAR)DeviceExtension->PortConfig->InitiatorBusId[BusNumber]);
315 RtlInitUnicodeString(&KeyName, NameBuffer);
317 &KeyName,
319 ScsiBusKey,
320 NULL);
321 Status = ZwCreateKey(&ScsiInitiatorKey,
324 0,
325 NULL,
327 NULL);
328 if (!NT_SUCCESS(Status))
329 {
330 DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
331 goto ByeBye;
332 }
333
334 /* FIXME: Are there any initiator values (??) */
335
336 ZwClose(ScsiInitiatorKey);
337 ScsiInitiatorKey = NULL;
338
339 DeviceExtension->Buses[BusNumber].RegistryMapKey = ScsiBusKey;
340 ScsiBusKey = NULL;
341 }
342
343ByeBye:
344 if (ScsiInitiatorKey != NULL)
345 ZwClose(ScsiInitiatorKey);
346
347 if (ScsiBusKey != NULL)
348 ZwClose(ScsiBusKey);
349
350 if (ScsiPortKey != NULL)
351 ZwClose(ScsiPortKey);
352
353 DPRINT("SpiBuildDeviceMap() done\n");
354
355 return Status;
356}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define ScsiPortConvertPhysicalAddressToUlong(Address)
Definition: srb.h:957
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define REG_SZ
Definition: layer.c:22
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define KEY_ALL_ACCESS
Definition: nt_native.h:1041
#define REG_OPTION_VOLATILE
Definition: nt_native.h:1060
#define UNICODE_NULL
#define REG_DWORD
Definition: sdbapi.c:596
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint16_t * PWCHAR
Definition: typedefs.h:56
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_In_opt_ PUNICODE_STRING _In_ PDRIVER_OBJECT _In_ PDEVICE_OBJECT _In_ INTERFACE_TYPE _In_ ULONG BusNumber
Definition: halfuncs.h:160
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by FdoStartAdapter().

◆ RegistryInitLunKey()

NTSTATUS RegistryInitLunKey ( _Inout_ PSCSI_PORT_LUN_EXTENSION  LunExtension)

Definition at line 359 of file registry.c.

361{
362 WCHAR nameBuffer[64];
363 UNICODE_STRING keyName;
364 UNICODE_STRING valueName;
365 OBJECT_ATTRIBUTES objectAttributes;
366 HANDLE targetKey;
368
369 // get the LUN's bus key
370 PSCSI_PORT_DEVICE_EXTENSION portExt = LunExtension->Common.LowerDevice->DeviceExtension;
371 HANDLE busKey = portExt->Buses[LunExtension->PathId].RegistryMapKey;
372
373 // create/open 'Target Id X' key
374 swprintf(nameBuffer, L"Target Id %lu", LunExtension->TargetId);
375 RtlInitUnicodeString(&keyName, nameBuffer);
376 InitializeObjectAttributes(&objectAttributes, &keyName, OBJ_KERNEL_HANDLE, busKey, NULL);
377 status = ZwCreateKey(&targetKey,
379 &objectAttributes,
380 0,
381 NULL,
383 NULL);
384 if (!NT_SUCCESS(status))
385 {
386 DPRINT("ZwCreateKey() failed (Status %lx)\n", status);
387 return status;
388 }
389
390 // Create 'Logical Unit Id X' key
391 swprintf(nameBuffer, L"Logical Unit Id %lu", LunExtension->Lun);
392 RtlInitUnicodeString(&keyName, nameBuffer);
393 InitializeObjectAttributes(&objectAttributes, &keyName, OBJ_KERNEL_HANDLE, targetKey, NULL);
394 status = ZwCreateKey(&LunExtension->RegistryMapKey,
396 &objectAttributes,
397 0,
398 NULL,
400 NULL);
401 if (!NT_SUCCESS(status))
402 {
403 DPRINT("ZwCreateKey() failed (Status %lx)\n", status);
404 goto ByeBye;
405 }
406
407 // Set 'Identifier' (REG_SZ) value
408 swprintf(nameBuffer,
409 L"%.8S%.16S%.4S",
410 LunExtension->InquiryData.VendorId,
411 LunExtension->InquiryData.ProductId,
412 LunExtension->InquiryData.ProductRevisionLevel);
413 RtlInitUnicodeString(&valueName, L"Identifier");
414 status = ZwSetValueKey(LunExtension->RegistryMapKey,
415 &valueName,
416 0,
417 REG_SZ,
418 nameBuffer,
419 (wcslen(nameBuffer) + 1) * sizeof(WCHAR));
420 if (!NT_SUCCESS(status))
421 {
422 DPRINT("ZwSetValueKey('Identifier') failed (Status %lx)\n", status);
423 goto ByeBye;
424 }
425
426 // Set 'Type' (REG_SZ) value
427 PWCHAR typeName = (PWCHAR)GetPeripheralTypeW(&LunExtension->InquiryData);
428 DPRINT(" Type = '%S'\n", typeName);
429 RtlInitUnicodeString(&valueName, L"Type");
430 status = ZwSetValueKey(LunExtension->RegistryMapKey,
431 &valueName,
432 0,
433 REG_SZ,
434 typeName,
435 (wcslen(typeName) + 1) * sizeof(WCHAR));
436 if (!NT_SUCCESS(status))
437 {
438 DPRINT("ZwSetValueKey('Type') failed (Status %lx)\n", status);
439 goto ByeBye;
440 }
441
442 // Set 'InquiryData' (REG_BINARY) value
443 RtlInitUnicodeString(&valueName, L"InquiryData");
444 status = ZwSetValueKey(LunExtension->RegistryMapKey,
445 &valueName,
446 0,
448 &LunExtension->InquiryData,
450 if (!NT_SUCCESS(status))
451 {
452 DPRINT("ZwSetValueKey('InquiryData') failed (Status %lx)\n", status);
453 goto ByeBye;
454 }
455
456ByeBye:
457 ZwClose(targetKey);
458 // TODO: maybe we will need it in future
459 ZwClose(LunExtension->RegistryMapKey);
460
461 return status;
462}
#define INQUIRYDATABUFFERSIZE
Definition: cdrw_hw.h:1113
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define REG_BINARY
Definition: nt_native.h:1496
FORCEINLINE PCWSTR GetPeripheralTypeW(_In_ PINQUIRYDATA InquiryData)
Definition: scsitypes.h:87

Referenced by PdoDispatchPnp().

◆ 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 404 of file ioctl.c.

407{
409 PSCSI_PORT_COMMON_EXTENSION comExt = DeviceObject->DeviceExtension;
413
414 DPRINT("ScsiPortDeviceControl()\n");
415
416 Irp->IoStatus.Information = 0;
417
419
420 switch (Stack->Parameters.DeviceIoControl.IoControlCode)
421 {
423 {
424 DPRINT(" IOCTL_STORAGE_QUERY_PROPERTY\n");
425
427 {
429 break;
430 }
431
432 if (comExt->IsFDO)
434 else
436 }
438 {
439 DPRINT(" IOCTL_SCSI_GET_ADDRESS\n");
440
441 if (comExt->IsFDO)
442 {
444 break;
445 }
446
447 PSCSI_ADDRESS address = Irp->AssociatedIrp.SystemBuffer;
448 if (!VerifyIrpOutBufferSize(Irp, sizeof(*address)))
449 {
451 break;
452 }
453
454 lunExt = DeviceObject->DeviceExtension;
455 portExt = comExt->LowerDevice->DeviceExtension;
456
457 address->Length = sizeof(SCSI_ADDRESS);
458 address->PortNumber = portExt->PortNumber;
459 address->PathId = lunExt->PathId;
460 address->TargetId = lunExt->TargetId;
461 address->Lun = lunExt->Lun;
462
463 Irp->IoStatus.Information = sizeof(SCSI_ADDRESS);
465 break;
466 }
468 {
469 DPRINT(" IOCTL_SCSI_GET_DUMP_POINTERS\n");
470
471 if (!comExt->IsFDO)
472 {
474 return IoCallDriver(comExt->LowerDevice, Irp);
475 }
476
477 PDUMP_POINTERS dumpPointers = Irp->AssociatedIrp.SystemBuffer;
478 if (!VerifyIrpOutBufferSize(Irp, sizeof(*dumpPointers)))
479 {
481 break;
482 }
483
484 dumpPointers->DeviceObject = DeviceObject;
485 /* More data.. ? */
486
488 Irp->IoStatus.Information = sizeof(DUMP_POINTERS);
489 break;
490 }
492 {
493 DPRINT(" IOCTL_SCSI_GET_CAPABILITIES\n");
494
495 if (!comExt->IsFDO)
496 {
498 break;
499 }
500
502 {
504 break;
505 }
506
507 portExt = DeviceObject->DeviceExtension;
508
509 RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
510 &portExt->PortCapabilities,
511 sizeof(IO_SCSI_CAPABILITIES));
512
514 Irp->IoStatus.Information = sizeof(IO_SCSI_CAPABILITIES);
515 break;
516 }
518 {
519 DPRINT(" IOCTL_SCSI_GET_INQUIRY_DATA\n");
520
521 if (!comExt->IsFDO)
522 {
524 break;
525 }
526
527 /* Copy inquiry data to the port device extension */
528 status = SpiGetInquiryData(DeviceObject->DeviceExtension, Irp);
529 break;
530 }
532 DPRINT1("IOCTL_SCSI_MINIPORT unimplemented!\n");
534 break;
535
537 DPRINT1("IOCTL_SCSI_PASS_THROUGH unimplemented!\n");
539 break;
540
541 default:
542 DPRINT1("unknown ioctl code: 0x%lX\n", Stack->Parameters.DeviceIoControl.IoControlCode);
544 break;
545 }
546
547 /* Complete the request with the given status */
548 Irp->IoStatus.Status = status;
550
551 return status;
552}
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
static NTSTATUS SpiGetInquiryData(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _In_ PIRP Irp)
Definition: ioctl.c:18
static NTSTATUS FdoHandleQueryProperty(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: ioctl.c:293
static NTSTATUS PdoHandleQueryProperty(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
Definition: ioctl.c:147
GLuint address
Definition: glext.h:9393
#define IOCTL_STORAGE_QUERY_PROPERTY
Definition: ntddstor.h:178
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
FORCEINLINE BOOLEAN VerifyIrpInBufferSize(_In_ PIRP Irp, _In_ SIZE_T Size)
Definition: partmgr.h:187
FORCEINLINE BOOLEAN VerifyIrpOutBufferSize(_In_ PIRP Irp, _In_ SIZE_T Size)
Definition: partmgr.h:172
#define IOCTL_SCSI_GET_DUMP_POINTERS
Definition: scsi_port.h:54
#define IOCTL_SCSI_PASS_THROUGH
Definition: scsi_port.h:47
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
#define IOCTL_SCSI_GET_CAPABILITIES
Definition: scsi_port.h:50
#define IOCTL_SCSI_MINIPORT
Definition: scsi_port.h:48
struct _SCSI_ADDRESS SCSI_ADDRESS
#define IOCTL_SCSI_GET_INQUIRY_DATA
Definition: scsi_port.h:49
struct _IO_SCSI_CAPABILITIES IO_SCSI_CAPABILITIES
struct _DUMP_POINTERS DUMP_POINTERS
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
IO_SCSI_CAPABILITIES PortCapabilities
Definition: scsiport.c:78
PVOID DeviceObject
Definition: ntddscsi.h:321
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639

Referenced by ScsiPortInitialize().

◆ SpiAdapterControl()

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

◆ SpiGetNextRequestFromLun()

VOID SpiGetNextRequestFromLun ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension,
_Inout_ PSCSI_PORT_LUN_EXTENSION  LunExtension,
_Inout_opt_ PKIRQL  OldIrql 
)

Definition at line 342 of file scsi.c.

347{
348 PIO_STACK_LOCATION IrpStack;
349 PIRP NextIrp;
352
353
354 /* If LUN is not active or queue is more than maximum allowed */
355 if (LunExtension->QueueCount >= LunExtension->MaxQueueCount ||
356 !(LunExtension->Flags & SCSI_PORT_LU_ACTIVE))
357 {
358 /* Release the spinlock and exit */
359 if (OldIrql != NULL)
360 KeReleaseSpinLock(&DeviceExtension->SpinLock, *OldIrql);
361 else
362 KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
363 return;
364 }
365
366 /* Check if we can get a next request */
367 if (LunExtension->Flags &
370 {
371 /* Pending requests can only be started if the queue is empty */
372 if (IsListEmpty(&LunExtension->SrbInfo.Requests) &&
373 !(LunExtension->Flags &
375 {
376 /* Make sure we have SRB */
377 ASSERT(LunExtension->SrbInfo.Srb == NULL);
378
379 /* Clear active and pending flags */
380 LunExtension->Flags &= ~(LUNEX_REQUEST_PENDING | SCSI_PORT_LU_ACTIVE);
381
382 /* Get next Irp, and clear pending requests list */
383 NextIrp = LunExtension->PendingRequest;
384 LunExtension->PendingRequest = NULL;
385
386 /* Set attempt counter to zero */
387 LunExtension->AttemptCount = 0;
388
389 /* Release the spinlock */
390 if (OldIrql != NULL)
391 KeReleaseSpinLock(&DeviceExtension->SpinLock, *OldIrql);
392 else
393 KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
394
395 /* Start the next pending request */
396 IoStartPacket(DeviceExtension->Common.DeviceObject, NextIrp, (PULONG)NULL, NULL);
397
398 return;
399 }
400 else
401 {
402 /* Release the spinlock, without clearing any flags and exit */
403 if (OldIrql != NULL)
404 KeReleaseSpinLock(&DeviceExtension->SpinLock, *OldIrql);
405 else
406 KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
407
408 return;
409 }
410 }
411
412 /* Reset active flag */
413 LunExtension->Flags &= ~SCSI_PORT_LU_ACTIVE;
414
415 /* Set attempt counter to zero */
416 LunExtension->AttemptCount = 0;
417
418 /* Remove packet from the device queue */
419 Entry = KeRemoveByKeyDeviceQueue(&LunExtension->DeviceQueue, LunExtension->SortKey);
420
421 if (Entry != NULL)
422 {
423 /* Get pointer to the next irp */
424 NextIrp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.DeviceQueueEntry);
425
426 /* Get point to the SRB */
427 IrpStack = IoGetCurrentIrpStackLocation(NextIrp);
428 Srb = (PSCSI_REQUEST_BLOCK)IrpStack->Parameters.Others.Argument1;
429
430 /* Set new key*/
431 LunExtension->SortKey = Srb->QueueSortKey;
432 LunExtension->SortKey++;
433
434 /* Release the spinlock */
435 if (OldIrql != NULL)
436 KeReleaseSpinLock(&DeviceExtension->SpinLock, *OldIrql);
437 else
438 KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
439
440 /* Start the next pending request */
441 IoStartPacket(DeviceExtension->Common.DeviceObject, NextIrp, (PULONG)NULL, NULL);
442 }
443 else
444 {
445 /* Release the spinlock */
446 if (OldIrql != NULL)
447 KeReleaseSpinLock(&DeviceExtension->SpinLock, *OldIrql);
448 else
449 KeReleaseSpinLockFromDpcLevel(&DeviceExtension->SpinLock);
450 }
451}
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: cdrom.h:989
PKDEVICE_QUEUE_ENTRY NTAPI KeRemoveByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue, IN ULONG SortKey)
Definition: devqueue.c:197
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
if(dx< 0)
Definition: linetemp.h:194
VOID NTAPI IoStartPacket(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key, IN PDRIVER_CANCEL CancelFunction)
Definition: device.c:1876
#define LUNEX_FULL_QUEUE
Definition: scsiport.h:49
#define LUNEX_BUSY
Definition: scsiport.h:48
#define LUNEX_FROZEN_QUEUE
Definition: scsiport.h:46
#define LUNEX_NEED_REQUEST_SENSE
Definition: scsiport.h:47
#define SCSI_PORT_LU_ACTIVE
Definition: scsiport.h:30
#define LUNEX_REQUEST_PENDING
Definition: scsiport.h:50
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135
base of all file and directory entries
Definition: entries.h:83
struct _IO_STACK_LOCATION::@3980::@4019 Others
Definition: ketypes.h:578
ULONG QueueSortKey
Definition: srb.h:270
uint32_t * PULONG
Definition: typedefs.h:59

Referenced by FdoSendInquiry(), ScsiPortDispatchScsi(), ScsiPortDpcForIsr(), SpiProcessCompletedRequest(), and SpiSenseCompletionRoutine().

◆ SpiGetSrbData()

PSCSI_REQUEST_BLOCK_INFO SpiGetSrbData ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension,
_In_ PSCSI_PORT_LUN_EXTENSION  LunExtension,
_In_ UCHAR  QueueTag 
)

Definition at line 102 of file pdo.c.

106{
107 if (QueueTag == SP_UNTAGGED)
108 {
109 /* Return the pointer to SrbInfo */
110 return &LunExtension->SrbInfo;
111 }
112 else
113 {
114 /* Make sure the tag is valid, if it is - return the data */
115 if (QueueTag > DeviceExtension->SrbDataCount || QueueTag < 1)
116 return NULL;
117 else
118 return &DeviceExtension->SrbInfo[QueueTag -1];
119 }
120}
#define SP_UNTAGGED
Definition: srb.h:233

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

◆ SpiInitOpenKeys()

VOID SpiInitOpenKeys ( _Inout_ PCONFIGURATION_INFO  ConfigInfo,
_In_ PSCSI_PORT_DRIVER_EXTENSION  DriverExtension 
)

Definition at line 18 of file registry.c.

21{
25 HANDLE parametersKey;
26
27 DriverExtension->IsLegacyDriver = TRUE;
28
29 /* Open the service key */
31 &DriverExtension->RegistryPath,
33 NULL,
34 NULL);
35
36 Status = ZwOpenKey(&ConfigInfo->ServiceKey, KEY_READ, &ObjectAttributes);
37
38 if (!NT_SUCCESS(Status))
39 {
40 DPRINT("Unable to open driver's registry key %wZ, status 0x%08x\n",
41 DriverExtension->RegistryPath, Status);
42 ConfigInfo->ServiceKey = NULL;
43 }
44
45 /* If we could open driver's service key, then proceed to the Parameters key */
46 if (ConfigInfo->ServiceKey != NULL)
47 {
48 RtlInitUnicodeString(&KeyName, L"Parameters");
50 &KeyName,
52 ConfigInfo->ServiceKey,
53 NULL);
54
55 /* Try to open it */
56 Status = ZwOpenKey(&ConfigInfo->DeviceKey, KEY_READ, &ObjectAttributes);
57
58 if (NT_SUCCESS(Status))
59 {
60 /* Yes, Parameters key exist, and it must be used instead of
61 the Service key */
62 ZwClose(ConfigInfo->ServiceKey);
63 ConfigInfo->ServiceKey = ConfigInfo->DeviceKey;
64 ConfigInfo->DeviceKey = NULL;
65 }
66 }
67
68 if (ConfigInfo->ServiceKey != NULL)
69 {
70 /* Open the Device key */
73 &KeyName,
75 ConfigInfo->ServiceKey,
76 NULL);
77
78 /* We don't check for failure here - not needed */
79 ZwOpenKey(&ConfigInfo->DeviceKey, KEY_READ, &ObjectAttributes);
80
81 // Detect the driver PnP capabilities via its Parameters\PnpInterface key
82 // for example: HKLM\SYSTEM\CurrentControlSet\Services\UNIATA\Parameters\PnpInterface
83
84 RtlInitUnicodeString(&KeyName, L"PnpInterface");
86 &KeyName,
88 ConfigInfo->ServiceKey,
89 NULL);
90
91 Status = ZwOpenKey(&parametersKey, KEY_READ, &ObjectAttributes);
92
93 if (NT_SUCCESS(Status))
94 {
95 // if the key exists, it's enough for us for now
96 // (the proper check should iterate over INTERFACE_TYPE values)
97 DriverExtension->IsLegacyDriver = FALSE;
98 ZwClose(parametersKey);
99 }
100 }
101}
#define KEY_READ
Definition: nt_native.h:1023
PPCI_DRIVER_EXTENSION DriverExtension
Definition: pci.c:31

Referenced by ScsiPortInitialize().

◆ VerifyIrpInBufferSize()

FORCEINLINE BOOLEAN VerifyIrpInBufferSize ( _In_ PIRP  Irp,
_In_ SIZE_T  Size 
)

Definition at line 356 of file scsiport.h.

359{
361 if (ioStack->Parameters.DeviceIoControl.InputBufferLength < Size)
362 {
363 Irp->IoStatus.Information = Size;
364 return FALSE;
365 }
366 return TRUE;
367}
struct _IO_STACK_LOCATION::@1581::@1582 DeviceIoControl
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

◆ VerifyIrpOutBufferSize()

FORCEINLINE BOOLEAN VerifyIrpOutBufferSize ( _In_ PIRP  Irp,
_In_ SIZE_T  Size 
)

Definition at line 341 of file scsiport.h.

344{
346 if (ioStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
347 {
348 Irp->IoStatus.Information = Size;
349 return FALSE;
350 }
351 return TRUE;
352}

Variable Documentation

◆ ScsiPortDispatchPower

DRIVER_DISPATCH ScsiPortDispatchPower

Definition at line 426 of file scsiport.h.

Referenced by ScsiPortInitialize().

◆ ScsiPortDispatchScsi

DRIVER_DISPATCH ScsiPortDispatchScsi

Definition at line 452 of file scsiport.h.

Referenced by ScsiPortInitialize().

◆ ScsiPortDpcForIsr

IO_DPC_ROUTINE ScsiPortDpcForIsr

Definition at line 451 of file scsiport.h.

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

◆ ScsiPortIsr

KSERVICE_ROUTINE ScsiPortIsr

Definition at line 459 of file scsiport.h.

Referenced by FdoCallHWInitialize().

◆ ScsiPortStartIo

DRIVER_STARTIO ScsiPortStartIo

Definition at line 454 of file scsiport.h.

Referenced by ScsiPortDpcForIsr(), and ScsiPortInitialize().

◆ ScsiPortStartPacket

KSYNCHRONIZE_ROUTINE ScsiPortStartPacket